diff --git a/SYCL/Regression/device_num.cpp b/SYCL/Regression/device_num.cpp index 3ff8f1afd8..9f48bb822d 100644 --- a/SYCL/Regression/device_num.cpp +++ b/SYCL/Regression/device_num.cpp @@ -1,9 +1,9 @@ // RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out -// RUN: env SYCL_DEVICE_FILTER=0 %t.out -// RUN: env SYCL_DEVICE_FILTER=1 %t.out -// RUN: env SYCL_DEVICE_FILTER=2 %t.out -// RUN: env SYCL_DEVICE_FILTER=3 %t.out -// RUN: env SYCL_DEVICE_FILTER=4 %t.out +// RUN: env PRINT_FULL_DEVICE_INFO=1 %t.out > %t1.conf +// RUN: env SYCL_DEVICE_FILTER=0 env TEST_DEV_CONFIG_FILE_NAME=%t1.conf %t.out +// RUN: env SYCL_DEVICE_FILTER=1 env TEST_DEV_CONFIG_FILE_NAME=%t1.conf %t.out +// RUN: env SYCL_DEVICE_FILTER=2 env TEST_DEV_CONFIG_FILE_NAME=%t1.conf %t.out +// RUN: env SYCL_DEVICE_FILTER=3 env TEST_DEV_CONFIG_FILE_NAME=%t1.conf %t.out // The test is using all available BEs but CUDA machine in CI does not have // functional OpenCL RT @@ -11,84 +11,217 @@ #include #include +#include using namespace cl::sycl; using namespace std; +const std::map DeviceTypeStringMap = { + {info::device_type::cpu, "cpu"}, + {info::device_type::gpu, "gpu"}, + {info::device_type::host, "host"}, + {info::device_type::accelerator, "acc"}}; + +const std::map BackendStringMap = { + {backend::opencl, "opencl"}, + {backend::host, "host"}, + {backend::ext_oneapi_level_zero, "ext_oneapi_level_zero"}, + {backend::ext_intel_esimd_emulator, "ext_intel_esimd_emulator"}}; + +std::string getDeviceTypeName(const device &d) { + auto DeviceType = d.get_info(); + std::string DeviceTypeName = "unknown"; + auto it = DeviceTypeStringMap.find(DeviceType); + if (it != DeviceTypeStringMap.end()) + DeviceTypeName = it->second; + return DeviceTypeName; +} + void printDeviceType(const device &d) { string name = d.get_platform().get_info(); - auto DeviceType = d.get_info(); - std::string DeviceTypeName; - - switch (DeviceType) { - case info::device_type::cpu: - DeviceTypeName = "CPU "; - break; - case info::device_type::gpu: - DeviceTypeName = "GPU "; - break; - case info::device_type::host: - DeviceTypeName = "HOST "; - break; - case info::device_type::accelerator: - DeviceTypeName = "ACCELERATOR "; - break; - default: - DeviceTypeName = "UNKNOWN "; - break; + std::cout << getDeviceTypeName(d) << ", " << name << std::endl; +} + +// Applicable for backend and device info. +template +DevInfoEntry +getDeviceInfoByName(const std::string &name, + const std::map &mapWithNames) { + auto it = std::find_if( + mapWithNames.begin(), mapWithNames.end(), + [&name](auto &entry) { return entry.second.compare(name) == 0; }); + // Invalid or unknown configuration if not found. + assert(it != mapWithNames.end()); + return it->first; +} + +void PrintSystemConfiguration() { + const auto &Platforms = platform::get_platforms(); + + // Keep track of the number of devices per backend. + std::map DeviceNums; + + for (const auto &Platform : Platforms) { + backend Backend = Platform.get_backend(); + auto PlatformName = Platform.get_info(); + const auto &Devices = Platform.get_devices(); + for (const auto &Device : Devices) { + std::cout << Backend << ":" << getDeviceTypeName(Device) << ":" + << DeviceNums[Backend] << std::endl; + ++DeviceNums[Backend]; + } } - std::cout << DeviceTypeName << name << std::endl; +} + +using DevInfo = std::pair; +using DevInfoMap = std::map>; +bool ReadInitialSystemConfiguration(char *fileName, DevInfoMap &devices) { + fstream confFile; + confFile.open(fileName, ios::in); + if (!confFile.is_open()) + return false; + char linebuf[64]; + while (confFile.getline(linebuf, 64)) { + std::istringstream entry(linebuf); + std::string type, backend, devNum; + if (!std::getline(entry, backend, ':')) + return false; + if (!std::getline(entry, type, ':')) + return false; + if (!std::getline(entry, devNum)) + return false; + devices[std::atoi(devNum.data())].push_back( + make_pair(getDeviceInfoByName(type, DeviceTypeStringMap), + getDeviceInfoByName(backend, BackendStringMap))); + } + if (devices.size() == 0) + return false; + return true; +} + +int GetPreferredDeviceIndex(const std::vector &devices, + info::device_type type) { + // Note: scores can be not the same as in runtime, just keep the same + // preference. + // gpu L0, opencl + // cpu + // acc + // host + const std::map scoreByType = { + {info::device_type::cpu, 300}, + {info::device_type::gpu, 500}, + {info::device_type::accelerator, 75}, + {info::device_type::host, 100}}; + int score = -1; + int index = -1; + int devCount = devices.size(); + for (int i = 0; i < devCount; i++) { + int dev_score = 0; + auto deviceType = devices[i].get_info(); + auto backend = devices[i].get_backend(); + if ((type != info::device_type::all) && (deviceType != type)) + continue; + dev_score = scoreByType.at(deviceType); + if (backend == backend::ext_oneapi_level_zero) + dev_score += 100; + if (dev_score > score) { + score = dev_score; + index = i; + } + } + return index; } int main() { + // Expected that the sycl device filter is not set + if (getenv("PRINT_FULL_DEVICE_INFO")) { + PrintSystemConfiguration(); + return 0; + } + + DevInfoMap unfilteredDevices; + assert(ReadInitialSystemConfiguration(getenv("TEST_DEV_CONFIG_FILE_NAME"), + unfilteredDevices) && + "Failed to parse file with initial system configuration data"); + const char *envVal = std::getenv("SYCL_DEVICE_FILTER"); int deviceNum; std::cout << "SYCL_DEVICE_FILTER=" << envVal << std::endl; deviceNum = std::atoi(envVal); auto devices = device::get_devices(); - if (devices.size() > deviceNum) { - device targetDevice = devices[deviceNum]; - std::cout << "Target Device: "; - printDeviceType(targetDevice); - - { - default_selector ds; - device d = ds.select_device(); - std::cout << "default_selector selected "; - printDeviceType(d); - assert(targetDevice == d && - "The selected device is not the target device specified."); - } + std::cout << "Device count to analyze =" << devices.size() << std::endl; - if (targetDevice.is_gpu()) { - gpu_selector gs; - device d = gs.select_device(); - std::cout << "gpu_selector selected "; - printDeviceType(d); - assert(targetDevice == d && - "The selected device is not the target device specified."); - } else if (targetDevice.is_cpu()) { - cpu_selector cs; - device d = cs.select_device(); - std::cout << "cpu_selector selected "; - printDeviceType(d); - assert(targetDevice == d && - "The selected device is not the target device specified."); - } else if (targetDevice.is_accelerator()) { - accelerator_selector as; - device d = as.select_device(); - std::cout << "accelerator_selector selected "; - printDeviceType(d); - assert(targetDevice == d && - "The selected device is not the target device specified."); - } else if (targetDevice.is_host()) { - host_selector hs; - device d = hs.select_device(); - std::cout << "host_selector selected "; - printDeviceType(d); - assert(targetDevice == d && "The selected device is not a host device."); - } + auto expectedDevices = unfilteredDevices[deviceNum]; + size_t devCount = expectedDevices.size(); + assert(devices.size() == devCount && + "Devices seems to be filtered in a wrong way. Count of devices is " + "unexpected."); + + if (devices.size() == 0) { + std::cout << "No devices with such filter, skipping test." << std::endl; + return 0; } + + for (int i = 0; i < devCount; i++) { + auto deviceType = devices[i].get_info(); + assert(deviceType == std::get<0>(expectedDevices[i]) && + "Device type or device order is not expected."); + assert(devices[i].get_backend() == std::get<1>(expectedDevices[i]) && + "Device backend or device order is not expected."); + } + + int targetDevIndex = -1; + { + targetDevIndex = GetPreferredDeviceIndex(devices, info::device_type::all); + assert(targetDevIndex >= 0 && + "Failed to find target device for default selector."); + default_selector ds; + device d = ds.select_device(); + std::cout << "default_selector selected "; + printDeviceType(d); + assert(devices[targetDevIndex] == d && + "The selected device is not the target device specified."); + } + targetDevIndex = GetPreferredDeviceIndex(devices, info::device_type::gpu); + if (targetDevIndex >= 0) { + gpu_selector gs; + device d = gs.select_device(); + std::cout << "gpu_selector selected "; + printDeviceType(d); + assert(devices[targetDevIndex] == d && + "The selected device is not the target device specified."); + } + targetDevIndex = GetPreferredDeviceIndex(devices, info::device_type::cpu); + if (targetDevIndex >= 0) { + cpu_selector cs; + device d = cs.select_device(); + std::cout << "cpu_selector selected "; + printDeviceType(d); + assert(devices[targetDevIndex] == d && + "The selected device is not the target device specified."); + } + targetDevIndex = + GetPreferredDeviceIndex(devices, info::device_type::accelerator); + if (targetDevIndex >= 0) { + accelerator_selector as; + device d = as.select_device(); + std::cout << "accelerator_selector selected "; + printDeviceType(d); + assert(devices[targetDevIndex] == d && + "The selected device is not the target device specified."); + } + targetDevIndex = GetPreferredDeviceIndex(devices, info::device_type::host); + assert((targetDevIndex >= 0 || deviceNum != 0) && + "Failed to find host device."); + if (targetDevIndex >= 0) { + host_selector hs; + device d = hs.select_device(); + std::cout << "host_selector selected "; + printDeviceType(d); + assert(devices[targetDevIndex] == d && + "The selected device is not a host device."); + } + return 0; }