From 5c30ab7d1def72aa9a4d6df95366567e96732ffe Mon Sep 17 00:00:00 2001 From: Gail Lyons Date: Thu, 3 Sep 2020 06:55:50 -0700 Subject: [PATCH 1/9] SYCL_DEVICE_ALLOWLIST fix. WIP Signed-off-by: Gail Lyons --- sycl/source/detail/platform_impl.cpp | 21 ++- sycl/test/config/select_device.cpp | 229 +++++++++++++++++++++++++++ 2 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 sycl/test/config/select_device.cpp diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 34fc9bd09e119..1cc0db91aa8de 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -134,8 +134,8 @@ struct DevDescT { }; static std::vector getAllowListDesc() { - const char *str = SYCLConfig::get(); - if (!str) + const char *Str = SYCLConfig::get(); + if (!Str) return {}; std::vector decDescs; @@ -144,6 +144,23 @@ static std::vector getAllowListDesc() { const char platformNameStr[] = "PlatformName"; const char platformVerStr[] = "PlatformVersion"; decDescs.emplace_back(); + + std::cout << "Before: " << Str << std::endl; + + // Replace common special symbols with '.' which matches to any character +#if 0 // gail + std::string tmp(Str); + std::replace_if(tmp.begin(), tmp.end(), + [](const char sym) { return '(' == sym || ')' == sym; }, '.'); + const char * str = tmp.c_str(); +#endif //gail + + std::string tmp(Str); + std::replace(tmp.begin(), tmp.end(), '(', '.'); + std::replace(tmp.begin(), tmp.end(), ')', '.'); + const char * str = tmp.c_str(); + std::cout << "After : " << str << std::endl; + while ('\0' != *str) { const char **valuePtr = nullptr; int *size = nullptr; diff --git a/sycl/test/config/select_device.cpp b/sycl/test/config/select_device.cpp new file mode 100644 index 0000000000000..d26fa64f58097 --- /dev/null +++ b/sycl/test/config/select_device.cpp @@ -0,0 +1,229 @@ +// RUN: %clangxx -fsycl %s -o %t.out +// +// RUN: env WRITE_DEVICE_INFO=1 %t.out +// RUN: env READ_DEVICE_INFO=1 %t.out +// +// RUN: env WRITE_PLATFORM_INFO=1 %t.out +// RUN: env READ_PLATFORM_INFO=1 %t.out + +//==------------ select_device.cpp - SYCL_DEVICE_ALLOWLIST test ------------==// +// +// This test is unusual because it occurs in two phases. The first phase +// will find the GPU platforms, and write them to a file. The second phase +// will read the file, set SYCL_DEVICE_ALLOWLIST, and then find the correct +// platform. SYCL_DEVICE_ALLOWLIST is only evaluated once, the first time +// get_platforms() is called. Setting it later in the application has no +// effect. +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include + +using namespace cl::sycl; + +#ifdef _WIN32 +#define setenv(name, value, overwrite) _putenv_s (name, value) +#endif + +struct DevDescT { + std::string devName; + std::string devDriverVer; + std::string platName; + std::string platVer; +}; + +static std::vector getAllowListDesc(std::string allowList) { + if (allowList.empty()) + return {}; + + std::string deviceName("DeviceName:"); + std::string driverVersion("DriverVersion:"); + std::string platformName("PlatformName:"); + std::string platformVersion("PlatformVersion:"); + std::vector decDescs; + + size_t pos = 0; + while ( pos <= allowList.size()) { + decDescs.emplace_back(); + + if ((allowList.compare(pos, deviceName.size(), deviceName)) == 0) { + if ((pos = allowList.find("{{", pos)) == std::string::npos) { + throw std::runtime_error("Malformed device allowlist"); + } + size_t start = pos+2; + if ((pos = allowList.find("}},", pos)) == std::string::npos) { + throw std::runtime_error("Malformed device allowlist"); + } + decDescs.back().devName = allowList.substr(start, pos-start); + pos = pos+3; + if ((allowList.compare(pos, driverVersion.size(), driverVersion)) == 0) { + if ((pos = allowList.find("{{", pos)) == std::string::npos) { + throw std::runtime_error("Malformed device allowlist"); + } + start = pos+2; + if ((pos = allowList.find("}}", pos)) == std::string::npos) { + throw std::runtime_error("Malformed device allowlist"); + } + decDescs.back().devDriverVer = allowList.substr(start, pos-start); + pos = pos+3; + } else { + throw std::runtime_error("Malformed device allowlist"); + } + } + else if ((allowList.compare(pos, platformName.size(), platformName)) == 0) { + if ((pos = allowList.find("{{", pos)) == std::string::npos) { + throw std::runtime_error("Malformed platform allowlist"); + } + size_t start = pos+2; + if ((pos = allowList.find("}},", pos)) == std::string::npos) { + throw std::runtime_error("Malformed platform allowlist"); + } + decDescs.back().platName = allowList.substr(start, pos-start); + pos = pos+3; + if ((allowList.compare(pos, platformVersion.size(), platformVersion)) == 0) { + if ((pos = allowList.find("{{", pos)) == std::string::npos) { + throw std::runtime_error("Malformed platform allowlist"); + } + start = pos+2; + if ((pos = allowList.find("}}", pos)) == std::string::npos) { + throw std::runtime_error("Malformed platform allowlist"); + } + decDescs.back().platVer = allowList.substr(start, pos-start); + pos = pos+3; + } else { + throw std::runtime_error("Malformed platform allowlist"); + } + } + else if (allowList.find('|', pos) != std::string::npos) { + pos = allowList.find('|')+1; + while (allowList[pos] == ' ') { + pos++; + } + } + else { + throw std::runtime_error("Malformed platform allowlist"); + } + } // while (pos <= allowList.size()) + return decDescs; +} + + +int main() { + bool passed = false; + + // Find the GPU devices on this system + if (getenv("WRITE_DEVICE_INFO")) { + std::ofstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + for (const auto &plt : platform::get_platforms()) { + if (!plt.has(aspect::host)){ + for (const auto &dev : plt.get_devices()) { + if (dev.has(aspect::gpu)) { + std::string name = dev.get_info(); + std::string ver = dev.get_info(); + fs << "DeviceName:{{" << name + << "}},DriverVersion:{{" << ver << "}}" << std::endl; + passed=true; + break; + } + } + } + } + fs.close(); + } + } + else if (getenv("READ_DEVICE_INFO")) { + std::ifstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + std::string allowlist; + std::getline(fs, allowlist); + if (! allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + + cl::sycl::queue deviceQueue(gpu_selector{}); + device dev = deviceQueue.get_device(); + for (const DevDescT &desc : components) { + if ((dev.get_info() == desc.devName) && + (dev.get_info() == + desc.devDriverVer)) { + passed = true; + } + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + std::cout << "Device: " << dev.get_info() + << std::endl; + std::cout << "DriverVersion: " + << dev.get_info() + << std::endl; + } + } + fs.close(); + } + } + // Find the platforms on this system. + if (getenv("WRITE_PLATFORM_INFO")) { + std::ofstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + for (const auto &plt : platform::get_platforms()) { + if (plt.has(aspect::gpu)){ + std::string pname = plt.get_info(); + std::string pver = plt.get_info(); + fs << "PlatformName:{{" << pname + << "}},PlatformVersion:{{" << pver << "}}" << std::endl; + passed=true; + break; + } + } + } + fs.close(); + } + else if (getenv("READ_PLATFORM_INFO")) { + std::ifstream fs; + fs.open("select_device_config.txt", std::fstream::in); + if (fs.is_open()) { + std::string allowlist; + std::getline(fs, allowlist); + if (! allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + + for (const auto &plt : platform::get_platforms()) { + if (!plt.has(aspect::host)){ + for (const DevDescT &desc : components) { + if ((plt.get_info() == desc.platName) && + (plt.get_info() == + desc.platVer)) { + passed = true; + } + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + std::cout << "Platform: " << plt.get_info() + << std::endl; + std::cout << "Platform Version: " + << plt.get_info() + << std::endl; + } + } + } + } + fs.close(); + } + } + + if (passed) { + std::cout << "Passed." << std::endl; + return 0; + } else { + std:: cout << "Failed." << std::endl; + return 1; + } +} From dc5c005d56cb8c526d5dbbc66e58ae4b819db81c Mon Sep 17 00:00:00 2001 From: Gail Lyons Date: Wed, 16 Sep 2020 11:59:33 -0700 Subject: [PATCH 2/9] [SYCL] Additional support for SYCL_DEVICE_ALLOWLIST Added support for the case where multiple devices or platforms are listed in SYCL_DEVICE_ALLOWLIST. Also fixed a memory issue. Created a test case which tests both legal and illegal uses. Updated the documentation. Signed-off-by: Gail Lyons --- sycl/doc/EnvironmentVariables.md | 2 +- sycl/source/detail/platform_impl.cpp | 300 ++++++---- sycl/test/config/select_device.cpp | 834 ++++++++++++++++++++++++--- 3 files changed, 944 insertions(+), 192 deletions(-) diff --git a/sycl/doc/EnvironmentVariables.md b/sycl/doc/EnvironmentVariables.md index 0a1dcd0a03198..9eac42b39648f 100644 --- a/sycl/doc/EnvironmentVariables.md +++ b/sycl/doc/EnvironmentVariables.md @@ -22,7 +22,7 @@ subject to change. Do not rely on these variables in production code. | SYCL_DISABLE_EXECUTION_GRAPH_CLEANUP | Any(\*) | Disable cleanup of finished command nodes at host-device synchronization points. | | SYCL_THROW_ON_BLOCK | Any(\*) | Throw an exception on attempt to wait for a blocked command. | | SYCL_DEVICELIB_INHIBIT_NATIVE | String of device library extensions (separated by a whitespace) | Do not rely on device native support for devicelib extensions listed in this option. | -| SYCL_DEVICE_ALLOWLIST | A list of devices and their minimum driver version following the pattern: DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}. Also may contain PlatformName and PlatformVersion | Filter out devices that do not match the pattern specified. Regular expression can be passed and the DPC++ runtime will select only those devices which satisfy the regex. | +| SYCL_DEVICE_ALLOWLIST | A list of devices and their minimum driver version following the pattern: DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}. Also may contain PlatformName and PlatformVersion | Filter out devices that do not match the pattern specified. Regular expression can be passed and the DPC++ runtime will select only those devices which satisfy the regex. Note that the device name, platform name and their respective versions are regular expression. Special characters, such as parenthesis, must be escaped. | | SYCL_QUEUE_THREAD_POOL_SIZE | Positive integer | Number of threads in thread pool of queue. | | SYCL_DEVICELIB_NO_FALLBACK | Any(\*) | Disable loading and linking of device library images | | SYCL_PI_LEVEL0_MAX_COMMAND_LIST_CACHE | Positive integer | Maximum number of oneAPI Level Zero Command lists that can be allocated with no reuse before throwing an "out of resources" error. Default is 20000, threshold may be increased based on resource availabilty and workload demand. | diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 1cc0db91aa8de..838ee5514fc6c 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -16,6 +16,7 @@ #include #include #include +#include __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { @@ -121,112 +122,172 @@ vector_class platform_impl::get_platforms() { } struct DevDescT { - const char *devName = nullptr; - int devNameSize = 0; - const char *devDriverVer = nullptr; - int devDriverVerSize = 0; - - const char *platformName = nullptr; - int platformNameSize = 0; - - const char *platformVer = nullptr; - int platformVerSize = 0; + std::string devName; + std::string devDriverVer; + std::string platName; + std::string platVer; }; static std::vector getAllowListDesc() { - const char *Str = SYCLConfig::get(); - if (!Str) + std::string allowList(SYCLConfig::get()); + if (allowList.empty()) return {}; + std::string deviceName("DeviceName:"); + std::string driverVersion("DriverVersion:"); + std::string platformName("PlatformName:"); + std::string platformVersion("PlatformVersion:"); std::vector decDescs; - const char devNameStr[] = "DeviceName"; - const char driverVerStr[] = "DriverVersion"; - const char platformNameStr[] = "PlatformName"; - const char platformVerStr[] = "PlatformVersion"; decDescs.emplace_back(); - std::cout << "Before: " << Str << std::endl; - - // Replace common special symbols with '.' which matches to any character -#if 0 // gail - std::string tmp(Str); - std::replace_if(tmp.begin(), tmp.end(), - [](const char sym) { return '(' == sym || ')' == sym; }, '.'); - const char * str = tmp.c_str(); -#endif //gail - - std::string tmp(Str); - std::replace(tmp.begin(), tmp.end(), '(', '.'); - std::replace(tmp.begin(), tmp.end(), ')', '.'); - const char * str = tmp.c_str(); - std::cout << "After : " << str << std::endl; - - while ('\0' != *str) { - const char **valuePtr = nullptr; - int *size = nullptr; - - // -1 to avoid comparing null terminator - if (0 == strncmp(devNameStr, str, sizeof(devNameStr) - 1)) { - valuePtr = &decDescs.back().devName; - size = &decDescs.back().devNameSize; - str += sizeof(devNameStr) - 1; - } else if (0 == - strncmp(platformNameStr, str, sizeof(platformNameStr) - 1)) { - valuePtr = &decDescs.back().platformName; - size = &decDescs.back().platformNameSize; - str += sizeof(platformNameStr) - 1; - } else if (0 == strncmp(platformVerStr, str, sizeof(platformVerStr) - 1)) { - valuePtr = &decDescs.back().platformVer; - size = &decDescs.back().platformVerSize; - str += sizeof(platformVerStr) - 1; - } else if (0 == strncmp(driverVerStr, str, sizeof(driverVerStr) - 1)) { - valuePtr = &decDescs.back().devDriverVer; - size = &decDescs.back().devDriverVerSize; - str += sizeof(driverVerStr) - 1; - } else { - throw sycl::runtime_error("Unrecognized key in device allowlist", - PI_INVALID_VALUE); - } + size_t pos = 0; + size_t prev = pos; + while (pos < allowList.size()) { + if ((allowList.compare(pos, deviceName.size(), deviceName)) == 0) { + prev = pos; + if ((pos = allowList.find("{{", pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } + if (pos > prev + deviceName.size()) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } - if (':' != *str) - throw sycl::runtime_error("Malformed device allowlist", PI_INVALID_VALUE); + pos = pos + 2; + size_t start = pos; + if ((pos = allowList.find("}}", pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } + decDescs.back().devName = allowList.substr(start, pos - start); + pos = pos + 2; - // Skip ':' - str += 1; + if (allowList[pos] == ',') { + pos++; + } + } - if ('{' != *str || '{' != *(str + 1)) - throw sycl::runtime_error("Malformed device allowlist", PI_INVALID_VALUE); + else if ((allowList.compare(pos, driverVersion.size(), driverVersion)) == + 0) { + prev = pos; + if ((pos = allowList.find("{{", pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } + if (pos > prev + driverVersion.size()) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } - // Skip opening sequence "{{" - str += 2; + size_t start = pos + 2; + if ((pos = allowList.find("}}", pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } + decDescs.back().devDriverVer = allowList.substr(start, pos - start); + pos = pos + 2; - *valuePtr = str; + if (allowList[pos] == ',') { + pos++; + } + } + + else if ((allowList.compare(pos, platformName.size(), platformName)) == 0) { + prev = pos; + if ((pos = allowList.find("{{", pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } + if (pos > prev + platformName.size()) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } - // Increment until closing sequence is encountered - while (('\0' != *str) && ('}' != *str || '}' != *(str + 1))) - ++str; + size_t start = pos + 2; + if ((pos = allowList.find("}}", pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } + decDescs.back().platName = allowList.substr(start, pos - start); + pos = pos + 2; - if ('\0' == *str) - throw sycl::runtime_error("Malformed device allowlist", PI_INVALID_VALUE); + if (allowList[pos] == ',') { + pos++; + } - *size = str - *valuePtr; + } - // Skip closing sequence "}}" - str += 2; + else if ((allowList.compare(pos, platformVersion.size(), + platformVersion)) == 0) { + prev = pos; + if ((pos = allowList.find("{{", pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } + if (pos > prev + platformVersion.size()) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } - if ('\0' == *str) - break; + size_t start = pos + 2; + if ((pos = allowList.find("}}", pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } + decDescs.back().platVer = allowList.substr(start, pos - start); + pos = pos + 2; + } - // '|' means that the is another filter - if ('|' == *str) + else if (allowList.find('|', pos) != std::string::npos) { + pos = allowList.find('|') + 1; + while (allowList[pos] == ' ') { + pos++; + } decDescs.emplace_back(); - else if (',' != *str) - throw sycl::runtime_error("Malformed device allowlist", PI_INVALID_VALUE); + } - ++str; + else { + throw sycl::runtime_error("Unrecognized key in device allowlist", + PI_INVALID_VALUE); + } + } // while (pos <= allowList.size()) + return decDescs; +} + +std::vector convertVersionString(std::string version) { + // version string format is xx.yy.zzzzz + std::vector values; + size_t pos = 0; + size_t start = pos; + if ((pos = version.find(".", pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in version string", + PI_INVALID_VALUE); + } + values.push_back(std::stoi(version.substr(start, pos))); + pos++; + start = pos; + if ((pos = version.find(".", pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in version string", + PI_INVALID_VALUE); } + values.push_back(std::stoi(version.substr(start, pos))); + pos++; + values.push_back(std::stoi(version.substr(pos))); - return decDescs; + return values; +} + +enum MatchState { UNKNOWN, MATCH, NOMATCH }; + +MatchState matchVersions(std::string version1, std::string version2) { + std::vector v1 = convertVersionString(version1); + std::vector v2 = convertVersionString(version2); + if (v1[0] >= v2[0] && v1[1] >= v2[1] && v1[2] >= v2[2]) { + return MatchState::MATCH; + } else { + return MatchState::NOMATCH; + } } static void filterAllowList(vector_class &PiDevices, @@ -235,6 +296,11 @@ static void filterAllowList(vector_class &PiDevices, if (AllowList.empty()) return; + MatchState devNameState = UNKNOWN; + MatchState devVerState = UNKNOWN; + MatchState platNameState = UNKNOWN; + MatchState platVerState = UNKNOWN; + const string_class PlatformName = sycl::detail::get_platform_info::get( PiPlatform, Plugin); @@ -254,33 +320,57 @@ static void filterAllowList(vector_class &PiDevices, string_class, info::device::driver_version>::get(Device, Plugin); for (const DevDescT &Desc : AllowList) { - if (nullptr != Desc.platformName && - !std::regex_match(PlatformName, - std::regex(std::string(Desc.platformName, - Desc.platformNameSize)))) - continue; - - if (nullptr != Desc.platformVer && - !std::regex_match( - PlatformVer, - std::regex(std::string(Desc.platformVer, Desc.platformVerSize)))) - continue; - - if (nullptr != Desc.devName && - !std::regex_match(DeviceName, std::regex(std::string( - Desc.devName, Desc.devNameSize)))) - continue; - - if (nullptr != Desc.devDriverVer && - !std::regex_match(DeviceDriverVer, - std::regex(std::string(Desc.devDriverVer, - Desc.devDriverVerSize)))) - continue; + if (!Desc.platName.empty()) { + if (!std::regex_match(PlatformName, std::regex(Desc.platName))) { + platNameState = MatchState::NOMATCH; + continue; + } else { + platNameState = MatchState::MATCH; + } + } + + if (!Desc.platVer.empty()) { + if (!std::regex_match(PlatformVer, std::regex(Desc.platVer))) { + platVerState = MatchState::NOMATCH; + continue; + } else { + platVerState = MatchState::MATCH; + } + } + + if (!Desc.devName.empty()) { + if (!std::regex_match(DeviceName, std::regex(Desc.devName))) { + devNameState = MatchState::NOMATCH; + continue; + } else { + devNameState = MatchState::MATCH; + } + } + + if (!Desc.devDriverVer.empty()) { + if (!std::regex_match(DeviceDriverVer, std::regex(Desc.devDriverVer))) { + devVerState = matchVersions(DeviceDriverVer, Desc.devDriverVer); + if (devVerState == MatchState::NOMATCH) { + continue; + } + } else { + devVerState = MatchState::MATCH; + } + } PiDevices[InsertIDx++] = Device; break; } } + if (devNameState == MatchState::MATCH && devVerState == MatchState::NOMATCH) { + throw sycl::runtime_error("Requested SYCL device not found", + PI_DEVICE_NOT_FOUND); + } + if (platNameState == MatchState::MATCH && + platVerState == MatchState::NOMATCH) { + throw sycl::runtime_error("Requested SYCL platform not found", + PI_DEVICE_NOT_FOUND); + } PiDevices.resize(InsertIDx); } diff --git a/sycl/test/config/select_device.cpp b/sycl/test/config/select_device.cpp index d26fa64f58097..3825ac65e826d 100644 --- a/sycl/test/config/select_device.cpp +++ b/sycl/test/config/select_device.cpp @@ -5,6 +5,39 @@ // // RUN: env WRITE_PLATFORM_INFO=1 %t.out // RUN: env READ_PLATFORM_INFO=1 %t.out +// +// RUN: env WRITE_DEVICE_ERROR_INFO=1 %t.out +// RUN: env READ_DEVICE_ERROR_INFO=1 %t.out +// +// RUN: env WRITE_PLATFORM_ERROR_INFO=1 %t.out +// RUN: env READ_PLATFORM_ERROR_INFO=1 %t.out +// +// RUN: env WRITE_OLD_VERSION_INFO=1 %t.out +// RUN: env READ_OLD_VERSION_INFO=1 %t.out +// +// RUN: env WRITE_REG_EX_INFO=1 %t.out +// RUN: env READ_REG_EX_INFO=1 %t.out +// +// RUN: env WRITE_DEVICE_NAME_INFO=1 %t.out +// RUN: env READ_DEVICE_NAME_INFO=1 %t.out +// +// RUN: env WRITE_PLATFORM_NAME_INFO=1 %t.out +// RUN: env READ_PLATFORM_NAME_INFO=1 %t.out +// +// RUN: env WRITE_DEVICE_MULTI_INFO=1 %t.out +// RUN: env READ_DEVICE_MULTI_INFO=1 %t.out +// +// RUN: env WRITE_DEVICE_MALFORMED_INFO=1 %t.out +// RUN: env READ_DEVICE_MALFORMED_INFO=1 %t.out +// +// RUN: env WRITE_DRIVER_MALFORMED_INFO=1 %t.out +// RUN: env READ_DRIVER_MALFORMED_INFO=1 %t.out +// +// RUN: env WRITE_PLATFORM_MALFORMED_INFO=1 %t.out +// RUN: env READ_PLATFORM_MALFORMED_INFO=1 %t.out +// +// RUN: env WRITE_PLATFORM_VERSION_MALFORMED_INFO=1 %t.out +// RUN: env READ_PLATFORM_VERSION_MALFORMED_INFO=1 %t.out //==------------ select_device.cpp - SYCL_DEVICE_ALLOWLIST test ------------==// // @@ -22,14 +55,15 @@ //===----------------------------------------------------------------------===// #include -#include #include +#include +#include #include using namespace cl::sycl; #ifdef _WIN32 -#define setenv(name, value, overwrite) _putenv_s (name, value) +#define setenv(name, value, overwrite) _putenv_s(name, value) #endif struct DevDescT { @@ -39,6 +73,57 @@ struct DevDescT { std::string platVer; }; +static void replaceSpecialCharacters(std::string &str) { + std::string lparen("("); + std::string rparen(")"); + std::string esclparen("\\("); + std::string escrparen("\\)"); + + size_t pos = 0; + while ((pos = str.find(lparen, pos)) != std::string::npos) { + str.replace(pos, lparen.size(), esclparen); + pos += esclparen.size(); + } + pos = 0; + while ((pos = str.find(rparen, pos)) != std::string::npos) { + str.replace(pos, rparen.size(), escrparen); + pos += escrparen.size(); + } +} + +std::vector convertVersionString(std::string version) { + // version string format is xx.yy.zzzzz + std::vector values; + size_t pos = 0; + size_t start = pos; + if ((pos = version.find(".", pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in version string", + PI_INVALID_VALUE); + } + values.push_back(std::stoi(version.substr(start, pos))); + pos++; + start = pos; + if ((pos = version.find(".", pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in version string", + PI_INVALID_VALUE); + } + values.push_back(std::stoi(version.substr(start, pos))); + pos++; + values.push_back(std::stoi(version.substr(pos))); + + return values; +} + +bool matchVersions(std::string version1, std::string version2) { + std::vector v1 = convertVersionString(version1); + std::vector v2 = convertVersionString(version2); + if (v1[0] >= v2[0] && v1[1] >= v2[1] && v1[2] >= v2[2]) { + return true; + } else { + return false; + } +} + static std::vector getAllowListDesc(std::string allowList) { if (allowList.empty()) return {}; @@ -48,90 +133,98 @@ static std::vector getAllowListDesc(std::string allowList) { std::string platformName("PlatformName:"); std::string platformVersion("PlatformVersion:"); std::vector decDescs; + decDescs.emplace_back(); size_t pos = 0; - while ( pos <= allowList.size()) { - decDescs.emplace_back(); - + while (pos < allowList.size()) { if ((allowList.compare(pos, deviceName.size(), deviceName)) == 0) { if ((pos = allowList.find("{{", pos)) == std::string::npos) { - throw std::runtime_error("Malformed device allowlist"); + throw std::runtime_error("Malformed device allowlist"); } - size_t start = pos+2; - if ((pos = allowList.find("}},", pos)) == std::string::npos) { - throw std::runtime_error("Malformed device allowlist"); + size_t start = pos + 2; + if ((pos = allowList.find("}}", pos)) == std::string::npos) { + throw std::runtime_error("Malformed device allowlist"); } - decDescs.back().devName = allowList.substr(start, pos-start); - pos = pos+3; - if ((allowList.compare(pos, driverVersion.size(), driverVersion)) == 0) { - if ((pos = allowList.find("{{", pos)) == std::string::npos) { - throw std::runtime_error("Malformed device allowlist"); - } - start = pos+2; - if ((pos = allowList.find("}}", pos)) == std::string::npos) { - throw std::runtime_error("Malformed device allowlist"); - } - decDescs.back().devDriverVer = allowList.substr(start, pos-start); - pos = pos+3; - } else { + decDescs.back().devName = allowList.substr(start, pos - start); + pos = pos + 2; + + if (allowList[pos] == ',') { + pos++; + } + } + + else if ((allowList.compare(pos, driverVersion.size(), driverVersion)) == + 0) { + if ((pos = allowList.find("{{", pos)) == std::string::npos) { + throw std::runtime_error("Malformed device allowlist"); + } + size_t start = pos + 2; + if ((pos = allowList.find("}}", pos)) == std::string::npos) { throw std::runtime_error("Malformed device allowlist"); } + decDescs.back().devDriverVer = allowList.substr(start, pos - start); + pos = pos + 3; } + else if ((allowList.compare(pos, platformName.size(), platformName)) == 0) { if ((pos = allowList.find("{{", pos)) == std::string::npos) { - throw std::runtime_error("Malformed platform allowlist"); + throw std::runtime_error("Malformed platform allowlist"); } - size_t start = pos+2; - if ((pos = allowList.find("}},", pos)) == std::string::npos) { - throw std::runtime_error("Malformed platform allowlist"); + size_t start = pos + 2; + if ((pos = allowList.find("}}", pos)) == std::string::npos) { + throw std::runtime_error("Malformed platform allowlist"); } - decDescs.back().platName = allowList.substr(start, pos-start); - pos = pos+3; - if ((allowList.compare(pos, platformVersion.size(), platformVersion)) == 0) { - if ((pos = allowList.find("{{", pos)) == std::string::npos) { - throw std::runtime_error("Malformed platform allowlist"); - } - start = pos+2; - if ((pos = allowList.find("}}", pos)) == std::string::npos) { - throw std::runtime_error("Malformed platform allowlist"); - } - decDescs.back().platVer = allowList.substr(start, pos-start); - pos = pos+3; - } else { + decDescs.back().platName = allowList.substr(start, pos - start); + pos = pos + 2; + if (allowList[pos] == ',') { + pos++; + } + } + + else if ((allowList.compare(pos, platformVersion.size(), + platformVersion)) == 0) { + if ((pos = allowList.find("{{", pos)) == std::string::npos) { + throw std::runtime_error("Malformed platform allowlist"); + } + size_t start = pos + 2; + if ((pos = allowList.find("}}", pos)) == std::string::npos) { throw std::runtime_error("Malformed platform allowlist"); } + decDescs.back().platVer = allowList.substr(start, pos - start); + pos = pos + 2; } + else if (allowList.find('|', pos) != std::string::npos) { - pos = allowList.find('|')+1; + pos = allowList.find('|') + 1; while (allowList[pos] == ' ') { pos++; } + decDescs.emplace_back(); + } else { + throw std::runtime_error("Malformed platform allowlist"); } - else { - throw std::runtime_error("Malformed platform allowlist"); - } - } // while (pos <= allowList.size()) + } // while (pos <= allowList.size()) return decDescs; } - int main() { bool passed = false; - // Find the GPU devices on this system + // Test the GPU devices name and version number. if (getenv("WRITE_DEVICE_INFO")) { std::ofstream fs; fs.open("select_device_config.txt"); if (fs.is_open()) { for (const auto &plt : platform::get_platforms()) { - if (!plt.has(aspect::host)){ - for (const auto &dev : plt.get_devices()) { + if (!plt.has(aspect::host)) { + for (const auto &dev : plt.get_devices()) { if (dev.has(aspect::gpu)) { std::string name = dev.get_info(); + replaceSpecialCharacters(name); std::string ver = dev.get_info(); - fs << "DeviceName:{{" << name - << "}},DriverVersion:{{" << ver << "}}" << std::endl; - passed=true; + fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver + << "}}" << std::endl; + passed = true; break; } } @@ -139,91 +232,660 @@ int main() { } fs.close(); } + } else if (getenv("READ_DEVICE_INFO")) { + std::ifstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + std::string allowlist; + std::getline(fs, allowlist); + if (!allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + + cl::sycl::queue deviceQueue(gpu_selector{}); + device dev = deviceQueue.get_device(); + for (const DevDescT &desc : components) { + if ((std::regex_match(dev.get_info(), + std::regex(desc.devName))) && + (std::regex_match(dev.get_info(), + std::regex(desc.devDriverVer)))) { + passed = true; + } + std::cout << "Device: " << dev.get_info() + << std::endl; + std::cout << "DriverVersion: " + << dev.get_info() + << std::endl; + } + } + fs.close(); + } + } + + // Test the platform name and version number. + if (getenv("WRITE_PLATFORM_INFO")) { + std::ofstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + for (const auto &plt : platform::get_platforms()) { + if (plt.has(aspect::gpu)) { + std::string name = plt.get_info(); + replaceSpecialCharacters(name); + std::string ver = plt.get_info(); + fs << "PlatformName:{{" << name << "}},PlatformVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } + } + } + fs.close(); + } else if (getenv("READ_PLATFORM_INFO")) { + std::ifstream fs; + fs.open("select_device_config.txt", std::fstream::in); + if (fs.is_open()) { + std::string allowlist; + std::getline(fs, allowlist); + if (!allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + + cl::sycl::queue deviceQueue(gpu_selector{}); + device dev = deviceQueue.get_device(); + const auto &plt = dev.get_platform(); + for (const DevDescT &desc : components) { + if ((std::regex_match(plt.get_info(), + std::regex(desc.platName))) && + (std::regex_match(plt.get_info(), + std::regex(desc.platVer)))) { + passed = true; + } + } + std::cout << "Platform: " << plt.get_info() + << std::endl; + std::cout << "Platform Version: " + << plt.get_info() << std::endl; + } + fs.close(); + } } - else if (getenv("READ_DEVICE_INFO")) { + + // Test error handling. + if (getenv("WRITE_DEVICE_ERROR_INFO")) { + std::ofstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + for (const auto &plt : platform::get_platforms()) { + if (!plt.has(aspect::host)) { + for (const auto &dev : plt.get_devices()) { + if (dev.has(aspect::gpu)) { + std::string name = dev.get_info(); + replaceSpecialCharacters(name); + std::string ver("12.34.56789"); + fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } + } + } + } + fs.close(); + } + } else if (getenv("READ_DEVICE_ERROR_INFO")) { std::ifstream fs; fs.open("select_device_config.txt"); if (fs.is_open()) { std::string allowlist; std::getline(fs, allowlist); - if (! allowlist.empty()) { - setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); - std::vector components(getAllowListDesc(allowlist)); + if (!allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + + try { + cl::sycl::queue deviceQueue(gpu_selector{}); + device dev = deviceQueue.get_device(); + const auto &plt = dev.get_platform(); + } catch (sycl::runtime_error &E) { + const std::string expectedMsg("Requested SYCL device not found"); + const std::string gotMessage(E.what()); + if (gotMessage.find(expectedMsg) != std::string::npos) { + passed = true; + } else { + passed = false; + } + } + } + fs.close(); + } + } + + // Test error condition when version number is not found. + if (getenv("WRITE_PLATFORM_ERROR_INFO")) { + std::ofstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + for (const auto &plt : platform::get_platforms()) { + if (plt.has(aspect::gpu)) { + std::string name = plt.get_info(); + replaceSpecialCharacters(name); + std::string ver("OpenCL 12.34"); + fs << "PlatformName:{{" << name << "}},PlatformVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } + } + } + fs.close(); + } else if (getenv("READ_PLATFORM_ERROR_INFO")) { + std::ifstream fs; + fs.open("select_device_config.txt", std::fstream::in); + if (fs.is_open()) { + std::string allowlist; + std::getline(fs, allowlist); + if (!allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + try { cl::sycl::queue deviceQueue(gpu_selector{}); device dev = deviceQueue.get_device(); - for (const DevDescT &desc : components) { - if ((dev.get_info() == desc.devName) && - (dev.get_info() == - desc.devDriverVer)) { + const auto &plt = dev.get_platform(); + } catch (sycl::runtime_error &E) { + const std::string expectedMsg("Requested SYCL platform not found"); + const std::string gotMessage(E.what()); + if (gotMessage.find(expectedMsg) != std::string::npos) { + passed = true; + } else { + passed = false; + } + } + } + fs.close(); + } + } + + // Test that the device driver version number is >= the provided version + // number. + if (getenv("WRITE_OLD_VERSION_INFO")) { + std::ofstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + for (const auto &plt : platform::get_platforms()) { + if (!plt.has(aspect::host)) { + for (const auto &dev : plt.get_devices()) { + if (dev.has(aspect::gpu)) { + std::string name = dev.get_info(); + replaceSpecialCharacters(name); + std::string ver = dev.get_info(); + size_t pos = 0; + if ((pos = ver.rfind(".")) == std::string::npos) { + throw std::runtime_error("Malformed syntax in version string"); + } + pos = ver.length() - pos; + int num = stoi(ver.substr(pos)); + if (num > 20) { + num = num - 20; + } + std::string str = ver.substr(0, pos) + std::to_string(num); + fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << str + << "}}" << std::endl; + passed = true; + break; + } + } + } + } + fs.close(); + } + } else if (getenv("READ_OLD_VERSION_INFO")) { + std::ifstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + std::string allowlist; + std::getline(fs, allowlist); + if (!allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + + cl::sycl::queue deviceQueue(gpu_selector{}); + device dev = deviceQueue.get_device(); + for (const DevDescT &desc : components) { + if ((std::regex_match(dev.get_info(), + std::regex(desc.devName))) && + (matchVersions(dev.get_info(), + desc.devDriverVer) == true)) { + passed = true; + } + std::cout << "Device: " << dev.get_info() + << std::endl; + std::cout << "DriverVersion: " + << dev.get_info() + << std::endl; + } + } + fs.close(); + } + } + + // Test handling a regular expression in the device driver version number. + if (getenv("WRITE_REG_EX_INFO")) { + std::ofstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + for (const auto &plt : platform::get_platforms()) { + if (!plt.has(aspect::host)) { + for (const auto &dev : plt.get_devices()) { + if (dev.has(aspect::gpu)) { + std::string name = dev.get_info(); + replaceSpecialCharacters(name); + std::string ver = dev.get_info(); + size_t pos = 0; + if ((pos = ver.find(".")) == std::string::npos) { + throw std::runtime_error("Malformed syntax in version string"); + } + pos++; + size_t start = pos; + if ((pos = ver.find(".", pos)) == std::string::npos) { + throw std::runtime_error("Malformed syntax in version string"); + } + ver.replace(start, pos - start, "*"); + fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } + } + } + } + fs.close(); + } + } else if (getenv("READ_REG_EX_INFO")) { + std::ifstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + std::string allowlist; + std::getline(fs, allowlist); + if (!allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + + cl::sycl::queue deviceQueue(gpu_selector{}); + device dev = deviceQueue.get_device(); + for (const DevDescT &desc : components) { + if ((std::regex_match(dev.get_info(), + std::regex(desc.devName))) && + (std::regex_match(dev.get_info(), + std::regex(desc.devDriverVer)))) { + passed = true; + } + std::cout << "Device: " << dev.get_info() + << std::endl; + std::cout << "DriverVersion: " + << dev.get_info() + << std::endl; + } + } + fs.close(); + } + } + + // Test providing only the device name. + if (getenv("WRITE_DEVICE_NAME_INFO")) { + std::ofstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + for (const auto &plt : platform::get_platforms()) { + if (!plt.has(aspect::host)) { + for (const auto &dev : plt.get_devices()) { + if (dev.has(aspect::gpu)) { + std::string name = dev.get_info(); + replaceSpecialCharacters(name); + fs << "DeviceName:{{" << name << "}}" << std::endl; passed = true; + break; } - std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + } + } + } + fs.close(); + } + } else if (getenv("READ_DEVICE_NAME_INFO")) { + std::ifstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + std::string allowlist; + std::getline(fs, allowlist); + if (!allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + + cl::sycl::queue deviceQueue(gpu_selector{}); + device dev = deviceQueue.get_device(); + for (const DevDescT &desc : components) { + if (std::regex_match(dev.get_info(), + std::regex(desc.devName))) { + passed = true; + } + std::cout << "Device: " << dev.get_info() + << std::endl; + } + } + fs.close(); + } + } + + // Test providing the platform name only. + if (getenv("WRITE_PLATFORM_NAME_INFO")) { + std::ofstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + for (const auto &plt : platform::get_platforms()) { + if (plt.has(aspect::gpu)) { + std::string name = plt.get_info(); + replaceSpecialCharacters(name); + fs << "PlatformName:{{" << name << "}}" << std::endl; + passed = true; + break; + } + } + } + fs.close(); + } else if (getenv("READ_PLATFORM_NAME_INFO")) { + std::ifstream fs; + fs.open("select_device_config.txt", std::fstream::in); + if (fs.is_open()) { + std::string allowlist; + std::getline(fs, allowlist); + if (!allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + + cl::sycl::queue deviceQueue(gpu_selector{}); + device dev = deviceQueue.get_device(); + const auto &plt = dev.get_platform(); + for (const DevDescT &desc : components) { + if (std::regex_match(plt.get_info(), + std::regex(desc.platName))) { + passed = true; + } + std::cout << "Platform: " << plt.get_info() + << std::endl; + } + } + fs.close(); + } + } + + // Test the GPU multiple devices option. + if (getenv("WRITE_DEVICE_MULTI_INFO")) { + std::ofstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + std::stringstream ss; + int count = 0; + for (const auto &plt : platform::get_platforms()) { + if (!plt.has(aspect::host)) { + for (const auto &dev : plt.get_devices()) { + if (dev.has(aspect::gpu)) { + std::string name = dev.get_info(); + replaceSpecialCharacters(name); + std::string ver = dev.get_info(); + if (count > 0) { + ss << " | "; + } + ss << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver + << "}}"; + count++; + passed = true; + } + } + } + } + fs << ss.str() << std::endl; + fs.close(); + } + } else if (getenv("READ_DEVICE_MULTI_INFO")) { + std::ifstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + std::string allowlist; + std::getline(fs, allowlist); + if (!allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + + cl::sycl::queue deviceQueue(gpu_selector{}); + device dev = deviceQueue.get_device(); + for (const DevDescT &desc : components) { + if ((std::regex_match(dev.get_info(), + std::regex(desc.devName))) && + (std::regex_match(dev.get_info(), + std::regex(desc.devDriverVer)))) { + passed = true; std::cout << "Device: " << dev.get_info() << std::endl; std::cout << "DriverVersion: " << dev.get_info() << std::endl; } + } } fs.close(); } } - // Find the platforms on this system. - if (getenv("WRITE_PLATFORM_INFO")) { + + // Test providing malformed syntax in the device name. + if (getenv("WRITE_DEVICE_MALFORMED_INFO")) { + std::ofstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + for (const auto &plt : platform::get_platforms()) { + if (!plt.has(aspect::host)) { + for (const auto &dev : plt.get_devices()) { + if (dev.has(aspect::gpu)) { + std::string name = dev.get_info(); + replaceSpecialCharacters(name); + fs << "DeviceName:HAHA{{" << name << "}}" << std::endl; + passed = true; + break; + } + } + } + } + fs.close(); + } + } else if (getenv("READ_DEVICE_MALFORMED_INFO")) { + std::ifstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + std::string allowlist; + std::getline(fs, allowlist); + if (!allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + + try { + cl::sycl::queue deviceQueue(gpu_selector{}); + device dev = deviceQueue.get_device(); + const auto &plt = dev.get_platform(); + } catch (sycl::runtime_error &E) { + const std::string expectedMsg( + "Malformed syntax in SYCL_DEVICE_ALLOWLIST"); + const std::string gotMessage(E.what()); + if (gotMessage.find(expectedMsg) != std::string::npos) { + passed = true; + } else { + passed = false; + } + } + } + fs.close(); + } + } + + // Test providing the platform name only. + if (getenv("WRITE_PLATFORM_MALFORMED_INFO")) { std::ofstream fs; fs.open("select_device_config.txt"); if (fs.is_open()) { for (const auto &plt : platform::get_platforms()) { - if (plt.has(aspect::gpu)){ - std::string pname = plt.get_info(); - std::string pver = plt.get_info(); - fs << "PlatformName:{{" << pname - << "}},PlatformVersion:{{" << pver << "}}" << std::endl; - passed=true; + if (plt.has(aspect::gpu)) { + std::string name = plt.get_info(); + replaceSpecialCharacters(name); + fs << "PlatformName:HAHA{{" << name << "}}" << std::endl; + passed = true; break; } } } fs.close(); - } - else if (getenv("READ_PLATFORM_INFO")) { + } else if (getenv("READ_PLATFORM_MALFORMED_INFO")) { std::ifstream fs; fs.open("select_device_config.txt", std::fstream::in); if (fs.is_open()) { std::string allowlist; std::getline(fs, allowlist); - if (! allowlist.empty()) { + if (!allowlist.empty()) { setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); std::vector components(getAllowListDesc(allowlist)); + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; - for (const auto &plt : platform::get_platforms()) { - if (!plt.has(aspect::host)){ - for (const DevDescT &desc : components) { - if ((plt.get_info() == desc.platName) && - (plt.get_info() == - desc.platVer)) { - passed = true; - } - std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; - std::cout << "Platform: " << plt.get_info() - << std::endl; - std::cout << "Platform Version: " - << plt.get_info() - << std::endl; + try { + cl::sycl::queue deviceQueue(gpu_selector{}); + device dev = deviceQueue.get_device(); + const auto &plt = dev.get_platform(); + } catch (sycl::runtime_error &E) { + const std::string expectedMsg( + "Malformed syntax in SYCL_DEVICE_ALLOWLIST"); + const std::string gotMessage(E.what()); + if (gotMessage.find(expectedMsg) != std::string::npos) { + passed = true; + } else { + passed = false; + } + } + } + fs.close(); + } + } + + // Test a malformed device version number. + if (getenv("WRITE_DRIVER_MALFORMED_INFO")) { + std::ofstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + for (const auto &plt : platform::get_platforms()) { + if (!plt.has(aspect::host)) { + for (const auto &dev : plt.get_devices()) { + if (dev.has(aspect::gpu)) { + std::string name = dev.get_info(); + replaceSpecialCharacters(name); + std::string ver = dev.get_info(); + fs << "DeviceName:{{" << name << "}},DriverVersion:HAHA{{" << ver + << "}}" << std::endl; + passed = true; + break; } } } } fs.close(); } + } else if (getenv("READ_DRIVER_MALFORMED_INFO")) { + std::ifstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + std::string allowlist; + std::getline(fs, allowlist); + if (!allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + + try { + cl::sycl::queue deviceQueue(gpu_selector{}); + device dev = deviceQueue.get_device(); + const auto &plt = dev.get_platform(); + } catch (sycl::runtime_error &E) { + const std::string expectedMsg( + "Malformed syntax in SYCL_DEVICE_ALLOWLIST"); + const std::string gotMessage(E.what()); + if (gotMessage.find(expectedMsg) != std::string::npos) { + passed = true; + } else { + passed = false; + } + } + } + fs.close(); + } + } + + // Test the platform name and version number. + if (getenv("WRITE_PLATFORM_VERSION_MALFORMED_INFO")) { + std::ofstream fs; + fs.open("select_device_config.txt"); + if (fs.is_open()) { + for (const auto &plt : platform::get_platforms()) { + if (plt.has(aspect::gpu)) { + std::string name = plt.get_info(); + replaceSpecialCharacters(name); + std::string ver = plt.get_info(); + fs << "PlatformName:{{" << name << "}},PlatformVersion:HAHA{{" << ver + << "}}" << std::endl; + passed = true; + break; + } + } + } + fs.close(); + } else if (getenv("READ_PLATFORM_VERSION_MALFORMED_INFO")) { + std::ifstream fs; + fs.open("select_device_config.txt", std::fstream::in); + if (fs.is_open()) { + std::string allowlist; + std::getline(fs, allowlist); + if (!allowlist.empty()) { + setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); + std::vector components(getAllowListDesc(allowlist)); + std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; + + try { + cl::sycl::queue deviceQueue(gpu_selector{}); + device dev = deviceQueue.get_device(); + const auto &plt = dev.get_platform(); + } catch (sycl::runtime_error &E) { + const std::string expectedMsg( + "Malformed syntax in SYCL_DEVICE_ALLOWLIST"); + const std::string gotMessage(E.what()); + if (gotMessage.find(expectedMsg) != std::string::npos) { + passed = true; + } else { + passed = false; + } + } + } + fs.close(); + } } if (passed) { std::cout << "Passed." << std::endl; return 0; } else { - std:: cout << "Failed." << std::endl; + std::cout << "Failed." << std::endl; return 1; } } From aff799ff8c842ef9490d073e1b56133995e0fc5c Mon Sep 17 00:00:00 2001 From: Gail Lyons Date: Tue, 22 Sep 2020 12:43:25 -0700 Subject: [PATCH 3/9] Incorporated code review comments Signed-off-by: Gail Lyons --- sycl/doc/EnvironmentVariables.md | 2 +- sycl/source/detail/platform_impl.cpp | 282 ++++++++++++--------------- sycl/test/config/select_device.cpp | 37 +++- 3 files changed, 158 insertions(+), 163 deletions(-) diff --git a/sycl/doc/EnvironmentVariables.md b/sycl/doc/EnvironmentVariables.md index 9eac42b39648f..3378a2f1fd7fc 100644 --- a/sycl/doc/EnvironmentVariables.md +++ b/sycl/doc/EnvironmentVariables.md @@ -22,7 +22,7 @@ subject to change. Do not rely on these variables in production code. | SYCL_DISABLE_EXECUTION_GRAPH_CLEANUP | Any(\*) | Disable cleanup of finished command nodes at host-device synchronization points. | | SYCL_THROW_ON_BLOCK | Any(\*) | Throw an exception on attempt to wait for a blocked command. | | SYCL_DEVICELIB_INHIBIT_NATIVE | String of device library extensions (separated by a whitespace) | Do not rely on device native support for devicelib extensions listed in this option. | -| SYCL_DEVICE_ALLOWLIST | A list of devices and their minimum driver version following the pattern: DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}. Also may contain PlatformName and PlatformVersion | Filter out devices that do not match the pattern specified. Regular expression can be passed and the DPC++ runtime will select only those devices which satisfy the regex. Note that the device name, platform name and their respective versions are regular expression. Special characters, such as parenthesis, must be escaped. | +| SYCL_DEVICE_ALLOWLIST | A list of devices and their minimum driver version following the pattern: DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}. Also may contain PlatformName and PlatformVersion | Filter out devices that do not match the pattern specified. Regular expression can be passed and the DPC++ runtime will select only those devices which satisfy the regex. Note that the device name, platform name and platform version are regular expressions. Special characters, such as parenthesis, must be escaped. The device driver version is treated as 4 regular expressions, separated by ".". More than one device can be specified using "|".| | SYCL_QUEUE_THREAD_POOL_SIZE | Positive integer | Number of threads in thread pool of queue. | | SYCL_DEVICELIB_NO_FALLBACK | Any(\*) | Disable loading and linking of device library images | | SYCL_PI_LEVEL0_MAX_COMMAND_LIST_CACHE | Positive integer | Maximum number of oneAPI Level Zero Command lists that can be allocated with no reuse before throwing an "out of resources" error. Default is 20000, threshold may be increased based on resource availabilty and workload demand. | diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 838ee5514fc6c..4a43ca16b411d 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -121,173 +121,147 @@ vector_class platform_impl::get_platforms() { return Platforms; } +std::string getValue(/*const*/ std::string &AllowList, size_t &Pos, + unsigned long int Size) { + size_t Prev = Pos; + if ((Pos = AllowList.find("{{", Pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } + if (Pos > Prev + Size) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } + + Pos = Pos + 2; + size_t Start = Pos; + if ((Pos = AllowList.find("}}", Pos)) == std::string::npos) { + throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", + PI_INVALID_VALUE); + } + std::string Value = AllowList.substr(Start, Pos - Start); + Pos = Pos + 2; + return Value; +} + struct DevDescT { - std::string devName; - std::string devDriverVer; - std::string platName; - std::string platVer; + std::string DevName; + std::string DevDriverVer; + std::string PlatName; + std::string PlatVer; }; static std::vector getAllowListDesc() { - std::string allowList(SYCLConfig::get()); - if (allowList.empty()) + std::string AllowList(SYCLConfig::get()); + if (AllowList.empty()) return {}; - std::string deviceName("DeviceName:"); - std::string driverVersion("DriverVersion:"); - std::string platformName("PlatformName:"); - std::string platformVersion("PlatformVersion:"); - std::vector decDescs; - decDescs.emplace_back(); - - size_t pos = 0; - size_t prev = pos; - while (pos < allowList.size()) { - if ((allowList.compare(pos, deviceName.size(), deviceName)) == 0) { - prev = pos; - if ((pos = allowList.find("{{", pos)) == std::string::npos) { - throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", - PI_INVALID_VALUE); - } - if (pos > prev + deviceName.size()) { - throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", - PI_INVALID_VALUE); - } - - pos = pos + 2; - size_t start = pos; - if ((pos = allowList.find("}}", pos)) == std::string::npos) { - throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", - PI_INVALID_VALUE); - } - decDescs.back().devName = allowList.substr(start, pos - start); - pos = pos + 2; - - if (allowList[pos] == ',') { - pos++; + std::string DeviceName("DeviceName:"); + std::string DriverVersion("DriverVersion:"); + std::string PlatformName("PlatformName:"); + std::string PlatformVersion("PlatformVersion:"); + std::vector DecDescs; + DecDescs.emplace_back(); + + size_t Pos = 0; + while (Pos < AllowList.size()) { + if ((AllowList.compare(Pos, DeviceName.size(), DeviceName)) == 0) { + DecDescs.back().DevName = getValue(AllowList, Pos, DeviceName.size()); + if (AllowList[Pos] == ',') { + Pos++; } } - else if ((allowList.compare(pos, driverVersion.size(), driverVersion)) == + else if ((AllowList.compare(Pos, DriverVersion.size(), DriverVersion)) == 0) { - prev = pos; - if ((pos = allowList.find("{{", pos)) == std::string::npos) { - throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", - PI_INVALID_VALUE); - } - if (pos > prev + driverVersion.size()) { - throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", - PI_INVALID_VALUE); - } - - size_t start = pos + 2; - if ((pos = allowList.find("}}", pos)) == std::string::npos) { - throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", - PI_INVALID_VALUE); - } - decDescs.back().devDriverVer = allowList.substr(start, pos - start); - pos = pos + 2; - - if (allowList[pos] == ',') { - pos++; - } - } - - else if ((allowList.compare(pos, platformName.size(), platformName)) == 0) { - prev = pos; - if ((pos = allowList.find("{{", pos)) == std::string::npos) { - throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", - PI_INVALID_VALUE); + DecDescs.back().DevDriverVer = + getValue(AllowList, Pos, DriverVersion.size()); + if (AllowList[Pos] == ',') { + Pos++; } - if (pos > prev + platformName.size()) { - throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", - PI_INVALID_VALUE); - } - - size_t start = pos + 2; - if ((pos = allowList.find("}}", pos)) == std::string::npos) { - throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", - PI_INVALID_VALUE); - } - decDescs.back().platName = allowList.substr(start, pos - start); - pos = pos + 2; - - if (allowList[pos] == ',') { - pos++; - } - } - else if ((allowList.compare(pos, platformVersion.size(), - platformVersion)) == 0) { - prev = pos; - if ((pos = allowList.find("{{", pos)) == std::string::npos) { - throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", - PI_INVALID_VALUE); + else if ((AllowList.compare(Pos, PlatformName.size(), PlatformName)) == 0) { + DecDescs.back().PlatName = getValue(AllowList, Pos, PlatformName.size()); + if (AllowList[Pos] == ',') { + Pos++; } - if (pos > prev + platformVersion.size()) { - throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", - PI_INVALID_VALUE); - } - - size_t start = pos + 2; - if ((pos = allowList.find("}}", pos)) == std::string::npos) { - throw sycl::runtime_error("Malformed syntax in SYCL_DEVICE_ALLOWLIST", - PI_INVALID_VALUE); - } - decDescs.back().platVer = allowList.substr(start, pos - start); - pos = pos + 2; } - else if (allowList.find('|', pos) != std::string::npos) { - pos = allowList.find('|') + 1; - while (allowList[pos] == ' ') { - pos++; + else if ((AllowList.compare(Pos, PlatformVersion.size(), + PlatformVersion)) == 0) { + DecDescs.back().PlatVer = + getValue(AllowList, Pos, PlatformVersion.size()); + } else if (AllowList.find('|', Pos) != std::string::npos) { + Pos = AllowList.find('|') + 1; + while (AllowList[Pos] == ' ') { + Pos++; } - decDescs.emplace_back(); + DecDescs.emplace_back(); } else { throw sycl::runtime_error("Unrecognized key in device allowlist", PI_INVALID_VALUE); } - } // while (pos <= allowList.size()) - return decDescs; + } // while (Pos <= AllowList.size()) + return DecDescs; } -std::vector convertVersionString(std::string version) { - // version string format is xx.yy.zzzzz - std::vector values; - size_t pos = 0; - size_t start = pos; - if ((pos = version.find(".", pos)) == std::string::npos) { +std::vector convertVersionString(std::string Version) { + // version string format is xx.yy.zzzzz.ww WW is optional + std::vector Values; + size_t Pos = 0; + size_t Start = Pos; + if ((Pos = Version.find(".", Pos)) == std::string::npos) { throw sycl::runtime_error("Malformed syntax in version string", PI_INVALID_VALUE); } - values.push_back(std::stoi(version.substr(start, pos))); - pos++; - start = pos; - if ((pos = version.find(".", pos)) == std::string::npos) { + Values.push_back(std::stoi(Version.substr(Start, Pos - Start))); + Pos++; + Start = Pos; + if ((Pos = Version.find(".", Pos)) == std::string::npos) { throw sycl::runtime_error("Malformed syntax in version string", PI_INVALID_VALUE); } - values.push_back(std::stoi(version.substr(start, pos))); - pos++; - values.push_back(std::stoi(version.substr(pos))); - - return values; + Values.push_back(std::stoi(Version.substr(Start, Pos - Start))); + Pos++; + size_t Prev = Pos; + if ((Pos = Version.find(".", Pos)) == std::string::npos) { + Values.push_back(std::stoi(Version.substr(Prev))); + } else { + Values.push_back(std::stoi(Version.substr(Start, Pos - Start))); + Pos++; + Values.push_back(std::stoi(Version.substr(Pos))); + } + return Values; } enum MatchState { UNKNOWN, MATCH, NOMATCH }; -MatchState matchVersions(std::string version1, std::string version2) { - std::vector v1 = convertVersionString(version1); - std::vector v2 = convertVersionString(version2); - if (v1[0] >= v2[0] && v1[1] >= v2[1] && v1[2] >= v2[2]) { - return MatchState::MATCH; - } else { +MatchState matchVersions(std::string Version1, std::string Version2) { + std::vector V1 = convertVersionString(Version1); + std::vector V2 = convertVersionString(Version2); + + if (V1.size() != V2.size()) { return MatchState::NOMATCH; } + if (V1[0] > V2[0]) { + return MatchState::MATCH; + } + if ((V1[0] == V2[0]) && (V1[1] >= V2[1])) { + return MatchState::MATCH; + } + if ((V1[0] == V2[0]) && (V1[1] == V2[1]) && (V1[2] >= V2[2])) { + return MatchState::MATCH; + } + if (V1.size() == 4) { + if ((V1[0] == V2[0]) && (V1[1] == V2[1]) && (V1[2] == V2[2]) && + (V1[3] >= V2[3])) { + return MatchState::MATCH; + } + } + return MatchState::NOMATCH; } static void filterAllowList(vector_class &PiDevices, @@ -296,10 +270,10 @@ static void filterAllowList(vector_class &PiDevices, if (AllowList.empty()) return; - MatchState devNameState = UNKNOWN; - MatchState devVerState = UNKNOWN; - MatchState platNameState = UNKNOWN; - MatchState platVerState = UNKNOWN; + MatchState DevNameState = UNKNOWN; + MatchState DevVerState = UNKNOWN; + MatchState PlatNameState = UNKNOWN; + MatchState PlatVerState = UNKNOWN; const string_class PlatformName = sycl::detail::get_platform_info::get( @@ -320,41 +294,41 @@ static void filterAllowList(vector_class &PiDevices, string_class, info::device::driver_version>::get(Device, Plugin); for (const DevDescT &Desc : AllowList) { - if (!Desc.platName.empty()) { - if (!std::regex_match(PlatformName, std::regex(Desc.platName))) { - platNameState = MatchState::NOMATCH; + if (!Desc.PlatName.empty()) { + if (!std::regex_match(PlatformName, std::regex(Desc.PlatName))) { + PlatNameState = MatchState::NOMATCH; continue; } else { - platNameState = MatchState::MATCH; + PlatNameState = MatchState::MATCH; } } - if (!Desc.platVer.empty()) { - if (!std::regex_match(PlatformVer, std::regex(Desc.platVer))) { - platVerState = MatchState::NOMATCH; + if (!Desc.PlatVer.empty()) { + if (!std::regex_match(PlatformVer, std::regex(Desc.PlatVer))) { + PlatVerState = MatchState::NOMATCH; continue; } else { - platVerState = MatchState::MATCH; + PlatVerState = MatchState::MATCH; } } - if (!Desc.devName.empty()) { - if (!std::regex_match(DeviceName, std::regex(Desc.devName))) { - devNameState = MatchState::NOMATCH; + if (!Desc.DevName.empty()) { + if (!std::regex_match(DeviceName, std::regex(Desc.DevName))) { + DevNameState = MatchState::NOMATCH; continue; } else { - devNameState = MatchState::MATCH; + DevNameState = MatchState::MATCH; } } - if (!Desc.devDriverVer.empty()) { - if (!std::regex_match(DeviceDriverVer, std::regex(Desc.devDriverVer))) { - devVerState = matchVersions(DeviceDriverVer, Desc.devDriverVer); - if (devVerState == MatchState::NOMATCH) { + if (!Desc.DevDriverVer.empty()) { + if (!std::regex_match(DeviceDriverVer, std::regex(Desc.DevDriverVer))) { + DevVerState = matchVersions(DeviceDriverVer, Desc.DevDriverVer); + if (DevVerState == MatchState::NOMATCH) { continue; } } else { - devVerState = MatchState::MATCH; + DevVerState = MatchState::MATCH; } } @@ -362,12 +336,12 @@ static void filterAllowList(vector_class &PiDevices, break; } } - if (devNameState == MatchState::MATCH && devVerState == MatchState::NOMATCH) { + if (DevNameState == MatchState::MATCH && DevVerState == MatchState::NOMATCH) { throw sycl::runtime_error("Requested SYCL device not found", PI_DEVICE_NOT_FOUND); } - if (platNameState == MatchState::MATCH && - platVerState == MatchState::NOMATCH) { + if (PlatNameState == MatchState::MATCH && + PlatVerState == MatchState::NOMATCH) { throw sycl::runtime_error("Requested SYCL platform not found", PI_DEVICE_NOT_FOUND); } diff --git a/sycl/test/config/select_device.cpp b/sycl/test/config/select_device.cpp index 3825ac65e826d..671784e3b96b6 100644 --- a/sycl/test/config/select_device.cpp +++ b/sycl/test/config/select_device.cpp @@ -100,28 +100,49 @@ std::vector convertVersionString(std::string version) { throw sycl::runtime_error("Malformed syntax in version string", PI_INVALID_VALUE); } - values.push_back(std::stoi(version.substr(start, pos))); + values.push_back(std::stoi(version.substr(start, pos - start))); pos++; start = pos; if ((pos = version.find(".", pos)) == std::string::npos) { throw sycl::runtime_error("Malformed syntax in version string", PI_INVALID_VALUE); } - values.push_back(std::stoi(version.substr(start, pos))); + values.push_back(std::stoi(version.substr(start, pos - start))); pos++; - values.push_back(std::stoi(version.substr(pos))); - + size_t prev = pos; + if ((pos = version.find(".", pos)) == std::string::npos) { + values.push_back(std::stoi(version.substr(prev))); + } else { + values.push_back(std::stoi(version.substr(start, pos - start))); + pos++; + values.push_back(std::stoi(version.substr(pos))); + } return values; } bool matchVersions(std::string version1, std::string version2) { std::vector v1 = convertVersionString(version1); std::vector v2 = convertVersionString(version2); - if (v1[0] >= v2[0] && v1[1] >= v2[1] && v1[2] >= v2[2]) { - return true; - } else { + + if (v1.size() != v2.size()) { return false; } + if (v1[0] > v2[0]) { + return true; + } + if ((v1[0] == v2[0]) && (v1[1] >= v2[1])) { + return true; + } + if ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] >= v2[2])) { + return true; + } + if (v1.size() == 4) { + if ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2]) && + (v1[3] >= v2[3])) { + return true; + } + } + return false; } static std::vector getAllowListDesc(std::string allowList) { @@ -323,7 +344,7 @@ int main() { if (dev.has(aspect::gpu)) { std::string name = dev.get_info(); replaceSpecialCharacters(name); - std::string ver("12.34.56789"); + std::string ver("98.76.54321"); fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver << "}}" << std::endl; passed = true; From 49e41f765c5cdbe543a995c633f824bb7d09d523 Mon Sep 17 00:00:00 2001 From: Gail Lyons Date: Fri, 25 Sep 2020 07:49:08 -0700 Subject: [PATCH 4/9] Incorporating code review comments Signed-off-by: Gail Lyons --- sycl/doc/EnvironmentVariables.md | 2 +- sycl/source/detail/platform_impl.cpp | 60 +---- sycl/test/config/select_device.cpp | 382 +++++++++++++-------------- 3 files changed, 191 insertions(+), 253 deletions(-) diff --git a/sycl/doc/EnvironmentVariables.md b/sycl/doc/EnvironmentVariables.md index 3378a2f1fd7fc..6fc47127c0e2d 100644 --- a/sycl/doc/EnvironmentVariables.md +++ b/sycl/doc/EnvironmentVariables.md @@ -22,7 +22,7 @@ subject to change. Do not rely on these variables in production code. | SYCL_DISABLE_EXECUTION_GRAPH_CLEANUP | Any(\*) | Disable cleanup of finished command nodes at host-device synchronization points. | | SYCL_THROW_ON_BLOCK | Any(\*) | Throw an exception on attempt to wait for a blocked command. | | SYCL_DEVICELIB_INHIBIT_NATIVE | String of device library extensions (separated by a whitespace) | Do not rely on device native support for devicelib extensions listed in this option. | -| SYCL_DEVICE_ALLOWLIST | A list of devices and their minimum driver version following the pattern: DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}. Also may contain PlatformName and PlatformVersion | Filter out devices that do not match the pattern specified. Regular expression can be passed and the DPC++ runtime will select only those devices which satisfy the regex. Note that the device name, platform name and platform version are regular expressions. Special characters, such as parenthesis, must be escaped. The device driver version is treated as 4 regular expressions, separated by ".". More than one device can be specified using "|".| +| SYCL_DEVICE_ALLOWLIST | A list of devices and their driver version following the pattern: DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}. Also may contain PlatformName and PlatformVersion | Filter out devices that do not match the pattern specified. Regular expression can be passed and the DPC++ runtime will select only those devices which satisfy the regex. Special characters, such as parenthesis, must be escaped. More than one device can be specified using the piping symbol "|".| | SYCL_QUEUE_THREAD_POOL_SIZE | Positive integer | Number of threads in thread pool of queue. | | SYCL_DEVICELIB_NO_FALLBACK | Any(\*) | Disable loading and linking of device library images | | SYCL_PI_LEVEL0_MAX_COMMAND_LIST_CACHE | Positive integer | Maximum number of oneAPI Level Zero Command lists that can be allocated with no reuse before throwing an "out of resources" error. Default is 20000, threshold may be increased based on resource availabilty and workload demand. | diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 4a43ca16b411d..34e51ee7ef4c2 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -208,62 +208,8 @@ static std::vector getAllowListDesc() { return DecDescs; } -std::vector convertVersionString(std::string Version) { - // version string format is xx.yy.zzzzz.ww WW is optional - std::vector Values; - size_t Pos = 0; - size_t Start = Pos; - if ((Pos = Version.find(".", Pos)) == std::string::npos) { - throw sycl::runtime_error("Malformed syntax in version string", - PI_INVALID_VALUE); - } - Values.push_back(std::stoi(Version.substr(Start, Pos - Start))); - Pos++; - Start = Pos; - if ((Pos = Version.find(".", Pos)) == std::string::npos) { - throw sycl::runtime_error("Malformed syntax in version string", - PI_INVALID_VALUE); - } - Values.push_back(std::stoi(Version.substr(Start, Pos - Start))); - Pos++; - size_t Prev = Pos; - if ((Pos = Version.find(".", Pos)) == std::string::npos) { - Values.push_back(std::stoi(Version.substr(Prev))); - } else { - Values.push_back(std::stoi(Version.substr(Start, Pos - Start))); - Pos++; - Values.push_back(std::stoi(Version.substr(Pos))); - } - return Values; -} - enum MatchState { UNKNOWN, MATCH, NOMATCH }; -MatchState matchVersions(std::string Version1, std::string Version2) { - std::vector V1 = convertVersionString(Version1); - std::vector V2 = convertVersionString(Version2); - - if (V1.size() != V2.size()) { - return MatchState::NOMATCH; - } - if (V1[0] > V2[0]) { - return MatchState::MATCH; - } - if ((V1[0] == V2[0]) && (V1[1] >= V2[1])) { - return MatchState::MATCH; - } - if ((V1[0] == V2[0]) && (V1[1] == V2[1]) && (V1[2] >= V2[2])) { - return MatchState::MATCH; - } - if (V1.size() == 4) { - if ((V1[0] == V2[0]) && (V1[1] == V2[1]) && (V1[2] == V2[2]) && - (V1[3] >= V2[3])) { - return MatchState::MATCH; - } - } - return MatchState::NOMATCH; -} - static void filterAllowList(vector_class &PiDevices, RT::PiPlatform PiPlatform, const plugin &Plugin) { const std::vector AllowList(getAllowListDesc()); @@ -323,10 +269,8 @@ static void filterAllowList(vector_class &PiDevices, if (!Desc.DevDriverVer.empty()) { if (!std::regex_match(DeviceDriverVer, std::regex(Desc.DevDriverVer))) { - DevVerState = matchVersions(DeviceDriverVer, Desc.DevDriverVer); - if (DevVerState == MatchState::NOMATCH) { - continue; - } + DevVerState = MatchState::NOMATCH; + continue; } else { DevVerState = MatchState::MATCH; } diff --git a/sycl/test/config/select_device.cpp b/sycl/test/config/select_device.cpp index 671784e3b96b6..54bb1d0468e54 100644 --- a/sycl/test/config/select_device.cpp +++ b/sycl/test/config/select_device.cpp @@ -1,43 +1,44 @@ // RUN: %clangxx -fsycl %s -o %t.out // -// RUN: env WRITE_DEVICE_INFO=1 %t.out -// RUN: env READ_DEVICE_INFO=1 %t.out +// RUN: env WRITE_DEVICE_INFO=1 %GPU_RUN_PLACEHOLDER %t.out +// RUN: env READ_DEVICE_INFO=1 %GPU_RUN_PLACEHOLDER %t.out // -// RUN: env WRITE_PLATFORM_INFO=1 %t.out -// RUN: env READ_PLATFORM_INFO=1 %t.out +// RUN: env WRITE_PLATFORM_INFO=1 %GPU_RUN_PLACEHOLDER %t.out +// RUN: env READ_PLATFORM_INFO=1 %GPU_RUN_PLACEHOLDER %t.out // -// RUN: env WRITE_DEVICE_ERROR_INFO=1 %t.out -// RUN: env READ_DEVICE_ERROR_INFO=1 %t.out +// RUN: env WRITE_DEVICE_ERROR_INFO=1 %GPU_RUN_PLACEHOLDER %t.out +// RUN: env READ_DEVICE_ERROR_INFO=1 %GPU_RUN_PLACEHOLDER %t.out // -// RUN: env WRITE_PLATFORM_ERROR_INFO=1 %t.out -// RUN: env READ_PLATFORM_ERROR_INFO=1 %t.out +// RUN: env WRITE_PLATFORM_ERROR_INFO=1 %GPU_RUN_PLACEHOLDER %t.out +// RUN: env READ_PLATFORM_ERROR_INFO=1 %GPU_RUN_PLACEHOLDER %t.out // -// RUN: env WRITE_OLD_VERSION_INFO=1 %t.out -// RUN: env READ_OLD_VERSION_INFO=1 %t.out +// RUN: env WRITE_REG_EX_INFO=1 %GPU_RUN_PLACEHOLDER %t.out +// RUN: env READ_REG_EX_INFO=1 %GPU_RUN_PLACEHOLDER %t.out // -// RUN: env WRITE_REG_EX_INFO=1 %t.out -// RUN: env READ_REG_EX_INFO=1 %t.out +// RUN: env WRITE_DEVICE_NAME_INFO=1 %GPU_RUN_PLACEHOLDER %t.out +// RUN: env READ_DEVICE_NAME_INFO=1 %GPU_RUN_PLACEHOLDER %t.out // -// RUN: env WRITE_DEVICE_NAME_INFO=1 %t.out -// RUN: env READ_DEVICE_NAME_INFO=1 %t.out +// RUN: env WRITE_PLATFORM_NAME_INFO=1 %GPU_RUN_PLACEHOLDER %t.out +// RUN: env READ_PLATFORM_NAME_INFO=1 %GPU_RUN_PLACEHOLDER %t.out // -// RUN: env WRITE_PLATFORM_NAME_INFO=1 %t.out -// RUN: env READ_PLATFORM_NAME_INFO=1 %t.out +// RUN: env WRITE_DEVICE_MULTI_INFO=1 %GPU_RUN_PLACEHOLDER %t.out +// RUN: env READ_DEVICE_MULTI_INFO=1 %GPU_RUN_PLACEHOLDER %t.out // -// RUN: env WRITE_DEVICE_MULTI_INFO=1 %t.out -// RUN: env READ_DEVICE_MULTI_INFO=1 %t.out +// RUN: env WRITE_DEVICE_MALFORMED_INFO=1 %GPU_RUN_PLACEHOLDER %t.out +// RUN: env READ_DEVICE_MALFORMED_INFO=1 %GPU_RUN_PLACEHOLDER %t.out // -// RUN: env WRITE_DEVICE_MALFORMED_INFO=1 %t.out -// RUN: env READ_DEVICE_MALFORMED_INFO=1 %t.out +// RUN: env WRITE_DRIVER_MALFORMED_INFO=1 %GPU_RUN_PLACEHOLDER %t.out +// RUN: env READ_DRIVER_MALFORMED_INFO=1 %GPU_RUN_PLACEHOLDER %t.out // -// RUN: env WRITE_DRIVER_MALFORMED_INFO=1 %t.out -// RUN: env READ_DRIVER_MALFORMED_INFO=1 %t.out +// RUN: env WRITE_PLATFORM_MALFORMED_INFO=1 %GPU_RUN_PLACEHOLDER %t.out +// RUN: env READ_PLATFORM_MALFORMED_INFO=1 %GPU_RUN_PLACEHOLDER %t.out // -// RUN: env WRITE_PLATFORM_MALFORMED_INFO=1 %t.out -// RUN: env READ_PLATFORM_MALFORMED_INFO=1 %t.out +// RUN: env WRITE_PLATVER_MALFORMED_INFO=1 %GPU_RUN_PLACEHOLDER %t.out +// RUN: env READ_PLATVER_MALFORMED_INFO=1 %GPU_RUN_PLACEHOLDER %t.out // -// RUN: env WRITE_PLATFORM_VERSION_MALFORMED_INFO=1 %t.out -// RUN: env READ_PLATFORM_VERSION_MALFORMED_INFO=1 %t.out +// REQUIRES: gpu +// +// TODO: Update this test when SYCL_DEVICE_FILTER support in enabled. //==------------ select_device.cpp - SYCL_DEVICE_ALLOWLIST test ------------==// // @@ -91,60 +92,6 @@ static void replaceSpecialCharacters(std::string &str) { } } -std::vector convertVersionString(std::string version) { - // version string format is xx.yy.zzzzz - std::vector values; - size_t pos = 0; - size_t start = pos; - if ((pos = version.find(".", pos)) == std::string::npos) { - throw sycl::runtime_error("Malformed syntax in version string", - PI_INVALID_VALUE); - } - values.push_back(std::stoi(version.substr(start, pos - start))); - pos++; - start = pos; - if ((pos = version.find(".", pos)) == std::string::npos) { - throw sycl::runtime_error("Malformed syntax in version string", - PI_INVALID_VALUE); - } - values.push_back(std::stoi(version.substr(start, pos - start))); - pos++; - size_t prev = pos; - if ((pos = version.find(".", pos)) == std::string::npos) { - values.push_back(std::stoi(version.substr(prev))); - } else { - values.push_back(std::stoi(version.substr(start, pos - start))); - pos++; - values.push_back(std::stoi(version.substr(pos))); - } - return values; -} - -bool matchVersions(std::string version1, std::string version2) { - std::vector v1 = convertVersionString(version1); - std::vector v2 = convertVersionString(version2); - - if (v1.size() != v2.size()) { - return false; - } - if (v1[0] > v2[0]) { - return true; - } - if ((v1[0] == v2[0]) && (v1[1] >= v2[1])) { - return true; - } - if ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] >= v2[2])) { - return true; - } - if (v1.size() == 4) { - if ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2]) && - (v1[3] >= v2[3])) { - return true; - } - } - return false; -} - static std::vector getAllowListDesc(std::string allowList) { if (allowList.empty()) return {}; @@ -230,6 +177,7 @@ static std::vector getAllowListDesc(std::string allowList) { int main() { bool passed = false; + std::string sycl_be = getenv("SYCL_BE"); // Test the GPU devices name and version number. if (getenv("WRITE_DEVICE_INFO")) { @@ -243,10 +191,19 @@ int main() { std::string name = dev.get_info(); replaceSpecialCharacters(name); std::string ver = dev.get_info(); - fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver - << "}}" << std::endl; - passed = true; - break; + if ((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) { + fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } else if ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } } } } @@ -294,14 +251,23 @@ int main() { std::string name = plt.get_info(); replaceSpecialCharacters(name); std::string ver = plt.get_info(); - fs << "PlatformName:{{" << name << "}},PlatformVersion:{{" << ver - << "}}" << std::endl; - passed = true; - break; + if ((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) { + fs << "PlatformName:{{" << name << "}},PlatformVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } else if ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + fs << "PlatformName:{{" << name << "}},PlatformVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } } } + fs.close(); } - fs.close(); } else if (getenv("READ_PLATFORM_INFO")) { std::ifstream fs; fs.open("select_device_config.txt", std::fstream::in); @@ -345,10 +311,19 @@ int main() { std::string name = dev.get_info(); replaceSpecialCharacters(name); std::string ver("98.76.54321"); - fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver - << "}}" << std::endl; - passed = true; - break; + if ((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) { + fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } else if ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } } } } @@ -393,11 +368,21 @@ int main() { if (plt.has(aspect::gpu)) { std::string name = plt.get_info(); replaceSpecialCharacters(name); - std::string ver("OpenCL 12.34"); - fs << "PlatformName:{{" << name << "}},PlatformVersion:{{" << ver - << "}}" << std::endl; - passed = true; - break; + if ((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) { + std::string ver("OpenCL 12.34"); + fs << "PlatformName:{{" << name << "}},PlatformVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } else if ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + std::string ver("12.34"); + fs << "PlatformName:{{" << name << "}},PlatformVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } } } } @@ -431,70 +416,6 @@ int main() { } } - // Test that the device driver version number is >= the provided version - // number. - if (getenv("WRITE_OLD_VERSION_INFO")) { - std::ofstream fs; - fs.open("select_device_config.txt"); - if (fs.is_open()) { - for (const auto &plt : platform::get_platforms()) { - if (!plt.has(aspect::host)) { - for (const auto &dev : plt.get_devices()) { - if (dev.has(aspect::gpu)) { - std::string name = dev.get_info(); - replaceSpecialCharacters(name); - std::string ver = dev.get_info(); - size_t pos = 0; - if ((pos = ver.rfind(".")) == std::string::npos) { - throw std::runtime_error("Malformed syntax in version string"); - } - pos = ver.length() - pos; - int num = stoi(ver.substr(pos)); - if (num > 20) { - num = num - 20; - } - std::string str = ver.substr(0, pos) + std::to_string(num); - fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << str - << "}}" << std::endl; - passed = true; - break; - } - } - } - } - fs.close(); - } - } else if (getenv("READ_OLD_VERSION_INFO")) { - std::ifstream fs; - fs.open("select_device_config.txt"); - if (fs.is_open()) { - std::string allowlist; - std::getline(fs, allowlist); - if (!allowlist.empty()) { - setenv("SYCL_DEVICE_ALLOWLIST", allowlist.c_str(), 0); - std::vector components(getAllowListDesc(allowlist)); - std::cout << "SYCL_DEVICE_ALLOWLIST=" << allowlist << std::endl; - - cl::sycl::queue deviceQueue(gpu_selector{}); - device dev = deviceQueue.get_device(); - for (const DevDescT &desc : components) { - if ((std::regex_match(dev.get_info(), - std::regex(desc.devName))) && - (matchVersions(dev.get_info(), - desc.devDriverVer) == true)) { - passed = true; - } - std::cout << "Device: " << dev.get_info() - << std::endl; - std::cout << "DriverVersion: " - << dev.get_info() - << std::endl; - } - } - fs.close(); - } - } - // Test handling a regular expression in the device driver version number. if (getenv("WRITE_REG_EX_INFO")) { std::ofstream fs; @@ -517,10 +438,19 @@ int main() { throw std::runtime_error("Malformed syntax in version string"); } ver.replace(start, pos - start, "*"); - fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver - << "}}" << std::endl; - passed = true; - break; + if ((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) { + fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } else if ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver + << "}}" << std::endl; + passed = true; + break; + } } } } @@ -569,9 +499,17 @@ int main() { if (dev.has(aspect::gpu)) { std::string name = dev.get_info(); replaceSpecialCharacters(name); - fs << "DeviceName:{{" << name << "}}" << std::endl; - passed = true; - break; + if ((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) { + fs << "DeviceName:{{" << name << "}}" << std::endl; + passed = true; + break; + } else if ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + fs << "DeviceName:{{" << name << "}}" << std::endl; + passed = true; + break; + } } } } @@ -613,9 +551,17 @@ int main() { if (plt.has(aspect::gpu)) { std::string name = plt.get_info(); replaceSpecialCharacters(name); - fs << "PlatformName:{{" << name << "}}" << std::endl; - passed = true; - break; + if ((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) { + fs << "PlatformName:{{" << name << "}}" << std::endl; + passed = true; + break; + } else if ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + fs << "PlatformName:{{" << name << "}}" << std::endl; + passed = true; + break; + } } } } @@ -661,13 +607,27 @@ int main() { std::string name = dev.get_info(); replaceSpecialCharacters(name); std::string ver = dev.get_info(); - if (count > 0) { - ss << " | "; + if ((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) { + if (count > 0) { + ss << " | "; + } + ss << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver + << "}}"; + count++; + passed = true; + break; + } else if ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + if (count > 0) { + ss << " | "; + } + ss << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver + << "}}"; + count++; + passed = true; + break; } - ss << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver - << "}}"; - count++; - passed = true; } } } @@ -717,9 +677,17 @@ int main() { if (dev.has(aspect::gpu)) { std::string name = dev.get_info(); replaceSpecialCharacters(name); - fs << "DeviceName:HAHA{{" << name << "}}" << std::endl; - passed = true; - break; + if ((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) { + fs << "DeviceName:HAHA{{" << name << "}}" << std::endl; + passed = true; + break; + } else if ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + fs << "DeviceName:HAHA{{" << name << "}}" << std::endl; + passed = true; + break; + } } } } @@ -765,9 +733,17 @@ int main() { if (plt.has(aspect::gpu)) { std::string name = plt.get_info(); replaceSpecialCharacters(name); - fs << "PlatformName:HAHA{{" << name << "}}" << std::endl; - passed = true; - break; + if ((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) { + fs << "PlatformName:HAHA{{" << name << "}}" << std::endl; + passed = true; + break; + } else if ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + fs << "PlatformName:HAHA{{" << name << "}}" << std::endl; + passed = true; + break; + } } } } @@ -814,10 +790,19 @@ int main() { std::string name = dev.get_info(); replaceSpecialCharacters(name); std::string ver = dev.get_info(); - fs << "DeviceName:{{" << name << "}},DriverVersion:HAHA{{" << ver - << "}}" << std::endl; - passed = true; - break; + if ((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) { + fs << "DeviceName:{{" << name << "}},DriverVersion:HAHA{{" + << ver << "}}" << std::endl; + passed = true; + break; + } else if ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + fs << "DeviceName:{{" << name << "}},DriverVersion:HAHA{{" + << ver << "}}" << std::endl; + passed = true; + break; + } } } } @@ -855,7 +840,7 @@ int main() { } // Test the platform name and version number. - if (getenv("WRITE_PLATFORM_VERSION_MALFORMED_INFO")) { + if (getenv("WRITE_PLATVER_MALFORMED_INFO")) { std::ofstream fs; fs.open("select_device_config.txt"); if (fs.is_open()) { @@ -864,15 +849,24 @@ int main() { std::string name = plt.get_info(); replaceSpecialCharacters(name); std::string ver = plt.get_info(); - fs << "PlatformName:{{" << name << "}},PlatformVersion:HAHA{{" << ver - << "}}" << std::endl; - passed = true; - break; + if ((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) { + fs << "PlatformName:{{" << name << "}},PlatformVersion:HAHA{{" + << ver << "}}" << std::endl; + passed = true; + break; + } else if ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + fs << "PlatformName:{{" << name << "}},PlatformVersion:HAHA{{" + << ver << "}}" << std::endl; + passed = true; + break; + } } } } fs.close(); - } else if (getenv("READ_PLATFORM_VERSION_MALFORMED_INFO")) { + } else if (getenv("READ_PLATVER_MALFORMED_INFO")) { std::ifstream fs; fs.open("select_device_config.txt", std::fstream::in); if (fs.is_open()) { From 267ad4f8666ef47705db880fdcc89e731aeb4495 Mon Sep 17 00:00:00 2001 From: Gail Lyons Date: Fri, 25 Sep 2020 11:38:33 -0700 Subject: [PATCH 5/9] Mark test case as expected to fail on cuda. Signed-off-by: Gail Lyons --- sycl/test/config/select_device.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sycl/test/config/select_device.cpp b/sycl/test/config/select_device.cpp index 54bb1d0468e54..f9ff05d64c50b 100644 --- a/sycl/test/config/select_device.cpp +++ b/sycl/test/config/select_device.cpp @@ -38,6 +38,8 @@ // // REQUIRES: gpu // +// XFAIL: cuda +// // TODO: Update this test when SYCL_DEVICE_FILTER support in enabled. //==------------ select_device.cpp - SYCL_DEVICE_ALLOWLIST test ------------==// From cfb40d76cfc58d2779df557ae3a73fdd96f7570a Mon Sep 17 00:00:00 2001 From: Gail Lyons Date: Fri, 25 Sep 2020 13:33:48 -0700 Subject: [PATCH 6/9] Fixed a bug in the test program. Signed-off-by: Gail Lyons --- sycl/test/config/select_device.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sycl/test/config/select_device.cpp b/sycl/test/config/select_device.cpp index f9ff05d64c50b..1012b67d2554e 100644 --- a/sycl/test/config/select_device.cpp +++ b/sycl/test/config/select_device.cpp @@ -179,7 +179,10 @@ static std::vector getAllowListDesc(std::string allowList) { int main() { bool passed = false; - std::string sycl_be = getenv("SYCL_BE"); + std::string sycl_be("PI_OPENCL"); + if (getenv("SYCL_BE")) { + sycl_be = getenv("SYCL_BE"); + } // Test the GPU devices name and version number. if (getenv("WRITE_DEVICE_INFO")) { From 55b0857685125b492c402e8b4ca88af9cbefe994 Mon Sep 17 00:00:00 2001 From: Gail Lyons Date: Mon, 28 Sep 2020 05:53:40 -0700 Subject: [PATCH 7/9] Incorporating code review comments. Signed-off-by: Gail Lyons --- sycl/doc/EnvironmentVariables.md | 2 +- sycl/source/detail/platform_impl.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/doc/EnvironmentVariables.md b/sycl/doc/EnvironmentVariables.md index 6fc47127c0e2d..403d7cc47e13b 100644 --- a/sycl/doc/EnvironmentVariables.md +++ b/sycl/doc/EnvironmentVariables.md @@ -22,7 +22,7 @@ subject to change. Do not rely on these variables in production code. | SYCL_DISABLE_EXECUTION_GRAPH_CLEANUP | Any(\*) | Disable cleanup of finished command nodes at host-device synchronization points. | | SYCL_THROW_ON_BLOCK | Any(\*) | Throw an exception on attempt to wait for a blocked command. | | SYCL_DEVICELIB_INHIBIT_NATIVE | String of device library extensions (separated by a whitespace) | Do not rely on device native support for devicelib extensions listed in this option. | -| SYCL_DEVICE_ALLOWLIST | A list of devices and their driver version following the pattern: DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}. Also may contain PlatformName and PlatformVersion | Filter out devices that do not match the pattern specified. Regular expression can be passed and the DPC++ runtime will select only those devices which satisfy the regex. Special characters, such as parenthesis, must be escaped. More than one device can be specified using the piping symbol "|".| +| SYCL_DEVICE_ALLOWLIST | A list of devices and their driver version following the pattern: DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}. Also may contain PlatformName and PlatformVersion | Filter out devices that do not match the pattern specified. Regular expression can be passed and the DPC++ runtime will select only those devices which satisfy the regex. Special characters, such as parenthesis, must be escaped. More than one device can be specified using the piping symbol "|".| | SYCL_QUEUE_THREAD_POOL_SIZE | Positive integer | Number of threads in thread pool of queue. | | SYCL_DEVICELIB_NO_FALLBACK | Any(\*) | Disable loading and linking of device library images | | SYCL_PI_LEVEL0_MAX_COMMAND_LIST_CACHE | Positive integer | Maximum number of oneAPI Level Zero Command lists that can be allocated with no reuse before throwing an "out of resources" error. Default is 20000, threshold may be increased based on resource availabilty and workload demand. | diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 34e51ee7ef4c2..cc0c01f5a8779 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -121,7 +121,7 @@ vector_class platform_impl::get_platforms() { return Platforms; } -std::string getValue(/*const*/ std::string &AllowList, size_t &Pos, +std::string getValue(const std::string &AllowList, size_t &Pos, unsigned long int Size) { size_t Prev = Pos; if ((Pos = AllowList.find("{{", Pos)) == std::string::npos) { From 650d475deb7e6803030a771f18151a0e6a15eb59 Mon Sep 17 00:00:00 2001 From: Gail Lyons Date: Tue, 29 Sep 2020 10:53:45 -0700 Subject: [PATCH 8/9] Incorporated code review comments Signed-off-by: Gail Lyons --- sycl/test/config/select_device.cpp | 127 +++++++++++------------------ 1 file changed, 47 insertions(+), 80 deletions(-) diff --git a/sycl/test/config/select_device.cpp b/sycl/test/config/select_device.cpp index 1012b67d2554e..d8b1ec97d5a8d 100644 --- a/sycl/test/config/select_device.cpp +++ b/sycl/test/config/select_device.cpp @@ -81,6 +81,8 @@ static void replaceSpecialCharacters(std::string &str) { std::string rparen(")"); std::string esclparen("\\("); std::string escrparen("\\)"); + std::string period("."); + std::string escperiod("\\."); size_t pos = 0; while ((pos = str.find(lparen, pos)) != std::string::npos) { @@ -92,6 +94,11 @@ static void replaceSpecialCharacters(std::string &str) { str.replace(pos, rparen.size(), escrparen); pos += escrparen.size(); } + pos = 0; + while ((pos = str.find(period, pos)) != std::string::npos) { + str.replace(pos, period.size(), escperiod); + pos += escperiod.size(); + } } static std::vector getAllowListDesc(std::string allowList) { @@ -256,14 +263,10 @@ int main() { std::string name = plt.get_info(); replaceSpecialCharacters(name); std::string ver = plt.get_info(); - if ((plt.get_backend() == backend::opencl) && - (sycl_be.find("OPENCL") != std::string::npos)) { - fs << "PlatformName:{{" << name << "}},PlatformVersion:{{" << ver - << "}}" << std::endl; - passed = true; - break; - } else if ((plt.get_backend() == backend::level_zero) && - (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + if (((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) || + ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos))) { fs << "PlatformName:{{" << name << "}},PlatformVersion:{{" << ver << "}}" << std::endl; passed = true; @@ -316,14 +319,10 @@ int main() { std::string name = dev.get_info(); replaceSpecialCharacters(name); std::string ver("98.76.54321"); - if ((plt.get_backend() == backend::opencl) && - (sycl_be.find("OPENCL") != std::string::npos)) { - fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver - << "}}" << std::endl; - passed = true; - break; - } else if ((plt.get_backend() == backend::level_zero) && - (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + if (((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) || + ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos))) { fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver << "}}" << std::endl; passed = true; @@ -443,14 +442,10 @@ int main() { throw std::runtime_error("Malformed syntax in version string"); } ver.replace(start, pos - start, "*"); - if ((plt.get_backend() == backend::opencl) && - (sycl_be.find("OPENCL") != std::string::npos)) { - fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver - << "}}" << std::endl; - passed = true; - break; - } else if ((plt.get_backend() == backend::level_zero) && - (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + if (((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) || + ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos))) { fs << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver << "}}" << std::endl; passed = true; @@ -504,13 +499,10 @@ int main() { if (dev.has(aspect::gpu)) { std::string name = dev.get_info(); replaceSpecialCharacters(name); - if ((plt.get_backend() == backend::opencl) && - (sycl_be.find("OPENCL") != std::string::npos)) { - fs << "DeviceName:{{" << name << "}}" << std::endl; - passed = true; - break; - } else if ((plt.get_backend() == backend::level_zero) && - (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + if (((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) || + ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos))) { fs << "DeviceName:{{" << name << "}}" << std::endl; passed = true; break; @@ -556,13 +548,10 @@ int main() { if (plt.has(aspect::gpu)) { std::string name = plt.get_info(); replaceSpecialCharacters(name); - if ((plt.get_backend() == backend::opencl) && - (sycl_be.find("OPENCL") != std::string::npos)) { - fs << "PlatformName:{{" << name << "}}" << std::endl; - passed = true; - break; - } else if ((plt.get_backend() == backend::level_zero) && - (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + if (((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) || + ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos))) { fs << "PlatformName:{{" << name << "}}" << std::endl; passed = true; break; @@ -612,18 +601,10 @@ int main() { std::string name = dev.get_info(); replaceSpecialCharacters(name); std::string ver = dev.get_info(); - if ((plt.get_backend() == backend::opencl) && - (sycl_be.find("OPENCL") != std::string::npos)) { - if (count > 0) { - ss << " | "; - } - ss << "DeviceName:{{" << name << "}},DriverVersion:{{" << ver - << "}}"; - count++; - passed = true; - break; - } else if ((plt.get_backend() == backend::level_zero) && - (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + if (((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) || + ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos))) { if (count > 0) { ss << " | "; } @@ -682,13 +663,10 @@ int main() { if (dev.has(aspect::gpu)) { std::string name = dev.get_info(); replaceSpecialCharacters(name); - if ((plt.get_backend() == backend::opencl) && - (sycl_be.find("OPENCL") != std::string::npos)) { - fs << "DeviceName:HAHA{{" << name << "}}" << std::endl; - passed = true; - break; - } else if ((plt.get_backend() == backend::level_zero) && - (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + if (((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) || + ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos))) { fs << "DeviceName:HAHA{{" << name << "}}" << std::endl; passed = true; break; @@ -738,13 +716,10 @@ int main() { if (plt.has(aspect::gpu)) { std::string name = plt.get_info(); replaceSpecialCharacters(name); - if ((plt.get_backend() == backend::opencl) && - (sycl_be.find("OPENCL") != std::string::npos)) { - fs << "PlatformName:HAHA{{" << name << "}}" << std::endl; - passed = true; - break; - } else if ((plt.get_backend() == backend::level_zero) && - (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + if (((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) || + ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos))) { fs << "PlatformName:HAHA{{" << name << "}}" << std::endl; passed = true; break; @@ -795,14 +770,10 @@ int main() { std::string name = dev.get_info(); replaceSpecialCharacters(name); std::string ver = dev.get_info(); - if ((plt.get_backend() == backend::opencl) && - (sycl_be.find("OPENCL") != std::string::npos)) { - fs << "DeviceName:{{" << name << "}},DriverVersion:HAHA{{" - << ver << "}}" << std::endl; - passed = true; - break; - } else if ((plt.get_backend() == backend::level_zero) && - (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + if (((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) || + ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos))) { fs << "DeviceName:{{" << name << "}},DriverVersion:HAHA{{" << ver << "}}" << std::endl; passed = true; @@ -854,14 +825,10 @@ int main() { std::string name = plt.get_info(); replaceSpecialCharacters(name); std::string ver = plt.get_info(); - if ((plt.get_backend() == backend::opencl) && - (sycl_be.find("OPENCL") != std::string::npos)) { - fs << "PlatformName:{{" << name << "}},PlatformVersion:HAHA{{" - << ver << "}}" << std::endl; - passed = true; - break; - } else if ((plt.get_backend() == backend::level_zero) && - (sycl_be.find("LEVEL_ZERO") != std::string::npos)) { + if (((plt.get_backend() == backend::opencl) && + (sycl_be.find("OPENCL") != std::string::npos)) || + ((plt.get_backend() == backend::level_zero) && + (sycl_be.find("LEVEL_ZERO") != std::string::npos))) { fs << "PlatformName:{{" << name << "}},PlatformVersion:HAHA{{" << ver << "}}" << std::endl; passed = true; From 5fb7393e7196773ff58d232c36bfdb03cdf53802 Mon Sep 17 00:00:00 2001 From: Gail Lyons Date: Wed, 30 Sep 2020 11:23:43 -0700 Subject: [PATCH 9/9] Incorporating code review comments Signed-off-by: Gail Lyons --- sycl/doc/EnvironmentVariables.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/doc/EnvironmentVariables.md b/sycl/doc/EnvironmentVariables.md index 403d7cc47e13b..8811d6cd354bf 100644 --- a/sycl/doc/EnvironmentVariables.md +++ b/sycl/doc/EnvironmentVariables.md @@ -22,7 +22,7 @@ subject to change. Do not rely on these variables in production code. | SYCL_DISABLE_EXECUTION_GRAPH_CLEANUP | Any(\*) | Disable cleanup of finished command nodes at host-device synchronization points. | | SYCL_THROW_ON_BLOCK | Any(\*) | Throw an exception on attempt to wait for a blocked command. | | SYCL_DEVICELIB_INHIBIT_NATIVE | String of device library extensions (separated by a whitespace) | Do not rely on device native support for devicelib extensions listed in this option. | -| SYCL_DEVICE_ALLOWLIST | A list of devices and their driver version following the pattern: DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}. Also may contain PlatformName and PlatformVersion | Filter out devices that do not match the pattern specified. Regular expression can be passed and the DPC++ runtime will select only those devices which satisfy the regex. Special characters, such as parenthesis, must be escaped. More than one device can be specified using the piping symbol "|".| +| SYCL_DEVICE_ALLOWLIST | A list of devices and their driver version following the pattern: DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}. Also may contain PlatformName and PlatformVersion | Filter out devices that do not match the pattern specified. Regular expression can be passed and the DPC++ runtime will select only those devices which satisfy the regex. Special characters, such as parenthesis, must be escaped. More than one device can be specified using the piping symbol "\|".| | SYCL_QUEUE_THREAD_POOL_SIZE | Positive integer | Number of threads in thread pool of queue. | | SYCL_DEVICELIB_NO_FALLBACK | Any(\*) | Disable loading and linking of device library images | | SYCL_PI_LEVEL0_MAX_COMMAND_LIST_CACHE | Positive integer | Maximum number of oneAPI Level Zero Command lists that can be allocated with no reuse before throwing an "out of resources" error. Default is 20000, threshold may be increased based on resource availabilty and workload demand. |