diff --git a/sycl/doc/extensions/IntelGPU/IntelGPUDeviceInfo.md b/sycl/doc/extensions/IntelGPU/IntelGPUDeviceInfo.md index 8468ea5d98c97..06be3c70fbad8 100644 --- a/sycl/doc/extensions/IntelGPU/IntelGPUDeviceInfo.md +++ b/sycl/doc/extensions/IntelGPU/IntelGPUDeviceInfo.md @@ -9,9 +9,50 @@ This proposal details what is required to provide this information as a SYCL ext ## Feature Test Macro ## -The Feature Test Macro will be defined as: +The Feature Test Macro SYCL\_EXT\_INTEL\_DEVICE\_INFO will be defined as one of the values defined in the table below. The existence of this macro can be tested to determine if the implementation supports this feature, or applications can test the macro's value to determine which of the extension's APIs the implementation supports. + +| Value | Description | +| ----- | ----------- | +| 1 | Initial extension version\. Base features are supported | +| 2 | Device UUID is supported | + + +# Device UUID # + +A new device descriptor will be added which will provide the device Universal Unique ID (UUID). + +This new device descriptor is currently only available for devices in the Level Zero platform, and the matching aspect is only true for those devices. The DPC++ default behavior would be to expose the UUIDs of all supported devices which enables detection of total number of unique devices. + + +## Version ## + +The extension supports this query in version 2 and later. + + +## Device Information Descriptors ## + +| Device Descriptors | Return Type | Description | +| ------------------ | ----------- | ----------- | +| info\:\:device\:\:ext\_intel\_device\_info\_uuid | unsigned char | Returns the device UUID| + + +## Aspects ## + +A new aspect, ext\_intel\_device\_info\_uuid, will be added. + +## Error Condition ## + +An invalid object runtime error will be thrown if the device does not support aspect\:\:ext\_intel\_device\_info\_uuid. + + +## Example Usage ## + +The UUID can be obtained using the standard get\_info() interface. + + if (dev.has(aspect::ext_intel_device_info_uuid)) { + auto UUID = dev.get_info(); + } - #define SYCL_EXT_INTEL_DEVICE_INFO 1 # PCI Address # @@ -23,6 +64,11 @@ This new device descriptor is only available for devices in the Level Zero platf **Note:** The environment variable SYCL\_ENABLE\_PCI must be set to 1 to obtain the PCI address. +## Version ## + +All versions of the extension support this query. + + ## Device Information Descriptors ## | Device Descriptors | Return Type | Description | @@ -56,6 +102,11 @@ A new device descriptor will be added which will provide the physical SIMD width This new device descriptor is only available for devices in the Level Zero platform, and the matching aspect is only true for those devices. The DPC++ default behavior is to expose GPU devices through the Level Zero platform. +## Version ## + +All versions of the extension support this query. + + ## Device Information Descriptors ## | Device Descriptors | Return Type | Description | @@ -91,6 +142,11 @@ This new device descriptor will provide the same information as "max\_compute\_u This new device descriptor is only available for devices in the Level Zero platform, and the matching aspect is only true for those devices. The DPC++ default behavior is to expose GPU devices through the Level Zero platform. +## Version ## + +All versions of the extension support this query. + + ## Device Information Descriptors ## | Device Descriptors | Return Type | Description | @@ -124,6 +180,11 @@ A new device descriptor will be added which will provide the number of slices on This new device descriptor is only available for devices in the Level Zero platform, and the matching aspect is only true for those devices. The DPC++ default behavior is to expose GPU devices through the Level Zero platform. +## Version ## + +All versions of the extension support this query. + + ## Device Information Descriptors ## | Device Descriptors | Return Type | Description | @@ -156,6 +217,11 @@ A new device descriptor will be added which will provide the number of subslices This new device descriptor is only available for devices in the Level Zero platform, and the matching aspect is only true for those devices. The DPC++ default behavior is to expose GPU devices through the Level Zero platform. +## Version ## + +All versions of the extension support this query. + + ## Device Information Descriptors ## | Device Descriptors | Return Type | Description | @@ -188,6 +254,11 @@ A new device descriptor will be added which will provide the number of EUs per s This new device descriptor is only available for devices in the Level Zero platform, and the matching aspect is only true for those devices. The DPC++ default behavior is to expose GPU devices through the Level Zero platform. +## Version ## + +All versions of the extension support this query. + + ## Device Information Descriptors ## | Device Descriptors | Return Type | Description | @@ -220,6 +291,11 @@ A new device descriptor will be added which will provide the maximum memory band This new device descriptor is only available for devices in the Level Zero platform, and the matching aspect is only true for those devices. The DPC++ default behavior is to expose GPU devices through the Level Zero platform. +## Version ## + +All versions of the extension support this query. + + ## Device Information Descriptors ## | Device Descriptors | Return Type | Description | diff --git a/sycl/include/CL/sycl/aspects.hpp b/sycl/include/CL/sycl/aspects.hpp index fbc13e967cc96..47eb64765069b 100644 --- a/sycl/include/CL/sycl/aspects.hpp +++ b/sycl/include/CL/sycl/aspects.hpp @@ -41,7 +41,8 @@ enum class aspect { ext_intel_mem_channel = 25, usm_atomic_host_allocations = 26, usm_atomic_shared_allocations = 27, - atomic64 = 28 + atomic64 = 28, + ext_intel_device_info_uuid = 29, }; } // namespace sycl diff --git a/sycl/include/CL/sycl/detail/pi.h b/sycl/include/CL/sycl/detail/pi.h index 5f2735add28c5..d682e35ef8f47 100644 --- a/sycl/include/CL/sycl/detail/pi.h +++ b/sycl/include/CL/sycl/detail/pi.h @@ -52,6 +52,7 @@ #include #include #include + #include #ifdef __cplusplus @@ -278,6 +279,8 @@ typedef enum { CL_DEVICE_CROSS_DEVICE_SHARED_MEM_CAPABILITIES_INTEL, PI_DEVICE_INFO_USM_SYSTEM_SHARED_SUPPORT = CL_DEVICE_SHARED_SYSTEM_MEM_CAPABILITIES_INTEL, + // Intel UUID extension. + PI_DEVICE_INFO_UUID = CL_DEVICE_UUID_KHR, // These are Intel-specific extensions. PI_DEVICE_INFO_PCI_ADDRESS = 0x10020, PI_DEVICE_INFO_GPU_EU_COUNT = 0x10021, diff --git a/sycl/include/CL/sycl/detail/type_traits.hpp b/sycl/include/CL/sycl/detail/type_traits.hpp index 98989ab9fba2a..d1f45601c500f 100644 --- a/sycl/include/CL/sycl/detail/type_traits.hpp +++ b/sycl/include/CL/sycl/detail/type_traits.hpp @@ -13,6 +13,7 @@ #include #include +#include #include __SYCL_INLINE_NAMESPACE(cl) { @@ -51,6 +52,11 @@ __SYCL_INLINE_CONSTEXPR bool is_group_v = detail::is_group::value || detail::is_sub_group::value; namespace detail { +// Type for Intel device UUID extension. +// For details about this extension, see +// sycl/doc/extensions/IntelGPU/IntelGPUDeviceInfo.md +using uuid_type = std::array; + template struct copy_cv_qualifiers; template diff --git a/sycl/include/CL/sycl/feature_test.hpp b/sycl/include/CL/sycl/feature_test.hpp index ea3f7f2e264a9..634fd9379f721 100644 --- a/sycl/include/CL/sycl/feature_test.hpp +++ b/sycl/include/CL/sycl/feature_test.hpp @@ -13,7 +13,7 @@ namespace sycl { // Feature test macro definitions // TODO: Move these feature-test macros to compiler driver. -#define SYCL_EXT_INTEL_DEVICE_INFO 1 +#define SYCL_EXT_INTEL_DEVICE_INFO 2 #define SYCL_EXT_ONEAPI_MATRIX 1 } // namespace sycl diff --git a/sycl/include/CL/sycl/info/device_traits.def b/sycl/include/CL/sycl/info/device_traits.def index 440f774bd989b..efb2adf63575d 100644 --- a/sycl/include/CL/sycl/info/device_traits.def +++ b/sycl/include/CL/sycl/info/device_traits.def @@ -94,3 +94,4 @@ __SYCL_PARAM_TRAITS_SPEC(device, ext_intel_gpu_subslices_per_slice, pi_uint32) __SYCL_PARAM_TRAITS_SPEC(device, ext_intel_gpu_eu_count_per_subslice, pi_uint32) __SYCL_PARAM_TRAITS_SPEC(device, ext_intel_max_mem_bandwidth, pi_uint64) __SYCL_PARAM_TRAITS_SPEC(device, ext_intel_mem_channel, bool) +__SYCL_PARAM_TRAITS_SPEC(device, ext_intel_device_info_uuid, detail::uuid_type) diff --git a/sycl/include/CL/sycl/info/info_desc.hpp b/sycl/include/CL/sycl/info/info_desc.hpp index 56f08800e4d86..fef70fd32bbc6 100644 --- a/sycl/include/CL/sycl/info/info_desc.hpp +++ b/sycl/include/CL/sycl/info/info_desc.hpp @@ -134,7 +134,6 @@ enum class device : cl_device_info { usm_shared_allocations = PI_USM_SINGLE_SHARED_SUPPORT, usm_restricted_shared_allocations = PI_USM_CROSS_SHARED_SUPPORT, usm_system_allocator = PI_USM_SYSTEM_SHARED_SUPPORT, - // intel extensions ext_intel_pci_address = PI_DEVICE_INFO_PCI_ADDRESS, ext_intel_gpu_eu_count = PI_DEVICE_INFO_GPU_EU_COUNT, @@ -145,6 +144,7 @@ enum class device : cl_device_info { PI_DEVICE_INFO_GPU_EU_COUNT_PER_SUBSLICE, ext_intel_max_mem_bandwidth = PI_DEVICE_INFO_MAX_MEM_BANDWIDTH, ext_intel_mem_channel = PI_MEM_PROPERTIES_CHANNEL, + ext_intel_device_info_uuid = PI_DEVICE_INFO_UUID, atomic64 = PI_DEVICE_INFO_ATOMIC_64 }; diff --git a/sycl/plugins/cuda/pi_cuda.cpp b/sycl/plugins/cuda/pi_cuda.cpp index a21268a46319e..a5f8f2faacd4a 100644 --- a/sycl/plugins/cuda/pi_cuda.cpp +++ b/sycl/plugins/cuda/pi_cuda.cpp @@ -1551,6 +1551,10 @@ pi_result cuda_piDeviceGetInfo(pi_device device, pi_device_info param_name, case PI_DEVICE_INFO_GPU_SUBSLICES_PER_SLICE: case PI_DEVICE_INFO_GPU_EU_COUNT_PER_SUBSLICE: case PI_DEVICE_INFO_MAX_MEM_BANDWIDTH: + // TODO: Check if Intel device UUID extension is utilized for CUDA. + // For details about this extension, see + // sycl/doc/extensions/IntelGPU/IntelGPUDeviceInfo.md + case PI_DEVICE_INFO_UUID: return PI_INVALID_VALUE; default: diff --git a/sycl/plugins/level_zero/pi_level_zero.cpp b/sycl/plugins/level_zero/pi_level_zero.cpp index d7d30fb3faa4b..d869b7b16ebdd 100644 --- a/sycl/plugins/level_zero/pi_level_zero.cpp +++ b/sycl/plugins/level_zero/pi_level_zero.cpp @@ -1655,6 +1655,11 @@ pi_result piDeviceGetInfo(pi_device Device, pi_device_info ParamName, return ReturnValue(Device->Platform); case PI_DEVICE_INFO_VENDOR_ID: return ReturnValue(pi_uint32{Device->ZeDeviceProperties.vendorId}); + case PI_DEVICE_INFO_UUID: + // Intel extension for device UUID. This returns the UUID as + // std::array. For details about this extension, + // see sycl/doc/extensions/IntelGPU/IntelGPUDeviceInfo.md. + return ReturnValue(Device->ZeDeviceProperties.uuid.id); case PI_DEVICE_INFO_EXTENSIONS: { // Convention adopted from OpenCL: // "Returns a space separated list of extension names (the extension diff --git a/sycl/plugins/opencl/pi_opencl.cpp b/sycl/plugins/opencl/pi_opencl.cpp index 61be57c0fc745..6e3f569a94dce 100644 --- a/sycl/plugins/opencl/pi_opencl.cpp +++ b/sycl/plugins/opencl/pi_opencl.cpp @@ -169,8 +169,8 @@ pi_result piDeviceGetInfo(pi_device device, pi_device_info paramName, size_t paramValueSize, void *paramValue, size_t *paramValueSizeRet) { switch (paramName) { - // Intel GPU EU device-specific information extensions. // TODO: Check regularly to see if support in enabled in OpenCL. + // Intel GPU EU device-specific information extensions. case PI_DEVICE_INFO_PCI_ADDRESS: case PI_DEVICE_INFO_GPU_EU_COUNT: case PI_DEVICE_INFO_GPU_EU_SIMD_WIDTH: @@ -178,6 +178,10 @@ pi_result piDeviceGetInfo(pi_device device, pi_device_info paramName, case PI_DEVICE_INFO_GPU_SUBSLICES_PER_SLICE: case PI_DEVICE_INFO_GPU_EU_COUNT_PER_SUBSLICE: case PI_DEVICE_INFO_MAX_MEM_BANDWIDTH: + // TODO: Check if device UUID extension is enabled in OpenCL. + // For details about Intel UUID extension, see + // sycl/doc/extensions/IntelGPU/IntelGPUDeviceInfo.md + case PI_DEVICE_INFO_UUID: case PI_DEVICE_INFO_ATOMIC_64: return PI_INVALID_VALUE; diff --git a/sycl/source/detail/device_impl.cpp b/sycl/source/detail/device_impl.cpp index 2d1820ac233e3..6bbffd19f5acc 100644 --- a/sycl/source/detail/device_impl.cpp +++ b/sycl/source/detail/device_impl.cpp @@ -298,6 +298,20 @@ bool device_impl::has(aspect Aspect) const { MDevice, PI_DEVICE_INFO_GPU_EU_COUNT_PER_SUBSLICE, sizeof(pi_device_type), &device_type, &return_size) == PI_SUCCESS; + case aspect::ext_intel_device_info_uuid: { + auto Result = getPlugin().call_nocheck( + MDevice, PI_DEVICE_INFO_UUID, 0, nullptr, &return_size); + if (Result != PI_SUCCESS) { + return false; + } + + assert(return_size <= 16); + unsigned char UUID[16]; + + return getPlugin().call_nocheck( + MDevice, PI_DEVICE_INFO_UUID, 16 * sizeof(unsigned char), UUID, + nullptr) == PI_SUCCESS; + } case aspect::ext_intel_max_mem_bandwidth: // currently not supported return false; diff --git a/sycl/source/detail/device_info.hpp b/sycl/source/detail/device_info.hpp index a8c8aae07ef3a..d166fa86bf1ce 100644 --- a/sycl/source/detail/device_info.hpp +++ b/sycl/source/detail/device_info.hpp @@ -1101,6 +1101,14 @@ get_device_info_host() { PI_INVALID_DEVICE); } +template <> +inline detail::uuid_type +get_device_info_host() { + throw runtime_error( + "Obtaining the device uuid is not supported on HOST device", + PI_INVALID_DEVICE); +} + } // namespace detail } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/test/abi/sycl_symbols_linux.dump b/sycl/test/abi/sycl_symbols_linux.dump index 0771bed3c0010..24beb93029372 100644 --- a/sycl/test/abi/sycl_symbols_linux.dump +++ b/sycl/test/abi/sycl_symbols_linux.dump @@ -4120,6 +4120,7 @@ _ZNK2cl4sycl6device8get_infoILNS0_4info6deviceE4168EEENS3_12param_traitsIS4_XT_E _ZNK2cl4sycl6device8get_infoILNS0_4info6deviceE4169EEENS3_12param_traitsIS4_XT_EE11return_typeEv _ZNK2cl4sycl6device8get_infoILNS0_4info6deviceE4188EEENS3_12param_traitsIS4_XT_EE11return_typeEv _ZNK2cl4sycl6device8get_infoILNS0_4info6deviceE4189EEENS3_12param_traitsIS4_XT_EE11return_typeEv +_ZNK2cl4sycl6device8get_infoILNS0_4info6deviceE4202EEENS3_12param_traitsIS4_XT_EE11return_typeEv _ZNK2cl4sycl6device8get_infoILNS0_4info6deviceE65568EEENS3_12param_traitsIS4_XT_EE11return_typeEv _ZNK2cl4sycl6device8get_infoILNS0_4info6deviceE65569EEENS3_12param_traitsIS4_XT_EE11return_typeEv _ZNK2cl4sycl6device8get_infoILNS0_4info6deviceE65570EEENS3_12param_traitsIS4_XT_EE11return_typeEv diff --git a/sycl/unittests/kernel-and-program/CMakeLists.txt b/sycl/unittests/kernel-and-program/CMakeLists.txt index b6e5d3edbcd3f..ff102c5aaffb9 100644 --- a/sycl/unittests/kernel-and-program/CMakeLists.txt +++ b/sycl/unittests/kernel-and-program/CMakeLists.txt @@ -1,6 +1,7 @@ add_sycl_unittest(KernelAndProgramTests OBJECT KernelRelease.cpp KernelInfo.cpp + DeviceInfo.cpp PersistentDeviceCodeCache.cpp ) add_subdirectory(device) diff --git a/sycl/unittests/kernel-and-program/DeviceInfo.cpp b/sycl/unittests/kernel-and-program/DeviceInfo.cpp new file mode 100644 index 0000000000000..57139b368cb41 --- /dev/null +++ b/sycl/unittests/kernel-and-program/DeviceInfo.cpp @@ -0,0 +1,87 @@ +//==-------------- DeviceInfo.cpp --- device info unit test ----------------==// +// +// 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 sycl; + +namespace { +struct TestCtx { + TestCtx(context &Ctx) : Ctx{Ctx} {} + + context &Ctx; + bool UUIDInfoCalled = false; +}; +} // namespace + +static std::unique_ptr TestContext; + +static pi_result redefinedDeviceGetInfo(pi_device device, + pi_device_info param_name, + size_t param_value_size, + void *param_value, + size_t *param_value_size_ret) { + if (param_name == PI_DEVICE_INFO_UUID) { + TestContext->UUIDInfoCalled = true; + } + + return PI_SUCCESS; +} + +class DeviceInfoTest : public ::testing::Test { +public: + DeviceInfoTest() : Plt{default_selector()} {} + +protected: + void SetUp() override { + if (Plt.is_host()) { + std::clog << "This test is only supported on non-host platforms.\n"; + std::clog << "Current platform is " + << Plt.get_info() << "\n"; + return; + } + + Mock = std::make_unique(Plt); + + Mock->redefine(redefinedDeviceGetInfo); + } + +protected: + platform Plt; + std::unique_ptr Mock; +}; + +TEST_F(DeviceInfoTest, GetDeviceUUID) { + if (Plt.is_host()) { + return; + } + + context Ctx{Plt}; + TestContext.reset(new TestCtx(Ctx)); + + device Dev = Ctx.get_devices()[0]; + + if (!Dev.has(aspect::ext_intel_device_info_uuid)) { + std::clog + << "This test is only for the devices with UUID extension support.\n"; + return; + } + + auto UUID = Dev.get_info(); + + EXPECT_EQ(TestContext->UUIDInfoCalled, true) + << "Expect piDeviceGetInfo to be " + << "called with PI_DEVICE_INFO_UUID"; + + EXPECT_EQ(sizeof(UUID), 16 * sizeof(unsigned char)) + << "Expect device UUID to be " + << "of 16 bytes"; +}