Skip to content

Commit cf77e41

Browse files
author
Andrew Savonichev
authored
[SYCL][NFC] Add a test for SYCL subdevice feature (#1554)
The test verifies that subdevices can be created with separate, shared and fused contexts. Signed-off-by: Andrew Savonichev <andrew.savonichev@intel.com>
1 parent bc01115 commit cf77e41

File tree

1 file changed

+231
-0
lines changed

1 file changed

+231
-0
lines changed
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out
2+
// RUN: %CPU_RUN_PLACEHOLDER SYCL_PI_TRACE=1 %t.out separate equally %CPU_CHECK_PLACEHOLDER --check-prefix CHECK-SEPARATE
3+
// RUN: %CPU_RUN_PLACEHOLDER SYCL_PI_TRACE=1 %t.out shared equally %CPU_CHECK_PLACEHOLDER --check-prefix CHECK-SHARED --implicit-check-not piContextCreate --implicit-check-not piMemBufferCreate
4+
// RUN: %CPU_RUN_PLACEHOLDER SYCL_PI_TRACE=1 %t.out fused equally %CPU_CHECK_PLACEHOLDER --check-prefix CHECK-FUSED --implicit-check-not piContextCreate --implicit-check-not piMemBufferCreate
5+
//
6+
// Intel OpenCL CPU Runtime supports device partition on all (multi-core)
7+
// platforms. Other devices may not support this.
8+
9+
#include <CL/sycl.hpp>
10+
#include <string>
11+
#include <vector>
12+
13+
using namespace cl::sycl;
14+
15+
// Log to the same stream as SYCL_PI_TRACE
16+
static void log_pi(const char *msg) {
17+
std::cout << msg << std::endl;
18+
}
19+
20+
static void use_mem(buffer<int, 1> buf, queue q) {
21+
q.submit(
22+
[&](handler &cgh) {
23+
auto acc = buf.get_access<access::mode::read_write>(cgh);
24+
cgh.parallel_for<class sum1>(range<1>(buf.get_count()),
25+
[=](item<1> itemID) {
26+
acc[itemID] += 1;
27+
});
28+
});
29+
q.wait();
30+
}
31+
32+
typedef std::vector<device> (*partition_fn)(device dev);
33+
34+
// FIXME: `partition_by_affinity_domain' is currently not tested: OpenCL CPU
35+
// device only supports `partition_equally'.
36+
static std::vector<device> partition_affinity(device dev) {
37+
std::vector<device> subdevices =
38+
dev.create_sub_devices<info::partition_property::partition_by_affinity_domain>(
39+
info::partition_affinity_domain::next_partitionable);
40+
41+
return subdevices;
42+
}
43+
44+
static std::vector<device> partition_equally(device dev) {
45+
std::vector<device> subdevices =
46+
dev.create_sub_devices<info::partition_property::partition_equally>(1);
47+
48+
return subdevices;
49+
}
50+
51+
static bool check_separate(device dev, buffer<int, 1> buf,
52+
partition_fn partition) {
53+
log_pi("Create sub devices");
54+
std::vector<device> subdevices = partition(dev);
55+
assert(subdevices.size() > 1);
56+
// CHECK-SEPARATE: Create sub devices
57+
// CHECK-SEPARATE: ---> piDevicePartition
58+
59+
log_pi("Test sub device 0");
60+
{
61+
queue q0(subdevices[0]);
62+
use_mem(buf, q0);
63+
}
64+
// CHECK-SEPARATE: Test sub device 0
65+
// CHECK-SEPARATE: ---> piContextCreate
66+
// CHECK-SEPARATE: ---> piQueueCreate
67+
// CHECK-SEPARATE: ---> piMemBufferCreate
68+
// CHECK-SEPARATE: ---> piEnqueueKernelLaunch
69+
// CHECK-SEPARATE: ---> piEventsWait
70+
71+
log_pi("Test sub device 1");
72+
{
73+
queue q1(subdevices[1]);
74+
use_mem(buf, q1);
75+
}
76+
// CHECK-SEPARATE: Test sub device 1
77+
// CHECK-SEPARATE: ---> piContextCreate
78+
// CHECK-SEPARATE: ---> piQueueCreate
79+
// CHECK-SEPARATE: ---> piMemBufferCreate
80+
//
81+
// Verify that we have a memcpy between subdevices in this case
82+
// CHECK-SEPARATE: ---> piEnqueueMemBufferMap
83+
// CHECK-SEPARATE: ---> piEnqueueMemBufferWrite
84+
//
85+
// CHECK-SEPARATE: ---> piEnqueueKernelLaunch
86+
// CHECK-SEPARATE: ---> piEventsWait
87+
88+
return true;
89+
}
90+
91+
static bool check_shared_context(device dev, buffer<int, 1> buf,
92+
partition_fn partition) {
93+
log_pi("Create sub devices");
94+
std::vector<device> subdevices = partition(dev);
95+
assert(subdevices.size() > 1);
96+
// CHECK-SHARED: Create sub devices
97+
// CHECK-SHARED: ---> piDevicePartition
98+
99+
// Shared context: queues are bound to specific subdevices, but
100+
// memory does not migrate
101+
log_pi("Create shared context");
102+
context shared_context(subdevices);
103+
// CHECK-SHARED: Create shared context
104+
// CHECK-SHARED: ---> piContextCreate
105+
//
106+
// Make sure that a single context is created: see --implicit-check-not above.
107+
108+
log_pi("Test sub device 0");
109+
{
110+
queue q0(shared_context, subdevices[0]);
111+
use_mem(buf, q0);
112+
}
113+
// CHECK-SHARED: Test sub device 0
114+
// CHECK-SHARED: ---> piQueueCreate
115+
// CHECK-SHARED: ---> piMemBufferCreate
116+
//
117+
// Make sure that a single buffer is created (and shared between subdevices):
118+
// see --implicit-check-not above.
119+
//
120+
// CHECK-SHARED: ---> piEnqueueKernelLaunch
121+
// CHECK-SHARED: ---> piEventsWait
122+
123+
log_pi("Test sub device 1");
124+
{
125+
queue q1(shared_context, subdevices[1]);
126+
use_mem(buf, q1);
127+
}
128+
// CHECK-SHARED: Test sub device 1
129+
// CHECK-SHARED: ---> piQueueCreate
130+
// CHECK-SHARED: ---> piEnqueueKernelLaunch
131+
// CHECK-SHARED: ---> piEventsWait
132+
// CHECK-SHARED: ---> piEnqueueMemBufferRead
133+
134+
return true;
135+
}
136+
137+
static bool check_fused_context(device dev, buffer<int, 1> buf,
138+
partition_fn partition) {
139+
log_pi("Create sub devices");
140+
std::vector<device> subdevices = partition(dev);
141+
assert(subdevices.size() > 1);
142+
// CHECK-FUSED: Create sub devices
143+
// CHECK-FUSED: ---> piDevicePartition
144+
145+
// Fused context: same as shared context, but also includes the root device
146+
log_pi("Create fused context");
147+
std::vector<device> devices;
148+
devices.push_back(dev);
149+
devices.push_back(subdevices[0]);
150+
devices.push_back(subdevices[1]);
151+
context fused_context(devices);
152+
// CHECK-FUSED: Create fused context
153+
// CHECK-FUSED: ---> piContextCreate
154+
//
155+
// Make sure that a single context is created: see --implicit-check-not above.
156+
157+
log_pi("Test root device");
158+
{
159+
queue q(fused_context, dev);
160+
use_mem(buf, q);
161+
}
162+
// CHECK-FUSED: Test root device
163+
// CHECK-FUSED: ---> piQueueCreate
164+
// CHECK-FUSED: ---> piMemBufferCreate
165+
//
166+
// Make sure that a single buffer is created (and shared between subdevices
167+
// *and* the root device): see --implicit-check-not above.
168+
//
169+
// CHECK-FUSED: ---> piEnqueueKernelLaunch
170+
// CHECK-FUSED: ---> piEventsWait
171+
172+
log_pi("Test sub device 0");
173+
{
174+
queue q0(fused_context, subdevices[0]);
175+
use_mem(buf, q0);
176+
}
177+
// CHECK-FUSED: Test sub device 0
178+
// CHECK-FUSED: ---> piQueueCreate
179+
// CHECK-FUSED: ---> piEnqueueKernelLaunch
180+
// CHECK-FUSED: ---> piEventsWait
181+
182+
log_pi("Test sub device 1");
183+
{
184+
queue q1(fused_context, subdevices[1]);
185+
use_mem(buf, q1);
186+
}
187+
// CHECK-FUSED: Test sub device 1
188+
// CHECK-FUSED: ---> piQueueCreate
189+
// CHECK-FUSED: ---> piEnqueueKernelLaunch
190+
// CHECK-FUSED: ---> piEventsWait
191+
// CHECK-FUSED: ---> piEnqueueMemBufferRead
192+
193+
return true;
194+
}
195+
196+
int main(int argc, const char **argv) {
197+
assert(argc == 3 && "Invalid number of arguments");
198+
std::string test(argv[1]);
199+
std::string partition_type(argv[2]);
200+
201+
default_selector selector;
202+
device dev(selector);
203+
204+
std::vector<int> host_mem(1024, 1);
205+
buffer<int, 1> buf(&host_mem[0], host_mem.size());
206+
207+
partition_fn partition;
208+
if (partition_type == "equally") {
209+
partition = partition_equally;
210+
} else if (partition_type == "affinity") {
211+
partition = partition_affinity;
212+
} else {
213+
assert(0 && "Unsupported partition type");
214+
}
215+
216+
bool result = false;
217+
if (test == "separate") {
218+
result = check_separate(dev, buf, partition);
219+
} else if (test == "shared") {
220+
result = check_shared_context(dev, buf, partition);
221+
} else if (test == "fused") {
222+
result = check_fused_context(dev, buf, partition);
223+
} else {
224+
assert(0 && "Unknown test");
225+
}
226+
227+
if (!result) {
228+
fprintf(stderr, "FAILED\n");
229+
return EXIT_FAILURE;
230+
}
231+
}

0 commit comments

Comments
 (0)