From 1f9fed551c91894433feafb596307e8e8d5eb4ff Mon Sep 17 00:00:00 2001 From: Ross Brunton Date: Thu, 22 Aug 2024 15:32:38 +0100 Subject: [PATCH] [UR] Handle cases where UR can't provide IP ver. UR may respond with `UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION` when querying for the device's IP version. This patch handles that case by falling back to unknown or x86_64. --- sycl/source/detail/device_info.hpp | 47 +++++++++---------- sycl/unittests/Extensions/CMakeLists.txt | 1 + .../Extensions/NoDeviceIPVersion.cpp | 38 +++++++++++++++ 3 files changed, 61 insertions(+), 25 deletions(-) create mode 100644 sycl/unittests/Extensions/NoDeviceIPVersion.cpp diff --git a/sycl/source/detail/device_info.hpp b/sycl/source/detail/device_info.hpp index abc5d72a6ef3f..625e4bf948c62 100644 --- a/sycl/source/detail/device_info.hpp +++ b/sycl/source/detail/device_info.hpp @@ -688,22 +688,31 @@ struct get_device_info_impl< ext::oneapi::experimental::info::device::architecture> { static ext::oneapi::experimental::architecture get(const DeviceImplPtr &Dev) { backend CurrentBackend = Dev->getBackend(); - if (Dev->is_gpu() && (backend::ext_oneapi_level_zero == CurrentBackend || - backend::opencl == CurrentBackend)) { - auto MapArchIDToArchName = [](const int arch) { - for (const auto &Item : IntelGPUArchitectures) { - if (Item.first == arch) - return Item.second; - } - return ext::oneapi::experimental::architecture::unknown; - }; + auto LookupIPVersion = [&](auto &ArchList) + -> std::optional { uint32_t DeviceIp; - Dev->getPlugin()->call( + ur_result_t Err = Dev->getPlugin()->call_nocheck( urDeviceGetInfo, Dev->getHandleRef(), UrInfoCode< ext::oneapi::experimental::info::device::architecture>::value, sizeof(DeviceIp), &DeviceIp, nullptr); - return MapArchIDToArchName(DeviceIp); + if (Err == UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION) { + // Not all devices support this device info query + return std::nullopt; + } + Dev->getPlugin()->checkUrResult(Err); + + for (const auto &Item : ArchList) { + if (Item.first == static_cast(DeviceIp)) + return Item.second; + } + return std::nullopt; + }; + + if (Dev->is_gpu() && (backend::ext_oneapi_level_zero == CurrentBackend || + backend::opencl == CurrentBackend)) { + return LookupIPVersion(IntelGPUArchitectures) + .value_or(ext::oneapi::experimental::architecture::unknown); } else if (Dev->is_gpu() && (backend::ext_oneapi_cuda == CurrentBackend || backend::ext_oneapi_hip == CurrentBackend)) { auto MapArchIDToArchName = [](const char *arch) { @@ -726,20 +735,8 @@ struct get_device_info_impl< DeviceArchCopy.substr(0, DeviceArchCopy.find(":")); return MapArchIDToArchName(DeviceArchSubstr.data()); } else if (Dev->is_cpu() && backend::opencl == CurrentBackend) { - auto MapArchIDToArchName = [](const int arch) { - for (const auto &Item : IntelCPUArchitectures) { - if (Item.first == arch) - return Item.second; - } - return sycl::ext::oneapi::experimental::architecture::x86_64; - }; - uint32_t DeviceIp; - Dev->getPlugin()->call( - urDeviceGetInfo, Dev->getHandleRef(), - UrInfoCode< - ext::oneapi::experimental::info::device::architecture>::value, - sizeof(DeviceIp), &DeviceIp, nullptr); - return MapArchIDToArchName(DeviceIp); + return LookupIPVersion(IntelCPUArchitectures) + .value_or(ext::oneapi::experimental::architecture::x86_64); } // else is not needed // TODO: add support of other architectures by extending with else if return ext::oneapi::experimental::architecture::unknown; diff --git a/sycl/unittests/Extensions/CMakeLists.txt b/sycl/unittests/Extensions/CMakeLists.txt index 7ea07400d745a..9f251c5ea5de5 100644 --- a/sycl/unittests/Extensions/CMakeLists.txt +++ b/sycl/unittests/Extensions/CMakeLists.txt @@ -14,6 +14,7 @@ add_sycl_unittest(ExtensionsTests OBJECT DiscardEvent.cpp ProfilingTag.cpp KernelProperties.cpp + NoDeviceIPVersion.cpp ) add_subdirectory(CommandGraph) diff --git a/sycl/unittests/Extensions/NoDeviceIPVersion.cpp b/sycl/unittests/Extensions/NoDeviceIPVersion.cpp new file mode 100644 index 0000000000000..2ebc2e26a8848 --- /dev/null +++ b/sycl/unittests/Extensions/NoDeviceIPVersion.cpp @@ -0,0 +1,38 @@ +//==------------------- NoDeviceIPVersion.cpp ------------------------------==// +// +// 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 "sycl/ext/oneapi/experimental/device_architecture.hpp" +#include +#include +#include + +static ur_result_t afterDeviceGetInfo(void *pParams) { + auto params = *static_cast(pParams); + if (*params.ppropName == UR_DEVICE_INFO_IP_VERSION) { + return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION; + } + return UR_RESULT_SUCCESS; +} + +namespace syclex = sycl::ext::oneapi::experimental; +TEST(NoDeviceIPVersionTest, NoDeviceIPVersion) { + sycl::unittest::UrMock<> Mock; + mock::getCallbacks().set_after_callback("urDeviceGetInfo", + &afterDeviceGetInfo); + sycl::platform Plt = sycl::platform(); + auto Dev = Plt.get_devices()[0]; + if (Dev.get_backend() != sycl::backend::opencl && + Dev.get_backend() != sycl::backend::ext_oneapi_level_zero) { + GTEST_SKIP(); + } + + syclex::architecture DevArch = + Dev.get_info(); + ASSERT_TRUE(DevArch == syclex::architecture::unknown || + DevArch == syclex::architecture::x86_64); +}