Skip to content

Commit 8e347de

Browse files
authored
[SYCL] Add support for getting device LUID on windows (#19349)
Adds a new aspect to get device LUID. This feature is only available on Windows and allows for device matching when performing SYCL/DirectX interop
1 parent 0231525 commit 8e347de

File tree

25 files changed

+559
-3
lines changed

25 files changed

+559
-3
lines changed

llvm/include/llvm/SYCLLowerIR/DeviceConfigFile.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ def AspectExt_intel_current_clock_throttle_reasons : Aspect<"ext_intel_current_c
9292
def AspectExt_intel_fan_speed : Aspect<"ext_intel_fan_speed">;
9393
def AspectExt_intel_power_limits : Aspect<"ext_intel_power_limits">;
9494
def AspectExt_oneapi_async_memory_alloc : Aspect<"ext_oneapi_async_memory_alloc">;
95+
def AspectExt_intel_device_info_luid : Aspect<"ext_intel_device_info_luid">;
96+
def AspectExt_intel_device_info_node_mask : Aspect<"ext_intel_device_info_node_mask">;
9597

9698
// Deprecated aspects
9799
def AspectInt64_base_atomics : Aspect<"int64_base_atomics">;
@@ -163,7 +165,9 @@ def : TargetInfo<"__TestAspectList",
163165
AspectExt_intel_current_clock_throttle_reasons,
164166
AspectExt_intel_fan_speed,
165167
AspectExt_intel_power_limits,
166-
AspectExt_oneapi_async_memory_alloc],
168+
AspectExt_oneapi_async_memory_alloc,
169+
AspectExt_intel_device_info_luid,
170+
AspectExt_intel_device_info_node_mask],
167171
[]>;
168172
// This definition serves the only purpose of testing whether the deprecated aspect list defined in here and in SYCL RT
169173
// match.

sycl/doc/extensions/supported/sycl_ext_intel_device_info.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ The Feature Test Macro SYCL\_EXT\_INTEL\_DEVICE\_INFO will be defined as one of
2020
| 5 | Device ID is supported |
2121
| 6 | Memory clock rate and bus width queries are supported |
2222
| 7 | Throttle reasons, fan speed and power limits queries are supported |
23+
| 8 | Device LUID and device node mask is supported |
2324

2425

2526

