Skip to content

[SYCL] Adds support for device UUID as a SYCL extension. #3696

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Jul 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 78 additions & 2 deletions sycl/doc/extensions/IntelGPU/IntelGPUDeviceInfo.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<info::device::ext_intel_device_info_uuid>();
}

#define SYCL_EXT_INTEL_DEVICE_INFO 1


# PCI Address #
Expand All @@ -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 |
Expand Down Expand Up @@ -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 |
Expand Down Expand Up @@ -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 |
Expand Down Expand Up @@ -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 |
Expand Down Expand Up @@ -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 |
Expand Down Expand Up @@ -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 |
Expand Down Expand Up @@ -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 |
Expand Down
3 changes: 2 additions & 1 deletion sycl/include/CL/sycl/aspects.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions sycl/include/CL/sycl/detail/pi.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include <CL/cl_ext.h>
#include <CL/sycl/detail/cl.h>
#include <CL/sycl/detail/export.hpp>

#include <cstdint>

#ifdef __cplusplus
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions sycl/include/CL/sycl/detail/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <CL/sycl/detail/stl_type_traits.hpp>
#include <CL/sycl/detail/type_list.hpp>

#include <array>
#include <type_traits>

__SYCL_INLINE_NAMESPACE(cl) {
Expand Down Expand Up @@ -51,6 +52,11 @@ __SYCL_INLINE_CONSTEXPR bool is_group_v =
detail::is_group<T>::value || detail::is_sub_group<T>::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<unsigned char, 16>;

template <typename T, typename R> struct copy_cv_qualifiers;

template <typename T, typename R>
Expand Down
2 changes: 1 addition & 1 deletion sycl/include/CL/sycl/feature_test.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions sycl/include/CL/sycl/info/device_traits.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
2 changes: 1 addition & 1 deletion sycl/include/CL/sycl/info/info_desc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
};

Expand Down
4 changes: 4 additions & 0 deletions sycl/plugins/cuda/pi_cuda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
5 changes: 5 additions & 0 deletions sycl/plugins/level_zero/pi_level_zero.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::byte, 16>. 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
Expand Down
6 changes: 5 additions & 1 deletion sycl/plugins/opencl/pi_opencl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,19 @@ 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:
case PI_DEVICE_INFO_GPU_SLICES:
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;

Expand Down
14 changes: 14 additions & 0 deletions sycl/source/detail/device_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<detail::PiApiKind::piDeviceGetInfo>(
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<detail::PiApiKind::piDeviceGetInfo>(
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;
Expand Down
8 changes: 8 additions & 0 deletions sycl/source/detail/device_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,14 @@ get_device_info_host<info::device::ext_intel_max_mem_bandwidth>() {
PI_INVALID_DEVICE);
}

template <>
inline detail::uuid_type
get_device_info_host<info::device::ext_intel_device_info_uuid>() {
throw runtime_error(
"Obtaining the device uuid is not supported on HOST device",
PI_INVALID_DEVICE);
}

} // namespace detail
} // namespace sycl
} // __SYCL_INLINE_NAMESPACE(cl)
1 change: 1 addition & 0 deletions sycl/test/abi/sycl_symbols_linux.dump
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions sycl/unittests/kernel-and-program/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_sycl_unittest(KernelAndProgramTests OBJECT
KernelRelease.cpp
KernelInfo.cpp
DeviceInfo.cpp
PersistentDeviceCodeCache.cpp
)
add_subdirectory(device)
87 changes: 87 additions & 0 deletions sycl/unittests/kernel-and-program/DeviceInfo.cpp
Original file line number Diff line number Diff line change
@@ -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 <CL/sycl.hpp>
#include <detail/context_impl.hpp>
#include <gtest/gtest.h>
#include <helpers/PiMock.hpp>

using namespace sycl;

namespace {
struct TestCtx {
TestCtx(context &Ctx) : Ctx{Ctx} {}

context &Ctx;
bool UUIDInfoCalled = false;
};
} // namespace

static std::unique_ptr<TestCtx> 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<info::platform::name>() << "\n";
return;
}

Mock = std::make_unique<unittest::PiMock>(Plt);

Mock->redefine<detail::PiApiKind::piDeviceGetInfo>(redefinedDeviceGetInfo);
}

protected:
platform Plt;
std::unique_ptr<unittest::PiMock> 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<info::device::ext_intel_device_info_uuid>();

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";
}