Skip to content

Commit a8b1b8f

Browse files
add a test for serialization of command buffers
add new test fixture test serialization of the command buffer execution in an in-order queue
1 parent 5c30e32 commit a8b1b8f

File tree

2 files changed

+144
-31
lines changed

2 files changed

+144
-31
lines changed

unified-runtime/test/conformance/exp_command_buffer/enqueue.cpp

Lines changed: 119 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,23 @@
1717
// enqueue_update.cpp test for a test verifying the order of submissions, as
1818
// the input/output to the kernels can be modified between the submissions.
1919
struct urEnqueueCommandBufferExpTest
20-
: uur::command_buffer::urCommandBufferExpExecutionTest {
20+
: uur::command_buffer::urCommandBufferExpExecutionTestWithParam<ur_queue_flags_t> {
2121
virtual void SetUp() override {
2222
program_name = "increment";
23-
UUR_RETURN_ON_FATAL_FAILURE(urCommandBufferExpExecutionTest::SetUp());
23+
UUR_RETURN_ON_FATAL_FAILURE(urCommandBufferExpExecutionTestWithParam::SetUp());
2424

2525
// Create an in-order queue
26+
queue_type = std::get<1>(GetParam());
2627
ur_queue_properties_t queue_properties = {
27-
UR_STRUCTURE_TYPE_QUEUE_PROPERTIES, nullptr, 0};
28+
UR_STRUCTURE_TYPE_QUEUE_PROPERTIES, nullptr, queue_type}; //GetParam()}; //0};
2829
ASSERT_SUCCESS(
29-
urQueueCreate(context, device, &queue_properties, &in_order_queue));
30+
urQueueCreate(context, device, &queue_properties, &in_or_out_of_order_queue));
3031

31-
// Create an out-of-order queue
32-
queue_properties.flags = UR_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE;
33-
ASSERT_SUCCESS(
34-
urQueueCreate(context, device, &queue_properties, &out_of_order_queue));
35-
ASSERT_NE(out_of_order_queue, nullptr);
32+
// // Create an out-of-order queue
33+
// queue_properties.flags = UR_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE;
34+
// ASSERT_SUCCESS(
35+
// urQueueCreate(context, device, &queue_properties, &out_of_order_queue));
36+
// ASSERT_NE(out_of_order_queue, nullptr);
3637

3738
ASSERT_SUCCESS(urUSMDeviceAlloc(context, device, nullptr, nullptr,
3839
allocation_size, &device_ptr));
@@ -42,6 +43,17 @@ struct urEnqueueCommandBufferExpTest
4243
ASSERT_SUCCESS(urEnqueueUSMFill(queue, device_ptr, sizeof(zero_pattern),
4344
&zero_pattern, allocation_size, 0, nullptr,
4445
nullptr));
46+
47+
std::vector<int> temp_val(buffer_size, 3);
48+
49+
for (int i = 0; i < num_copy_buffers; i++) {
50+
ASSERT_SUCCESS(urUSMDeviceAlloc(context, device, nullptr, nullptr, buffer_size * sizeof(int), (void**) &(dst_buffers[i])));
51+
ASSERT_SUCCESS(urUSMDeviceAlloc(context, device, nullptr, nullptr, buffer_size * sizeof(int), (void**) &(src_buffers[i])));
52+
53+
ASSERT_SUCCESS(urEnqueueUSMMemcpy(in_or_out_of_order_queue, false, src_buffers[i], temp_val.data(), buffer_size * sizeof(int), 0, nullptr, nullptr));
54+
}
55+
56+
4557
ASSERT_SUCCESS(urQueueFinish(queue));
4658

4759
// Create command-buffer with a single kernel that does "Ptr[i] += 1;"
@@ -50,53 +62,108 @@ struct urEnqueueCommandBufferExpTest
5062
cmd_buf_handle, kernel, n_dimensions, &global_offset, &global_size,
5163
nullptr, 0, nullptr, 0, nullptr, 0, nullptr, nullptr, nullptr,
5264
nullptr));
65+
66+
67+
for (int i = 0; i < num_copy_buffers; i++) {
68+
ASSERT_SUCCESS(urCommandBufferAppendUSMMemcpyExp(cmd_buf_handle, dst_buffers[i], src_buffers[i], buffer_size * sizeof(int), 0, nullptr, 0, nullptr, nullptr, nullptr, nullptr));
69+
}
70+
5371
ASSERT_SUCCESS(urCommandBufferFinalizeExp(cmd_buf_handle));
5472
}
5573

