Skip to content

Commit d8cc532

Browse files
authored
Merge pull request #2170 from igchor/enqueueWaitTest
[CTS] extend tests for urEnqueueEventsWait
2 parents c32a78c + 2c60671 commit d8cc532

File tree

5 files changed

+288
-49
lines changed

5 files changed

+288
-49
lines changed

test/conformance/enqueue/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ add_conformance_test_with_kernels_environment(enqueue
77
urEnqueueDeviceGlobalVariableRead.cpp
88
urEnqueueDeviceGlobalVariableWrite.cpp
99
urEnqueueEventsWait.cpp
10+
urEnqueueEventsWaitMultiDevice.cpp
1011
urEnqueueEventsWaitWithBarrier.cpp
1112
urEnqueueKernelLaunch.cpp
1213
urEnqueueKernelLaunchAndMemcpyInOrder.cpp

test/conformance/enqueue/enqueue_adapter_native_cpu.match

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
{{NONDETERMINISTIC}}
2+
{{OPT}}urEnqueueEventsWaitMultiDeviceTest.EmptyWaitList
3+
{{OPT}}urEnqueueEventsWaitMultiDeviceTest.EmptyWaitListWithEvent
4+
{{OPT}}urEnqueueEventsWaitMultiDeviceTest.EnqueueWaitOnADifferentQueue
25
{{OPT}}urEnqueueDeviceGetGlobalVariableReadTest.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU__{{.*}}
36
{{OPT}}urEnqueueDeviceGetGlobalVariableReadTest.InvalidNullHandleQueue/SYCL_NATIVE_CPU___SYCL_Native_CPU__{{.*}}
47
{{OPT}}urEnqueueDeviceGetGlobalVariableReadTest.InvalidNullHandleProgram/SYCL_NATIVE_CPU___SYCL_Native_CPU__{{.*}}
@@ -16,6 +19,12 @@
1619
{{OPT}}urEnqueueDeviceGetGlobalVariableWriteTest.InvalidEventWaitInvalidEvent/SYCL_NATIVE_CPU___SYCL_Native_CPU__{{.*}}
1720
{{OPT}}urEnqueueEventsWaitTest.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU__{{.*}}
1821
{{OPT}}urEnqueueEventsWaitTest.InvalidNullPtrEventWaitList/SYCL_NATIVE_CPU___SYCL_Native_CPU__{{.*}}
22+
{{OPT}}urEnqueueEventsWaitMultiDeviceMTTest.EnqueueWaitSingleQueueMultiOps/MultiThread
23+
{{OPT}}urEnqueueEventsWaitMultiDeviceMTTest.EnqueueWaitSingleQueueMultiOps/NoMultiThread
24+
{{OPT}}urEnqueueEventsWaitMultiDeviceMTTest.EnqueueWaitOnAllQueues/MultiThread
25+
{{OPT}}urEnqueueEventsWaitMultiDeviceMTTest.EnqueueWaitOnAllQueues/NoMultiThread
26+
{{OPT}}urEnqueueEventsWaitMultiDeviceMTTest.EnqueueWaitOnAllQueuesCommonDependency/MultiThread
27+
{{OPT}}urEnqueueEventsWaitMultiDeviceMTTest.EnqueueWaitOnAllQueuesCommonDependency/NoMultiThread
1928
{{OPT}}urEnqueueEventsWaitWithBarrierTest.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU__{{.*}}
2029
{{OPT}}urEnqueueEventsWaitWithBarrierTest.InvalidNullPtrEventWaitList/SYCL_NATIVE_CPU___SYCL_Native_CPU__{{.*}}
2130
urEnqueueEventsWaitWithBarrierOrderingTest.SuccessEventDependenciesBarrierOnly/SYCL_NATIVE_CPU___SYCL_Native_CPU__{{.*}}_

test/conformance/enqueue/helpers.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,50 @@ printFillTestString(const testing::TestParamInfo<typename T::ParamType> &info) {
154154
return test_name.str();
155155
}
156156

157+
struct urMultiQueueMultiDeviceTest : uur::urMultiDeviceContextTestTemplate<1> {
158+
void initQueues(std::vector<ur_device_handle_t> srcDevices,
159+
size_t numDuplicate) {
160+
for (size_t i = 0; i < numDuplicate; i++) {
161+
devices.insert(devices.end(), srcDevices.begin(), srcDevices.end());
162+
}
163+
164+
for (auto &device : devices) {
165+
ur_queue_handle_t queue = nullptr;
166+
ASSERT_SUCCESS(urQueueCreate(context, device, nullptr, &queue));
167+
queues.push_back(queue);
168+
}
169+
}
170+
171+
// Default implementation that uses all available devices
172+
void SetUp() override {
173+
UUR_RETURN_ON_FATAL_FAILURE(
174+
uur::urMultiDeviceContextTestTemplate<1>::SetUp());
175+
initQueues(uur::KernelsEnvironment::instance->devices, 1);
176+
}
177+
178+
// Specialized implementation that duplicates all devices and queues
179+
void SetUp(std::vector<ur_device_handle_t> srcDevices,
180+
size_t numDuplicate) {
181+
UUR_RETURN_ON_FATAL_FAILURE(
182+
uur::urMultiDeviceContextTestTemplate<1>::SetUp());
183+
initQueues(srcDevices, numDuplicate);
184+
}
185+
186+
void TearDown() override {
187+
for (auto &queue : queues) {
188+
EXPECT_SUCCESS(urQueueRelease(queue));
189+
}
190+
UUR_RETURN_ON_FATAL_FAILURE(
191+
uur::urMultiDeviceContextTestTemplate<1>::TearDown());
192+
}
193+
std::function<std::tuple<std::vector<ur_device_handle_t>,
194+
std::vector<ur_queue_handle_t>>(void)>
195+
makeQueues;
196+
197+
std::vector<ur_device_handle_t> devices;
198+
std::vector<ur_queue_handle_t> queues;
199+
};
200+
157201
} // namespace uur
158202

