From 1757da8ebb807bd7217dc1323d31c00210f16245 Mon Sep 17 00:00:00 2001 From: Ruyman Reyes Date: Wed, 8 Apr 2020 12:40:28 +0000 Subject: [PATCH 01/11] [SYCL][CUDA] Fix for default selection of CUDA devices Signed-off-by: Ruyman Reyes --- sycl/plugins/cuda/pi_cuda.cpp | 2 +- sycl/source/detail/platform_impl.hpp | 6 ++--- .../program_manager/program_manager.cpp | 24 +------------------ sycl/source/device_selector.cpp | 10 ++++---- 4 files changed, 11 insertions(+), 31 deletions(-) diff --git a/sycl/plugins/cuda/pi_cuda.cpp b/sycl/plugins/cuda/pi_cuda.cpp index af15743438da8..556b4df5358d8 100644 --- a/sycl/plugins/cuda/pi_cuda.cpp +++ b/sycl/plugins/cuda/pi_cuda.cpp @@ -684,7 +684,7 @@ pi_result cuda_piPlatformGetInfo(pi_platform platform, switch (param_name) { case PI_PLATFORM_INFO_NAME: return getInfo(param_value_size, param_value, param_value_size_ret, - "NVIDIA CUDA"); + "NVIDIA CUDA BACKEND"); case PI_PLATFORM_INFO_VENDOR: return getInfo(param_value_size, param_value, param_value_size_ret, "NVIDIA Corporation"); diff --git a/sycl/source/detail/platform_impl.hpp b/sycl/source/detail/platform_impl.hpp index 80a62b56af96d..a080efac0e6b8 100644 --- a/sycl/source/detail/platform_impl.hpp +++ b/sycl/source/detail/platform_impl.hpp @@ -74,10 +74,10 @@ class platform_impl { bool is_host() const { return MHostPlatform; }; bool is_cuda() const { - const string_class CUDA_PLATFORM_STRING = "NVIDIA CUDA"; + const string_class CUDA_PLATFORM_STRING = "NVIDIA CUDA BACKEND"; const string_class PlatformName = - get_platform_info::get(MPlatform, - getPlugin()); + get_platform_info::get( + MPlatform, getPlugin()); return PlatformName == CUDA_PLATFORM_STRING; } diff --git a/sycl/source/detail/program_manager/program_manager.cpp b/sycl/source/detail/program_manager/program_manager.cpp index 064638eb8696f..d29cc96ecad03 100644 --- a/sycl/source/detail/program_manager/program_manager.cpp +++ b/sycl/source/detail/program_manager/program_manager.cpp @@ -84,29 +84,7 @@ static RT::PiProgram createBinaryProgram(const ContextImplPtr Context, RT::PiProgram Program; - bool IsCUDA = false; - - // TODO: Implement `piProgramCreateWithBinary` to not require extra logic for - // the CUDA backend. -#if USE_PI_CUDA - // All devices in a context are from the same platform. - RT::PiDevice Device = getFirstDevice(Context); - RT::PiPlatform Platform = nullptr; - Plugin.call(Device, PI_DEVICE_INFO_PLATFORM, sizeof(Platform), - &Platform, nullptr); - size_t PlatformNameSize = 0u; - Plugin.call(Platform, PI_PLATFORM_INFO_NAME, 0u, nullptr, - &PlatformNameSize); - std::vector PlatformName(PlatformNameSize, '\0'); - Plugin.call(Platform, PI_PLATFORM_INFO_NAME, - PlatformName.size(), PlatformName.data(), nullptr); - if (PlatformNameSize > 0u && - std::strncmp(PlatformName.data(), "NVIDIA CUDA", PlatformNameSize) == 0) { - IsCUDA = true; - } -#endif // USE_PI_CUDA - - if (IsCUDA) { + if (Context->getPlatformImpl()->is_cuda()) { // TODO: Reemplace CreateWithSource with CreateWithBinary in CUDA backend const char *SignedData = reinterpret_cast(Data); Plugin.call(Context->getHandleRef(), 1 /*one binary*/, &SignedData, diff --git a/sycl/source/device_selector.cpp b/sycl/source/device_selector.cpp index 6eb1a32d13471..ce8105edc7017 100644 --- a/sycl/source/device_selector.cpp +++ b/sycl/source/device_selector.cpp @@ -43,14 +43,16 @@ int default_selector::operator()(const device &dev) const { const platform platform = dev.get_info(); const std::string platformVersion = platform.get_info();; + const bool HasCudaString = + platformVersion.find("CUDA") != std::string::npos; + const bool HasOpenCLString = + platformVersion.find("OpenCL") != std::string::npos; // If using PI_CUDA, don't accept a non-CUDA device - if (platformVersion.find("CUDA") == std::string::npos && - backend == "PI_CUDA") { + if (HasCudaString && HasOpenCLString && backend == "PI_CUDA") { return -1; } // If using PI_OPENCL, don't accept a non-OpenCL device - if (platformVersion.find("OpenCL") == std::string::npos && - backend == "PI_OPENCL") { + if (HasCudaString && !HasOpenCLString && backend == "PI_OPENCL") { return -1; } } From aa384aec914307e6eb1144cf77ae8605839d8a61 Mon Sep 17 00:00:00 2001 From: Ruyman Reyes Date: Sat, 11 Apr 2020 15:51:36 +0000 Subject: [PATCH 02/11] [SYCL][CUDA] Missing return event on map/unmap Signed-off-by: Ruyman Reyes --- sycl/plugins/cuda/pi_cuda.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/sycl/plugins/cuda/pi_cuda.cpp b/sycl/plugins/cuda/pi_cuda.cpp index 556b4df5358d8..62f8ad91cbe65 100644 --- a/sycl/plugins/cuda/pi_cuda.cpp +++ b/sycl/plugins/cuda/pi_cuda.cpp @@ -3359,6 +3359,13 @@ pi_result cuda_piEnqueueMemBufferMap(pi_queue command_queue, pi_mem buffer, ret_err = cuda_piEnqueueMemBufferRead( command_queue, buffer, blocking_map, offset, size, hostPtr, num_events_in_wait_list, event_wait_list, retEvent); + } else { + if (retEvent) { + auto new_event = + _pi_event::make_native(PI_COMMAND_TYPE_MEM_BUFFER_MAP, command_queue); + new_event->record(); + *retEvent = new_event; + } } return ret_err; @@ -3372,7 +3379,7 @@ pi_result cuda_piEnqueueMemUnmap(pi_queue command_queue, pi_mem memobj, pi_uint32 num_events_in_wait_list, const pi_event *event_wait_list, pi_event *retEvent) { - pi_result ret_err = PI_INVALID_OPERATION; + pi_result ret_err = PI_SUCCESS; assert(mapped_ptr != nullptr); assert(memobj != nullptr); @@ -3385,6 +3392,13 @@ pi_result cuda_piEnqueueMemUnmap(pi_queue command_queue, pi_mem memobj, command_queue, memobj, true, memobj->get_map_offset(mapped_ptr), memobj->get_size(), mapped_ptr, num_events_in_wait_list, event_wait_list, retEvent); + } else { + if (retEvent) { + auto new_event = _pi_event::make_native(PI_COMMAND_TYPE_MEM_BUFFER_UNMAP, + command_queue); + new_event->record(); + *retEvent = new_event; + } } memobj->unmap(mapped_ptr); From f910c930845dc2c2e9cd28514869cfb897f4327c Mon Sep 17 00:00:00 2001 From: Ruyman Reyes Date: Fri, 17 Apr 2020 11:32:10 +0000 Subject: [PATCH 03/11] [SYCL][PI] Equality operator for PI plugins Implemented a comparison operator for the plugin class in SYCL RT: Two plugins are equal if the pointer to their string is the same. plugin constructor marked explicit to avoid accidental implicit conversions. Signed-off-by: Ruyman Reyes --- sycl/source/detail/plugin.hpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 14ddf8f9560e2..9da92c042276a 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -23,7 +23,7 @@ class plugin { public: plugin() = delete; - plugin(RT::PiPlugin Plugin) : MPlugin(Plugin) { + explicit plugin(RT::PiPlugin Plugin) : MPlugin(Plugin) { MPiEnableTrace = (std::getenv("SYCL_PI_TRACE") != nullptr); } @@ -79,6 +79,17 @@ class plugin { bool MPiEnableTrace; }; // class plugin + +/// Two plugins are the same if their string is the same. +/// There is no need to check the actual string, just the pointer, since +/// there is only one instance of the PiPlugin struct per backend. +/// +/// \ingroup sycl_pi +/// +inline bool operator==(const plugin &lhs, const plugin &rhs) { + return (lhs.getPiPlugin().PluginVersion == rhs.getPiPlugin().PluginVersion); +} + } // namespace detail } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) From 195414f9ea3bc2248b88a15afe6e8127ec1338c1 Mon Sep 17 00:00:00 2001 From: Ruyman Reyes Date: Fri, 17 Apr 2020 11:33:50 +0000 Subject: [PATCH 04/11] [SYCL][PI] Queue constr. throws if invalid backend Constructor of the SYCL queue throws an exception if the device passed in is from a different backend than the context that is associated with the queue. Signed-off-by: Ruyman Reyes --- sycl/source/detail/queue_impl.hpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sycl/source/detail/queue_impl.hpp b/sycl/source/detail/queue_impl.hpp index 937223f114c5f..22efcfcbcb4ba 100644 --- a/sycl/source/detail/queue_impl.hpp +++ b/sycl/source/detail/queue_impl.hpp @@ -69,14 +69,16 @@ class queue_impl { : MDevice(Device), MContext(Context), MAsyncHandler(AsyncHandler), MPropList(PropList), MHostQueue(MDevice->is_host()), MOpenCLInterop(!MHostQueue) { - if (!MHostQueue) { - MCommandQueue = createQueue(Order); - } + if (!Context->hasDevice(Device)) throw cl::sycl::invalid_parameter_error( "Queue cannot be constructed with the given context and device " "as the context does not contain the given device.", PI_INVALID_DEVICE); + + if (!MHostQueue) { + MCommandQueue = createQueue(Order); + } } /// Constructs a SYCL queue from plugin interoperability handle. @@ -240,6 +242,8 @@ class queue_impl { RT::PiContext Context = MContext->getHandleRef(); RT::PiDevice Device = MDevice->getHandleRef(); const detail::plugin &Plugin = getPlugin(); + + assert(Plugin == MDevice->getPlugin()); RT::PiResult Error = Plugin.call_nocheck( Context, Device, CreationFlags, &Queue); From 5f611cb88b9a1e645aa0af0a727d16f110d4a2d2 Mon Sep 17 00:00:00 2001 From: Ruyman Reyes Date: Thu, 23 Apr 2020 15:20:40 +0000 Subject: [PATCH 05/11] [SYCL][CUDA] Re-enabled DataMovement test for CUDA Signed-off-by: Ruyman Reyes --- sycl/test/scheduler/DataMovement.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/sycl/test/scheduler/DataMovement.cpp b/sycl/test/scheduler/DataMovement.cpp index 62319e35ccea8..b2a3c33ba1a63 100644 --- a/sycl/test/scheduler/DataMovement.cpp +++ b/sycl/test/scheduler/DataMovement.cpp @@ -1,6 +1,3 @@ -// XFAIL: cuda -// TODO: Fix accidential error return when unmapping read-only memory objects. -// // RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -I %sycl_source_dir %s -o %t.out -g // RUN: %CPU_RUN_PLACEHOLDER %t.out // RUN: %GPU_RUN_PLACEHOLDER %t.out From 09b98590b9d7b44f84d41d3c878aabaef1303891 Mon Sep 17 00:00:00 2001 From: Ruyman Reyes Date: Fri, 24 Apr 2020 10:12:19 +0000 Subject: [PATCH 06/11] [SYCL][CUDA] Using name to check for CUDA platform Fixes previous incorrect usage of version Signed-off-by: Ruyman Reyes --- sycl/source/detail/platform_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/source/detail/platform_impl.hpp b/sycl/source/detail/platform_impl.hpp index a080efac0e6b8..5e2832ccf0d95 100644 --- a/sycl/source/detail/platform_impl.hpp +++ b/sycl/source/detail/platform_impl.hpp @@ -76,8 +76,8 @@ class platform_impl { bool is_cuda() const { const string_class CUDA_PLATFORM_STRING = "NVIDIA CUDA BACKEND"; const string_class PlatformName = - get_platform_info::get( - MPlatform, getPlugin()); + get_platform_info::get(MPlatform, + getPlugin()); return PlatformName == CUDA_PLATFORM_STRING; } From ac3b6f80298f7cb6cbcb1b99028462d6d6cb612f Mon Sep 17 00:00:00 2001 From: Ruyman Reyes Date: Tue, 28 Apr 2020 14:13:09 +0000 Subject: [PATCH 07/11] [SYCL][CUDA] Remove CUDA OpenCL from selection The NVIDIA OpenCL platform is problematic for NVIDIA CUDA backend users and for overall DPCPP users, since it doesnt work straight away and is typically selected on OpenCL backend as a preference. This patch removes the CUDA OpenCL platform from the device selection, and prevents it from being used in the lit testing. Signed-off-by: Ruyman Reyes --- sycl/plugins/opencl/pi_opencl.cpp | 8 +++ sycl/source/detail/context_impl.cpp | 2 +- sycl/source/detail/platform_impl.cpp | 1 + sycl/source/detail/platform_impl.hpp | 8 --- .../program_manager/program_manager.cpp | 2 +- sycl/source/device_selector.cpp | 72 ++++++++++++++++++- sycl/test/basic_tests/get_nonhost_devices.cpp | 2 +- sycl/tools/get_device_count_by_type.cpp | 13 ++++ 8 files changed, 95 insertions(+), 13 deletions(-) diff --git a/sycl/plugins/opencl/pi_opencl.cpp b/sycl/plugins/opencl/pi_opencl.cpp index 733322fe0f577..ca9a0139ffc15 100644 --- a/sycl/plugins/opencl/pi_opencl.cpp +++ b/sycl/plugins/opencl/pi_opencl.cpp @@ -194,6 +194,14 @@ pi_result OCL(piDevicesGet)(pi_platform platform, pi_device_type device_type, *num_devices = 0; result = PI_SUCCESS; } + + // Absorb the CL_INVALID_DEVICE_TYPE error when the device type is + // not supported in some platforms and just return 0 in num_devices + if (result == CL_INVALID_DEVICE_TYPE) { + assert(num_devices != 0); + *num_devices = 0; + result = PI_SUCCESS; + } return cast(result); } diff --git a/sycl/source/detail/context_impl.cpp b/sycl/source/detail/context_impl.cpp index 8353396e7792d..ca57887a499e4 100644 --- a/sycl/source/detail/context_impl.cpp +++ b/sycl/source/detail/context_impl.cpp @@ -41,7 +41,7 @@ context_impl::context_impl(const vector_class Devices, DeviceIds.push_back(getSyclObjImpl(D)->getHandleRef()); } - if (MPlatform->is_cuda()) { + if (MPlatform->getPlugin().getBackend() == backend::cuda) { #if USE_PI_CUDA const pi_context_properties props[] = {PI_CONTEXT_PROPERTIES_CUDA_PRIMARY, UseCUDAPrimaryContext, 0}; diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 10fd2d0fc9aa2..7db4644145098 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -211,6 +211,7 @@ platform_impl::get_devices(info::device_type DeviceType) const { pi_uint32 NumDevices; const detail::plugin &Plugin = getPlugin(); + Plugin.call( MPlatform, pi::cast(DeviceType), 0, pi::cast(nullptr), &NumDevices); diff --git a/sycl/source/detail/platform_impl.hpp b/sycl/source/detail/platform_impl.hpp index 5e2832ccf0d95..cc2597f7a7a9e 100644 --- a/sycl/source/detail/platform_impl.hpp +++ b/sycl/source/detail/platform_impl.hpp @@ -73,14 +73,6 @@ class platform_impl { /// \return true if this SYCL platform is a host platform. bool is_host() const { return MHostPlatform; }; - bool is_cuda() const { - const string_class CUDA_PLATFORM_STRING = "NVIDIA CUDA BACKEND"; - const string_class PlatformName = - get_platform_info::get(MPlatform, - getPlugin()); - return PlatformName == CUDA_PLATFORM_STRING; - } - /// \return an instance of OpenCL cl_platform_id. cl_platform_id get() const { if (is_host()) diff --git a/sycl/source/detail/program_manager/program_manager.cpp b/sycl/source/detail/program_manager/program_manager.cpp index 88c79f3d76143..b3fc271cc8bf6 100644 --- a/sycl/source/detail/program_manager/program_manager.cpp +++ b/sycl/source/detail/program_manager/program_manager.cpp @@ -85,7 +85,7 @@ static RT::PiProgram createBinaryProgram(const ContextImplPtr Context, RT::PiProgram Program; - if (Context->getPlatformImpl()->is_cuda()) { + if (Context->getPlugin().getBackend() == backend::cuda) { // TODO: Reemplace CreateWithSource with CreateWithBinary in CUDA backend const char *SignedData = reinterpret_cast(Data); Plugin.call(Context->getHandleRef(), 1 /*one binary*/, &SignedData, diff --git a/sycl/source/device_selector.cpp b/sycl/source/device_selector.cpp index aba27e0c926fa..23a9e6e31a9b4 100644 --- a/sycl/source/device_selector.cpp +++ b/sycl/source/device_selector.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include // 4.6.1 Device selection class @@ -28,11 +29,60 @@ static bool isDeviceOfPreferredSyclBe(const device &Device) { backend::opencl; } +// @return True if the device is invalid for the current backend preferences +static bool isDeviceInvalidForBe(const device &Device) { + + if (Device.is_host()) + return false; + + // Taking the version information from the platform gives us more useful + // information than the driver_version of the device. + const platform platform = Device.get_info(); + const std::string platformVersion = + platform.get_info(); + + backend *BackendPref = detail::SYCLConfig::get(); + auto BackendType = detail::getSyclObjImpl(Device)->getPlugin().getBackend(); + static_assert(std::is_same(), + "Type is not the same"); + + // If no preference, assume OpenCL and reject CUDA backend + if (BackendType == backend::cuda && !BackendPref) { + return true; + } else if (!BackendPref) + return false; + + // If using PI_CUDA, don't accept a non-CUDA device + if (BackendType == backend::opencl && *BackendPref == backend::cuda) + return true; + + // If using PI_OPENCL, don't accept a non-OpenCL device + if (BackendType == backend::cuda && *BackendPref == backend::opencl) + return true; + + return false; +} + device device_selector::select_device() const { vector_class devices = device::get_devices(); int score = -1; const device *res = nullptr; for (const auto &dev : devices) { + + // Reject the NVIDIA OpenCL platform + if (!dev.is_host()) { + string_class PlatformName = dev.get_info() + .get_info(); + const bool IsCUDAPlatform = + PlatformName.find("CUDA") != std::string::npos; + + if (detail::getSyclObjImpl(dev)->getPlugin().getBackend() == + backend::opencl && + IsCUDAPlatform) { + continue; + } + } + int dev_score = (*this)(dev); if (detail::pi::trace(detail::pi::TraceLevel::PI_TRACE_ALL)) { string_class PlatformVersion = dev.get_info() @@ -81,6 +131,9 @@ int default_selector::operator()(const device &dev) const { int Score = -1; + if (isDeviceInvalidForBe(dev)) + return -1; + // Give preference to device of SYCL BE. if (isDeviceOfPreferredSyclBe(dev)) Score = 50; @@ -103,19 +156,28 @@ int default_selector::operator()(const device &dev) const { int gpu_selector::operator()(const device &dev) const { int Score = -1; + + if (isDeviceInvalidForBe(dev)) + return -1; + if (dev.is_gpu()) { Score = 1000; // Give preference to device of SYCL BE. if (isDeviceOfPreferredSyclBe(dev)) - Score += 50; + Score = 50; } return Score; } int cpu_selector::operator()(const device &dev) const { int Score = -1; + + if (isDeviceInvalidForBe(dev)) + return -1; + if (dev.is_cpu()) { Score = 1000; + // Give preference to device of SYCL BE. if (isDeviceOfPreferredSyclBe(dev)) Score += 50; @@ -125,6 +187,10 @@ int cpu_selector::operator()(const device &dev) const { int accelerator_selector::operator()(const device &dev) const { int Score = -1; + + if (isDeviceInvalidForBe(dev)) + return -1; + if (dev.is_accelerator()) { Score = 1000; // Give preference to device of SYCL BE. @@ -139,8 +205,10 @@ int host_selector::operator()(const device &dev) const { if (dev.is_host()) { Score = 1000; // Give preference to device of SYCL BE. - if (isDeviceOfPreferredSyclBe(dev)) + if (isDeviceOfPreferredSyclBe(dev)) { Score += 50; + } else if (isDeviceInvalidForBe(dev)) + return -1; } return Score; } diff --git a/sycl/test/basic_tests/get_nonhost_devices.cpp b/sycl/test/basic_tests/get_nonhost_devices.cpp index aefbfafce82cf..9a41965442874 100644 --- a/sycl/test/basic_tests/get_nonhost_devices.cpp +++ b/sycl/test/basic_tests/get_nonhost_devices.cpp @@ -1,4 +1,4 @@ -// RUN: %clangxx -fsycl %s -o %t.out +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out // RUN: %t.out // Check that the host device is not included in devices returned by diff --git a/sycl/tools/get_device_count_by_type.cpp b/sycl/tools/get_device_count_by_type.cpp index 31d741950730b..81e6a22a54551 100644 --- a/sycl/tools/get_device_count_by_type.cpp +++ b/sycl/tools/get_device_count_by_type.cpp @@ -8,6 +8,7 @@ #include #include +#include #ifdef USE_PI_CUDA #include @@ -82,6 +83,18 @@ static bool queryOpenCL(cl_device_type deviceType, cl_uint &deviceCount, } for (cl_uint i = 0; i < platformCount; i++) { + + const size_t MAX_PLATFORM_VENDOR = 100u; + char info[MAX_PLATFORM_VENDOR]; + // get platform attribute value + clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, MAX_PLATFORM_VENDOR, + info, NULL); + auto IsNVIDIAOpenCL = strstr(info, "NVIDIA") != NULL; + if (IsNVIDIAOpenCL) { + // Ignore NVIDIA OpenCL platform for testing + continue; + } + cl_uint deviceCountPart = 0; iRet = clGetDeviceIDs(platforms[i], deviceType, 0, nullptr, &deviceCountPart); From 70a3e08e0733f2dbef52c74f141ddd73a0486598 Mon Sep 17 00:00:00 2001 From: Ruyman Reyes Date: Wed, 29 Apr 2020 10:13:26 +0000 Subject: [PATCH 08/11] [SYCL][PI] Equality of plugins per backend Defines two plugins being equal if their backend types are the same. Signed-off-by: Ruyman Reyes --- 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 df01522d919cb..0f0057445619b 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -88,7 +88,7 @@ class plugin { /// \ingroup sycl_pi /// inline bool operator==(const plugin &lhs, const plugin &rhs) { - return (lhs.getPiPlugin().PluginVersion == rhs.getPiPlugin().PluginVersion); + return (lhs.getBackend() == rhs.getBackend()); } } // namespace detail From 17480e05ea46f256636cec59ab92ebfa13261e8a Mon Sep 17 00:00:00 2001 From: Ruyman Reyes Date: Wed, 29 Apr 2020 20:33:48 +0000 Subject: [PATCH 09/11] [SYCL][CUDA] CUDA OpenCL platform ignored in get_devices CUDA OpenCL platform is ignored on get_devices as suggested by feedback Signed-off-by: Ruyman Reyes --- sycl/source/detail/platform_impl.cpp | 38 ++++++++++++++++++++ sycl/source/device_selector.cpp | 53 ++-------------------------- 2 files changed, 41 insertions(+), 50 deletions(-) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 7db4644145098..6f4150fe62758 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -196,6 +196,41 @@ static void filterAllowList(vector_class &PiDevices, PiDevices.resize(InsertIDx); } + +// @return True if the device is invalid for the current backend preferences +static bool isDeviceInvalidForBe(const device &Device) { + + if (Device.is_host()) + return false; + + // Taking the version information from the platform gives us more useful + // information than the driver_version of the device. + const platform platform = Device.get_info(); + const std::string platformVersion = + platform.get_info(); + + backend *BackendPref = detail::SYCLConfig::get(); + auto BackendType = detail::getSyclObjImpl(Device)->getPlugin().getBackend(); + static_assert(std::is_same(), + "Type is not the same"); + + // If no preference, assume OpenCL and reject CUDA backend + if (BackendType == backend::cuda && !BackendPref) { + return true; + } else if (!BackendPref) + return false; + + // If using PI_CUDA, don't accept a non-CUDA device + if (BackendType == backend::opencl && *BackendPref == backend::cuda) + return true; + + // If using PI_OPENCL, don't accept a non-OpenCL device + if (BackendType == backend::cuda && *BackendPref == backend::opencl) + return true; + + return false; +} + vector_class platform_impl::get_devices(info::device_type DeviceType) const { vector_class Res; @@ -236,6 +271,9 @@ platform_impl::get_devices(info::device_type DeviceType) const { PiDevice, std::make_shared(*this))); }); + Res.erase(std::remove_if(Res.begin(), Res.end(), isDeviceInvalidForBe), + Res.end()); + return Res; } diff --git a/sycl/source/device_selector.cpp b/sycl/source/device_selector.cpp index 23a9e6e31a9b4..3721c2a9468bb 100644 --- a/sycl/source/device_selector.cpp +++ b/sycl/source/device_selector.cpp @@ -29,40 +29,6 @@ static bool isDeviceOfPreferredSyclBe(const device &Device) { backend::opencl; } -// @return True if the device is invalid for the current backend preferences -static bool isDeviceInvalidForBe(const device &Device) { - - if (Device.is_host()) - return false; - - // Taking the version information from the platform gives us more useful - // information than the driver_version of the device. - const platform platform = Device.get_info(); - const std::string platformVersion = - platform.get_info(); - - backend *BackendPref = detail::SYCLConfig::get(); - auto BackendType = detail::getSyclObjImpl(Device)->getPlugin().getBackend(); - static_assert(std::is_same(), - "Type is not the same"); - - // If no preference, assume OpenCL and reject CUDA backend - if (BackendType == backend::cuda && !BackendPref) { - return true; - } else if (!BackendPref) - return false; - - // If using PI_CUDA, don't accept a non-CUDA device - if (BackendType == backend::opencl && *BackendPref == backend::cuda) - return true; - - // If using PI_OPENCL, don't accept a non-OpenCL device - if (BackendType == backend::cuda && *BackendPref == backend::opencl) - return true; - - return false; -} - device device_selector::select_device() const { vector_class devices = device::get_devices(); int score = -1; @@ -102,7 +68,8 @@ device device_selector::select_device() const { // preference to the device of the preferred BE. // if (score < dev_score || - (score == dev_score && isDeviceOfPreferredSyclBe(dev))) { + (score == dev_score && isDeviceOfPreferredSyclBe(dev) + && dev_score != -1)) { res = &dev; score = dev_score; } @@ -131,9 +98,6 @@ int default_selector::operator()(const device &dev) const { int Score = -1; - if (isDeviceInvalidForBe(dev)) - return -1; - // Give preference to device of SYCL BE. if (isDeviceOfPreferredSyclBe(dev)) Score = 50; @@ -157,9 +121,6 @@ int default_selector::operator()(const device &dev) const { int gpu_selector::operator()(const device &dev) const { int Score = -1; - if (isDeviceInvalidForBe(dev)) - return -1; - if (dev.is_gpu()) { Score = 1000; // Give preference to device of SYCL BE. @@ -172,9 +133,6 @@ int gpu_selector::operator()(const device &dev) const { int cpu_selector::operator()(const device &dev) const { int Score = -1; - if (isDeviceInvalidForBe(dev)) - return -1; - if (dev.is_cpu()) { Score = 1000; @@ -188,9 +146,6 @@ int cpu_selector::operator()(const device &dev) const { int accelerator_selector::operator()(const device &dev) const { int Score = -1; - if (isDeviceInvalidForBe(dev)) - return -1; - if (dev.is_accelerator()) { Score = 1000; // Give preference to device of SYCL BE. @@ -205,10 +160,8 @@ int host_selector::operator()(const device &dev) const { if (dev.is_host()) { Score = 1000; // Give preference to device of SYCL BE. - if (isDeviceOfPreferredSyclBe(dev)) { + if (isDeviceOfPreferredSyclBe(dev)) Score += 50; - } else if (isDeviceInvalidForBe(dev)) - return -1; } return Score; } From 66810be1ac563195244e1d30692cf174c2502a91 Mon Sep 17 00:00:00 2001 From: Ruyman Reyes Date: Wed, 29 Apr 2020 20:40:27 +0000 Subject: [PATCH 10/11] [SYCL] clang-format affected files Signed-off-by: Ruyman Reyes --- sycl/source/detail/platform_impl.cpp | 5 ++--- sycl/source/device_selector.cpp | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 6f4150fe62758..307519df91040 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -196,7 +196,6 @@ static void filterAllowList(vector_class &PiDevices, PiDevices.resize(InsertIDx); } - // @return True if the device is invalid for the current backend preferences static bool isDeviceInvalidForBe(const device &Device) { @@ -271,8 +270,8 @@ platform_impl::get_devices(info::device_type DeviceType) const { PiDevice, std::make_shared(*this))); }); - Res.erase(std::remove_if(Res.begin(), Res.end(), isDeviceInvalidForBe), - Res.end()); + Res.erase(std::remove_if(Res.begin(), Res.end(), isDeviceInvalidForBe), + Res.end()); return Res; } diff --git a/sycl/source/device_selector.cpp b/sycl/source/device_selector.cpp index 3721c2a9468bb..e29d37e706275 100644 --- a/sycl/source/device_selector.cpp +++ b/sycl/source/device_selector.cpp @@ -68,8 +68,8 @@ device device_selector::select_device() const { // preference to the device of the preferred BE. // if (score < dev_score || - (score == dev_score && isDeviceOfPreferredSyclBe(dev) - && dev_score != -1)) { + (score == dev_score && isDeviceOfPreferredSyclBe(dev) && + dev_score != -1)) { res = &dev; score = dev_score; } From ad3951cb31899cdac307b12ef13114ba64064d71 Mon Sep 17 00:00:00 2001 From: Ruyman Reyes Date: Thu, 30 Apr 2020 11:01:07 +0000 Subject: [PATCH 11/11] [SYCL][CUDA] CUDA Device selection changes * Removes NVIDIA OpenCL from the available list of platforms * CUDA backend is available only if SYCL_BE=PI_CUDA is set Signed-off-by: Ruyman Reyes --- sycl/source/detail/platform_impl.cpp | 28 ++++++++++++++-------------- sycl/source/device_selector.cpp | 20 +------------------- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 307519df91040..a8ea3c213852e 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -202,29 +202,29 @@ static bool isDeviceInvalidForBe(const device &Device) { if (Device.is_host()) return false; - // Taking the version information from the platform gives us more useful - // information than the driver_version of the device. + // Retrieve Platform version to identify CUDA OpenCL platform + // String: OpenCL 1.2 CUDA const platform platform = Device.get_info(); const std::string platformVersion = platform.get_info(); + const bool HasOpenCL = (platformVersion.find("OpenCL") != std::string::npos); + const bool HasCUDA = (platformVersion.find("CUDA") != std::string::npos); - backend *BackendPref = detail::SYCLConfig::get(); - auto BackendType = detail::getSyclObjImpl(Device)->getPlugin().getBackend(); - static_assert(std::is_same(), - "Type is not the same"); + backend *PrefBackend = detail::SYCLConfig::get(); + auto DeviceBackend = detail::getSyclObjImpl(Device)->getPlugin().getBackend(); - // If no preference, assume OpenCL and reject CUDA backend - if (BackendType == backend::cuda && !BackendPref) { + // Reject the NVIDIA OpenCL implementation + if (DeviceBackend == backend::opencl && HasCUDA && HasOpenCL) return true; - } else if (!BackendPref) - return false; - // If using PI_CUDA, don't accept a non-CUDA device - if (BackendType == backend::opencl && *BackendPref == backend::cuda) + // If no preference, assume OpenCL and reject CUDA + if (DeviceBackend == backend::cuda && !PrefBackend) { return true; + } else if (!PrefBackend) + return false; - // If using PI_OPENCL, don't accept a non-OpenCL device - if (BackendType == backend::cuda && *BackendPref == backend::opencl) + // If using PI_OPENCL, reject the CUDA backend + if (DeviceBackend == backend::cuda && *PrefBackend == backend::opencl) return true; return false; diff --git a/sycl/source/device_selector.cpp b/sycl/source/device_selector.cpp index e29d37e706275..d7e0a586bde81 100644 --- a/sycl/source/device_selector.cpp +++ b/sycl/source/device_selector.cpp @@ -34,21 +34,6 @@ device device_selector::select_device() const { int score = -1; const device *res = nullptr; for (const auto &dev : devices) { - - // Reject the NVIDIA OpenCL platform - if (!dev.is_host()) { - string_class PlatformName = dev.get_info() - .get_info(); - const bool IsCUDAPlatform = - PlatformName.find("CUDA") != std::string::npos; - - if (detail::getSyclObjImpl(dev)->getPlugin().getBackend() == - backend::opencl && - IsCUDAPlatform) { - continue; - } - } - int dev_score = (*this)(dev); if (detail::pi::trace(detail::pi::TraceLevel::PI_TRACE_ALL)) { string_class PlatformVersion = dev.get_info() @@ -95,9 +80,7 @@ device device_selector::select_device() const { } int default_selector::operator()(const device &dev) const { - int Score = -1; - // Give preference to device of SYCL BE. if (isDeviceOfPreferredSyclBe(dev)) Score = 50; @@ -120,12 +103,11 @@ int default_selector::operator()(const device &dev) const { int gpu_selector::operator()(const device &dev) const { int Score = -1; - if (dev.is_gpu()) { Score = 1000; // Give preference to device of SYCL BE. if (isDeviceOfPreferredSyclBe(dev)) - Score = 50; + Score += 50; } return Score; }