5674
virtual void TearDown() override {
57-
if (in_order_queue) {
58-
EXPECT_SUCCESS(urQueueRelease(in_order_queue));
75+
if (in_or_out_of_order_queue) {
76+
EXPECT_SUCCESS(urQueueRelease(in_or_out_of_order_queue));
5977
}
6078

61-
if (out_of_order_queue) {
62-
EXPECT_SUCCESS(urQueueRelease(out_of_order_queue));
63-
}
79+
// if (out_of_order_queue) {
80+
// EXPECT_SUCCESS(urQueueRelease(out_of_order_queue));
81+
// }
6482

6583
if (device_ptr) {
6684
EXPECT_SUCCESS(urUSMFree(context, device_ptr));
6785
}
6886

69-
UUR_RETURN_ON_FATAL_FAILURE(urCommandBufferExpExecutionTest::TearDown());
87+
for (int i = 0; i < num_copy_buffers; i++) {
88+
if (dst_buffers[i]) {
89+
EXPECT_SUCCESS(urUSMFree(context, dst_buffers[i]));
90+
}
91+
92+
if (src_buffers[i]) {
93+
EXPECT_SUCCESS(urUSMFree(context, src_buffers[i]));
94+
}
95+
}
96+
97+
UUR_RETURN_ON_FATAL_FAILURE(urCommandBufferExpExecutionTestWithParam::TearDown());
7098
}
7199

72-
ur_queue_handle_t in_order_queue = nullptr;
73-
ur_queue_handle_t out_of_order_queue = nullptr;
100+
ur_queue_handle_t in_or_out_of_order_queue = nullptr;
101+
ur_queue_flags_t queue_type; // = 0;
102+
103+
// ur_queue_handle_t out_of_order_queue = nullptr;
74104

75105
static constexpr size_t global_size = 16;
76106
static constexpr size_t global_offset = 0;
77107
static constexpr size_t n_dimensions = 1;
78108
static constexpr size_t allocation_size = sizeof(uint32_t) * global_size;
79109
void *device_ptr = nullptr;
110+
111+
static constexpr int num_copy_buffers = 10;
112+
static constexpr int buffer_size = 512;
113+
int* dst_buffers[num_copy_buffers];
114+
int* src_buffers[num_copy_buffers];
80115
};
81116

82-
UUR_INSTANTIATE_DEVICE_TEST_SUITE(urEnqueueCommandBufferExpTest);
117+
118+
std::string deviceTestWithQueueTypePrinter(
119+
const ::testing::TestParamInfo<std::tuple<uur::DeviceTuple, ur_queue_flags_t>> &info) {
120+
auto device = std::get<0>(info.param).device;
121+
auto queue_type = std::get<1>(info.param);
122+
123+
std::stringstream ss;
124+
125+
switch (queue_type) {
126+
case 0:
127+
ss << "InOrderQueue";
128+
break;
129+
130+
// change to if and bitwise and?
131+
case UR_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE:
132+
ss << "OutOfOrderQueue";
133+
break;
134+
135+
default:
136+
ss << "UnspecifiedQueueType" << queue_type;
137+
}
138+
139+
140+
return uur::GetPlatformAndDeviceName(device) + "__" +
141+
uur::GTestSanitizeString(ss.str());
142+
}
143+
144+
// UUR_INSTANTIATE_DEVICE_TEST_SUITE(urEnqueueCommandBufferExpTest);
145+
UUR_DEVICE_TEST_SUITE_WITH_PARAM(urEnqueueCommandBufferExpTest, testing::Values(0, UR_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE), deviceTestWithQueueTypePrinter);
83146

