Skip to content

Commit 766367b

Browse files
[SYCL] properly report supported device partitioning in Level-Zero (#2751)
Signed-off-by: Sergey V Maslov <[email protected]>
1 parent 719a25b commit 766367b

File tree

2 files changed

+104
-3
lines changed

2 files changed

+104
-3
lines changed

sycl/plugins/level_zero/pi_level_zero.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,11 +1232,18 @@ pi_result piDeviceGetInfo(pi_device Device, pi_device_info ParamName,
12321232
case PI_DEVICE_INFO_REFERENCE_COUNT:
12331233
return ReturnValue(pi_uint32{Device->RefCount});
12341234
case PI_DEVICE_INFO_PARTITION_PROPERTIES: {
1235+
// SYCL spec says: if this SYCL device cannot be partitioned into at least
1236+
// two sub devices then the returned vector must be empty.
1237+
uint32_t ZeSubDeviceCount = 0;
1238+
ZE_CALL(zeDeviceGetSubDevices(ZeDevice, &ZeSubDeviceCount, nullptr));
1239+
if (ZeSubDeviceCount < 2) {
1240+
return ReturnValue(pi_device_partition_property{0});
1241+
}
12351242
// It is debatable if SYCL sub-device and partitioning APIs sufficient to
12361243
// expose Level Zero sub-devices? We start with support of
1237-
// "partition_by_affinity_domain" and "numa" but if that doesn't seem to
1238-
// be a good fit we could look at adding a more descriptive partitioning
1239-
// type.
1244+
// "partition_by_affinity_domain" and "next_partitionable" but if that
1245+
// doesn't seem to be a good fit we could look at adding a more descriptive
1246+
// partitioning type.
12401247
struct {
12411248
pi_device_partition_property Arr[2];
12421249
} PartitionProperties = {{PI_DEVICE_PARTITION_BY_AFFINITY_DOMAIN, 0}};
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out
2+
// RUN: %CPU_RUN_PLACEHOLDER %t.out
3+
// RUN: %GPU_RUN_PLACEHOLDER %t.out
4+
// RUN: %ACC_RUN_PLACEHOLDER %t.out
5+
6+
/* Check that:
7+
1) [info::device::partition_properties]: returns the partition properties
8+
supported by this SYCL device; a vector of info::partition_property. If this
9+
SYCL device cannot be partitioned into at least two sub devices then the
10+
returned vector **must be empty**.
11+
12+
2) [create_sub_devices()]: If the SYCL device
13+
does not support info::partition_property::partition_by_affinity_domain or the
14+
SYCL device does not support the info::partition_affinity_domain provided, an
15+
exception with the **feature_not_supported error code must be thrown**.
16+
*/
17+
18+
#include <CL/sycl.hpp>
19+
20+
/** returns true if the device supports a particular affinity domain
21+
*/
22+
static bool
23+
supports_affinity_domain(const cl::sycl::device &dev,
24+
cl::sycl::info::partition_property partitionProp,
25+
cl::sycl::info::partition_affinity_domain domain) {
26+
if (partitionProp !=
27+
cl::sycl::info::partition_property::partition_by_affinity_domain) {
28+
return true;
29+
}
30+
auto supported =
31+
dev.get_info<cl::sycl::info::device::partition_affinity_domains>();
32+
for (cl::sycl::info::partition_affinity_domain dom : supported) {
33+
if (dom == domain) {
34+
return true;
35+
}
36+
}
37+
return false;
38+
}
39+
40+
/** returns true if the device supports a particular partition property
41+
*/
42+
static bool
43+
supports_partition_property(const cl::sycl::device &dev,
44+
cl::sycl::info::partition_property partitionProp) {
45+
auto supported = dev.get_info<cl::sycl::info::device::partition_properties>();
46+
for (cl::sycl::info::partition_property prop : supported) {
47+
if (prop == partitionProp) {
48+
return true;
49+
}
50+
}
51+
return false;
52+
}
53+
54+
int main() {
55+
56+
auto dev = cl::sycl::device(cl::sycl::default_selector());
57+
58+
cl::sycl::info::partition_property partitionProperty =
59+
cl::sycl::info::partition_property::partition_by_affinity_domain;
60+
cl::sycl::info::partition_affinity_domain affinityDomain =
61+
cl::sycl::info::partition_affinity_domain::next_partitionable;
62+
63+
if (supports_partition_property(dev, partitionProperty)) {
64+
if (supports_affinity_domain(dev, partitionProperty, affinityDomain)) {
65+
auto subDevices = dev.create_sub_devices<
66+
cl::sycl::info::partition_property::partition_by_affinity_domain>(
67+
affinityDomain);
68+
69+
if (subDevices.size() < 2) {
70+
std::cerr << "device::create_sub_device(info::partition_affinity_"
71+
"domain) should have returned at least 2 devices"
72+
<< std::endl;
73+
return -1;
74+
}
75+
}
76+
} else {
77+
try {
78+
auto subDevices = dev.create_sub_devices<
79+
cl::sycl::info::partition_property::partition_by_affinity_domain>(
80+
affinityDomain);
81+
std::cerr << "device::create_sub_device(info::partition_affinity_domain) "
82+
"should have thrown an exception"
83+
<< std::endl;
84+
return -1;
85+
} catch (const cl::sycl::feature_not_supported &e) {
86+
} catch (...) {
87+
std::cerr << "device::create_sub_device(info::partition_affinity_domain) "
88+
"should have thrown cl::sycl::feature_not_supported"
89+
<< std::endl;
90+
return -1;
91+
}
92+
}
93+
return 0;
94+
}

0 commit comments

Comments
 (0)