159203
#endif // UUR_ENQUEUE_RECT_HELPERS_H_INCLUDED
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
// Copyright (C) 2024 Intel Corporation
2+
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
3+
// See LICENSE.TXT
4+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
6+
#include "helpers.h"
7+
8+
#include <thread>
9+
10+
#include <uur/fixtures.h>
11+
#include <uur/raii.h>
12+
13+
struct urEnqueueEventsWaitMultiDeviceTest : uur::urMultiQueueMultiDeviceTest {
14+
void SetUp() override { SetUp(2); /* we need at least 2 devices */ }
15+
16+
void SetUp(size_t numDuplicateDevices) {
17+
UUR_RETURN_ON_FATAL_FAILURE(uur::urMultiQueueMultiDeviceTest::SetUp(
18+
uur::KernelsEnvironment::instance->devices, numDuplicateDevices));
19+
20+
for (auto device : devices) {
21+
ur_device_usm_access_capability_flags_t shared_usm_single = 0;
22+
EXPECT_SUCCESS(uur::GetDeviceUSMSingleSharedSupport(
23+
device, shared_usm_single));
24+
if (!shared_usm_single) {
25+
GTEST_SKIP() << "Shared USM is not supported by the device.";
26+
}
27+
}
28+
29+
ptrs.resize(devices.size());
30+
for (size_t i = 0; i < devices.size(); i++) {
31+
EXPECT_SUCCESS(urUSMSharedAlloc(context, devices[i], nullptr,
32+
nullptr, size, &ptrs[i]));
33+
}
34+
}
35+
36+
void TearDown() override {
37+
for (auto ptr : ptrs) {
38+
if (ptr) {
39+
EXPECT_SUCCESS(urUSMFree(context, ptr));
40+
}
41+
}
42+
UUR_RETURN_ON_FATAL_FAILURE(
43+
uur::urMultiQueueMultiDeviceTest::TearDown());
44+
}
45+
46+
void initData() {
47+
EXPECT_SUCCESS(urEnqueueUSMFill(queues[0], ptrs[0], sizeof(pattern),
48+
&pattern, size, 0, nullptr, nullptr));
49+
EXPECT_SUCCESS(urQueueFinish(queues[0]));
50+
}
51+
52+
void verifyData(void *ptr, uint32_t pattern) {
53+
for (size_t i = 0; i < count; i++) {
54+
ASSERT_EQ(reinterpret_cast<uint32_t *>(ptr)[i], pattern);
55+
}
56+
}
57+
58+
uint32_t pattern = 42;
59+
const size_t count = 1024;
60+
const size_t size = sizeof(uint32_t) * count;
61+
62+
std::vector<void *> ptrs;
63+
};
64+
65+
TEST_F(urEnqueueEventsWaitMultiDeviceTest, EmptyWaitList) {
66+
initData();
67+
68+
ASSERT_SUCCESS(urEnqueueUSMMemcpy(queues[0], false, ptrs[1], ptrs[0], size,
69+
0, nullptr, nullptr));
70+
ASSERT_SUCCESS(urEnqueueEventsWait(queues[0], 0, nullptr, nullptr));
71+
ASSERT_SUCCESS(urQueueFinish(queues[0]));
72+
73+
verifyData(ptrs[1], pattern);
74+
}
75+
76+
TEST_F(urEnqueueEventsWaitMultiDeviceTest, EmptyWaitListWithEvent) {
77+
initData();
78+
79+
ASSERT_SUCCESS(urEnqueueUSMMemcpy(queues[0], false, ptrs[1], ptrs[0], size,
80+
0, nullptr, nullptr));
81+
82+
uur::raii::Event event;
83+
ASSERT_SUCCESS(urEnqueueEventsWait(queues[0], 0, nullptr, event.ptr()));
84+
ASSERT_SUCCESS(urEventWait(1, event.ptr()));
85+
86+
verifyData(ptrs[1], pattern);
87+
}
88+
89+
TEST_F(urEnqueueEventsWaitMultiDeviceTest, EnqueueWaitOnADifferentQueue) {
90+
initData();
91+
92+
uur::raii::Event event;
93+
ASSERT_SUCCESS(urEnqueueUSMMemcpy(queues[0], false, ptrs[1], ptrs[0], size,
94+
0, nullptr, event.ptr()));
95+
ASSERT_SUCCESS(urEnqueueEventsWait(queues[0], 1, event.ptr(), nullptr));
96+
ASSERT_SUCCESS(urQueueFinish(queues[0]));
97+
98+
verifyData(ptrs[1], pattern);
99+
}
100+
101+
struct urEnqueueEventsWaitMultiDeviceMTTest
102+
: urEnqueueEventsWaitMultiDeviceTest,
103+
testing::WithParamInterface<uur::BoolTestParam> {
104+
void doComputation(std::function<void(size_t)> work) {
105+
auto multiThread = GetParam().value;
106+
std::vector<std::thread> threads;
107+
for (size_t i = 0; i < devices.size(); i++) {
108+
if (multiThread) {
109+
threads.emplace_back(work, i);
110+
} else {
111+
work(i);
112+
}
113+
}
114+
for (auto &thread : threads) {
115+
thread.join();
116+
}
117+
}
118+
119+
void SetUp() override {
120+
const size_t numDuplicateDevices = 8;
121+
UUR_RETURN_ON_FATAL_FAILURE(
122+
urEnqueueEventsWaitMultiDeviceTest::SetUp(numDuplicateDevices));
123+
}
124+
125+
void TearDown() override { urEnqueueEventsWaitMultiDeviceTest::TearDown(); }
126+
};
127+
128+
template <typename T>
129+
inline std::string
130+
printParams(const testing::TestParamInfo<typename T::ParamType> &info) {
131+
std::stringstream ss;
132+
133+
auto param1 = info.param;
134+
ss << (param1.value ? "" : "No") << param1.name;
135+
136+
return ss.str();
137+
}
138+
139+
INSTANTIATE_TEST_SUITE_P(
140+
, urEnqueueEventsWaitMultiDeviceMTTest,
141+
testing::ValuesIn(uur::BoolTestParam::makeBoolParam("MultiThread")),
142+
printParams<urEnqueueEventsWaitMultiDeviceMTTest>);
143+
144+
TEST_P(urEnqueueEventsWaitMultiDeviceMTTest, EnqueueWaitSingleQueueMultiOps) {
145+
std::vector<uint32_t> data(count, pattern);
146+
147+
auto work = [this, &data](size_t i) {
148+
ASSERT_SUCCESS(urEnqueueUSMMemcpy(
149+
queues[0], false, ptrs[i], data.data(), size, 0, nullptr, nullptr));
150+
};
151+
152+
doComputation(work);
153+
154+
auto verify = [this](size_t i) {
155+
uur::raii::Event event;
156+
ASSERT_SUCCESS(urEnqueueEventsWait(queues[0], 0, nullptr, event.ptr()));
157+
ASSERT_SUCCESS(urEventWait(1, event.ptr()));
158+
159+
verifyData(ptrs[i], pattern);
160+
};
161+
162+
doComputation(verify);
163+
}
164+
165+
TEST_P(urEnqueueEventsWaitMultiDeviceMTTest, EnqueueWaitOnAllQueues) {
166+
std::vector<uur::raii::Event> eventsRaii(devices.size());
167+
std::vector<ur_event_handle_t> events(devices.size());
168+
auto work = [this, &events, &eventsRaii](size_t i) {
169+
ASSERT_SUCCESS(urEnqueueUSMFill(queues[i], ptrs[i], sizeof(pattern),
170+
&pattern, size, 0, nullptr,
171+
eventsRaii[i].ptr()));
172+
events[i] = eventsRaii[i].get();
173+
};
174+
175+
doComputation(work);
176+
177+
uur::raii::Event gatherEvent;
178+
ASSERT_SUCCESS(urEnqueueEventsWait(queues[0], devices.size(), events.data(),
179+
gatherEvent.ptr()));
180+
ASSERT_SUCCESS(urEventWait(1, gatherEvent.ptr()));
181+
182+
for (size_t i = 0; i < devices.size(); i++) {
183+
verifyData(ptrs[i], pattern);
184+
}
185+
}
186+
187+
TEST_P(urEnqueueEventsWaitMultiDeviceMTTest,
188+
EnqueueWaitOnAllQueuesCommonDependency) {
189+
uur::raii::Event event;
190+
ASSERT_SUCCESS(urEnqueueUSMFill(queues[0], ptrs[0], sizeof(pattern),
191+
&pattern, size, 0, nullptr, event.ptr()));
192+
193+
std::vector<uur::raii::Event> perQueueEvents(devices.size());
194+
std::vector<ur_event_handle_t> eventHandles(devices.size());
195+
auto work = [this, &event, &perQueueEvents, &eventHandles](size_t i) {
196+
ASSERT_SUCCESS(urEnqueueEventsWait(queues[i], 1, event.ptr(),
197+
perQueueEvents[i].ptr()));
198+
eventHandles[i] = perQueueEvents[i].get();
199+
};
200+
201+
doComputation(work);
202+
203+
uur::raii::Event hGatherEvent;
204+
ASSERT_SUCCESS(urEnqueueEventsWait(queues[0], eventHandles.size(),
205+
eventHandles.data(),
206+
hGatherEvent.ptr()));
207+
ASSERT_SUCCESS(urEventWait(1, hGatherEvent.ptr()));
208+
209+
for (auto &event : eventHandles) {
210+
ur_event_status_t status;
211+
ASSERT_SUCCESS(
212+
urEventGetInfo(event, UR_EVENT_INFO_COMMAND_EXECUTION_STATUS,
213+
sizeof(ur_event_status_t), &status, nullptr));
214+
ASSERT_EQ(status, UR_EVENT_STATUS_COMPLETE);
215+
}
216+
217+
verifyData(ptrs[0], pattern);
218+
}

0 commit comments

Comments
 (0)