84147
// Tests that the same command-buffer submitted across different in-order
85148
// queues has an implicit dependency on first submission
86149
TEST_P(urEnqueueCommandBufferExpTest, SerializeAcrossQueues) {
87150
// Execute command-buffer to first in-order queue (created by parent
88151
// urQueueTest fixture)
152+
if (queue_type == UR_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE) {
153+
GTEST_SKIP() << "unwantedoutoforder";
154+
}
155+
89156
ASSERT_SUCCESS(
90157
urEnqueueCommandBufferExp(queue, cmd_buf_handle, 0, nullptr, nullptr));
91158

92159
// Execute command-buffer to second in-order queue, should have implicit
93160
// dependency on first submission.
94-
ASSERT_SUCCESS(urEnqueueCommandBufferExp(in_order_queue, cmd_buf_handle, 0,
161+
ASSERT_SUCCESS(urEnqueueCommandBufferExp(in_or_out_of_order_queue, cmd_buf_handle, 0,
95162
nullptr, nullptr));
96163

97164
// Wait for both submissions to complete
98165
ASSERT_SUCCESS(urQueueFlush(queue));
99-
ASSERT_SUCCESS(urQueueFinish(in_order_queue));
166+
ASSERT_SUCCESS(urQueueFinish(in_or_out_of_order_queue));
100167

101168
std::vector<uint32_t> Output(global_size);
102169
ASSERT_SUCCESS(urEnqueueUSMMemcpy(queue, false, Output.data(), device_ptr,
@@ -110,25 +177,47 @@ TEST_P(urEnqueueCommandBufferExpTest, SerializeAcrossQueues) {
110177
}
111178
}
112179

113-
// Tests that submitting a command-buffer twice to an out-of-order queue
114-
// relying on implicit serialization semantics for dependencies.
115-
TEST_P(urEnqueueCommandBufferExpTest, SerializeOutofOrderQueue) {
116-
ASSERT_SUCCESS(urEnqueueCommandBufferExp(out_of_order_queue, cmd_buf_handle,
117-
0, nullptr, nullptr));
118-
ASSERT_SUCCESS(urEnqueueCommandBufferExp(out_of_order_queue, cmd_buf_handle,
180+
// // Tests that submitting a command-buffer twice to an out-of-order queue
181+
// // relying on implicit serialization semantics for dependencies.
182+
// TEST_P(urEnqueueCommandBufferExpTest, SerializeOutofOrderQueue) {
183+
// ASSERT_SUCCESS(urEnqueueCommandBufferExp(out_of_order_queue, cmd_buf_handle,
184+
// 0, nullptr, nullptr));
185+
// ASSERT_SUCCESS(urEnqueueCommandBufferExp(out_of_order_queue, cmd_buf_handle,
186+
// 0, nullptr, nullptr));
187+
188+
// // Wait for both submissions to complete
189+
// ASSERT_SUCCESS(urQueueFinish(out_of_order_queue));
190+
191+
// std::vector<uint32_t> Output(global_size);
192+
// ASSERT_SUCCESS(urEnqueueUSMMemcpy(out_of_order_queue, true, Output.data(),
193+
// device_ptr, allocation_size, 0, nullptr,
194+
// nullptr));
195+
196+
// // Verify
197+
// const uint32_t reference = 2;
198+
// for (size_t i = 0; i < global_size; i++) {
199+
// ASSERT_EQ(reference, Output[i]);
200+
// }
201+
// }
202+
203+
TEST_P(urEnqueueCommandBufferExpTest, SerializeInOrOutOfOrderQueue) {
204+
const int iterations = 5;
205+
for (int i = 0; i < iterations; i++) {
206+
ASSERT_SUCCESS(urEnqueueCommandBufferExp(in_or_out_of_order_queue, cmd_buf_handle,
119207
0, nullptr, nullptr));
208+
}
120209

121210
// Wait for both submissions to complete
122-
ASSERT_SUCCESS(urQueueFinish(out_of_order_queue));
211+
ASSERT_SUCCESS(urQueueFinish(in_or_out_of_order_queue));
123212

124213
std::vector<uint32_t> Output(global_size);
125-
ASSERT_SUCCESS(urEnqueueUSMMemcpy(out_of_order_queue, true, Output.data(),
214+
ASSERT_SUCCESS(urEnqueueUSMMemcpy(in_or_out_of_order_queue, true, Output.data(),
126215
device_ptr, allocation_size, 0, nullptr,
127216
nullptr));
128217

129218
// Verify
130-
const uint32_t reference = 2;
219+
const uint32_t reference = iterations;
131220
for (size_t i = 0; i < global_size; i++) {
132221
ASSERT_EQ(reference, Output[i]);
133222
}
134-
}
223+
}

unified-runtime/test/conformance/exp_command_buffer/fixtures.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ struct urCommandBufferExpExecutionTest : uur::urKernelExecutionTest {
9898
UUR_RETURN_ON_FATAL_FAILURE(checkCommandBufferSupport(device));
9999

100100
ur_exp_command_buffer_desc_t desc{UR_STRUCTURE_TYPE_EXP_COMMAND_BUFFER_DESC,
101-
nullptr, false, false, false};
101+
nullptr, false, false /* WAS: false */, false};
102102
ASSERT_SUCCESS(
103103
urCommandBufferCreateExp(context, device, &desc, &cmd_buf_handle));
104104
ASSERT_NE(cmd_buf_handle, nullptr);
@@ -114,6 +114,30 @@ struct urCommandBufferExpExecutionTest : uur::urKernelExecutionTest {
114114
ur_exp_command_buffer_handle_t cmd_buf_handle = nullptr;
115115
};
116116

117+
template <class T>
118+
struct urCommandBufferExpExecutionTestWithParam : urKernelExecutionTestWithParam<T> {
119+
void SetUp() override {
120+
UUR_RETURN_ON_FATAL_FAILURE(uur::urKernelExecutionTestWithParam<T>::SetUp());
121+
122+
UUR_RETURN_ON_FATAL_FAILURE(checkCommandBufferSupport(this->device));
123+
124+
ur_exp_command_buffer_desc_t desc{UR_STRUCTURE_TYPE_EXP_COMMAND_BUFFER_DESC,
125+
nullptr, false, false, false};
126+
ASSERT_SUCCESS(urCommandBufferCreateExp(this->context, this->device, &desc,
127+
&cmd_buf_handle));
128+
ASSERT_NE(cmd_buf_handle, nullptr);
129+
}
130+
131+
void TearDown() override {
132+
if (cmd_buf_handle) {
133+
EXPECT_SUCCESS(urCommandBufferReleaseExp(cmd_buf_handle));
134+
}
135+
UUR_RETURN_ON_FATAL_FAILURE(uur::urKernelExecutionTestWithParam<T>::TearDown());
136+
}
137+
138+
ur_exp_command_buffer_handle_t cmd_buf_handle = nullptr;
139+
};
140+
117141
struct urUpdatableCommandBufferExpTest : uur::urQueueTest {
118142
void SetUp() override {
119143
UUR_RETURN_ON_FATAL_FAILURE(uur::urQueueTest::SetUp());

0 commit comments

Comments
 (0)