@@ -626,7 +627,66 @@ Then the power limits can be obtained using the standard `get_info()` interface.
626627
```
627628

628629

630+
# Device LUID #
629631

632+
A new device descriptor is added which will provide the device Locally Unique ID (LUID).
633+
634+
## Version ##
635+
636+
The extension supports this query in version 8 and later.
637+
638+
| Device Descriptors | Return Type | Description |
639+
| ------------------ | ----------- | ----------- |
640+
|`ext::intel::info::device::luid` |`std::array<unsigned char, 8>` | Returns the device LUID. |
641+
642+
## Aspects ##
643+
644+
A new aspect, `ext_intel_device_info_luid`, is added.
645+
646+
## Error Condition ##
647+
648+
Throws a synchronous `exception` with the `errc::feature_not_supported` error code if the device does not have `aspect::ext_intel_device_info_luid`.
649+
650+
## Example Usage ##
651+
652+
The LUID can be obtained using the standard `get_info()` interface.
653+
654+
```
655+
if (dev.has(aspect::ext_intel_device_info_luid)) {
656+
auto LUID = dev.get_info<ext::intel::info::device::luid>();
657+
}
658+
```
659+
660+
661+
# Device Node Mask #
662+
663+
A new device descriptor is added which will provide the device node mask.
664+
665+
## Version ##
666+
667+
The extension supports this query in version 8 and later.
668+
669+
| Device Descriptors | Return Type | Description |
670+
| ------------------ | ----------- | ----------- |
671+
|`ext::intel::info::device::node_mask` |`unsigned int` | Returns the device node mask. |
672+
673+
## Aspects ##
674+
675+
A new aspect, `ext_intel_device_info_node_mask`, is added.
676+
677+
## Error Condition ##
678+
679+
Throws a synchronous `exception` with the `errc::feature_not_supported` error code if the device does not have `aspect::ext_intel_device_info_node_mask`.
680+
681+
## Example Usage ##
682+
683+
The device node mask can be obtained using the standard `get_info()` interface.
684+
685+
```
686+
if (dev.has(aspect::ext_intel_device_info_node_mask)) {
687+
auto node_mask = dev.get_info<ext::intel::info::device::node_mask>();
688+
}
689+
```
630690

631691
# Deprecated queries #
632692

sycl/include/sycl/detail/type_traits.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,11 @@ inline constexpr bool is_group_helper_v =
110110
} // namespace ext::oneapi::experimental
111111

112112
namespace detail {
113-
// Type for Intel device UUID extension.
113+
// Types for Intel's device UUID and device LUID extension.
114114
// For details about this extension, see
115115
// sycl/doc/extensions/supported/sycl_ext_intel_device_info.md
116116
using uuid_type = std::array<unsigned char, 16>;
117+
using luid_type = std::array<unsigned char, 8>;
117118

118119
template <typename T, typename R> struct copy_cv_qualifiers;
119120

sycl/include/sycl/info/aspects.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,6 @@ __SYCL_ASPECT(ext_intel_current_clock_throttle_reasons, 84)
7878
__SYCL_ASPECT(ext_intel_fan_speed, 85)
7979
__SYCL_ASPECT(ext_intel_power_limits, 86)
8080
__SYCL_ASPECT(ext_oneapi_async_memory_alloc, 87)
81+
__SYCL_ASPECT(ext_intel_device_info_luid, 88)
82+
__SYCL_ASPECT(ext_intel_device_info_node_mask, 89)
8183

sycl/include/sycl/info/ext_intel_device_traits.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ __SYCL_PARAM_TRAITS_SPEC(ext::intel, device, current_clock_throttle_reasons, std
2121
__SYCL_PARAM_TRAITS_SPEC(ext::intel, device, fan_speed, int32_t, UR_DEVICE_INFO_FAN_SPEED)
2222
__SYCL_PARAM_TRAITS_SPEC(ext::intel, device, min_power_limit, int32_t, UR_DEVICE_INFO_MIN_POWER_LIMIT)
2323
__SYCL_PARAM_TRAITS_SPEC(ext::intel, device, max_power_limit, int32_t, UR_DEVICE_INFO_MAX_POWER_LIMIT)
24+
__SYCL_PARAM_TRAITS_SPEC(ext::intel, device, luid, detail::luid_type, __SYCL_TRAIT_HANDLED_IN_RT)
25+
__SYCL_PARAM_TRAITS_SPEC(ext::intel, device, node_mask, uint32_t, __SYCL_TRAIT_HANDLED_IN_RT)
2426
#ifdef __SYCL_PARAM_TRAITS_TEMPLATE_SPEC_NEEDS_UNDEF
2527
#undef __SYCL_PARAM_TRAITS_TEMPLATE_SPEC
2628
#undef __SYCL_PARAM_TRAITS_TEMPLATE_SPEC_NEEDS_UNDEF

sycl/source/detail/device_impl.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,20 @@ class device_impl : public std::enable_shared_from_this<device_impl> {
11941194
"The device does not have the ext_intel_power_limits aspect");
11951195
return get_info_impl<UR_DEVICE_INFO_MIN_POWER_LIMIT>();
11961196
}
1197+
CASE(ext::intel::info::device::luid) {
1198+
if (!has(aspect::ext_intel_device_info_luid))
1199+
throw exception(
1200+
make_error_code(errc::feature_not_supported),
1201+
"The device does not have the ext_intel_device_info_luid aspect");
1202+
return get_info_impl<UR_DEVICE_INFO_LUID>();
1203+
}
1204+
CASE(ext::intel::info::device::node_mask) {
1205+
if (!has(aspect::ext_intel_device_info_node_mask))
1206+
throw exception(make_error_code(errc::feature_not_supported),
1207+
"The device does not have the "
1208+
"ext_intel_device_info_node_mask aspect");
1209+
return get_info_impl<UR_DEVICE_INFO_NODE_MASK>();
1210+
}
11971211
else {
11981212
constexpr auto Desc = UrInfoCode<Param>::value;
11991213
return static_cast<typename Param::return_type>(get_info_impl<Desc>());
@@ -1304,6 +1318,12 @@ class device_impl : public std::enable_shared_from_this<device_impl> {
13041318
CASE(ext_intel_device_info_uuid) {
13051319
return has_info_desc(UR_DEVICE_INFO_UUID);
13061320
}
1321+
CASE(ext_intel_device_info_luid) {
1322+
return has_info_desc(UR_DEVICE_INFO_LUID);
1323+
}
1324+
CASE(ext_intel_device_info_node_mask) {
1325+
return has_info_desc(UR_DEVICE_INFO_NODE_MASK);
1326+
}
13071327
CASE(ext_intel_max_mem_bandwidth) {
13081328
// currently not supported
13091329
return false;

sycl/source/detail/ur_device_info_ret_types.inc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ MAP(UR_DEVICE_INFO_FAN_SPEED, int32_t)
154154
MAP(UR_DEVICE_INFO_MIN_POWER_LIMIT, int32_t)
155155
MAP(UR_DEVICE_INFO_MAX_POWER_LIMIT, int32_t)
156156
MAP(UR_DEVICE_INFO_BFLOAT16_CONVERSIONS_NATIVE, ur_bool_t)
157+
MAP(UR_DEVICE_INFO_KERNEL_LAUNCH_CAPABILITIES, ur_kernel_launch_properties_flags_t)
158+
// Manually changed std::vector<uint8_t> -> std::array<uint8_t, 8>
159+
MAP(UR_DEVICE_INFO_LUID, std::array<uint8_t, 8>)
160+
MAP(UR_DEVICE_INFO_NODE_MASK, uint32_t)
157161

158162
// These aren't present in the specification, extracted from ur_api.h
159163
// instead.
@@ -187,5 +191,4 @@ MAP(UR_DEVICE_INFO_MIPMAP_LEVEL_REFERENCE_SUPPORT_EXP, ur_bool_t)
187191
MAP(UR_DEVICE_INFO_MIPMAP_MAX_ANISOTROPY_EXP, uint32_t)
188192
MAP(UR_DEVICE_INFO_MIPMAP_SUPPORT_EXP, ur_bool_t)
189193
MAP(UR_DEVICE_INFO_TIMESTAMP_RECORDING_SUPPORT_EXP, ur_bool_t)
190-
MAP(UR_DEVICE_INFO_KERNEL_LAUNCH_CAPABILITIES, ur_kernel_launch_properties_flags_t)
191194
// clang-format on
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// REQUIRES: aspect-ext_intel_device_info_luid
2+
// REQUIRES: gpu, level_zero, level_zero_dev_kit, windows
3+
4+
// RUN: %{build} %level_zero_options -o %t.out
5+
// RUN: %{run} %t.out
6+
7+
// Test that the LUID is read correctly from Level Zero.
8+
9+
#include <iomanip>
10+
#include <iostream>
11+
#include <level_zero/ze_api.h>
12+
#include <sstream>
13+
#include <sycl/backend.hpp>
14+
#include <sycl/detail/core.hpp>
15+
16+
int main() {
17+
sycl::device dev;
18+
auto luid = dev.get_info<sycl::ext::intel::info::device::luid>();
19+
20+
std::stringstream luid_sycl;
21+
for (int i = 0; i < luid.size(); ++i) {
22+
luid_sycl << std::hex << std::setw(2) << std::setfill('0') << int(luid[i]);
23+
}
24+
std::cout << "SYCL: " << luid_sycl.str() << std::endl;
25+
26+
auto zedev = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(dev);
27+
ze_device_properties_t device_properties{};
28+
device_properties.stype = ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES;
29+
30+
ze_device_luid_ext_properties_t luid_device_properties{};
31+
luid_device_properties.stype = ZE_STRUCTURE_TYPE_DEVICE_LUID_EXT_PROPERTIES;
32+
33+
device_properties.pNext = &luid_device_properties;
34+
35+
zeDeviceGetProperties(zedev, &device_properties);
36+
37+
ze_device_luid_ext_properties_t *luid_dev_prop =
38+
static_cast<ze_device_luid_ext_properties_t *>(device_properties.pNext);
39+
40+
std::stringstream luid_l0;
41+
for (int i = 0; i < ZE_MAX_DEVICE_LUID_SIZE_EXT; ++i)
42+
luid_l0 << std::hex << std::setw(2) << std::setfill('0')
43+
<< int(luid_dev_prop->luid.id[i]);
44+
std::cout << "L0 : " << luid_l0.str() << std::endl;
45+
46+
if (luid_sycl.str() != luid_l0.str()) {
47+
std::cout << "FAILED" << std::endl;
48+
return -1;
49+
}
50+
51+
std::cout << "PASSED" << std::endl;
52+
return 0;
53+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// REQUIRES: aspect-ext_intel_device_info_node_mask
2+
// REQUIRES: gpu, level_zero, level_zero_dev_kit, windows
3+
4+
// RUN: %{build} %level_zero_options -o %t.out
5+
// RUN: %{run} %t.out
6+
7+
// Test that the node mask is read correctly from Level Zero.
8+
9+
#include <iomanip>
10+
#include <iostream>
11+
#include <level_zero/ze_api.h>
12+
#include <sstream>
13+
#include <sycl/backend.hpp>
14+
#include <sycl/detail/core.hpp>
15+
16+
int main() {
17+
sycl::device dev;
18+
auto nodeMaskSYCL = dev.get_info<sycl::ext::intel::info::device::node_mask>();
19+
20+
std::cout << "SYCL: " << nodeMaskSYCL << std::endl;
21+
22+
auto zedev = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(dev);
23+
ze_device_properties_t device_properties{};
24+
device_properties.stype = ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES;
25+
26+
ze_device_luid_ext_properties_t luid_device_properties{};
27+
luid_device_properties.stype = ZE_STRUCTURE_TYPE_DEVICE_LUID_EXT_PROPERTIES;
28+
29+
device_properties.pNext = &luid_device_properties;
30+
31+
zeDeviceGetProperties(zedev, &device_properties);
32+
33+
ze_device_luid_ext_properties_t *luid_dev_prop =
34+
static_cast<ze_device_luid_ext_properties_t *>(device_properties.pNext);
35+
36+
uint32_t nodeMaskL0 = luid_dev_prop->nodeMask;
37+
38+
std::cout << "L0 : " << nodeMaskL0 << std::endl;
39+
40+
if (nodeMaskSYCL != nodeMaskL0) {
41+
std::cout << "FAILED" << std::endl;
42+
return -1;
43+
}
44+
45+
std::cout << "PASSED" << std::endl;
46+
return 0;
47+
}

sycl/test-e2e/Adapters/luid-cuda.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// REQUIRES: aspect-ext_intel_device_info_luid
2+
// REQUIRES: gpu, target-nvidia, cuda_dev_kit, windows
3+
4+
// RUN: %{build} %cuda_options -o %t.out
5+
// RUN: %{run} %t.out
6+
7+
// Test that the LUID is read correctly from CUDA.
8+
9+
#include <iomanip>
10+
#include <iostream>
11+
#include <sstream>
12+
#define SYCL_EXT_ONEAPI_BACKEND_CUDA_EXPERIMENTAL 1
13+
#include <cuda.h>
14+
#include <sycl/backend.hpp>
15+
#include <sycl/detail/core.hpp>
16+
17+
int main() {
18+
sycl::device dev;
19+
auto luid = dev.get_info<sycl::ext::intel::info::device::luid>();
20+
21+
std::stringstream luidSYCLHex;
22+
for (int i = 0; i < luid.size(); ++i) {
23+
luidSYCLHex << std::hex << std::setw(2) << std::setfill('0')
24+
<< int(luid[i]);
25+
}
26+
std::cout << "SYCL: " << luidSYCLHex.str() << std::endl;
27+
28+
CUdevice cudaDevice = sycl::get_native<sycl::backend::ext_oneapi_cuda>(dev);
29+
30+
std::array<char, 8> luidCuda{};
31+
32+
cuDeviceGetLuid(luidCuda.data(), nullptr, cudaDevice);
33+
34+
// Cuda returns luid as char, not unsigned char so convert that here.
35+
std::array<unsigned char, 8> luidCudaConverted{};
36+
std::copy(luidCuda.begin(), luidCuda.end(), luidCudaConverted.begin());
37+
38+
std::stringstream luidCudaHex;
39+
for (int i = 0; i < 8; ++i)
40+
luidCudaHex << std::hex << std::setw(2) << std::setfill('0')
41+
<< int(luidCudaConverted[i]);
42+
std::cout << "CUDA : " << luidCudaHex.str() << std::endl;
43+
44+
if (luidSYCLHex.str() != luidCudaHex.str()) {
45+
std::cout << "FAILED" << std::endl;
46+
return -1;
47+
}
48+
49+
std::cout << "PASSED" << std::endl;
50+
return 0;
51+
}

0 commit comments

Comments
 (0)