Skip to content
This repository was archived by the owner on Mar 28, 2023. It is now read-only.

Commit 1758a98

Browse files
[SYCL][Level Zero] Add a test for sycl_ext_intel_cslice extension (#1434)
Implementation is being done in intel/llvm#7626
1 parent b17da40 commit 1758a98

File tree

1 file changed

+191
-0
lines changed

1 file changed

+191
-0
lines changed
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %level_zero_options %s -o %t.out
2+
3+
// RUN: env ZEX_NUMBER_OF_CCS=0:4 env ZE_DEBUG=1 %GPU_RUN_PLACEHOLDER %t.out > %t.default.log 2>&1
4+
// RUN: %GPU_RUN_PLACEHOLDER FileCheck %s --check-prefixes=CHECK-PVC < %t.default.log
5+
6+
// RUN: env SYCL_PI_LEVEL_ZERO_EXPOSE_CSLICE_IN_AFFINITY_PARTITIONING=1 \
7+
// RUN: env ZEX_NUMBER_OF_CCS=0:4 env ZE_DEBUG=1 %GPU_RUN_PLACEHOLDER %t.out> %t.compat.log 2>&1
8+
// RUN: %GPU_RUN_PLACEHOLDER FileCheck %s --check-prefixes=CHECK-PVC,CHECK-PVC-AFFINITY < %t.compat.log
9+
10+
// Same, but using immediate commandlists:
11+
12+
// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1 env ZEX_NUMBER_OF_CCS=0:4 env ZE_DEBUG=1 %GPU_RUN_PLACEHOLDER %t.out > %t.default.log 2>&1
13+
// RUN: %GPU_RUN_PLACEHOLDER FileCheck %s --check-prefixes=CHECK-PVC < %t.default.log
14+
15+
// RUN: env SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1 env SYCL_PI_LEVEL_ZERO_EXPOSE_CSLICE_IN_AFFINITY_PARTITIONING=1 \
16+
// RUN: env ZEX_NUMBER_OF_CCS=0:4 env ZE_DEBUG=1 %GPU_RUN_PLACEHOLDER %t.out> %t.compat.log 2>&1
17+
// RUN: %GPU_RUN_PLACEHOLDER FileCheck %s --check-prefixes=CHECK-PVC,CHECK-PVC-AFFINITY < %t.compat.log
18+
19+
// Requires: level_zero
20+
21+
#include <sycl/sycl.hpp>
22+
23+
using namespace sycl;
24+
25+
// Specified in the RUN line.
26+
static constexpr int NumCSlices = 4;
27+
static const bool ExposeCSliceInAffinityPartitioning = [] {
28+
const char *Flag =
29+
std::getenv("SYCL_PI_LEVEL_ZERO_EXPOSE_CSLICE_IN_AFFINITY_PARTITIONING");
30+
return Flag ? std::atoi(Flag) != 0 : false;
31+
}();
32+
33+
template <typename RangeTy, typename ElemTy>
34+
bool contains(RangeTy &&Range, const ElemTy &Elem) {
35+
return std::find(Range.begin(), Range.end(), Elem) != Range.end();
36+
}
37+
38+
bool isPartitionableBy(device &Dev, info::partition_property Prop) {
39+
return contains(Dev.get_info<info::device::partition_properties>(), Prop);
40+
}
41+
42+
bool isPartitionableByCSlice(device &Dev) {
43+
return isPartitionableBy(
44+
Dev, info::partition_property::ext_intel_partition_by_cslice);
45+
}
46+
47+
bool isPartitionableByAffinityDomain(device &Dev) {
48+
return isPartitionableBy(
49+
Dev, info::partition_property::partition_by_affinity_domain);
50+
}
51+
52+
void test_pvc(device &d) {
53+
std::cout << "Test PVC Begin" << std::endl;
54+
// CHECK-PVC: Test PVC Begin
55+
bool IsPVC = [&]() {
56+
if (!d.has(aspect::ext_intel_device_id))
57+
return false;
58+
return (d.get_info<ext::intel::info::device::device_id>() & 0xff0) == 0xbd0;
59+
}();
60+
std::cout << "IsPVC: " << std::boolalpha << IsPVC << std::endl;
61+
if (IsPVC) {
62+
63+
assert(isPartitionableByAffinityDomain(d));
64+
assert(!isPartitionableByCSlice(d));
65+
{
66+
try {
67+
std::ignore = d.create_sub_devices<
68+
info::partition_property::ext_intel_partition_by_cslice>();
69+
assert(false && "Expected an exception to be thrown earlier!");
70+
} catch (sycl::exception &e) {
71+
assert(e.code() == errc::feature_not_supported);
72+
}
73+
}
74+
75+
auto sub_devices = d.create_sub_devices<
76+
info::partition_property::partition_by_affinity_domain>(
77+
info::partition_affinity_domain::next_partitionable);
78+
device &sub_device = sub_devices[1];
79+
assert(isPartitionableByAffinityDomain(sub_device) ==
80+
ExposeCSliceInAffinityPartitioning);
81+
assert(isPartitionableByCSlice(sub_device));
82+
assert(sub_device.get_info<info::device::partition_type_property>() ==
83+
info::partition_property::partition_by_affinity_domain);
84+
85+
{
86+
try {
87+
std::ignore = sub_device.create_sub_devices<
88+
info::partition_property::partition_by_affinity_domain>(
89+
info::partition_affinity_domain::next_partitionable);
90+
assert(ExposeCSliceInAffinityPartitioning &&
91+
"Expected an exception to be thrown earlier!");
92+
} catch (sycl::exception &e) {
93+
assert(e.code() == errc::feature_not_supported);
94+
}
95+
}
96+
97+
auto VerifySubSubDevice = [&](auto &sub_sub_devices) {
98+
device &sub_sub_device = sub_sub_devices[1];
99+
assert(sub_sub_devices.size() == NumCSlices);
100+
assert(!isPartitionableByAffinityDomain(sub_sub_device));
101+
assert(!isPartitionableByCSlice(sub_sub_device));
102+
103+
// Note that we still report this sub-sub-device as created via
104+
// partitioning by cslice even if it was partition by affinity domain.
105+
// This is a known limitation that we won't address as the whole code path
106+
// (exposing CSlice as sub-devices via partitioning by affinity domaing
107+
// using SYCL_PI_LEVEL_ZERO_EXPOSE_CSLICE_IN_AFFINITY_PARTITIONING
108+
// environment variable) is deprecated and is going to be removed.
109+
assert(sub_sub_device.get_info<info::device::partition_type_property>() ==
110+
info::partition_property::ext_intel_partition_by_cslice);
111+
112+
assert(sub_sub_device.get_info<info::device::max_compute_units>() *
113+
NumCSlices ==
114+
sub_device.get_info<info::device::max_compute_units>());
115+
116+
{
117+
queue q{sub_device};
118+
q.single_task([=]() {});
119+
}
120+
{
121+
queue q{sub_sub_device};
122+
q.single_task([=]() {});
123+
}
124+
// CHECK-PVC: [getZeQueue]: create queue ordinal = 0, index = 0 (round robin in [0, 0])
125+
// CHECK-PVC: [getZeQueue]: create queue ordinal = 0, index = 1 (round robin in [1, 1])
126+
// CHECK-PVC-AFFINITY: [getZeQueue]: create queue ordinal = 0, index = 0 (round robin in [0, 0])
127+
// CHECK-PVC-AFFINITY: [getZeQueue]: create queue ordinal = 0, index = 1 (round robin in [1, 1])
128+
};
129+
{
130+
auto sub_sub_devices = sub_device.create_sub_devices<
131+
info::partition_property::ext_intel_partition_by_cslice>();
132+
VerifySubSubDevice(sub_sub_devices);
133+
}
134+
135+
if (ExposeCSliceInAffinityPartitioning) {
136+
auto sub_sub_devices = sub_device.create_sub_devices<
137+
info::partition_property::partition_by_affinity_domain>(
138+
info::partition_affinity_domain::next_partitionable);
139+
VerifySubSubDevice(sub_sub_devices);
140+
}
141+
} else {
142+
// Make FileCheck pass.
143+
std::cout << "Fake ZE_DEBUG output for FileCheck:" << std::endl;
144+
// clang-format off
145+
std::cout << "[getZeQueue]: create queue ordinal = 0, index = 0 (round robin in [0, 0])" << std::endl;
146+
std::cout << "[getZeQueue]: create queue ordinal = 0, index = 1 (round robin in [1, 1])" << std::endl;
147+
if (ExposeCSliceInAffinityPartitioning) {
148+
std::cout << "[getZeQueue]: create queue ordinal = 0, index = 0 (round robin in [0, 0])" << std::endl;
149+
std::cout << "[getZeQueue]: create queue ordinal = 0, index = 1 (round robin in [1, 1])" << std::endl;
150+
}
151+
// clang-format on
152+
}
153+
std::cout << "Test PVC End" << std::endl;
154+
// CHECK-PVC: Test PVC End
155+
}
156+
157+
void test_non_pvc(device d) {
158+
bool IsPVC = [&]() {
159+
if (!d.has(aspect::ext_intel_device_id))
160+
return false;
161+
return (d.get_info<ext::intel::info::device::device_id>() & 0xff0) == 0xbd0;
162+
}();
163+
164+
if (IsPVC)
165+
return;
166+
167+
// Non-PVC devices are not partitionable by CSlice at any level of
168+
// partitioning.
169+
170+
while (true) {
171+
assert(!isPartitionableByCSlice(d));
172+
173+
if (!isPartitionableByAffinityDomain(d))
174+
// No more sub-devices.
175+
break;
176+
177+
auto sub_devices = d.create_sub_devices<
178+
info::partition_property::partition_by_affinity_domain>(
179+
info::partition_affinity_domain::next_partitionable);
180+
d = sub_devices[0];
181+
}
182+
}
183+
184+
int main() {
185+
device d;
186+
187+
test_pvc(d);
188+
test_non_pvc(d);
189+
190+
return 0;
191+
}

0 commit comments

Comments
 (0)