From 647b8caeef402e990da5d2d1a3228aaa28ef664e Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Tue, 3 Aug 2021 14:13:13 -0700 Subject: [PATCH 01/58] [SYCL] Make device ids unique per backend We decided to make device id numbers unique per backend. Also, by adding the device_type into each device prefix listing in sycl-ls, the user can easily set SYCL_DEVICE_FILTER correctly. Future work: refactor devices and plafroms cache to optimize the device retrieval. Signed-off-by: Byoungro So --- sycl/include/CL/sycl/detail/device_filter.hpp | 3 + sycl/source/detail/config.hpp | 4 +- sycl/source/detail/device_filter.cpp | 56 ++++++++++++------- sycl/source/detail/filter_selector_impl.cpp | 30 ++-------- sycl/source/detail/pi.cpp | 6 ++ sycl/source/detail/platform_impl.cpp | 28 +++++++--- sycl/source/detail/plugin.hpp | 46 +++++++++++++++ sycl/tools/sycl-ls/sycl-ls.cpp | 53 ++++++++++-------- 8 files changed, 147 insertions(+), 79 deletions(-) diff --git a/sycl/include/CL/sycl/detail/device_filter.hpp b/sycl/include/CL/sycl/detail/device_filter.hpp index 746f7714e21a0..813c22282fb14 100644 --- a/sycl/include/CL/sycl/detail/device_filter.hpp +++ b/sycl/include/CL/sycl/detail/device_filter.hpp @@ -82,6 +82,9 @@ inline std::ostream &operator<<(std::ostream &Out, return Out; } +std::vector tokenize(const std::string &Filter, + const std::string &Delim); + } // namespace detail } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/source/detail/config.hpp b/sycl/source/detail/config.hpp index b19152c912b1f..42acec1e1e61c 100644 --- a/sycl/source/detail/config.hpp +++ b/sycl/source/detail/config.hpp @@ -186,11 +186,11 @@ static const std::array, 5> // Array is used by SYCL_DEVICE_FILTER and SYCL_DEVICE_ALLOWLIST static const std::array, 6> SyclBeMap = { - {{"host", backend::host}, - {"opencl", backend::opencl}, + {{"opencl", backend::opencl}, {"level_zero", backend::level_zero}, {"cuda", backend::cuda}, {"rocm", backend::rocm}, + {"host", backend::host}, {"*", backend::all}}}; template <> class SYCLConfig { diff --git a/sycl/source/detail/device_filter.cpp b/sycl/source/detail/device_filter.cpp index 3b0847d105571..49fa95c6921a9 100644 --- a/sycl/source/detail/device_filter.cpp +++ b/sycl/source/detail/device_filter.cpp @@ -17,60 +17,76 @@ __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { namespace detail { +std::vector tokenize(const std::string &Filter, + const std::string &Delim) { + std::vector Tokens; + size_t Pos = 0; + std::string Input = Filter; + std::string Tok; + + while ((Pos = Input.find(Delim)) != std::string::npos) { + Tok = Input.substr(0, Pos); + Input.erase(0, Pos + Delim.length()); + + if (!Tok.empty()) { + Tokens.push_back(std::move(Tok)); + } + } + + // Add remainder + if (!Input.empty()) + Tokens.push_back(std::move(Input)); + + return Tokens; +} + device_filter::device_filter(const std::string &FilterString) { - size_t Cursor = 0; - size_t ColonPos = 0; - auto findElement = [&](auto Element) { - size_t Found = FilterString.find(Element.first, Cursor); + std::vector Tokens = tokenize(FilterString, ":"); + size_t I = 0; + + auto FindElement = [&](auto Element) { + size_t Found = Tokens[I].find(Element.first); if (Found == std::string::npos) return false; - Cursor = Found; return true; }; // Handle the optional 1st field of the filter, backend // Check if the first entry matches with a known backend type auto It = - std::find_if(std::begin(SyclBeMap), std::end(SyclBeMap), findElement); + std::find_if(std::begin(SyclBeMap), std::end(SyclBeMap), FindElement); // If no match is found, set the backend type backend::all // which actually means 'any backend' will be a match. if (It == SyclBeMap.end()) Backend = backend::all; else { Backend = It->second; - ColonPos = FilterString.find(":", Cursor); - if (ColonPos != std::string::npos) - Cursor = ColonPos + 1; - else - Cursor = Cursor + It->first.size(); + I++; } + // Handle the optional 2nd field of the filter - device type. // Check if the 2nd entry matches with any known device type. - if (Cursor >= FilterString.size()) { + if (I >= Tokens.size()) { DeviceType = info::device_type::all; } else { auto Iter = std::find_if(std::begin(SyclDeviceTypeMap), - std::end(SyclDeviceTypeMap), findElement); + std::end(SyclDeviceTypeMap), FindElement); // If no match is found, set device_type 'all', // which actually means 'any device_type' will be a match. if (Iter == SyclDeviceTypeMap.end()) DeviceType = info::device_type::all; else { DeviceType = Iter->second; - ColonPos = FilterString.find(":", Cursor); - if (ColonPos != std::string::npos) - Cursor = ColonPos + 1; - else - Cursor = Cursor + Iter->first.size(); + I++; } } // Handle the optional 3rd field of the filter, device number // Try to convert the remaining string to an integer. // If succeessful, the converted integer is the desired device num. - if (Cursor < FilterString.size()) { + if (I < Tokens.size()) { try { - DeviceNum = stoi(FilterString.substr(Cursor)); + DeviceNum = stoi(Tokens[I]); HasDeviceNum = true; } catch (...) { std::string Message = diff --git a/sycl/source/detail/filter_selector_impl.cpp b/sycl/source/detail/filter_selector_impl.cpp index 78fe5c6651a0c..ef034cb9b659e 100644 --- a/sycl/source/detail/filter_selector_impl.cpp +++ b/sycl/source/detail/filter_selector_impl.cpp @@ -1,4 +1,4 @@ -//==------ filter_selector.cpp - oneapi filter selector --------------------==// +//==------ filter_selector.cpp - ONEAPI filter selector --------------------==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,35 +25,12 @@ namespace ext { namespace oneapi { namespace detail { -std::vector tokenize(const std::string &Filter, - const std::string &Delim) { - std::vector Tokens; - size_t Pos = 0; - std::string Input = Filter; - std::string Tok; - - while ((Pos = Input.find(Delim)) != std::string::npos) { - Tok = Input.substr(0, Pos); - Input.erase(0, Pos + Delim.length()); - - if (!Tok.empty()) { - Tokens.push_back(std::move(Tok)); - } - } - - // Add remainder - if (!Input.empty()) - Tokens.push_back(std::move(Input)); - - return Tokens; -} - filter create_filter(const std::string &Input) { filter Result; constexpr auto Error = "Invalid filter string! Valid strings conform to " "BE:DeviceType:DeviceNum, where any are optional"; - std::vector Tokens = tokenize(Input, ":"); + std::vector Tokens = sycl::detail::tokenize(Input, ":"); std::regex IntegerExpr("[[:digit:]]+"); // There should only be up to 3 tokens. @@ -107,7 +84,7 @@ filter create_filter(const std::string &Input) { filter_selector_impl::filter_selector_impl(const std::string &Input) : mFilters(), mRanker(), mNumDevicesSeen(0), mMatchFound(false) { - std::vector Filters = detail::tokenize(Input, ","); + std::vector Filters = sycl::detail::tokenize(Input, ","); mNumTotalDevices = device::get_devices().size(); for (const std::string &Filter : Filters) { @@ -189,5 +166,6 @@ void filter_selector_impl::reset() const { namespace __SYCL2020_DEPRECATED("use 'ext::oneapi' instead") ONEAPI { using namespace ext::oneapi; } + } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index 7db4a3f073704..142efc295277e 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -375,6 +375,12 @@ const std::vector &initialize() { initializePlugins(&GlobalHandler::instance().getPlugins()); }); + // reset LastDeviceIds to zeros + vector_class Plugins = GlobalHandler::instance().getPlugins(); + for (plugin Plugin : Plugins) { + Plugin.resetLastDeviceIds(); + } + return GlobalHandler::instance().getPlugins(); } diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 42a639dae7835..043c0ef6527b8 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -95,10 +95,8 @@ static bool IsBannedPlatform(platform Platform) { std::vector platform_impl::get_platforms() { std::vector Platforms; const std::vector &Plugins = RT::initialize(); - info::device_type ForcedType = detail::get_forced_type(); for (unsigned int i = 0; i < Plugins.size(); i++) { - pi_uint32 NumPlatforms = 0; // Move to the next plugin if the plugin fails to initialize. // This way platforms from other plugins get a chance to be discovered. @@ -115,6 +113,8 @@ std::vector platform_impl::get_platforms() { for (const auto &PiPlatform : PiPlatforms) { platform Platform = detail::createSyclObjFromImpl( getOrMakePlatformImpl(PiPlatform, Plugins[i])); + // insert PiPlatform into the Plugin + Plugins[i].getPlatformId(PiPlatform); // Skip platforms which do not contain requested device types if (!Platform.get_devices(ForcedType).empty() && !IsBannedPlatform(Platform)) @@ -140,14 +140,22 @@ std::vector platform_impl::get_platforms() { // This function matches devices in the order of backend, device_type, and // device_num. static void filterDeviceFilter(std::vector &PiDevices, - const plugin &Plugin) { + RT::PiPlatform Platform) { device_filter_list *FilterList = SYCLConfig::get(); if (!FilterList) return; - + const std::vector &Plugins = GlobalHandler::instance().getPlugins(); + unsigned I; + for (I = 0; I < Plugins.size(); I++) { + if (Plugins[I].containsPiPlatform(Platform)) + break; + } + const plugin &Plugin = Plugins[I]; backend Backend = Plugin.getBackend(); int InsertIDx = 0; - int DeviceNum = 0; + // DeviceIds should be given consecutive numbers across platforms in the same + // backend + int DeviceNum = Plugin.getStartingDeviceId(Platform); for (RT::PiDevice Device : PiDevices) { RT::PiDeviceType PiDevType; Plugin.call(Device, PI_DEVICE_INFO_TYPE, @@ -180,6 +188,10 @@ static void filterDeviceFilter(std::vector &PiDevices, DeviceNum++; } PiDevices.resize(InsertIDx); + // remember the last backend that has gone through this filter function + // to assign a unique device id number across platforms that belong to + // the same backend. For example, opencl:cpu:0, opencl:acc:1, opencl:gpu:2 + Plugin.setLastDeviceId(Platform, DeviceNum); } std::shared_ptr platform_impl::getOrMakeDeviceImpl( @@ -236,12 +248,12 @@ platform_impl::get_devices(info::device_type DeviceType) const { // Filter out devices that are not present in the SYCL_DEVICE_ALLOWLIST if (SYCLConfig::get()) - applyAllowList(PiDevices, MPlatform, this->getPlugin()); + applyAllowList(PiDevices, MPlatform, Plugin); // Filter out devices that are not compatible with SYCL_DEVICE_FILTER - filterDeviceFilter(PiDevices, Plugin); + filterDeviceFilter(PiDevices, MPlatform); - PlatformImplPtr PlatformImpl = getOrMakePlatformImpl(MPlatform, *MPlugin); + PlatformImplPtr PlatformImpl = getOrMakePlatformImpl(MPlatform, Plugin); std::transform( PiDevices.begin(), PiDevices.end(), std::back_inserter(Res), [PlatformImpl](const RT::PiDevice &PiDevice) -> device { diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index bfd614893f221..7ddcf77c32317 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -184,11 +184,57 @@ class plugin { void *getLibraryHandle() { return MLibraryHandle; } int unload() { return RT::unloadPlugin(MLibraryHandle); } + // return the index of PiPlatforms. + // If not found, add it and return its index. + int getPlatformId(RT::PiPlatform Platform) const { + auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); + if (It != PiPlatforms.end()) { + return It - PiPlatforms.begin(); + } else { + PiPlatforms.push_back(Platform); + LastDeviceIds.push_back(0); + return PiPlatforms.size() - 1; + } + } + // Device ids are consecutive across platforms within a plugin. + // We need to return the same starting index for the given platform. + // So, instead of returing the last device id of the given platform, + // return the last device id of the predecessor platform. + int getStartingDeviceId(RT::PiPlatform Platform) const { + int PlatformId = getPlatformId(Platform); + if (PlatformId == 0) + return 0; + else + return LastDeviceIds[PlatformId - 1]; + } + // set the id of the last device for the given platform + void setLastDeviceId(RT::PiPlatform Platform, int Id) const { + int PlatformId = getPlatformId(Platform); + LastDeviceIds[PlatformId] = Id; + } + // reset all last device ids to zeros + void resetLastDeviceIds() { + std::fill(LastDeviceIds.begin(), LastDeviceIds.end(), 0); + } + + bool containsPiPlatform(RT::PiPlatform Platform) const { + for (RT::PiPlatform Plt : PiPlatforms) { + if (Platform == Plt) + return true; + } + return false; + } + private: RT::PiPlugin MPlugin; backend MBackend; void *MLibraryHandle; // the handle returned from dlopen std::shared_ptr TracingMutex; + // vector of PiPlatforms that belong to this plugin + mutable std::vector PiPlatforms; + // represents the unique ids of the last device of each platform + // index of this vector corresponds to the index in PiPlatforms vector. + mutable std::vector LastDeviceIds; }; // class plugin } // namespace detail } // namespace sycl diff --git a/sycl/tools/sycl-ls/sycl-ls.cpp b/sycl/tools/sycl-ls/sycl-ls.cpp index a50371ed8c934..b9b38ca73e91b 100644 --- a/sycl/tools/sycl-ls/sycl-ls.cpp +++ b/sycl/tools/sycl-ls/sycl-ls.cpp @@ -38,44 +38,38 @@ class custom_selector : public device_selector { } }; -static void printDeviceInfo(const device &Device, const std::string &Prepend) { +std::string getDeviceTypeName(const device &Device) { auto DeviceType = Device.get_info(); - std::string DeviceTypeName; switch (DeviceType) { case info::device_type::cpu: - DeviceTypeName = "CPU "; - break; + return "cpu"; case info::device_type::gpu: - DeviceTypeName = "GPU "; - break; + return "gpu"; case info::device_type::host: - DeviceTypeName = "HOST"; - break; + return "host"; case info::device_type::accelerator: - DeviceTypeName = "ACC "; - break; + return "acc"; default: - DeviceTypeName = "UNKNOWN"; - break; + return "unknown"; } +} +static void printDeviceInfo(const device &Device, const std::string &Prepend) { auto DeviceVersion = Device.get_info(); auto DeviceName = Device.get_info(); auto DeviceVendor = Device.get_info(); auto DeviceDriverVersion = Device.get_info(); if (verbose) { - std::cout << Prepend << "Type : " << DeviceTypeName << std::endl; + std::cout << Prepend << "Type : " << getDeviceTypeName(Device) + << std::endl; std::cout << Prepend << "Version : " << DeviceVersion << std::endl; std::cout << Prepend << "Name : " << DeviceName << std::endl; std::cout << Prepend << "Vendor : " << DeviceVendor << std::endl; std::cout << Prepend << "Driver : " << DeviceDriverVersion << std::endl; } else { - auto DevicePlatform = Device.get_info(); - auto DevicePlatformName = DevicePlatform.get_info(); - std::cout << Prepend << DeviceTypeName << ": " << DevicePlatformName << " " - << DeviceVersion << " [" << DeviceDriverVersion << "]" - << std::endl; + std::cout << Prepend << " : " << DeviceName << " " << DeviceVersion << " [" + << DeviceDriverVersion << "]" << std::endl; } } @@ -83,8 +77,8 @@ static void printSelectorChoice(const device_selector &Selector, const std::string &Prepend) { try { const auto &Dev = device(Selector); - printDeviceInfo(Dev, Prepend); - + std::string DeviceTypeName = getDeviceTypeName(Dev); + printDeviceInfo(Dev, Prepend + DeviceTypeName); } catch (const cl::sycl::runtime_error &Exception) { // Truncate long string so it can fit in one-line std::string What = Exception.what(); @@ -106,14 +100,26 @@ int main(int argc, char **argv) { return EXIT_FAILURE; } + const char *filter = std::getenv("SYCL_DEVICE_FILTER"); + if (filter) { + std::cout << "Warning: SYCL_DEVICE_FILTER environment variable is set to " + << filter << "." << std::endl; + std::cout + << "To see the correct device id, please unset SYCL_DEVICE_FILTER." + << std::endl + << std::endl; + } + const auto &Platforms = platform::get_platforms(); if (verbose) std::cout << "Platforms: " << Platforms.size() << std::endl; uint32_t PlatformNum = 0; + // For each backend, device num starts at zero. + std::vector DeviceNums(static_cast(backend::all), 0); for (const auto &Platform : Platforms) { - uint32_t DeviceNum = 0; + backend Backend = Platform.get_backend(); ++PlatformNum; if (verbose) { auto PlatformVersion = Platform.get_info(); @@ -128,11 +134,12 @@ int main(int argc, char **argv) { if (verbose) std::cout << " Devices : " << Devices.size() << std::endl; for (const auto &Device : Devices) { + uint32_t DeviceNum = DeviceNums[(int)Backend]++; if (verbose) std::cout << " Device [#" << DeviceNum << "]:" << std::endl; else { - backend Backend = Platform.get_backend(); - std::cout << "[" << Backend << ":" << DeviceNum << "] "; + std::cout << "[" << Backend << ":" << getDeviceTypeName(Device) << ":" + << DeviceNum << "]"; } ++DeviceNum; printDeviceInfo(Device, verbose ? " " : ""); From 3054c5c790d04f9ee56cd27a8651629099ef227c Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Tue, 3 Aug 2021 16:46:18 -0700 Subject: [PATCH 02/58] revert the order of backend Signed-off-by: Byoungro So --- sycl/source/detail/config.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/source/detail/config.hpp b/sycl/source/detail/config.hpp index 42acec1e1e61c..b19152c912b1f 100644 --- a/sycl/source/detail/config.hpp +++ b/sycl/source/detail/config.hpp @@ -186,11 +186,11 @@ static const std::array, 5> // Array is used by SYCL_DEVICE_FILTER and SYCL_DEVICE_ALLOWLIST static const std::array, 6> SyclBeMap = { - {{"opencl", backend::opencl}, + {{"host", backend::host}, + {"opencl", backend::opencl}, {"level_zero", backend::level_zero}, {"cuda", backend::cuda}, {"rocm", backend::rocm}, - {"host", backend::host}, {"*", backend::all}}}; template <> class SYCLConfig { From d0a967541d203b827bcaad3f49a9c1633f89fd02 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 5 Aug 2021 16:00:36 -0700 Subject: [PATCH 03/58] fix cuda errors Signed-off-by: Byoungro So --- sycl/source/detail/platform_impl.cpp | 7 ++++--- sycl/source/detail/plugin.hpp | 30 +++++++++++++++++----------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 043c0ef6527b8..02fff5120de95 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -94,7 +94,8 @@ static bool IsBannedPlatform(platform Platform) { std::vector platform_impl::get_platforms() { std::vector Platforms; - const std::vector &Plugins = RT::initialize(); + RT::initialize(); + std::vector &Plugins = GlobalHandler::instance().getPlugins(); info::device_type ForcedType = detail::get_forced_type(); for (unsigned int i = 0; i < Plugins.size(); i++) { pi_uint32 NumPlatforms = 0; @@ -144,13 +145,13 @@ static void filterDeviceFilter(std::vector &PiDevices, device_filter_list *FilterList = SYCLConfig::get(); if (!FilterList) return; - const std::vector &Plugins = GlobalHandler::instance().getPlugins(); + std::vector &Plugins = GlobalHandler::instance().getPlugins(); unsigned I; for (I = 0; I < Plugins.size(); I++) { if (Plugins[I].containsPiPlatform(Platform)) break; } - const plugin &Plugin = Plugins[I]; + plugin &Plugin = Plugins[I]; backend Backend = Plugin.getBackend(); int InsertIDx = 0; // DeviceIds should be given consecutive numbers across platforms in the same diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 7ddcf77c32317..282584e6b9a54 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -186,21 +186,23 @@ class plugin { // return the index of PiPlatforms. // If not found, add it and return its index. - int getPlatformId(RT::PiPlatform Platform) const { - auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); - if (It != PiPlatforms.end()) { - return It - PiPlatforms.begin(); + int getPlatformId(RT::PiPlatform Platform) { + auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); + if (It != PiPlatforms->end()) { + return It - PiPlatforms->begin(); } else { - PiPlatforms.push_back(Platform); + PiPlatforms->push_back(Platform); LastDeviceIds.push_back(0); - return PiPlatforms.size() - 1; + return PiPlatforms->size() - 1; } } // Device ids are consecutive across platforms within a plugin. // We need to return the same starting index for the given platform. // So, instead of returing the last device id of the given platform, // return the last device id of the predecessor platform. - int getStartingDeviceId(RT::PiPlatform Platform) const { + int getStartingDeviceId(RT::PiPlatform Platform) { + if (PiPlatforms == nullptr) + PiPlatforms = new std::vector; int PlatformId = getPlatformId(Platform); if (PlatformId == 0) return 0; @@ -208,7 +210,7 @@ class plugin { return LastDeviceIds[PlatformId - 1]; } // set the id of the last device for the given platform - void setLastDeviceId(RT::PiPlatform Platform, int Id) const { + void setLastDeviceId(RT::PiPlatform Platform, int Id) { int PlatformId = getPlatformId(Platform); LastDeviceIds[PlatformId] = Id; } @@ -217,8 +219,12 @@ class plugin { std::fill(LastDeviceIds.begin(), LastDeviceIds.end(), 0); } - bool containsPiPlatform(RT::PiPlatform Platform) const { - for (RT::PiPlatform Plt : PiPlatforms) { + // Do not leave PiPlatform pointers so that they will not be + // released twice at the shutdown time. + void resetPiPlatforms() { PiPlatforms = nullptr; } + + bool containsPiPlatform(RT::PiPlatform Platform) { + for (RT::PiPlatform Plt : *PiPlatforms) { if (Platform == Plt) return true; } @@ -231,10 +237,10 @@ class plugin { void *MLibraryHandle; // the handle returned from dlopen std::shared_ptr TracingMutex; // vector of PiPlatforms that belong to this plugin - mutable std::vector PiPlatforms; + std::vector *PiPlatforms = nullptr; // represents the unique ids of the last device of each platform // index of this vector corresponds to the index in PiPlatforms vector. - mutable std::vector LastDeviceIds; + std::vector LastDeviceIds; }; // class plugin } // namespace detail } // namespace sycl From 4d3e6bef4a2997c5f9a4385fef4bc1e5d11a69de Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 5 Aug 2021 21:08:08 -0700 Subject: [PATCH 04/58] fix bugs Signed-off-by: Byoungro So --- sycl/source/detail/platform_impl.cpp | 6 ++++++ sycl/source/detail/plugin.hpp | 24 +++++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 02fff5120de95..4b218eb156a0c 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -146,11 +146,17 @@ static void filterDeviceFilter(std::vector &PiDevices, if (!FilterList) return; std::vector &Plugins = GlobalHandler::instance().getPlugins(); + if (Plugins.size() == 0) { + RT::initialize(); + } unsigned I; for (I = 0; I < Plugins.size(); I++) { if (Plugins[I].containsPiPlatform(Platform)) break; } + if (I == Plugins.size()) { + return; + } plugin &Plugin = Plugins[I]; backend Backend = Plugin.getBackend(); int InsertIDx = 0; diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 282584e6b9a54..f1df20da53a6f 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -187,13 +187,17 @@ class plugin { // return the index of PiPlatforms. // If not found, add it and return its index. int getPlatformId(RT::PiPlatform Platform) { - auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); - if (It != PiPlatforms->end()) { - return It - PiPlatforms->begin(); + if (PiPlatforms) { + auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); + if (It != PiPlatforms->end()) { + return It - PiPlatforms->begin(); + } else { + PiPlatforms->push_back(Platform); + LastDeviceIds.push_back(0); + return PiPlatforms->size() - 1; + } } else { - PiPlatforms->push_back(Platform); - LastDeviceIds.push_back(0); - return PiPlatforms->size() - 1; + return -1; } } // Device ids are consecutive across platforms within a plugin. @@ -224,9 +228,11 @@ class plugin { void resetPiPlatforms() { PiPlatforms = nullptr; } bool containsPiPlatform(RT::PiPlatform Platform) { - for (RT::PiPlatform Plt : *PiPlatforms) { - if (Platform == Plt) - return true; + if (PiPlatforms) { + for (RT::PiPlatform Plt : *PiPlatforms) { + if (Platform == Plt) + return true; + } } return false; } From 843c63d04764d831461a157075a117611daba6cd Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 5 Aug 2021 23:40:44 -0700 Subject: [PATCH 05/58] fix device_num test Signed-off-by: Byoungro So --- sycl/test/on-device/regression/device_num.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sycl/test/on-device/regression/device_num.cpp b/sycl/test/on-device/regression/device_num.cpp index 6fbfc093b8e89..c62c8f94d96a5 100644 --- a/sycl/test/on-device/regression/device_num.cpp +++ b/sycl/test/on-device/regression/device_num.cpp @@ -82,14 +82,12 @@ int main() { printDeviceType(d); assert(targetDevice == d && "The selected device is not the target device specified."); - } - // HOST device is always available regardless of SYCL_DEVICE_FILTER - { + } else if (targetDevice.is_host()) { host_selector hs; device d = hs.select_device(); std::cout << "host_selector selected "; printDeviceType(d); - assert(d.is_host() && "The selected device is not a host device."); + assert(targetDevice == d && "The selected device is not a host device."); } } return 0; From 0b6524d7e9d3cc8ad51a660fa9f2c06b807306b5 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Fri, 6 Aug 2021 16:22:37 -0700 Subject: [PATCH 06/58] update doc Signed-off-by: Byoungro So --- sycl/doc/EnvironmentVariables.md | 29 +++++++++---------- sycl/source/detail/filter_selector_impl.cpp | 3 +- sycl/source/detail/plugin.hpp | 32 +++++++++------------ 3 files changed, 28 insertions(+), 36 deletions(-) diff --git a/sycl/doc/EnvironmentVariables.md b/sycl/doc/EnvironmentVariables.md index 2fd2acf037367..c80ae04cf71df 100644 --- a/sycl/doc/EnvironmentVariables.md +++ b/sycl/doc/EnvironmentVariables.md @@ -32,7 +32,6 @@ subject to change. Do not rely on these variables in production code. | `SYCL_PI_LEVEL_ZERO_BATCH_SIZE` | Integer | Sets a preferred number of commands to batch into a command list before executing the command list. A value of 0 causes the batch size to be adjusted dynamically. A value greater than 0 specifies fixed size batching, with the batch size set to the specified value. The default is 0. | | `SYCL_PI_LEVEL_ZERO_FILTER_EVENT_WAIT_LIST` | Integer | When set to 0, disables filtering of signaled events from wait lists when using the Level Zero backend. The default is 1. | | `SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE` | Integer | Allows the use of copy engine, if available in the device, in Level Zero plugin to transfer SYCL buffer or image data between the host and/or device(s) and to fill SYCL buffer or image data in device or shared memory. The default is 1. | -| `SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE_FOR_D2D_COPY` (experimental) | Integer | Allows the use of copy engine, if available in the device, in Level Zero plugin for device to device copy operations. The default is 0. This option is experimental and will be removed once heuristics are added to make a decision about use of copy engine for device to device copy operations. | | `SYCL_PI_LEVEL_ZERO_TRACK_INDIRECT_ACCESS_MEMORY` | Any(\*) | Enable support of the kernels with indirect access and corresponding deferred release of memory allocations in the Level Zero plugin. | | `SYCL_PARALLEL_FOR_RANGE_ROUNDING_TRACE` | Any(\*) | Enables tracing of `parallel_for` invocations with rounded-up ranges. | | `SYCL_DISABLE_PARALLEL_FOR_RANGE_ROUNDING` | Any(\*) | Disables automatic rounding-up of `parallel_for` invocation ranges. | @@ -54,25 +53,25 @@ subject to change. Do not rely on these variables in production code. This environment variable limits the SYCL RT to use only a subset of the system's devices. Setting this environment variable affects all of the device query functions (`platform::get_devices()` and `platform::get_platforms()`) and all of the device selectors. -The value of this environment variable is a comma separated list of filters, where each filter is a triple of the form "`backend:device_type:device_num`" (without the quotes). Each element of the triple is optional, but each filter must have at least one value. Possible values of "backend" are: -- host +The value of this environment variable is a comma separated list of filters, where each filter is a triple of the form "`backend`:`device_type`:`device_num`" (without the quotes). Each element of the triple is optional, but each filter must have at least one value. Possible values of `backend` are: +- `host` - `level_zero` -- opencl -- cuda -- \* +- `opencl` +- `cuda` +- `*` -Possible values of "`device_type`" are: -- host -- cpu -- gpu -- acc -- \* +Possible values of `device_type` are: +- `host` +- `cpu` +- `gpu` +- `acc` +- `*` -`Device_num` is an integer that indexes the enumeration of devices from the sycl-ls utility tool, where the first device in that enumeration has index zero in each backend. For example, `SYCL_DEVICE_FILTER`=2 will return all devices with index '2' from all different backends. If multiple devices satisfy this device number (e.g., GPU and CPU devices can be assigned device number '2'), then default_selector will choose the device with the highest heuristic point. +`device_num` is an integer that indexes the enumeration of devices from the sycl-ls utility tool, where the first device in that enumeration has index zero in each backend. For example, `SYCL_DEVICE_FILTER=2` will return all devices with index '2' from all different backends. If multiple devices satisfy this device number (e.g., GPU and CPU devices can be assigned device number '2'), then default_selector will choose the device with the highest heuristic point. When `SYCL_DEVICE_ALLOWLIST` is set, it is applied before enumerating devices and affects `device_num` values. -Assuming a filter has all three elements of the triple, it selects only those devices that come from the given backend, have the specified device type, AND have the given device index. If more than one filter is specified, the RT is restricted to the union of devices selected by all filters. The RT does not include the "host" backend and the host device automatically unless one of the filters explicitly specifies the "host" device type. Therefore, `SYCL_DEVICE_FILTER`=host should be set to enforce SYCL to use the host device only. +Assuming a filter has all three elements of the triple, it selects only those devices that come from the given backend, have the specified device type, AND have the given device index. If more than one filter is specified, the RT is restricted to the union of devices selected by all filters. The RT does not include the `host` backend and the `host` device automatically unless one of the filters explicitly specifies the `host` device type. Therefore, `SYCL_DEVICE_FILTER=host` should be set to enforce SYCL to use the `host` device only. -Note that all device selectors will throw an exception if the filtered list of devices does not include a device that satisfies the selector. For instance, `SYCL_DEVICE_FILTER`=cpu,level_zero will cause host_selector() to throw an exception. `SYCL_DEVICE_FILTER` also limits loading only specified plugins into the SYCL RT. In particular, `SYCL_DEVICE_FILTER`=level_zero will cause the cpu_selector to throw an exception since SYCL RT will only load the level_zero backend which does not support any CPU devices at this time. When multiple devices satisfy the filter (e..g, `SYCL_DEVICE_FILTER`=gpu), only one of them will be selected. +Note that all device selectors will throw an exception if the filtered list of devices does not include a device that satisfies the selector. For instance, `SYCL_DEVICE_FILTER=cpu,level_zero` will cause `host_selector()` to throw an exception. `SYCL_DEVICE_FILTER` also limits loading only specified plugins into the SYCL RT. In particular, `SYCL_DEVICE_FILTER=level_zero` will cause the `cpu_selector` to throw an exception since SYCL RT will only load the `level_zero` backend which does not support any CPU devices at this time. When multiple devices satisfy the filter (e..g, `SYCL_DEVICE_FILTER=gpu`), only one of them will be selected. ### `SYCL_PRINT_EXECUTION_GRAPH` Options diff --git a/sycl/source/detail/filter_selector_impl.cpp b/sycl/source/detail/filter_selector_impl.cpp index ef034cb9b659e..8cc0f7e2b8352 100644 --- a/sycl/source/detail/filter_selector_impl.cpp +++ b/sycl/source/detail/filter_selector_impl.cpp @@ -1,4 +1,4 @@ -//==------ filter_selector.cpp - ONEAPI filter selector --------------------==// +//==------ filter_selector.cpp - oneapi filter selector --------------------==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -166,6 +166,5 @@ void filter_selector_impl::reset() const { namespace __SYCL2020_DEPRECATED("use 'ext::oneapi' instead") ONEAPI { using namespace ext::oneapi; } - } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index f1df20da53a6f..e63155173d6c6 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -187,17 +187,13 @@ class plugin { // return the index of PiPlatforms. // If not found, add it and return its index. int getPlatformId(RT::PiPlatform Platform) { - if (PiPlatforms) { - auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); - if (It != PiPlatforms->end()) { - return It - PiPlatforms->begin(); - } else { - PiPlatforms->push_back(Platform); - LastDeviceIds.push_back(0); - return PiPlatforms->size() - 1; - } + auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); + if (It != PiPlatforms.end()) { + return It - PiPlatforms.begin(); } else { - return -1; + PiPlatforms.push_back(Platform); + LastDeviceIds.push_back(0); + return PiPlatforms.size() - 1; } } // Device ids are consecutive across platforms within a plugin. @@ -205,8 +201,6 @@ class plugin { // So, instead of returing the last device id of the given platform, // return the last device id of the predecessor platform. int getStartingDeviceId(RT::PiPlatform Platform) { - if (PiPlatforms == nullptr) - PiPlatforms = new std::vector; int PlatformId = getPlatformId(Platform); if (PlatformId == 0) return 0; @@ -225,14 +219,14 @@ class plugin { // Do not leave PiPlatform pointers so that they will not be // released twice at the shutdown time. - void resetPiPlatforms() { PiPlatforms = nullptr; } + void resetPiPlatforms() { + std::fill(PiPlatforms.begin(), PiPlatforms.end(), nullptr); + } bool containsPiPlatform(RT::PiPlatform Platform) { - if (PiPlatforms) { - for (RT::PiPlatform Plt : *PiPlatforms) { - if (Platform == Plt) - return true; - } + for (RT::PiPlatform Plt : PiPlatforms) { + if (Platform == Plt) + return true; } return false; } @@ -243,7 +237,7 @@ class plugin { void *MLibraryHandle; // the handle returned from dlopen std::shared_ptr TracingMutex; // vector of PiPlatforms that belong to this plugin - std::vector *PiPlatforms = nullptr; + std::vector PiPlatforms; // represents the unique ids of the last device of each platform // index of this vector corresponds to the index in PiPlatforms vector. std::vector LastDeviceIds; From a7e25dcb1cb2eb5adcfe0880c82c70ddeb27a89d Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Fri, 6 Aug 2021 16:25:47 -0700 Subject: [PATCH 07/58] clang-format Signed-off-by: Byoungro So --- sycl/source/detail/plugin.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index e63155173d6c6..22c8e53bc3abd 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -219,8 +219,8 @@ class plugin { // Do not leave PiPlatform pointers so that they will not be // released twice at the shutdown time. - void resetPiPlatforms() { - std::fill(PiPlatforms.begin(), PiPlatforms.end(), nullptr); + void resetPiPlatforms() { + std::fill(PiPlatforms.begin(), PiPlatforms.end(), nullptr); } bool containsPiPlatform(RT::PiPlatform Platform) { From 64620b45b8e60647f49d1cd7fb3664ec2e486e7b Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Fri, 6 Aug 2021 21:10:03 -0700 Subject: [PATCH 08/58] revert Signed-off-by: Byoungro So --- sycl/source/detail/global_handler.cpp | 1 + sycl/source/detail/plugin.hpp | 31 +++++++++++++++++---------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/sycl/source/detail/global_handler.cpp b/sycl/source/detail/global_handler.cpp index 5b3647c6c920d..409431a60eceb 100644 --- a/sycl/source/detail/global_handler.cpp +++ b/sycl/source/detail/global_handler.cpp @@ -91,6 +91,7 @@ void shutdown() { // Currently, it is not used. void *PluginParameter = nullptr; Plugin.call(PluginParameter); + Plugin.resetPiPlatforms(); Plugin.unload(); } GlobalHandler::instance().MPlugins.Inst.reset(nullptr); diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 22c8e53bc3abd..ed8f9ce7aa910 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -187,13 +187,17 @@ class plugin { // return the index of PiPlatforms. // If not found, add it and return its index. int getPlatformId(RT::PiPlatform Platform) { - auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); - if (It != PiPlatforms.end()) { - return It - PiPlatforms.begin(); + if (PiPlatforms) { + auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); + if (It != PiPlatforms->end()) { + return It - PiPlatforms->begin(); + } else { + PiPlatforms->push_back(Platform); + LastDeviceIds.push_back(0); + return PiPlatforms->size() - 1; + } } else { - PiPlatforms.push_back(Platform); - LastDeviceIds.push_back(0); - return PiPlatforms.size() - 1; + return -1; } } // Device ids are consecutive across platforms within a plugin. @@ -201,6 +205,8 @@ class plugin { // So, instead of returing the last device id of the given platform, // return the last device id of the predecessor platform. int getStartingDeviceId(RT::PiPlatform Platform) { + if (!PiPlatforms) + PiPlatforms = new std::vector; int PlatformId = getPlatformId(Platform); if (PlatformId == 0) return 0; @@ -220,13 +226,16 @@ class plugin { // Do not leave PiPlatform pointers so that they will not be // released twice at the shutdown time. void resetPiPlatforms() { - std::fill(PiPlatforms.begin(), PiPlatforms.end(), nullptr); + delete PiPlatforms; + PiPlatforms = nullptr; } bool containsPiPlatform(RT::PiPlatform Platform) { - for (RT::PiPlatform Plt : PiPlatforms) { - if (Platform == Plt) - return true; + if (PiPlatforms) { + for (RT::PiPlatform Plt : *PiPlatforms) { + if (Platform == Plt) + return true; + } } return false; } @@ -237,7 +246,7 @@ class plugin { void *MLibraryHandle; // the handle returned from dlopen std::shared_ptr TracingMutex; // vector of PiPlatforms that belong to this plugin - std::vector PiPlatforms; + std::vector *PiPlatforms = nullptr; // represents the unique ids of the last device of each platform // index of this vector corresponds to the index in PiPlatforms vector. std::vector LastDeviceIds; From 846e2d0ce7de4e5117cd41811cc7632322c3d797 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Tue, 17 Aug 2021 11:35:35 -0700 Subject: [PATCH 09/58] update Signed-off-by: Byoungro So --- sycl/source/detail/device_filter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sycl/source/detail/device_filter.cpp b/sycl/source/detail/device_filter.cpp index 0ed50c3939f2d..b4d15d0d35694 100644 --- a/sycl/source/detail/device_filter.cpp +++ b/sycl/source/detail/device_filter.cpp @@ -54,7 +54,6 @@ device_filter::device_filter(const std::string &FilterString) { // Handle the optional 1st field of the filter, backend // Check if the first entry matches with a known backend type auto It = std::find_if(std::begin(getSyclBeMap()), std::end(getSyclBeMap()), - std::find_if(std::begin(SyclBeMap), std::end(SyclBeMap), FindElement); FindElement); // If no match is found, set the backend type backend::all // which actually means 'any backend' will be a match. From 9fd42426b115e9a156cc87533e8bcc22903605a1 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Wed, 18 Aug 2021 18:01:35 -0700 Subject: [PATCH 10/58] Update sycl/source/detail/platform_impl.cpp Co-authored-by: Alexey Bader --- sycl/source/detail/platform_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 4b218eb156a0c..5859a34950275 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -146,9 +146,9 @@ static void filterDeviceFilter(std::vector &PiDevices, if (!FilterList) return; std::vector &Plugins = GlobalHandler::instance().getPlugins(); - if (Plugins.size() == 0) { + if (Plugins.size() == 0) RT::initialize(); - } + unsigned I; for (I = 0; I < Plugins.size(); I++) { if (Plugins[I].containsPiPlatform(Platform)) From 0b32652de7998bc5fd6b5385e58dc7ccc36d9974 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Wed, 18 Aug 2021 18:02:01 -0700 Subject: [PATCH 11/58] Update sycl/source/detail/platform_impl.cpp Co-authored-by: Alexey Bader --- sycl/source/detail/platform_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 5859a34950275..13918623e846c 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -154,9 +154,9 @@ static void filterDeviceFilter(std::vector &PiDevices, if (Plugins[I].containsPiPlatform(Platform)) break; } - if (I == Plugins.size()) { + if (I == Plugins.size()) return; - } + plugin &Plugin = Plugins[I]; backend Backend = Plugin.getBackend(); int InsertIDx = 0; From cc0310b600c9e1198d2136898654aea6a7743566 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Wed, 18 Aug 2021 18:04:06 -0700 Subject: [PATCH 12/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Alexey Bader --- sycl/source/detail/plugin.hpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index ed8f9ce7aa910..7246937e02213 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -189,16 +189,15 @@ class plugin { int getPlatformId(RT::PiPlatform Platform) { if (PiPlatforms) { auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); - if (It != PiPlatforms->end()) { + if (It != PiPlatforms->end()) return It - PiPlatforms->begin(); - } else { - PiPlatforms->push_back(Platform); - LastDeviceIds.push_back(0); - return PiPlatforms->size() - 1; - } - } else { - return -1; + + PiPlatforms->push_back(Platform); + LastDeviceIds.push_back(0); + return PiPlatforms->size() - 1; } + + return -1; } // Device ids are consecutive across platforms within a plugin. // We need to return the same starting index for the given platform. From cf2403d32b6925515808d6d54ea210ee81f6d2ec Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Wed, 18 Aug 2021 18:04:17 -0700 Subject: [PATCH 13/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Alexey Bader --- sycl/source/detail/plugin.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 7246937e02213..885a9175b6433 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -209,8 +209,8 @@ class plugin { int PlatformId = getPlatformId(Platform); if (PlatformId == 0) return 0; - else - return LastDeviceIds[PlatformId - 1]; + + return LastDeviceIds[PlatformId - 1]; } // set the id of the last device for the given platform void setLastDeviceId(RT::PiPlatform Platform, int Id) { From 258db05404e5d9888c8dbcedee8a6a8d0edfdfc5 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Wed, 18 Aug 2021 18:05:42 -0700 Subject: [PATCH 14/58] add missed env var Signed-off-by: Byoungro So --- sycl/doc/EnvironmentVariables.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sycl/doc/EnvironmentVariables.md b/sycl/doc/EnvironmentVariables.md index c80ae04cf71df..bc7c3278f93b4 100644 --- a/sycl/doc/EnvironmentVariables.md +++ b/sycl/doc/EnvironmentVariables.md @@ -32,6 +32,7 @@ subject to change. Do not rely on these variables in production code. | `SYCL_PI_LEVEL_ZERO_BATCH_SIZE` | Integer | Sets a preferred number of commands to batch into a command list before executing the command list. A value of 0 causes the batch size to be adjusted dynamically. A value greater than 0 specifies fixed size batching, with the batch size set to the specified value. The default is 0. | | `SYCL_PI_LEVEL_ZERO_FILTER_EVENT_WAIT_LIST` | Integer | When set to 0, disables filtering of signaled events from wait lists when using the Level Zero backend. The default is 1. | | `SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE` | Integer | Allows the use of copy engine, if available in the device, in Level Zero plugin to transfer SYCL buffer or image data between the host and/or device(s) and to fill SYCL buffer or image data in device or shared memory. The default is 1. | +| `SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE_FOR_D2D_COPY` (experimental) | Integer | Allows the use of copy engine, if available in the device, in Level Zero plugin for device to device copy operations. The default is 0. This option is experimental and will be removed once heuristics are added to make a decision about use of copy engine for device to device copy operations. | | `SYCL_PI_LEVEL_ZERO_TRACK_INDIRECT_ACCESS_MEMORY` | Any(\*) | Enable support of the kernels with indirect access and corresponding deferred release of memory allocations in the Level Zero plugin. | | `SYCL_PARALLEL_FOR_RANGE_ROUNDING_TRACE` | Any(\*) | Enables tracing of `parallel_for` invocations with rounded-up ranges. | | `SYCL_DISABLE_PARALLEL_FOR_RANGE_ROUNDING` | Any(\*) | Disables automatic rounding-up of `parallel_for` invocation ranges. | From 4581603e50c677d2f4557020e448accb73379886 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Mon, 23 Aug 2021 11:18:07 -0700 Subject: [PATCH 15/58] Update sycl/source/detail/device_filter.cpp Co-authored-by: Romanov Vlad --- sycl/source/detail/device_filter.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sycl/source/detail/device_filter.cpp b/sycl/source/detail/device_filter.cpp index b4d15d0d35694..f277e9a163b8a 100644 --- a/sycl/source/detail/device_filter.cpp +++ b/sycl/source/detail/device_filter.cpp @@ -45,9 +45,7 @@ device_filter::device_filter(const std::string &FilterString) { size_t I = 0; auto FindElement = [&](auto Element) { - size_t Found = Tokens[I].find(Element.first); - if (Found == std::string::npos) - return false; + return std::string::npos != Tokens[I].find(Element.first); return true; }; From c8d214c7e06e63e1c85d9752357a9b87ee211d00 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Mon, 23 Aug 2021 11:26:45 -0700 Subject: [PATCH 16/58] Update sycl/source/detail/pi.cpp Co-authored-by: Romanov Vlad --- sycl/source/detail/pi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index 142efc295277e..f6f84a4c23fd0 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -376,8 +376,8 @@ const std::vector &initialize() { }); // reset LastDeviceIds to zeros - vector_class Plugins = GlobalHandler::instance().getPlugins(); - for (plugin Plugin : Plugins) { + vector_class &Plugins = GlobalHandler::instance().getPlugins(); + for (plugin &Plugin : Plugins) { Plugin.resetLastDeviceIds(); } From d0497c5f7e0a88f382ee8482db806245006de614 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Mon, 23 Aug 2021 11:28:51 -0700 Subject: [PATCH 17/58] Update sycl/source/detail/device_filter.cpp Co-authored-by: Alexey Bader --- sycl/source/detail/device_filter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sycl/source/detail/device_filter.cpp b/sycl/source/detail/device_filter.cpp index f277e9a163b8a..f67aaf2524911 100644 --- a/sycl/source/detail/device_filter.cpp +++ b/sycl/source/detail/device_filter.cpp @@ -46,7 +46,6 @@ device_filter::device_filter(const std::string &FilterString) { auto FindElement = [&](auto Element) { return std::string::npos != Tokens[I].find(Element.first); - return true; }; // Handle the optional 1st field of the filter, backend From 17fd9cd1929c17b42696e64c77c8bf4ab72dd96b Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Mon, 23 Aug 2021 11:50:13 -0700 Subject: [PATCH 18/58] Update sycl/source/detail/device_filter.cpp Co-authored-by: Romanov Vlad --- sycl/source/detail/device_filter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/source/detail/device_filter.cpp b/sycl/source/detail/device_filter.cpp index f67aaf2524911..1b71869577ea3 100644 --- a/sycl/source/detail/device_filter.cpp +++ b/sycl/source/detail/device_filter.cpp @@ -42,7 +42,7 @@ std::vector tokenize(const std::string &Filter, device_filter::device_filter(const std::string &FilterString) { std::vector Tokens = tokenize(FilterString, ":"); - size_t I = 0; + size_t TripleValueID = 0; auto FindElement = [&](auto Element) { return std::string::npos != Tokens[I].find(Element.first); From 8ba9a745973ef603a617db6a53e00d3df069f1b3 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Mon, 23 Aug 2021 17:43:00 -0700 Subject: [PATCH 19/58] address feedback Signed-off-by: Byoungro So --- sycl/source/detail/device_filter.cpp | 12 ++++++------ sycl/source/detail/platform_impl.cpp | 13 ++++++------- sycl/source/detail/plugin.hpp | 7 +++---- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/sycl/source/detail/device_filter.cpp b/sycl/source/detail/device_filter.cpp index 1b71869577ea3..d6061b9422265 100644 --- a/sycl/source/detail/device_filter.cpp +++ b/sycl/source/detail/device_filter.cpp @@ -45,7 +45,7 @@ device_filter::device_filter(const std::string &FilterString) { size_t TripleValueID = 0; auto FindElement = [&](auto Element) { - return std::string::npos != Tokens[I].find(Element.first); + return std::string::npos != Tokens[TripleValueID].find(Element.first); }; // Handle the optional 1st field of the filter, backend @@ -58,12 +58,12 @@ device_filter::device_filter(const std::string &FilterString) { Backend = backend::all; else { Backend = It->second; - I++; + TripleValueID++; } // Handle the optional 2nd field of the filter - device type. // Check if the 2nd entry matches with any known device type. - if (I >= Tokens.size()) { + if (TripleValueID >= Tokens.size()) { DeviceType = info::device_type::all; } else { auto Iter = std::find_if(std::begin(getSyclDeviceTypeMap()), @@ -74,16 +74,16 @@ device_filter::device_filter(const std::string &FilterString) { DeviceType = info::device_type::all; else { DeviceType = Iter->second; - I++; + TripleValueID++; } } // Handle the optional 3rd field of the filter, device number // Try to convert the remaining string to an integer. // If succeessful, the converted integer is the desired device num. - if (I < Tokens.size()) { + if (TripleValueID < Tokens.size()) { try { - DeviceNum = stoi(Tokens[I]); + DeviceNum = stoi(Tokens[TripleValueID]); HasDeviceNum = true; } catch (...) { std::string Message = diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 13918623e846c..af5f2b2c034ff 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -149,15 +149,14 @@ static void filterDeviceFilter(std::vector &PiDevices, if (Plugins.size() == 0) RT::initialize(); - unsigned I; - for (I = 0; I < Plugins.size(); I++) { - if (Plugins[I].containsPiPlatform(Platform)) - break; - } - if (I == Plugins.size()) + auto It = + std::find_if(Plugins.begin(), Plugins.end(), [Platform](plugin &Plugin) { + return Plugin.containsPiPlatform(Platform); + }); + if (It == Plugins.end()) return; - plugin &Plugin = Plugins[I]; + plugin &Plugin = *It; backend Backend = Plugin.getBackend(); int InsertIDx = 0; // DeviceIds should be given consecutive numbers across platforms in the same diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 885a9175b6433..033069b4fcdd0 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -231,10 +231,9 @@ class plugin { bool containsPiPlatform(RT::PiPlatform Platform) { if (PiPlatforms) { - for (RT::PiPlatform Plt : *PiPlatforms) { - if (Platform == Plt) - return true; - } + auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); + if (It != PiPlatforms->end()) + return true; } return false; } From b02c8bf16b1d6a16c95bce4797f60d824cdc167e Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Mon, 30 Aug 2021 23:05:21 -0700 Subject: [PATCH 20/58] make thread-safe Signed-off-by: Byoungro So --- sycl/include/CL/sycl/detail/device_filter.hpp | 3 -- sycl/source/detail/device_filter.cpp | 32 +++++++++-------- sycl/source/detail/filter_selector_impl.cpp | 27 ++++++++++++-- sycl/source/detail/global_handler.cpp | 5 ++- sycl/source/detail/global_handler.hpp | 2 ++ sycl/source/detail/pi.cpp | 2 ++ sycl/source/detail/platform_impl.cpp | 2 ++ sycl/source/detail/plugin.hpp | 35 ++++++------------- 8 files changed, 62 insertions(+), 46 deletions(-) diff --git a/sycl/include/CL/sycl/detail/device_filter.hpp b/sycl/include/CL/sycl/detail/device_filter.hpp index 813c22282fb14..746f7714e21a0 100644 --- a/sycl/include/CL/sycl/detail/device_filter.hpp +++ b/sycl/include/CL/sycl/detail/device_filter.hpp @@ -82,9 +82,6 @@ inline std::ostream &operator<<(std::ostream &Out, return Out; } -std::vector tokenize(const std::string &Filter, - const std::string &Delim); - } // namespace detail } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/source/detail/device_filter.cpp b/sycl/source/detail/device_filter.cpp index d6061b9422265..c8c933c6fca7b 100644 --- a/sycl/source/detail/device_filter.cpp +++ b/sycl/source/detail/device_filter.cpp @@ -12,36 +12,38 @@ #include #include +#include __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { namespace detail { -std::vector tokenize(const std::string &Filter, - const std::string &Delim) { - std::vector Tokens; +std::vector tokenize(const std::string &Filter, + const std::string &Delim) { + std::vector Tokens; size_t Pos = 0; - std::string Input = Filter; - std::string Tok; + size_t LastPos = 0; - while ((Pos = Input.find(Delim)) != std::string::npos) { - Tok = Input.substr(0, Pos); - Input.erase(0, Pos + Delim.length()); + while ((Pos = Filter.find(Delim, LastPos)) != std::string::npos) { + std::string_view Tok(Filter.data() + LastPos, (Pos - LastPos)); if (!Tok.empty()) { - Tokens.push_back(std::move(Tok)); + Tokens.push_back(Tok); } + // move the search starting index + LastPos = Pos + 1; } - // Add remainder - if (!Input.empty()) - Tokens.push_back(std::move(Input)); - + // Add remainder if any + if (LastPos < Filter.size()) { + std::string_view Tok(Filter.data() + LastPos, Filter.size() - LastPos); + Tokens.push_back(Tok); + } return Tokens; } device_filter::device_filter(const std::string &FilterString) { - std::vector Tokens = tokenize(FilterString, ":"); + std::vector Tokens = tokenize(FilterString, ":"); size_t TripleValueID = 0; auto FindElement = [&](auto Element) { @@ -83,7 +85,7 @@ device_filter::device_filter(const std::string &FilterString) { // If succeessful, the converted integer is the desired device num. if (TripleValueID < Tokens.size()) { try { - DeviceNum = stoi(Tokens[TripleValueID]); + DeviceNum = std::stoi(Tokens[TripleValueID].data()); HasDeviceNum = true; } catch (...) { std::string Message = diff --git a/sycl/source/detail/filter_selector_impl.cpp b/sycl/source/detail/filter_selector_impl.cpp index 8cc0f7e2b8352..78fe5c6651a0c 100644 --- a/sycl/source/detail/filter_selector_impl.cpp +++ b/sycl/source/detail/filter_selector_impl.cpp @@ -25,12 +25,35 @@ namespace ext { namespace oneapi { namespace detail { +std::vector tokenize(const std::string &Filter, + const std::string &Delim) { + std::vector Tokens; + size_t Pos = 0; + std::string Input = Filter; + std::string Tok; + + while ((Pos = Input.find(Delim)) != std::string::npos) { + Tok = Input.substr(0, Pos); + Input.erase(0, Pos + Delim.length()); + + if (!Tok.empty()) { + Tokens.push_back(std::move(Tok)); + } + } + + // Add remainder + if (!Input.empty()) + Tokens.push_back(std::move(Input)); + + return Tokens; +} + filter create_filter(const std::string &Input) { filter Result; constexpr auto Error = "Invalid filter string! Valid strings conform to " "BE:DeviceType:DeviceNum, where any are optional"; - std::vector Tokens = sycl::detail::tokenize(Input, ":"); + std::vector Tokens = tokenize(Input, ":"); std::regex IntegerExpr("[[:digit:]]+"); // There should only be up to 3 tokens. @@ -84,7 +107,7 @@ filter create_filter(const std::string &Input) { filter_selector_impl::filter_selector_impl(const std::string &Input) : mFilters(), mRanker(), mNumDevicesSeen(0), mMatchFound(false) { - std::vector Filters = sycl::detail::tokenize(Input, ","); + std::vector Filters = detail::tokenize(Input, ","); mNumTotalDevices = device::get_devices().size(); for (const std::string &Filter : Filters) { diff --git a/sycl/source/detail/global_handler.cpp b/sycl/source/detail/global_handler.cpp index 409431a60eceb..cd04d5dfea4a1 100644 --- a/sycl/source/detail/global_handler.cpp +++ b/sycl/source/detail/global_handler.cpp @@ -75,6 +75,10 @@ std::mutex &GlobalHandler::getHandlerExtendedMembersMutex() { return getOrCreate(MHandlerExtendedMembersMutex); } +std::mutex &GlobalHandler::getPluginsMutex() { + return getOrCreate(MPluginsMutex); +} + void shutdown() { // First, release resources, that may access plugins. GlobalHandler::instance().MScheduler.Inst.reset(nullptr); @@ -91,7 +95,6 @@ void shutdown() { // Currently, it is not used. void *PluginParameter = nullptr; Plugin.call(PluginParameter); - Plugin.resetPiPlatforms(); Plugin.unload(); } GlobalHandler::instance().MPlugins.Inst.reset(nullptr); diff --git a/sycl/source/detail/global_handler.hpp b/sycl/source/detail/global_handler.hpp index 9e3e3305c1f19..209bc9a04ecf3 100644 --- a/sycl/source/detail/global_handler.hpp +++ b/sycl/source/detail/global_handler.hpp @@ -57,6 +57,7 @@ class GlobalHandler { std::vector &getPlugins(); device_filter_list &getDeviceFilterList(const std::string &InitValue); std::mutex &getHandlerExtendedMembersMutex(); + std::mutex &getPluginsMutex(); private: friend void shutdown(); @@ -81,6 +82,7 @@ class GlobalHandler { InstWithLock MPlatformMapMutex; InstWithLock MFilterMutex; InstWithLock> MPlugins; + InstWithLock MPluginsMutex; InstWithLock MDeviceFilterList; // The mutex for synchronizing accesses to handlers extended members InstWithLock MHandlerExtendedMembersMutex; diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index f6f84a4c23fd0..4a7271e9460b8 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -370,6 +370,8 @@ bool trace(TraceLevel Level) { // Initializes all available Plugins. const std::vector &initialize() { static std::once_flag PluginsInitDone; + const std::lock_guard Guard( + GlobalHandler::instance().getPluginsMutex()); std::call_once(PluginsInitDone, []() { initializePlugins(&GlobalHandler::instance().getPlugins()); diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index af5f2b2c034ff..cd0bf2d86e816 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -145,6 +145,8 @@ static void filterDeviceFilter(std::vector &PiDevices, device_filter_list *FilterList = SYCLConfig::get(); if (!FilterList) return; + const std::lock_guard Guard( + GlobalHandler::instance().getPluginsMutex()); std::vector &Plugins = GlobalHandler::instance().getPlugins(); if (Plugins.size() == 0) RT::initialize(); diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 033069b4fcdd0..253fd66d469c9 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -187,25 +187,19 @@ class plugin { // return the index of PiPlatforms. // If not found, add it and return its index. int getPlatformId(RT::PiPlatform Platform) { - if (PiPlatforms) { - auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); - if (It != PiPlatforms->end()) - return It - PiPlatforms->begin(); - - PiPlatforms->push_back(Platform); - LastDeviceIds.push_back(0); - return PiPlatforms->size() - 1; - } + auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); + if (It != PiPlatforms.end()) + return It - PiPlatforms.begin(); - return -1; + PiPlatforms.push_back(Platform); + LastDeviceIds.push_back(0); + return PiPlatforms.size() - 1; } // Device ids are consecutive across platforms within a plugin. // We need to return the same starting index for the given platform. // So, instead of returing the last device id of the given platform, // return the last device id of the predecessor platform. int getStartingDeviceId(RT::PiPlatform Platform) { - if (!PiPlatforms) - PiPlatforms = new std::vector; int PlatformId = getPlatformId(Platform); if (PlatformId == 0) return 0; @@ -222,19 +216,10 @@ class plugin { std::fill(LastDeviceIds.begin(), LastDeviceIds.end(), 0); } - // Do not leave PiPlatform pointers so that they will not be - // released twice at the shutdown time. - void resetPiPlatforms() { - delete PiPlatforms; - PiPlatforms = nullptr; - } - bool containsPiPlatform(RT::PiPlatform Platform) { - if (PiPlatforms) { - auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); - if (It != PiPlatforms->end()) - return true; - } + auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); + if (It != PiPlatforms.end()) + return true; return false; } @@ -244,7 +229,7 @@ class plugin { void *MLibraryHandle; // the handle returned from dlopen std::shared_ptr TracingMutex; // vector of PiPlatforms that belong to this plugin - std::vector *PiPlatforms = nullptr; + std::vector PiPlatforms; // represents the unique ids of the last device of each platform // index of this vector corresponds to the index in PiPlatforms vector. std::vector LastDeviceIds; From 3f51214005250bb0081762178a70e731dda080fe Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Tue, 31 Aug 2021 15:53:48 -0700 Subject: [PATCH 21/58] fix cuda issue Signed-off-by: Byoungro So --- sycl/source/detail/global_handler.cpp | 1 + sycl/source/detail/plugin.hpp | 34 ++++++++++++++++++--------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/sycl/source/detail/global_handler.cpp b/sycl/source/detail/global_handler.cpp index 8ff39b69da77a..fed42f4ffa410 100644 --- a/sycl/source/detail/global_handler.cpp +++ b/sycl/source/detail/global_handler.cpp @@ -100,6 +100,7 @@ void shutdown() { // Currently, it is not used. void *PluginParameter = nullptr; Plugin.call(PluginParameter); + Plugin.resetPiPlatforms(); Plugin.unload(); } GlobalHandler::instance().MPlugins.Inst.reset(nullptr); diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 253fd66d469c9..3a8111901bbc5 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -187,19 +187,24 @@ class plugin { // return the index of PiPlatforms. // If not found, add it and return its index. int getPlatformId(RT::PiPlatform Platform) { - auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); - if (It != PiPlatforms.end()) - return It - PiPlatforms.begin(); - - PiPlatforms.push_back(Platform); - LastDeviceIds.push_back(0); - return PiPlatforms.size() - 1; + if (PiPlatforms) { + auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); + if (It != PiPlatforms->end()) + return It - PiPlatforms->begin(); + + PiPlatforms->push_back(Platform); + LastDeviceIds.push_back(0); + return PiPlatforms->size() - 1; + } + return -1; } // Device ids are consecutive across platforms within a plugin. // We need to return the same starting index for the given platform. // So, instead of returing the last device id of the given platform, // return the last device id of the predecessor platform. int getStartingDeviceId(RT::PiPlatform Platform) { + if (!PiPlatforms) + PiPlatforms = new std::vector; int PlatformId = getPlatformId(Platform); if (PlatformId == 0) return 0; @@ -216,10 +221,17 @@ class plugin { std::fill(LastDeviceIds.begin(), LastDeviceIds.end(), 0); } + void resetPiPlatforms() { + delete PiPlatforms; + PiPlatforms = nullptr; + } + bool containsPiPlatform(RT::PiPlatform Platform) { - auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); - if (It != PiPlatforms.end()) - return true; + if (PiPlatforms) { + auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); + if (It != PiPlatforms->end()) + return true; + } return false; } @@ -229,7 +241,7 @@ class plugin { void *MLibraryHandle; // the handle returned from dlopen std::shared_ptr TracingMutex; // vector of PiPlatforms that belong to this plugin - std::vector PiPlatforms; + std::vector *PiPlatforms = nullptr; // represents the unique ids of the last device of each platform // index of this vector corresponds to the index in PiPlatforms vector. std::vector LastDeviceIds; From 917ab915126c169cafe70db79477c78b56858fbd Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Tue, 31 Aug 2021 19:06:31 -0700 Subject: [PATCH 22/58] handle -1 Signed-off-by: Byoungro So --- sycl/source/detail/plugin.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 3a8111901bbc5..df5e066eb6999 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -206,7 +206,7 @@ class plugin { if (!PiPlatforms) PiPlatforms = new std::vector; int PlatformId = getPlatformId(Platform); - if (PlatformId == 0) + if (PlatformId <= 0) return 0; return LastDeviceIds[PlatformId - 1]; From f7ebfcef450752d983e112061c96d90fc8f2f4e1 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Tue, 7 Sep 2021 12:38:22 -0700 Subject: [PATCH 23/58] address feedback Signed-off-by: Byoungro So --- sycl/source/detail/global_handler.cpp | 7 ++++++- sycl/source/detail/pi.cpp | 3 --- sycl/source/detail/platform_impl.cpp | 5 ----- sycl/source/detail/plugin.hpp | 22 ++++++++-------------- 4 files changed, 14 insertions(+), 23 deletions(-) diff --git a/sycl/source/detail/global_handler.cpp b/sycl/source/detail/global_handler.cpp index fed42f4ffa410..f969f0d2e0750 100644 --- a/sycl/source/detail/global_handler.cpp +++ b/sycl/source/detail/global_handler.cpp @@ -65,7 +65,12 @@ std::mutex &GlobalHandler::getFilterMutex() { return getOrCreate(MFilterMutex); } std::vector &GlobalHandler::getPlugins() { - return getOrCreate(MPlugins); + const std::lock_guard Guard( + GlobalHandler::instance().getPluginsMutex()); + std::vector &Plugins = getOrCreate(MPlugins); + if (Plugins.empty()) + RT::initialize(); + return Plugins; } device_filter_list & GlobalHandler::getDeviceFilterList(const std::string &InitValue) { diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index 0cc614ab3a0e2..4856a48bedf3a 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -371,9 +371,6 @@ bool trace(TraceLevel Level) { // Initializes all available Plugins. const std::vector &initialize() { static std::once_flag PluginsInitDone; - const std::lock_guard Guard( - GlobalHandler::instance().getPluginsMutex()); - std::call_once(PluginsInitDone, []() { initializePlugins(&GlobalHandler::instance().getPlugins()); }); diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index cd0bf2d86e816..d61068f8f149b 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -94,7 +94,6 @@ static bool IsBannedPlatform(platform Platform) { std::vector platform_impl::get_platforms() { std::vector Platforms; - RT::initialize(); std::vector &Plugins = GlobalHandler::instance().getPlugins(); info::device_type ForcedType = detail::get_forced_type(); for (unsigned int i = 0; i < Plugins.size(); i++) { @@ -145,11 +144,7 @@ static void filterDeviceFilter(std::vector &PiDevices, device_filter_list *FilterList = SYCLConfig::get(); if (!FilterList) return; - const std::lock_guard Guard( - GlobalHandler::instance().getPluginsMutex()); std::vector &Plugins = GlobalHandler::instance().getPlugins(); - if (Plugins.size() == 0) - RT::initialize(); auto It = std::find_if(Plugins.begin(), Plugins.end(), [Platform](plugin &Plugin) { diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index df5e066eb6999..88b8f4fe15496 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -187,28 +187,22 @@ class plugin { // return the index of PiPlatforms. // If not found, add it and return its index. int getPlatformId(RT::PiPlatform Platform) { - if (PiPlatforms) { - auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); - if (It != PiPlatforms->end()) - return It - PiPlatforms->begin(); + if (!PiPlatforms) + PiPlatforms = new std::vector; + auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); + if (It != PiPlatforms->end()) + return It - PiPlatforms->begin(); - PiPlatforms->push_back(Platform); - LastDeviceIds.push_back(0); - return PiPlatforms->size() - 1; - } - return -1; + PiPlatforms->push_back(Platform); + LastDeviceIds.push_back(0); + return PiPlatforms->size() - 1; } // Device ids are consecutive across platforms within a plugin. // We need to return the same starting index for the given platform. // So, instead of returing the last device id of the given platform, // return the last device id of the predecessor platform. int getStartingDeviceId(RT::PiPlatform Platform) { - if (!PiPlatforms) - PiPlatforms = new std::vector; int PlatformId = getPlatformId(Platform); - if (PlatformId <= 0) - return 0; - return LastDeviceIds[PlatformId - 1]; } // set the id of the last device for the given platform From 2a0b146922ba61e41320e3b8a981d76b64cf0825 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Tue, 7 Sep 2021 17:37:48 -0700 Subject: [PATCH 24/58] fix deadlock Signed-off-by: Byoungro So --- sycl/source/detail/global_handler.cpp | 7 +------ sycl/source/detail/pi.cpp | 17 ++++++++--------- sycl/source/detail/platform_impl.cpp | 4 ++++ 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/sycl/source/detail/global_handler.cpp b/sycl/source/detail/global_handler.cpp index f969f0d2e0750..fed42f4ffa410 100644 --- a/sycl/source/detail/global_handler.cpp +++ b/sycl/source/detail/global_handler.cpp @@ -65,12 +65,7 @@ std::mutex &GlobalHandler::getFilterMutex() { return getOrCreate(MFilterMutex); } std::vector &GlobalHandler::getPlugins() { - const std::lock_guard Guard( - GlobalHandler::instance().getPluginsMutex()); - std::vector &Plugins = getOrCreate(MPlugins); - if (Plugins.empty()) - RT::initialize(); - return Plugins; + return getOrCreate(MPlugins); } device_filter_list & GlobalHandler::getDeviceFilterList(const std::string &InitValue) { diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index 4856a48bedf3a..18201629dd295 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -78,7 +78,7 @@ getPluginOpaqueData(void *); namespace pi { -static void initializePlugins(std::vector *Plugins); +static void initializePlugins(std::vector &Plugins); bool XPTIInitDone = false; @@ -371,20 +371,19 @@ bool trace(TraceLevel Level) { // Initializes all available Plugins. const std::vector &initialize() { static std::once_flag PluginsInitDone; - std::call_once(PluginsInitDone, []() { - initializePlugins(&GlobalHandler::instance().getPlugins()); - }); + const std::lock_guard Guard( + GlobalHandler::instance().getPluginsMutex()); + std::vector &Plugins = GlobalHandler::instance().getPlugins(); + std::call_once(PluginsInitDone, [&]() { initializePlugins(Plugins); }); // reset LastDeviceIds to zeros - vector_class &Plugins = GlobalHandler::instance().getPlugins(); for (plugin &Plugin : Plugins) { Plugin.resetLastDeviceIds(); } - - return GlobalHandler::instance().getPlugins(); + return Plugins; } -static void initializePlugins(std::vector *Plugins) { +static void initializePlugins(std::vector &Plugins) { std::vector> PluginNames = findPlugins(); if (PluginNames.empty() && trace(PI_TRACE_ALL)) @@ -443,7 +442,7 @@ static void initializePlugins(std::vector *Plugins) { GlobalPlugin = std::make_shared(PluginInformation, backend::level_zero, Library); } - Plugins->emplace_back( + Plugins.emplace_back( plugin(PluginInformation, PluginNames[I].second, Library)); if (trace(TraceLevel::PI_TRACE_BASIC)) std::cerr << "SYCL_PI_TRACE[basic]: " diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index d61068f8f149b..afb37d94356f9 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -94,6 +94,7 @@ static bool IsBannedPlatform(platform Platform) { std::vector platform_impl::get_platforms() { std::vector Platforms; + RT::initialize(); std::vector &Plugins = GlobalHandler::instance().getPlugins(); info::device_type ForcedType = detail::get_forced_type(); for (unsigned int i = 0; i < Plugins.size(); i++) { @@ -144,7 +145,10 @@ static void filterDeviceFilter(std::vector &PiDevices, device_filter_list *FilterList = SYCLConfig::get(); if (!FilterList) return; + std::vector &Plugins = GlobalHandler::instance().getPlugins(); + if (Plugins.empty()) + RT::initialize(); auto It = std::find_if(Plugins.begin(), Plugins.end(), [Platform](plugin &Plugin) { From b0bfd315ab216a9b8f6dc0bc2ad31d39f7ed3374 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Tue, 7 Sep 2021 19:45:34 -0700 Subject: [PATCH 25/58] first platform Signed-off-by: Byoungro So --- sycl/source/detail/plugin.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 88b8f4fe15496..d72705dde8a50 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -203,6 +203,8 @@ class plugin { // return the last device id of the predecessor platform. int getStartingDeviceId(RT::PiPlatform Platform) { int PlatformId = getPlatformId(Platform); + if (PlatformId == 0) + return 0; return LastDeviceIds[PlatformId - 1]; } // set the id of the last device for the given platform From b94648296f68cb459510a0e0846878d2b4090dfd Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Wed, 8 Sep 2021 10:38:18 -0700 Subject: [PATCH 26/58] fix race Signed-off-by: Byoungro So --- sycl/include/CL/sycl/detail/pi.hpp | 2 +- sycl/source/detail/pi.cpp | 4 ++-- sycl/source/detail/platform_impl.cpp | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/sycl/include/CL/sycl/detail/pi.hpp b/sycl/include/CL/sycl/detail/pi.hpp index dcde4e1d807d7..442c52c7e7482 100644 --- a/sycl/include/CL/sycl/detail/pi.hpp +++ b/sycl/include/CL/sycl/detail/pi.hpp @@ -154,7 +154,7 @@ template To cast(From value); extern std::shared_ptr GlobalPlugin; // Performs PI one-time initialization. -const std::vector &initialize(); +std::vector &initialize(); // Get the plugin serving given backend. template __SYCL_EXPORT const plugin &getPlugin(); diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index 18201629dd295..c2fd4e29ef12e 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -369,7 +369,7 @@ bool trace(TraceLevel Level) { } // Initializes all available Plugins. -const std::vector &initialize() { +std::vector &initialize() { static std::once_flag PluginsInitDone; const std::lock_guard Guard( GlobalHandler::instance().getPluginsMutex()); @@ -507,7 +507,7 @@ template const plugin &getPlugin() { if (Plugin) return *Plugin; - const std::vector &Plugins = pi::initialize(); + std::vector &Plugins = pi::initialize(); for (const auto &P : Plugins) if (P.getBackend() == BE) { Plugin = &P; diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index afb37d94356f9..3658eb4d362c6 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -146,9 +146,7 @@ static void filterDeviceFilter(std::vector &PiDevices, if (!FilterList) return; - std::vector &Plugins = GlobalHandler::instance().getPlugins(); - if (Plugins.empty()) - RT::initialize(); + std::vector &Plugins = RT::initialize(); auto It = std::find_if(Plugins.begin(), Plugins.end(), [Platform](plugin &Plugin) { From 262d0ac78538c527496a5888d0b4108011e2f6cd Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Wed, 8 Sep 2021 11:09:27 -0700 Subject: [PATCH 27/58] reset device id Signed-off-by: Byoungro So --- sycl/source/detail/pi.cpp | 6 +++--- sycl/source/detail/platform_impl.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index c2fd4e29ef12e..6ace992821416 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -377,9 +377,9 @@ std::vector &initialize() { std::call_once(PluginsInitDone, [&]() { initializePlugins(Plugins); }); // reset LastDeviceIds to zeros - for (plugin &Plugin : Plugins) { - Plugin.resetLastDeviceIds(); - } + // for (plugin &Plugin : Plugins) { + // Plugin.resetLastDeviceIds(); + //} return Plugins; } diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 3658eb4d362c6..86808ca7c9c3a 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -94,10 +94,10 @@ static bool IsBannedPlatform(platform Platform) { std::vector platform_impl::get_platforms() { std::vector Platforms; - RT::initialize(); - std::vector &Plugins = GlobalHandler::instance().getPlugins(); + std::vector &Plugins = RT::initialize(); info::device_type ForcedType = detail::get_forced_type(); for (unsigned int i = 0; i < Plugins.size(); i++) { + Plugins[i].resetLastDeviceIds(); pi_uint32 NumPlatforms = 0; // Move to the next plugin if the plugin fails to initialize. // This way platforms from other plugins get a chance to be discovered. From 6c4415677c751287536c4a3970ac347ee711593b Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 9 Sep 2021 08:55:12 -0700 Subject: [PATCH 28/58] try not resetting PiPlatforms Signed-off-by: Byoungro So --- sycl/source/detail/global_handler.cpp | 2 +- sycl/source/detail/pi.cpp | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/sycl/source/detail/global_handler.cpp b/sycl/source/detail/global_handler.cpp index fed42f4ffa410..345d4ea0c9a6f 100644 --- a/sycl/source/detail/global_handler.cpp +++ b/sycl/source/detail/global_handler.cpp @@ -100,7 +100,7 @@ void shutdown() { // Currently, it is not used. void *PluginParameter = nullptr; Plugin.call(PluginParameter); - Plugin.resetPiPlatforms(); + // Plugin.resetPiPlatforms(); Plugin.unload(); } GlobalHandler::instance().MPlugins.Inst.reset(nullptr); diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index 6ace992821416..8e94ada2009ff 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -375,11 +375,6 @@ std::vector &initialize() { GlobalHandler::instance().getPluginsMutex()); std::vector &Plugins = GlobalHandler::instance().getPlugins(); std::call_once(PluginsInitDone, [&]() { initializePlugins(Plugins); }); - - // reset LastDeviceIds to zeros - // for (plugin &Plugin : Plugins) { - // Plugin.resetLastDeviceIds(); - //} return Plugins; } From 8b5961567a1263708fc8a5c8437c7b8e3ed5d605 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 9 Sep 2021 16:49:08 -0700 Subject: [PATCH 29/58] change PiPlatform as vector Signed-off-by: Byoungro So --- sycl/source/detail/global_handler.cpp | 1 - sycl/source/detail/plugin.hpp | 27 +++++++++------------------ 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/sycl/source/detail/global_handler.cpp b/sycl/source/detail/global_handler.cpp index 345d4ea0c9a6f..8ff39b69da77a 100644 --- a/sycl/source/detail/global_handler.cpp +++ b/sycl/source/detail/global_handler.cpp @@ -100,7 +100,6 @@ void shutdown() { // Currently, it is not used. void *PluginParameter = nullptr; Plugin.call(PluginParameter); - // Plugin.resetPiPlatforms(); Plugin.unload(); } GlobalHandler::instance().MPlugins.Inst.reset(nullptr); diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index d72705dde8a50..3aa70d5a0d488 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -187,15 +187,13 @@ class plugin { // return the index of PiPlatforms. // If not found, add it and return its index. int getPlatformId(RT::PiPlatform Platform) { - if (!PiPlatforms) - PiPlatforms = new std::vector; - auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); - if (It != PiPlatforms->end()) - return It - PiPlatforms->begin(); + auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); + if (It != PiPlatforms.end()) + return It - PiPlatforms.begin(); - PiPlatforms->push_back(Platform); + PiPlatforms.push_back(Platform); LastDeviceIds.push_back(0); - return PiPlatforms->size() - 1; + return PiPlatforms.size() - 1; } // Device ids are consecutive across platforms within a plugin. // We need to return the same starting index for the given platform. @@ -217,17 +215,10 @@ class plugin { std::fill(LastDeviceIds.begin(), LastDeviceIds.end(), 0); } - void resetPiPlatforms() { - delete PiPlatforms; - PiPlatforms = nullptr; - } - bool containsPiPlatform(RT::PiPlatform Platform) { - if (PiPlatforms) { - auto It = std::find(PiPlatforms->begin(), PiPlatforms->end(), Platform); - if (It != PiPlatforms->end()) - return true; - } + auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); + if (It != PiPlatforms.end()) + return true; return false; } @@ -237,7 +228,7 @@ class plugin { void *MLibraryHandle; // the handle returned from dlopen std::shared_ptr TracingMutex; // vector of PiPlatforms that belong to this plugin - std::vector *PiPlatforms = nullptr; + std::vector PiPlatforms; // represents the unique ids of the last device of each platform // index of this vector corresponds to the index in PiPlatforms vector. std::vector LastDeviceIds; From efd6b1c80982f73f45088dd64d2c198df84c01fb Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Fri, 10 Sep 2021 10:42:59 -0700 Subject: [PATCH 30/58] add locks Signed-off-by: Byoungro So --- sycl/source/detail/plugin.hpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 3aa70d5a0d488..eb3aec4e1878c 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -92,7 +92,9 @@ class plugin { plugin(RT::PiPlugin Plugin, backend UseBackend, void *LibraryHandle) : MPlugin(Plugin), MBackend(UseBackend), MLibraryHandle(LibraryHandle), - TracingMutex(std::make_shared()) {} + TracingMutex(std::make_shared()), + DeviceIdMutex(std::make_shared()), + PlatformIdMutex(std::make_shared()) {} plugin &operator=(const plugin &) = default; plugin(const plugin &) = default; @@ -187,6 +189,7 @@ class plugin { // return the index of PiPlatforms. // If not found, add it and return its index. int getPlatformId(RT::PiPlatform Platform) { + std::lock_guard Guard(*PlatformIdMutex); auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); if (It != PiPlatforms.end()) return It - PiPlatforms.begin(); @@ -203,19 +206,23 @@ class plugin { int PlatformId = getPlatformId(Platform); if (PlatformId == 0) return 0; + std::lock_guard Guard(*DeviceIdMutex); return LastDeviceIds[PlatformId - 1]; } // set the id of the last device for the given platform void setLastDeviceId(RT::PiPlatform Platform, int Id) { int PlatformId = getPlatformId(Platform); + std::lock_guard Guard(*DeviceIdMutex); LastDeviceIds[PlatformId] = Id; } // reset all last device ids to zeros void resetLastDeviceIds() { + std::lock_guard Guard(*DeviceIdMutex); std::fill(LastDeviceIds.begin(), LastDeviceIds.end(), 0); } bool containsPiPlatform(RT::PiPlatform Platform) { + std::lock_guard Guard(*PlatformIdMutex); auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); if (It != PiPlatforms.end()) return true; @@ -227,6 +234,8 @@ class plugin { backend MBackend; void *MLibraryHandle; // the handle returned from dlopen std::shared_ptr TracingMutex; + std::shared_ptr DeviceIdMutex; + std::shared_ptr PlatformIdMutex; // vector of PiPlatforms that belong to this plugin std::vector PiPlatforms; // represents the unique ids of the last device of each platform From f4234716492b130729ff04c3abb1ee3b06ae3d7f Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:33:05 -0700 Subject: [PATCH 31/58] Update sycl/source/detail/pi.cpp Co-authored-by: Romanov Vlad --- sycl/source/detail/pi.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index 5225d36a4f937..2c9cf007e067c 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -371,10 +371,8 @@ bool trace(TraceLevel Level) { // Initializes all available Plugins. std::vector &initialize() { static std::once_flag PluginsInitDone; - const std::lock_guard Guard( - GlobalHandler::instance().getPluginsMutex()); - std::vector &Plugins = GlobalHandler::instance().getPlugins(); - std::call_once(PluginsInitDone, [&]() { initializePlugins(Plugins); }); + std::call_once(PluginsInitDone, [&]() { initializePlugins(GlobalHandler::instance().getPlugins()); }); + return GlobalHandler::instance().getPlugins(); return Plugins; } From 9d191879a93cae9d97508815f889c615f88826c1 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:33:16 -0700 Subject: [PATCH 32/58] Update sycl/source/detail/pi.cpp Co-authored-by: Romanov Vlad --- sycl/source/detail/pi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index 2c9cf007e067c..1dbe48eb02494 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -500,7 +500,7 @@ template const plugin &getPlugin() { if (Plugin) return *Plugin; - std::vector &Plugins = pi::initialize(); + const std::vector &Plugins = pi::initialize(); for (const auto &P : Plugins) if (P.getBackend() == BE) { Plugin = &P; From bc5373d811368245b9450ef0ca9a7465daefb3f4 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:33:25 -0700 Subject: [PATCH 33/58] Update sycl/source/detail/platform_impl.cpp Co-authored-by: Romanov Vlad --- sycl/source/detail/platform_impl.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 86376bd1a1b1e..7f7d4fdbf8da5 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -96,6 +96,9 @@ static bool IsBannedPlatform(platform Platform) { std::vector platform_impl::get_platforms() { std::vector Platforms; std::vector &Plugins = RT::initialize(); + // Locking plugins mutex as the function modifies plugins state. + const std::lock_guard Guard( + GlobalHandler::instance().getPluginsMutex()); info::device_type ForcedType = detail::get_forced_type(); for (unsigned int i = 0; i < Plugins.size(); i++) { Plugins[i].resetLastDeviceIds(); From 6e5e7b74a3f1418fd6b5de29969b1191921fe3ca Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:33:32 -0700 Subject: [PATCH 34/58] Update sycl/source/detail/platform_impl.cpp Co-authored-by: Romanov Vlad --- sycl/source/detail/platform_impl.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 7f7d4fdbf8da5..8791cbacca872 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -151,6 +151,9 @@ static void filterDeviceFilter(std::vector &PiDevices, return; std::vector &Plugins = RT::initialize(); +// Locking plugins mutex as the function modifies plugins state. + const std::lock_guard Guard( + GlobalHandler::instance().getPluginsMutex()); auto It = std::find_if(Plugins.begin(), Plugins.end(), [Platform](plugin &Plugin) { From 51a6a71762bee10eab58346c81594f0cfc783607 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:33:39 -0700 Subject: [PATCH 35/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Romanov Vlad --- sycl/source/detail/plugin.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index eb3aec4e1878c..4abd13effbbe8 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -216,6 +216,7 @@ class plugin { LastDeviceIds[PlatformId] = Id; } // reset all last device ids to zeros + // The function is expected to be called in a thread safe manner void resetLastDeviceIds() { std::lock_guard Guard(*DeviceIdMutex); std::fill(LastDeviceIds.begin(), LastDeviceIds.end(), 0); From 041279133a36697b121e24678fef4f6775670f05 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:33:45 -0700 Subject: [PATCH 36/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Romanov Vlad --- sycl/source/detail/plugin.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 4abd13effbbe8..6ad47a1153542 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -222,6 +222,7 @@ class plugin { std::fill(LastDeviceIds.begin(), LastDeviceIds.end(), 0); } +// The function is expected to be called in a thread safe manner bool containsPiPlatform(RT::PiPlatform Platform) { std::lock_guard Guard(*PlatformIdMutex); auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); From b73cae4ec68294f50416bc14934bd24d508dd2d5 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:33:54 -0700 Subject: [PATCH 37/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Romanov Vlad --- sycl/source/detail/plugin.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 6ad47a1153542..dff11e9831ebb 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -189,7 +189,7 @@ class plugin { // return the index of PiPlatforms. // If not found, add it and return its index. int getPlatformId(RT::PiPlatform Platform) { - std::lock_guard Guard(*PlatformIdMutex); +// The function is expected to be called in a thread safe manner auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); if (It != PiPlatforms.end()) return It - PiPlatforms.begin(); From 58aaf3156f6a6bbf11b56743924eb5d6195bd20b Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:34:01 -0700 Subject: [PATCH 38/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Romanov Vlad --- sycl/source/detail/plugin.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index dff11e9831ebb..c24283fd94178 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -224,7 +224,6 @@ class plugin { // The function is expected to be called in a thread safe manner bool containsPiPlatform(RT::PiPlatform Platform) { - std::lock_guard Guard(*PlatformIdMutex); auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); if (It != PiPlatforms.end()) return true; From a5b50f1e083863c43c058a6ec40111e508ad88d3 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:34:09 -0700 Subject: [PATCH 39/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Romanov Vlad --- sycl/source/detail/plugin.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index c24283fd94178..ab8e63a3892e6 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -225,9 +225,7 @@ class plugin { // The function is expected to be called in a thread safe manner bool containsPiPlatform(RT::PiPlatform Platform) { auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); - if (It != PiPlatforms.end()) - return true; - return false; + return It != PiPlatforms.end(); } private: From 23609bff941d3038a9410d9c1168dab3a8127cb3 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:34:18 -0700 Subject: [PATCH 40/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Romanov Vlad --- sycl/source/detail/plugin.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index ab8e63a3892e6..aa2335545712f 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -233,8 +233,6 @@ class plugin { backend MBackend; void *MLibraryHandle; // the handle returned from dlopen std::shared_ptr TracingMutex; - std::shared_ptr DeviceIdMutex; - std::shared_ptr PlatformIdMutex; // vector of PiPlatforms that belong to this plugin std::vector PiPlatforms; // represents the unique ids of the last device of each platform From fbaade4c8e7ebd77c6086ef5e54b4638845d2d78 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:34:30 -0700 Subject: [PATCH 41/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Romanov Vlad --- sycl/source/detail/plugin.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index aa2335545712f..918cde242ee44 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -206,7 +206,6 @@ class plugin { int PlatformId = getPlatformId(Platform); if (PlatformId == 0) return 0; - std::lock_guard Guard(*DeviceIdMutex); return LastDeviceIds[PlatformId - 1]; } // set the id of the last device for the given platform From 5d00fccaa2ceaadab7e9ef47690974923dcca91b Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:34:40 -0700 Subject: [PATCH 42/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Romanov Vlad --- sycl/source/detail/plugin.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 918cde242ee44..bf244dc329d7d 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -202,6 +202,7 @@ class plugin { // We need to return the same starting index for the given platform. // So, instead of returing the last device id of the given platform, // return the last device id of the predecessor platform. + // The function is expected to be called in a thread safe manner int getStartingDeviceId(RT::PiPlatform Platform) { int PlatformId = getPlatformId(Platform); if (PlatformId == 0) From 117b886a33d7430f91449a087fa5005ae588af3c Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:34:48 -0700 Subject: [PATCH 43/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Romanov Vlad --- sycl/source/detail/plugin.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index bf244dc329d7d..0f7adfbb77070 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -210,6 +210,7 @@ class plugin { return LastDeviceIds[PlatformId - 1]; } // set the id of the last device for the given platform + // The function is expected to be called in a thread safe manner void setLastDeviceId(RT::PiPlatform Platform, int Id) { int PlatformId = getPlatformId(Platform); std::lock_guard Guard(*DeviceIdMutex); From 3d7c6526383eeee38a0e710c944a68a56a043e3e Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:34:57 -0700 Subject: [PATCH 44/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Romanov Vlad --- sycl/source/detail/plugin.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 0f7adfbb77070..b876da2599003 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -213,7 +213,6 @@ class plugin { // The function is expected to be called in a thread safe manner void setLastDeviceId(RT::PiPlatform Platform, int Id) { int PlatformId = getPlatformId(Platform); - std::lock_guard Guard(*DeviceIdMutex); LastDeviceIds[PlatformId] = Id; } // reset all last device ids to zeros From 6dbcd1986a594af9cf04ea15939e337ddc7a6cb5 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:35:06 -0700 Subject: [PATCH 45/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Romanov Vlad --- sycl/source/detail/plugin.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index b876da2599003..29ff7d674e6cc 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -218,7 +218,6 @@ class plugin { // reset all last device ids to zeros // The function is expected to be called in a thread safe manner void resetLastDeviceIds() { - std::lock_guard Guard(*DeviceIdMutex); std::fill(LastDeviceIds.begin(), LastDeviceIds.end(), 0); } From e65d394574161ac312a9a107eb75411ba3d8ca22 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:39:47 -0700 Subject: [PATCH 46/58] clang-format Signed-off-by: Byoungro So --- sycl/source/detail/pi.cpp | 4 +++- sycl/source/detail/platform_impl.cpp | 6 +++--- sycl/source/detail/plugin.hpp | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index 1dbe48eb02494..c15e133e5d2fb 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -371,7 +371,9 @@ bool trace(TraceLevel Level) { // Initializes all available Plugins. std::vector &initialize() { static std::once_flag PluginsInitDone; - std::call_once(PluginsInitDone, [&]() { initializePlugins(GlobalHandler::instance().getPlugins()); }); + std::call_once(PluginsInitDone, [&]() { + initializePlugins(GlobalHandler::instance().getPlugins()); + }); return GlobalHandler::instance().getPlugins(); return Plugins; } diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 8791cbacca872..048f51e70beed 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -96,8 +96,8 @@ static bool IsBannedPlatform(platform Platform) { std::vector platform_impl::get_platforms() { std::vector Platforms; std::vector &Plugins = RT::initialize(); - // Locking plugins mutex as the function modifies plugins state. - const std::lock_guard Guard( + // Locking plugins mutex as the function modifies plugins state. + const std::lock_guard Guard( GlobalHandler::instance().getPluginsMutex()); info::device_type ForcedType = detail::get_forced_type(); for (unsigned int i = 0; i < Plugins.size(); i++) { @@ -151,7 +151,7 @@ static void filterDeviceFilter(std::vector &PiDevices, return; std::vector &Plugins = RT::initialize(); -// Locking plugins mutex as the function modifies plugins state. + // Locking plugins mutex as the function modifies plugins state. const std::lock_guard Guard( GlobalHandler::instance().getPluginsMutex()); diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 29ff7d674e6cc..fff7c6fffe3a9 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -189,7 +189,7 @@ class plugin { // return the index of PiPlatforms. // If not found, add it and return its index. int getPlatformId(RT::PiPlatform Platform) { -// The function is expected to be called in a thread safe manner + // The function is expected to be called in a thread safe manner auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); if (It != PiPlatforms.end()) return It - PiPlatforms.begin(); @@ -221,7 +221,7 @@ class plugin { std::fill(LastDeviceIds.begin(), LastDeviceIds.end(), 0); } -// The function is expected to be called in a thread safe manner + // The function is expected to be called in a thread safe manner bool containsPiPlatform(RT::PiPlatform Platform) { auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); return It != PiPlatforms.end(); From 316a9dc1fa19c867b10f4b07f1f09e28204a58d2 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 09:52:52 -0700 Subject: [PATCH 47/58] cleanup residue Signed-off-by: Byoungro So --- sycl/source/detail/pi.cpp | 1 - sycl/source/detail/plugin.hpp | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index c15e133e5d2fb..c67c402c61f76 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -375,7 +375,6 @@ std::vector &initialize() { initializePlugins(GlobalHandler::instance().getPlugins()); }); return GlobalHandler::instance().getPlugins(); - return Plugins; } static void initializePlugins(std::vector &Plugins) { diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index fff7c6fffe3a9..bc7fbd272a96e 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -89,12 +89,9 @@ auto packCallArguments(ArgsT &&... Args) { class plugin { public: plugin() = delete; - plugin(RT::PiPlugin Plugin, backend UseBackend, void *LibraryHandle) : MPlugin(Plugin), MBackend(UseBackend), MLibraryHandle(LibraryHandle), - TracingMutex(std::make_shared()), - DeviceIdMutex(std::make_shared()), - PlatformIdMutex(std::make_shared()) {} + TracingMutex(std::make_shared()) {} plugin &operator=(const plugin &) = default; plugin(const plugin &) = default; From 54e0c8a3cbda24b7dd06a194dcbdc21ebb929e99 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 14:21:41 -0700 Subject: [PATCH 48/58] revert to fix deadlock Signed-off-by: Byoungro So --- sycl/source/detail/pi.cpp | 5 +++++ sycl/source/detail/platform_impl.cpp | 7 ------- sycl/source/detail/plugin.hpp | 12 +++++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index c67c402c61f76..ca39686026181 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -371,6 +371,11 @@ bool trace(TraceLevel Level) { // Initializes all available Plugins. std::vector &initialize() { static std::once_flag PluginsInitDone; + // PluginsMutex is needed here to guardi the global plugins vector itself. + // Each individual plugin in the vector needs its own lock when its status + // is changed somewhere else. + const std::lock_guard Guard( + GlobalHandler::instance().getPluginsMutex()); std::call_once(PluginsInitDone, [&]() { initializePlugins(GlobalHandler::instance().getPlugins()); }); diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 048f51e70beed..a5367a0028c20 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -96,9 +96,6 @@ static bool IsBannedPlatform(platform Platform) { std::vector platform_impl::get_platforms() { std::vector Platforms; std::vector &Plugins = RT::initialize(); - // Locking plugins mutex as the function modifies plugins state. - const std::lock_guard Guard( - GlobalHandler::instance().getPluginsMutex()); info::device_type ForcedType = detail::get_forced_type(); for (unsigned int i = 0; i < Plugins.size(); i++) { Plugins[i].resetLastDeviceIds(); @@ -151,10 +148,6 @@ static void filterDeviceFilter(std::vector &PiDevices, return; std::vector &Plugins = RT::initialize(); - // Locking plugins mutex as the function modifies plugins state. - const std::lock_guard Guard( - GlobalHandler::instance().getPluginsMutex()); - auto It = std::find_if(Plugins.begin(), Plugins.end(), [Platform](plugin &Plugin) { return Plugin.containsPiPlatform(Platform); diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index bc7fbd272a96e..bf298fd657b10 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -186,7 +186,7 @@ class plugin { // return the index of PiPlatforms. // If not found, add it and return its index. int getPlatformId(RT::PiPlatform Platform) { - // The function is expected to be called in a thread safe manner + std::lock_guard Guard(*PlatformIdMutex); auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); if (It != PiPlatforms.end()) return It - PiPlatforms.begin(); @@ -199,27 +199,27 @@ class plugin { // We need to return the same starting index for the given platform. // So, instead of returing the last device id of the given platform, // return the last device id of the predecessor platform. - // The function is expected to be called in a thread safe manner int getStartingDeviceId(RT::PiPlatform Platform) { int PlatformId = getPlatformId(Platform); if (PlatformId == 0) return 0; + std::lock_guard Guard(*DeviceIdMutex); return LastDeviceIds[PlatformId - 1]; } // set the id of the last device for the given platform - // The function is expected to be called in a thread safe manner void setLastDeviceId(RT::PiPlatform Platform, int Id) { int PlatformId = getPlatformId(Platform); + std::lock_guard Guard(*DeviceIdMutex); LastDeviceIds[PlatformId] = Id; } // reset all last device ids to zeros - // The function is expected to be called in a thread safe manner void resetLastDeviceIds() { + std::lock_guard Guard(*DeviceIdMutex); std::fill(LastDeviceIds.begin(), LastDeviceIds.end(), 0); } - // The function is expected to be called in a thread safe manner bool containsPiPlatform(RT::PiPlatform Platform) { + std::lock_guard Guard(*PlatformIdMutex); auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); return It != PiPlatforms.end(); } @@ -229,6 +229,8 @@ class plugin { backend MBackend; void *MLibraryHandle; // the handle returned from dlopen std::shared_ptr TracingMutex; + std::shared_ptr DeviceIdMutex; + std::shared_ptr PlatformIdMutex; // vector of PiPlatforms that belong to this plugin std::vector PiPlatforms; // represents the unique ids of the last device of each platform From cef727f645884039b337b192d55de8acddd4113c Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 15:48:34 -0700 Subject: [PATCH 49/58] missed init mutexes Signed-off-by: Byoungro So --- sycl/source/detail/plugin.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index bf298fd657b10..b0fc4d7269c5c 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -91,7 +91,9 @@ class plugin { plugin() = delete; plugin(RT::PiPlugin Plugin, backend UseBackend, void *LibraryHandle) : MPlugin(Plugin), MBackend(UseBackend), MLibraryHandle(LibraryHandle), - TracingMutex(std::make_shared()) {} + TracingMutex(std::make_shared()), + DeviceIdMutex(std::make_shared()), + PlatformIdMutex(std::make_shared()) {} plugin &operator=(const plugin &) = default; plugin(const plugin &) = default; From b8af7ea180c9d3f98e1aec9ab6c14db24913b7eb Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Thu, 16 Sep 2021 15:51:01 -0700 Subject: [PATCH 50/58] add comments Signed-off-by: Byoungro So --- sycl/source/detail/global_handler.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sycl/source/detail/global_handler.hpp b/sycl/source/detail/global_handler.hpp index 4f570e6e8e6b9..e8112aa85ade3 100644 --- a/sycl/source/detail/global_handler.hpp +++ b/sycl/source/detail/global_handler.hpp @@ -95,6 +95,8 @@ class GlobalHandler { InstWithLock MPlatformMapMutex; InstWithLock MFilterMutex; InstWithLock> MPlugins; + // MPluginsMutex is used to guard the MPlugins vector only. + // Each individual plugin change should use plugin's mutex data members. InstWithLock MPluginsMutex; InstWithLock MDeviceFilterList; InstWithLock MXPTIRegistry; From f55bb5a7893a9569a536400c466b6a270785f194 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Fri, 17 Sep 2021 12:53:32 -0700 Subject: [PATCH 51/58] address feedback Signed-off-by: Byoungro So --- sycl/source/detail/global_handler.cpp | 4 ---- sycl/source/detail/global_handler.hpp | 4 ---- sycl/source/detail/pi.cpp | 7 ++----- sycl/source/detail/platform_impl.cpp | 2 +- sycl/source/detail/plugin.hpp | 25 ++++++++++++------------- 5 files changed, 15 insertions(+), 27 deletions(-) diff --git a/sycl/source/detail/global_handler.cpp b/sycl/source/detail/global_handler.cpp index 5dbe08f1d3eb7..e889368aa71ab 100644 --- a/sycl/source/detail/global_handler.cpp +++ b/sycl/source/detail/global_handler.cpp @@ -89,10 +89,6 @@ std::mutex &GlobalHandler::getHandlerExtendedMembersMutex() { return getOrCreate(MHandlerExtendedMembersMutex); } -std::mutex &GlobalHandler::getPluginsMutex() { - return getOrCreate(MPluginsMutex); -} - void shutdown() { // First, release resources, that may access plugins. GlobalHandler::instance().MScheduler.Inst.reset(nullptr); diff --git a/sycl/source/detail/global_handler.hpp b/sycl/source/detail/global_handler.hpp index e8112aa85ade3..c5cfb7bdbfc46 100644 --- a/sycl/source/detail/global_handler.hpp +++ b/sycl/source/detail/global_handler.hpp @@ -67,7 +67,6 @@ class GlobalHandler { device_filter_list &getDeviceFilterList(const std::string &InitValue); XPTIRegistry &getXPTIRegistry(); std::mutex &getHandlerExtendedMembersMutex(); - std::mutex &getPluginsMutex(); private: friend void shutdown(); @@ -95,9 +94,6 @@ class GlobalHandler { InstWithLock MPlatformMapMutex; InstWithLock MFilterMutex; InstWithLock> MPlugins; - // MPluginsMutex is used to guard the MPlugins vector only. - // Each individual plugin change should use plugin's mutex data members. - InstWithLock MPluginsMutex; InstWithLock MDeviceFilterList; InstWithLock MXPTIRegistry; // The mutex for synchronizing accesses to handlers extended members diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index ca39686026181..855bbac4cfb02 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -371,11 +371,8 @@ bool trace(TraceLevel Level) { // Initializes all available Plugins. std::vector &initialize() { static std::once_flag PluginsInitDone; - // PluginsMutex is needed here to guardi the global plugins vector itself. - // Each individual plugin in the vector needs its own lock when its status - // is changed somewhere else. - const std::lock_guard Guard( - GlobalHandler::instance().getPluginsMutex()); + // std::call_once is blocking all other threads if a thread is already + // creating a vector of plugins. So, no additional lock is needed. std::call_once(PluginsInitDone, [&]() { initializePlugins(GlobalHandler::instance().getPlugins()); }); diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index a5367a0028c20..d9daa3b91e086 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -98,7 +98,6 @@ std::vector platform_impl::get_platforms() { std::vector &Plugins = RT::initialize(); info::device_type ForcedType = detail::get_forced_type(); for (unsigned int i = 0; i < Plugins.size(); i++) { - Plugins[i].resetLastDeviceIds(); pi_uint32 NumPlatforms = 0; // Move to the next plugin if the plugin fails to initialize. // This way platforms from other plugins get a chance to be discovered. @@ -160,6 +159,7 @@ static void filterDeviceFilter(std::vector &PiDevices, int InsertIDx = 0; // DeviceIds should be given consecutive numbers across platforms in the same // backend + std::lock_guard Guard(*Plugin.getPluginMutex()); int DeviceNum = Plugin.getStartingDeviceId(Platform); for (RT::PiDevice Device : PiDevices) { RT::PiDeviceType PiDevType; diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index b0fc4d7269c5c..d660b6dd057bb 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -92,8 +92,7 @@ class plugin { plugin(RT::PiPlugin Plugin, backend UseBackend, void *LibraryHandle) : MPlugin(Plugin), MBackend(UseBackend), MLibraryHandle(LibraryHandle), TracingMutex(std::make_shared()), - DeviceIdMutex(std::make_shared()), - PlatformIdMutex(std::make_shared()) {} + MPluginMutex(std::make_shared()) {} plugin &operator=(const plugin &) = default; plugin(const plugin &) = default; @@ -187,8 +186,8 @@ class plugin { // return the index of PiPlatforms. // If not found, add it and return its index. + // The function is expected to be called in a thread safe manner. int getPlatformId(RT::PiPlatform Platform) { - std::lock_guard Guard(*PlatformIdMutex); auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); if (It != PiPlatforms.end()) return It - PiPlatforms.begin(); @@ -197,42 +196,42 @@ class plugin { LastDeviceIds.push_back(0); return PiPlatforms.size() - 1; } + // Device ids are consecutive across platforms within a plugin. // We need to return the same starting index for the given platform. // So, instead of returing the last device id of the given platform, // return the last device id of the predecessor platform. + // The function is expected to be called in a thread safe manner. int getStartingDeviceId(RT::PiPlatform Platform) { int PlatformId = getPlatformId(Platform); if (PlatformId == 0) return 0; - std::lock_guard Guard(*DeviceIdMutex); return LastDeviceIds[PlatformId - 1]; } + // set the id of the last device for the given platform + // The function is expected to be called in a thread safe manner. void setLastDeviceId(RT::PiPlatform Platform, int Id) { int PlatformId = getPlatformId(Platform); - std::lock_guard Guard(*DeviceIdMutex); LastDeviceIds[PlatformId] = Id; } - // reset all last device ids to zeros - void resetLastDeviceIds() { - std::lock_guard Guard(*DeviceIdMutex); - std::fill(LastDeviceIds.begin(), LastDeviceIds.end(), 0); - } bool containsPiPlatform(RT::PiPlatform Platform) { - std::lock_guard Guard(*PlatformIdMutex); auto It = std::find(PiPlatforms.begin(), PiPlatforms.end(), Platform); return It != PiPlatforms.end(); } + std::shared_ptr getPluginMutex() { return MPluginMutex; } + private: RT::PiPlugin MPlugin; backend MBackend; void *MLibraryHandle; // the handle returned from dlopen std::shared_ptr TracingMutex; - std::shared_ptr DeviceIdMutex; - std::shared_ptr PlatformIdMutex; + // Mutex to guard PiPlatforms and LastDeviceIds. + // Note that this is a temporary solution until we implement the global + // Device/Platform cache later. + std::shared_ptr MPluginMutex; // vector of PiPlatforms that belong to this plugin std::vector PiPlatforms; // represents the unique ids of the last device of each platform From 7e02fb51189e60b852fde60d18d9210da1fe8d03 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Sat, 18 Sep 2021 11:51:28 -0700 Subject: [PATCH 52/58] print platform name Signed-off-by: Byoungro So --- sycl/tools/sycl-ls/sycl-ls.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sycl/tools/sycl-ls/sycl-ls.cpp b/sycl/tools/sycl-ls/sycl-ls.cpp index b9b38ca73e91b..0481d26247838 100644 --- a/sycl/tools/sycl-ls/sycl-ls.cpp +++ b/sycl/tools/sycl-ls/sycl-ls.cpp @@ -76,9 +76,11 @@ static void printDeviceInfo(const device &Device, const std::string &Prepend) { static void printSelectorChoice(const device_selector &Selector, const std::string &Prepend) { try { - const auto &Dev = device(Selector); - std::string DeviceTypeName = getDeviceTypeName(Dev); - printDeviceInfo(Dev, Prepend + DeviceTypeName); + const auto &Device = device(Selector); + std::string DeviceTypeName = getDeviceTypeName(Device); + auto Platform = Device.get_info(); + auto PlatformName = Platform.get_info(); + printDeviceInfo(Device, Prepend + DeviceTypeName + " : " + PlatformName); } catch (const cl::sycl::runtime_error &Exception) { // Truncate long string so it can fit in one-line std::string What = Exception.what(); From 239b483d8e73ceac1547ac19f2dd525dc5565848 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Tue, 21 Sep 2021 09:25:03 -0700 Subject: [PATCH 53/58] Update sycl/source/detail/platform_impl.cpp Co-authored-by: Romanov Vlad --- sycl/source/detail/platform_impl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index d9daa3b91e086..c89b7dda9023a 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -114,6 +114,7 @@ std::vector platform_impl::get_platforms() { for (const auto &PiPlatform : PiPlatforms) { platform Platform = detail::createSyclObjFromImpl( getOrMakePlatformImpl(PiPlatform, Plugins[i])); + std::lock_guard Guard(*Plugin.getPluginMutex()); // insert PiPlatform into the Plugin Plugins[i].getPlatformId(PiPlatform); // Skip platforms which do not contain requested device types From 972c7894af4ccd4993f8c1cf0b20f1dbbfc1b561 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Tue, 21 Sep 2021 11:00:08 -0700 Subject: [PATCH 54/58] fix plugin index Signed-off-by: Byoungro So --- sycl/source/detail/platform_impl.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index c89b7dda9023a..5f1404ed3c272 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -97,26 +97,26 @@ std::vector platform_impl::get_platforms() { std::vector Platforms; std::vector &Plugins = RT::initialize(); info::device_type ForcedType = detail::get_forced_type(); - for (unsigned int i = 0; i < Plugins.size(); i++) { + for (unsigned int I = 0; I < Plugins.size(); I++) { pi_uint32 NumPlatforms = 0; // Move to the next plugin if the plugin fails to initialize. // This way platforms from other plugins get a chance to be discovered. - if (Plugins[i].call_nocheck( + if (Plugins[I].call_nocheck( 0, nullptr, &NumPlatforms) != PI_SUCCESS) continue; if (NumPlatforms) { std::vector PiPlatforms(NumPlatforms); - if (Plugins[i].call_nocheck( + if (Plugins[I].call_nocheck( NumPlatforms, PiPlatforms.data(), nullptr) != PI_SUCCESS) return Platforms; for (const auto &PiPlatform : PiPlatforms) { platform Platform = detail::createSyclObjFromImpl( - getOrMakePlatformImpl(PiPlatform, Plugins[i])); - std::lock_guard Guard(*Plugin.getPluginMutex()); + getOrMakePlatformImpl(PiPlatform, Plugins[I])); + std::lock_guard Guard(*Plugins[I].getPluginMutex()); // insert PiPlatform into the Plugin - Plugins[i].getPlatformId(PiPlatform); + Plugins[I].getPlatformId(PiPlatform); // Skip platforms which do not contain requested device types if (!Platform.get_devices(ForcedType).empty() && !IsBannedPlatform(Platform)) From 4b2d9bdbefca27a6e95c2c3d6ba2bcac615ad554 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Tue, 21 Sep 2021 14:55:35 -0700 Subject: [PATCH 55/58] fix deadlock Signed-off-by: Byoungro So --- sycl/source/detail/platform_impl.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 5f1404ed3c272..ef3ea4688bec9 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -114,9 +114,11 @@ std::vector platform_impl::get_platforms() { for (const auto &PiPlatform : PiPlatforms) { platform Platform = detail::createSyclObjFromImpl( getOrMakePlatformImpl(PiPlatform, Plugins[I])); - std::lock_guard Guard(*Plugins[I].getPluginMutex()); - // insert PiPlatform into the Plugin - Plugins[I].getPlatformId(PiPlatform); + { + std::lock_guard Guard(*Plugins[I].getPluginMutex()); + // insert PiPlatform into the Plugin + Plugins[I].getPlatformId(PiPlatform); + } // Skip platforms which do not contain requested device types if (!Platform.get_devices(ForcedType).empty() && !IsBannedPlatform(Platform)) From 16d98cb2d423daca27ee842011d759651c64d3ce Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Wed, 22 Sep 2021 10:01:32 -0700 Subject: [PATCH 56/58] Update sycl/source/detail/platform_impl.cpp Co-authored-by: Romanov Vlad --- sycl/source/detail/platform_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index ef3ea4688bec9..327e8c7cc0351 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -97,7 +97,7 @@ std::vector platform_impl::get_platforms() { std::vector Platforms; std::vector &Plugins = RT::initialize(); info::device_type ForcedType = detail::get_forced_type(); - for (unsigned int I = 0; I < Plugins.size(); I++) { + for (plugin &Plugin: Plugins.size()) { pi_uint32 NumPlatforms = 0; // Move to the next plugin if the plugin fails to initialize. // This way platforms from other plugins get a chance to be discovered. From 63de1704feb2b1333d92907e74d229102aa51c23 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Wed, 22 Sep 2021 10:01:41 -0700 Subject: [PATCH 57/58] Update sycl/source/detail/plugin.hpp Co-authored-by: Romanov Vlad --- sycl/source/detail/plugin.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index d660b6dd057bb..d95157d7b0cff 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -231,7 +231,7 @@ class plugin { // Mutex to guard PiPlatforms and LastDeviceIds. // Note that this is a temporary solution until we implement the global // Device/Platform cache later. - std::shared_ptr MPluginMutex; + std::mutex MPluginMutex; // vector of PiPlatforms that belong to this plugin std::vector PiPlatforms; // represents the unique ids of the last device of each platform From 814e1e9376d52fc09b9e043aba5078f1518faa21 Mon Sep 17 00:00:00 2001 From: Byoungro So Date: Wed, 22 Sep 2021 12:28:32 -0700 Subject: [PATCH 58/58] address feedback Signed-off-by: Byoungro So --- sycl/source/detail/platform_impl.cpp | 12 +++---- sycl/source/detail/plugin.hpp | 2 +- sycl/tools/sycl-ls/sycl-ls.cpp | 54 ++++++++++++++++------------ 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 327e8c7cc0351..3823d2322cac9 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -97,27 +97,27 @@ std::vector platform_impl::get_platforms() { std::vector Platforms; std::vector &Plugins = RT::initialize(); info::device_type ForcedType = detail::get_forced_type(); - for (plugin &Plugin: Plugins.size()) { + for (plugin &Plugin : Plugins) { pi_uint32 NumPlatforms = 0; // Move to the next plugin if the plugin fails to initialize. // This way platforms from other plugins get a chance to be discovered. - if (Plugins[I].call_nocheck( + if (Plugin.call_nocheck( 0, nullptr, &NumPlatforms) != PI_SUCCESS) continue; if (NumPlatforms) { std::vector PiPlatforms(NumPlatforms); - if (Plugins[I].call_nocheck( + if (Plugin.call_nocheck( NumPlatforms, PiPlatforms.data(), nullptr) != PI_SUCCESS) return Platforms; for (const auto &PiPlatform : PiPlatforms) { platform Platform = detail::createSyclObjFromImpl( - getOrMakePlatformImpl(PiPlatform, Plugins[I])); + getOrMakePlatformImpl(PiPlatform, Plugin)); { - std::lock_guard Guard(*Plugins[I].getPluginMutex()); + std::lock_guard Guard(*Plugin.getPluginMutex()); // insert PiPlatform into the Plugin - Plugins[I].getPlatformId(PiPlatform); + Plugin.getPlatformId(PiPlatform); } // Skip platforms which do not contain requested device types if (!Platform.get_devices(ForcedType).empty() && diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index d95157d7b0cff..d660b6dd057bb 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -231,7 +231,7 @@ class plugin { // Mutex to guard PiPlatforms and LastDeviceIds. // Note that this is a temporary solution until we implement the global // Device/Platform cache later. - std::mutex MPluginMutex; + std::shared_ptr MPluginMutex; // vector of PiPlatforms that belong to this plugin std::vector PiPlatforms; // represents the unique ids of the last device of each platform diff --git a/sycl/tools/sycl-ls/sycl-ls.cpp b/sycl/tools/sycl-ls/sycl-ls.cpp index 0481d26247838..364382b579211 100644 --- a/sycl/tools/sycl-ls/sycl-ls.cpp +++ b/sycl/tools/sycl-ls/sycl-ls.cpp @@ -54,13 +54,14 @@ std::string getDeviceTypeName(const device &Device) { } } -static void printDeviceInfo(const device &Device, const std::string &Prepend) { +static void printDeviceInfo(const device &Device, bool Verbose, + const std::string &Prepend) { auto DeviceVersion = Device.get_info(); auto DeviceName = Device.get_info(); auto DeviceVendor = Device.get_info(); auto DeviceDriverVersion = Device.get_info(); - if (verbose) { + if (Verbose) { std::cout << Prepend << "Type : " << getDeviceTypeName(Device) << std::endl; std::cout << Prepend << "Version : " << DeviceVersion << std::endl; @@ -68,7 +69,7 @@ static void printDeviceInfo(const device &Device, const std::string &Prepend) { std::cout << Prepend << "Vendor : " << DeviceVendor << std::endl; std::cout << Prepend << "Driver : " << DeviceDriverVersion << std::endl; } else { - std::cout << Prepend << " : " << DeviceName << " " << DeviceVersion << " [" + std::cout << Prepend << ", " << DeviceName << " " << DeviceVersion << " [" << DeviceDriverVersion << "]" << std::endl; } } @@ -80,7 +81,8 @@ static void printSelectorChoice(const device_selector &Selector, std::string DeviceTypeName = getDeviceTypeName(Device); auto Platform = Device.get_info(); auto PlatformName = Platform.get_info(); - printDeviceInfo(Device, Prepend + DeviceTypeName + " : " + PlatformName); + printDeviceInfo(Device, verbose, + Prepend + DeviceTypeName + ", " + PlatformName); } catch (const cl::sycl::runtime_error &Exception) { // Truncate long string so it can fit in one-line std::string What = Exception.what(); @@ -113,17 +115,30 @@ int main(int argc, char **argv) { } const auto &Platforms = platform::get_platforms(); - if (verbose) - std::cout << "Platforms: " << Platforms.size() << std::endl; - uint32_t PlatformNum = 0; // For each backend, device num starts at zero. std::vector DeviceNums(static_cast(backend::all), 0); for (const auto &Platform : Platforms) { backend Backend = Platform.get_backend(); - ++PlatformNum; - if (verbose) { + auto PlatformName = Platform.get_info(); + const auto &Devices = Platform.get_devices(); + for (const auto &Device : Devices) { + uint32_t DeviceNum = DeviceNums[(int)Backend]++; + std::cout << "[" << Backend << ":" << getDeviceTypeName(Device) << ":" + << DeviceNum << "] "; + ++DeviceNum; + // Verbose parameter is set to false to print regular devices output first + printDeviceInfo(Device, false, PlatformName); + } + } + + if (verbose) { + std::cout << "\nPlatforms: " << Platforms.size() << std::endl; + uint32_t PlatformNum = 0; + for (const auto &Platform : Platforms) { + backend Backend = Platform.get_backend(); + ++PlatformNum; auto PlatformVersion = Platform.get_info(); auto PlatformName = Platform.get_info(); auto PlatformVendor = Platform.get_info(); @@ -131,24 +146,17 @@ int main(int argc, char **argv) { std::cout << " Version : " << PlatformVersion << std::endl; std::cout << " Name : " << PlatformName << std::endl; std::cout << " Vendor : " << PlatformVendor << std::endl; - } - const auto &Devices = Platform.get_devices(); - if (verbose) + + const auto &Devices = Platform.get_devices(); std::cout << " Devices : " << Devices.size() << std::endl; - for (const auto &Device : Devices) { - uint32_t DeviceNum = DeviceNums[(int)Backend]++; - if (verbose) + for (const auto &Device : Devices) { + uint32_t DeviceNum = DeviceNums[(int)Backend]++; std::cout << " Device [#" << DeviceNum << "]:" << std::endl; - else { - std::cout << "[" << Backend << ":" << getDeviceTypeName(Device) << ":" - << DeviceNum << "]"; + ++DeviceNum; + printDeviceInfo(Device, true, " "); } - ++DeviceNum; - printDeviceInfo(Device, verbose ? " " : ""); } - } - - if (!verbose) { + } else { return EXIT_SUCCESS; }