1 //
2 // Copyright (c) 2022 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "basic_command_buffer.h"
18 #include "procs.h"
19
20 #include <vector>
21
22 //--------------------------------------------------------------------------
23 enum class EventMode
24 {
25 RET_REGULAR_WAIT_FOR_COMBUF = 0,
26 RET_COMBUF_WAIT_FOR_COMBUF,
27 RET_COMBUF_WAIT_FOR_SEC_COMBUF,
28 RET_EVENT_CALLBACK,
29 RET_CLWAITFOREVENTS_SINGLE,
30 RET_CLWAITFOREVENTS,
31 RET_COMBUF_WAIT_FOR_REGULAR,
32 RET_WAIT_FOR_SEC_QUEUE_EVENT,
33 USER_EVENT_WAIT,
34 USER_EVENTS_WAIT,
35 USER_EVENT_CALLBACK
36 };
37
38 //--------------------------------------------------------------------------
combuf_event_callback_function(cl_event event,cl_int commandStatus,void * userData)39 void CL_CALLBACK combuf_event_callback_function(cl_event event,
40 cl_int commandStatus,
41 void *userData)
42 {
43 bool *pdata = static_cast<bool *>(userData);
44 log_info("\tEvent callback of clEnqueueCommandBufferKHR triggered\n");
45 *pdata = true;
46 }
47
48 namespace {
49
50 ////////////////////////////////////////////////////////////////////////////////
51 // event sync test cases for cl_khr_command_buffer which handles:
52 // -test that an event returned by a command-buffer enqueue can be waited on by
53 // regular commands
54 // -test that an event returned by a command-buffer enqueue can
55 // be waited on an enqueue of the same command-buffer
56 // -tests that a command buffer enqueue can wait on the enqueue of a different
57 // command buffer
58 // -test clSetEventCallback works correctly on an event returned by
59 // clEnqueueCommandBufferKHR
60 // -test clWaitForEvents on a single event returned from a
61 // clEnqueueCommandBufferKHR
62 // -test clWaitForEvents on multiple events returned from different
63 // clEnqueueCommandBufferKHR calls
64
65
66 //
67 //
68 // -test clSetEventCallback works correctly on an user defined event waited by
69 // clEnqueueCommandBufferKHR
70 //
71 //
72
73 template <EventMode event_mode, bool out_of_order_requested>
74 struct CommandBufferEventSync : public BasicCommandBufferTest
75 {
CommandBufferEventSync__anon7d9a26a30111::CommandBufferEventSync76 CommandBufferEventSync(cl_device_id device, cl_context context,
77 cl_command_queue queue)
78 : BasicCommandBufferTest(device, context, queue),
79 command_buffer_sec(this), kernel_sec(nullptr), in_mem_sec(nullptr),
80 out_mem_sec(nullptr), off_mem_sec(nullptr), test_event(nullptr)
81 {
82 simultaneous_use_requested =
83 (event_mode == EventMode::RET_COMBUF_WAIT_FOR_COMBUF) ? true
84 : false;
85 }
86
87 //--------------------------------------------------------------------------
SetUpKernel__anon7d9a26a30111::CommandBufferEventSync88 cl_int SetUpKernel() override
89 {
90 cl_int error = BasicCommandBufferTest::SetUpKernel();
91 test_error(error, "BasicCommandBufferTest::SetUpKernel failed");
92
93 // due to possible out-of-order command queue copy the kernel for below
94 // case scenarios
95 if (event_mode == EventMode::RET_COMBUF_WAIT_FOR_SEC_COMBUF
96 || event_mode == EventMode::RET_CLWAITFOREVENTS)
97 {
98 kernel_sec = clCreateKernel(program, "copy", &error);
99 test_error(error, "Failed to create copy kernel");
100 }
101
102 return CL_SUCCESS;
103 }
104
105 //--------------------------------------------------------------------------
SetUpKernelArgs__anon7d9a26a30111::CommandBufferEventSync106 cl_int SetUpKernelArgs() override
107 {
108 // due to possible out-of-order command queue it is necessary to create
109 // separate set of kernel args for below cases
110 if (event_mode == EventMode::RET_COMBUF_WAIT_FOR_SEC_COMBUF
111 || event_mode == EventMode::RET_CLWAITFOREVENTS)
112 {
113 // setup arguments for secondary kernel
114 std::swap(kernel, kernel_sec);
115
116 cl_int error = BasicCommandBufferTest::SetUpKernelArgs();
117 test_error(error, "BasicCommandBufferTest::SetUpKernel failed");
118
119 // swap arguments for base class setup
120 in_mem_sec = in_mem;
121 out_mem_sec = out_mem;
122 off_mem_sec = off_mem;
123 std::swap(kernel, kernel_sec);
124 }
125
126 cl_int error = BasicCommandBufferTest::SetUpKernelArgs();
127 test_error(error, "BasicCommandBufferTest::SetUpKernel failed");
128
129 if (out_of_order_requested && out_of_order_support)
130 {
131 queue = clCreateCommandQueue(context, device,
132 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
133 &error);
134 test_error(error, "Unable to create command queue to test with");
135 }
136
137 return CL_SUCCESS;
138 }
139
140 //--------------------------------------------------------------------------
SetUp__anon7d9a26a30111::CommandBufferEventSync141 cl_int SetUp(int elements) override
142 {
143 cl_int error = BasicCommandBufferTest::SetUp(elements);
144 test_error(error, "BasicCommandBufferTest::SetUp failed");
145
146 if (event_mode == EventMode::RET_COMBUF_WAIT_FOR_SEC_COMBUF
147 || event_mode == EventMode::RET_CLWAITFOREVENTS)
148 {
149 command_buffer_sec =
150 clCreateCommandBufferKHR(1, &queue, nullptr, &error);
151 test_error(error, "clCreateCommandBufferKHR failed");
152 }
153 return CL_SUCCESS;
154 }
155
156 //--------------------------------------------------------------------------
Skip__anon7d9a26a30111::CommandBufferEventSync157 bool Skip() override
158 {
159 if (BasicCommandBufferTest::Skip()) return true;
160
161 if (simultaneous_use_requested && !simultaneous_use_support)
162 return true;
163
164 if (out_of_order_requested && !out_of_order_support) return true;
165
166 return false;
167 }
168
169 //--------------------------------------------------------------------------
Run__anon7d9a26a30111::CommandBufferEventSync170 cl_int Run() override
171 {
172 cl_int error = CL_SUCCESS;
173
174 // record command buffer
175 error = RecordCommandBuffer(command_buffer, kernel);
176 test_error(error, "RecordCommandBuffer failed");
177
178 switch (event_mode)
179 {
180 case EventMode::RET_REGULAR_WAIT_FOR_COMBUF:
181 error = RunRegularWaitForCombuf();
182 test_error(error, "RunRegularWaitForCombuf failed");
183 break;
184 case EventMode::RET_COMBUF_WAIT_FOR_COMBUF:
185 error = RunCombufWaitForCombuf();
186 test_error(error, "RunCombufWaitForCombuf failed");
187 break;
188 case EventMode::RET_COMBUF_WAIT_FOR_SEC_COMBUF:
189 error = RunCombufWaitForSecCombuf();
190 test_error(error, "RunCombufWaitForSecCombuf failed");
191 break;
192 case EventMode::RET_EVENT_CALLBACK:
193 error = RunReturnEventCallback();
194 test_error(error, "RunReturnEventCallback failed");
195 break;
196 case EventMode::RET_CLWAITFOREVENTS_SINGLE:
197 error = RunWaitForEvent();
198 test_error(error, "RunWaitForEvent failed");
199 break;
200 case EventMode::RET_CLWAITFOREVENTS:
201 error = RunWaitForEvents();
202 test_error(error, "RunWaitForEvents failed");
203 break;
204 case EventMode::RET_COMBUF_WAIT_FOR_REGULAR:
205 error = RunCombufWaitForRegular();
206 test_error(error, "RunCombufWaitForRegular failed");
207 break;
208 case EventMode::RET_WAIT_FOR_SEC_QUEUE_EVENT:
209 error = RunCombufWaitForSecQueueCombuf();
210 test_error(error, "RunCombufWaitForSecQueueCombuf failed");
211 break;
212 case EventMode::USER_EVENT_WAIT:
213 error = RunUserEventWait();
214 test_error(error, "RunUserEventWait failed");
215 break;
216 case EventMode::USER_EVENTS_WAIT:
217 error = RunUserEventsWait();
218 test_error(error, "RunUserEventsWait failed");
219 break;
220 case EventMode::USER_EVENT_CALLBACK:
221 error = RunUserEventCallback();
222 test_error(error, "RunUserEventCallback failed");
223 break;
224 }
225
226 return CL_SUCCESS;
227 }
228
229 //--------------------------------------------------------------------------
RecordCommandBuffer__anon7d9a26a30111::CommandBufferEventSync230 cl_int RecordCommandBuffer(clCommandBufferWrapper &combuf,
231 clKernelWrapper &kern)
232 {
233 cl_int error = clCommandNDRangeKernelKHR(
234 combuf, nullptr, nullptr, kern, 1, nullptr, &num_elements, nullptr,
235 0, nullptr, nullptr, nullptr);
236 test_error(error, "clCommandNDRangeKernelKHR failed");
237
238 error = clFinalizeCommandBufferKHR(combuf);
239 test_error(error, "clFinalizeCommandBufferKHR failed");
240 return CL_SUCCESS;
241 }
242
243 //--------------------------------------------------------------------------
InitInOrderEvents__anon7d9a26a30111::CommandBufferEventSync244 void InitInOrderEvents(std::vector<cl_event *> &event_ptrs)
245 {
246 if (out_of_order_requested)
247 {
248 in_order_events.resize(event_ptrs.size());
249 for (size_t i = 0; i < in_order_events.size(); i++)
250 {
251 event_ptrs[i] = &in_order_events[i];
252 }
253 }
254 }
255
256 //--------------------------------------------------------------------------
RunRegularWaitForCombuf__anon7d9a26a30111::CommandBufferEventSync257 cl_int RunRegularWaitForCombuf()
258 {
259 std::vector<cl_int> output_data(num_elements);
260
261 // if out-of-order queue requested it is necessary to secure proper
262 // order of commands
263 std::vector<cl_event *> event_ptrs = { nullptr };
264 InitInOrderEvents(event_ptrs);
265
266 cl_int error =
267 clEnqueueFillBuffer(queue, in_mem, &pattern_pri, sizeof(cl_int), 0,
268 data_size(), 0, nullptr, event_ptrs[0]);
269 test_error(error, "clEnqueueFillBuffer failed");
270
271 error = clEnqueueCommandBufferKHR(
272 0, nullptr, command_buffer, wait_count, event_ptrs[0], &test_event);
273 test_error(error, "clEnqueueCommandBufferKHR failed");
274
275 error =
276 clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
277 output_data.data(), 1, &test_event, nullptr);
278 test_error(error, "clEnqueueReadBuffer failed");
279
280 error = clFinish(queue);
281 test_error(error, "clFinish failed");
282
283 // verify the result - result buffer must contain initial pattern
284 for (size_t i = 0; i < num_elements; i++)
285 {
286 CHECK_VERIFICATION_ERROR(pattern_pri, output_data[i], i);
287 }
288
289 return CL_SUCCESS;
290 }
291
292 //--------------------------------------------------------------------------
RunCombufWaitForCombuf__anon7d9a26a30111::CommandBufferEventSync293 cl_int RunCombufWaitForCombuf()
294 {
295 std::vector<cl_int> output_data(num_elements);
296
297 // if out-of-order queue requested it is necessary to secure proper
298 // order of all commands
299 std::vector<cl_event *> event_ptrs = { nullptr, nullptr };
300 InitInOrderEvents(event_ptrs);
301
302 cl_int error =
303 clEnqueueFillBuffer(queue, in_mem, &pattern_pri, sizeof(cl_int), 0,
304 data_size(), 0, nullptr, event_ptrs[0]);
305 test_error(error, "clEnqueueFillBuffer failed");
306
307 error = clEnqueueCommandBufferKHR(
308 0, nullptr, command_buffer, wait_count, event_ptrs[0], &test_event);
309 test_error(error, "clEnqueueCommandBufferKHR failed");
310
311 error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 1,
312 &test_event, event_ptrs[1]);
313 test_error(error, "clEnqueueCommandBufferKHR failed");
314
315 error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
316 output_data.data(), wait_count,
317 event_ptrs[1], nullptr);
318 test_error(error, "clEnqueueReadBuffer failed");
319
320 error = clFinish(queue);
321 test_error(error, "clFinish failed");
322
323 // verify the result - result buffer must contain initial pattern
324 for (size_t i = 0; i < num_elements; i++)
325 {
326 CHECK_VERIFICATION_ERROR(pattern_pri, output_data[i], i);
327 }
328 return CL_SUCCESS;
329 }
330
331 //--------------------------------------------------------------------------
RunCombufWaitForSecCombuf__anon7d9a26a30111::CommandBufferEventSync332 cl_int RunCombufWaitForSecCombuf()
333 {
334 std::vector<cl_int> output_data(num_elements);
335
336 // if out-of-order queue requested it is necessary to secure proper
337 // order of all commands
338 std::vector<cl_event *> event_ptrs = { nullptr, nullptr, nullptr };
339 InitInOrderEvents(event_ptrs);
340
341 // record other command buffer
342 cl_int error = RecordCommandBuffer(command_buffer_sec, kernel_sec);
343 test_error(error, "RecordCommandBuffer failed");
344
345 error =
346 clEnqueueFillBuffer(queue, in_mem_sec, &pattern_pri, sizeof(cl_int),
347 0, data_size(), 0, nullptr, event_ptrs[0]);
348 test_error(error, "clEnqueueFillBuffer failed");
349
350 error =
351 clEnqueueCommandBufferKHR(0, nullptr, command_buffer_sec,
352 wait_count, event_ptrs[0], &test_event);
353 test_error(error, "clEnqueueCommandBufferKHR failed");
354
355 error = clEnqueueFillBuffer(queue, in_mem, &pattern_sec, sizeof(cl_int),
356 0, data_size(), 0, nullptr, event_ptrs[1]);
357 test_error(error, "clEnqueueFillBuffer failed");
358
359 cl_event wait_list[] = { test_event,
360 event_ptrs[1] != nullptr ? *event_ptrs[1]
361 : nullptr };
362 error =
363 clEnqueueCommandBufferKHR(0, nullptr, command_buffer,
364 1 + wait_count, wait_list, event_ptrs[2]);
365 test_error(error, "clEnqueueCommandBufferKHR failed");
366
367 error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
368 output_data.data(), wait_count,
369 event_ptrs[2], nullptr);
370 test_error(error, "clEnqueueReadBuffer failed");
371
372 error = clFinish(queue);
373 test_error(error, "clFinish failed");
374
375 // verify the result - result buffer must contain initial pattern
376 for (size_t i = 0; i < num_elements; i++)
377 {
378 CHECK_VERIFICATION_ERROR(pattern_sec, output_data[i], i);
379 }
380
381 return CL_SUCCESS;
382 }
383
384 //--------------------------------------------------------------------------
RunReturnEventCallback__anon7d9a26a30111::CommandBufferEventSync385 cl_int RunReturnEventCallback()
386 {
387 std::vector<cl_int> output_data(num_elements);
388
389 // if out-of-order queue requested it is necessary to secure proper
390 // order of all commands
391 std::vector<cl_event *> event_ptrs = { nullptr };
392 InitInOrderEvents(event_ptrs);
393
394 cl_int error =
395 clEnqueueFillBuffer(queue, in_mem, &pattern_pri, sizeof(cl_int), 0,
396 data_size(), 0, nullptr, event_ptrs[0]);
397 test_error(error, "clEnqueueFillBuffer failed");
398
399 error = clEnqueueCommandBufferKHR(
400 0, nullptr, command_buffer, wait_count, event_ptrs[0], &test_event);
401 test_error(error, "clEnqueueCommandBufferKHR failed");
402
403 bool confirmation = false;
404 error =
405 clSetEventCallback(test_event, CL_COMPLETE,
406 combuf_event_callback_function, &confirmation);
407 test_error(error, "clSetEventCallback failed");
408
409 error = clWaitForEvents(1, &test_event);
410 test_error(error, "clWaitForEvents failed");
411
412 error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
413 output_data.data(), 0, nullptr, nullptr);
414 test_error(error, "clEnqueueReadBuffer failed");
415
416 error = clFinish(queue);
417 test_error(error, "clFinish failed");
418
419 // verify the result
420 if (!confirmation)
421 {
422 log_error("combuf_event_callback_function invocation failure\n");
423 return TEST_FAIL;
424 }
425 return CL_SUCCESS;
426 }
427
428 //--------------------------------------------------------------------------
RunWaitForEvent__anon7d9a26a30111::CommandBufferEventSync429 cl_int RunWaitForEvent()
430 {
431 std::vector<cl_int> output_data(num_elements);
432
433 // if out-of-order queue requested it is necessary to secure proper
434 // order of all commands
435 std::vector<cl_event *> event_ptrs = { nullptr };
436 InitInOrderEvents(event_ptrs);
437
438 cl_int error =
439 clEnqueueFillBuffer(queue, in_mem, &pattern_pri, sizeof(cl_int), 0,
440 data_size(), 0, nullptr, event_ptrs[0]);
441 test_error(error, "clEnqueueFillBuffer failed");
442
443 error = clEnqueueCommandBufferKHR(
444 0, nullptr, command_buffer, wait_count, event_ptrs[0], &test_event);
445 test_error(error, "clEnqueueCommandBufferKHR failed");
446
447 error = clWaitForEvents(1, &test_event);
448 test_error(error, "clWaitForEvents failed");
449
450 error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
451 output_data.data(), 0, nullptr, nullptr);
452 test_error(error, "clEnqueueReadBuffer failed");
453
454 error = clFinish(queue);
455 test_error(error, "clFinish failed");
456
457 // verify the result - result buffer must contain initial pattern
458 for (size_t i = 0; i < num_elements; i++)
459 {
460 CHECK_VERIFICATION_ERROR(pattern_pri, output_data[i], i);
461 }
462 return CL_SUCCESS;
463 }
464
465 //--------------------------------------------------------------------------
RunWaitForEvents__anon7d9a26a30111::CommandBufferEventSync466 cl_int RunWaitForEvents()
467 {
468 std::vector<cl_int> output_data(num_elements);
469 clEventWrapper test_events[2];
470
471 // if out-of-order queue requested it is necessary to secure proper
472 // order of all commands
473 std::vector<cl_event *> event_ptrs = { nullptr, nullptr };
474 InitInOrderEvents(event_ptrs);
475
476 // record other command buffer
477 cl_int error = RecordCommandBuffer(command_buffer_sec, kernel_sec);
478 test_error(error, "RecordCommandBuffer failed");
479
480 error =
481 clEnqueueFillBuffer(queue, in_mem_sec, &pattern_pri, sizeof(cl_int),
482 0, data_size(), 0, nullptr, event_ptrs[0]);
483 test_error(error, "clEnqueueFillBuffer failed");
484
485 error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer_sec,
486 wait_count, event_ptrs[0],
487 &test_events[0]);
488 test_error(error, "clEnqueueCommandBufferKHR failed");
489
490 error = clEnqueueFillBuffer(queue, in_mem, &pattern_sec, sizeof(cl_int),
491 0, data_size(), 0, nullptr, event_ptrs[1]);
492 test_error(error, "clEnqueueFillBuffer failed");
493
494 error =
495 clEnqueueCommandBufferKHR(0, nullptr, command_buffer, wait_count,
496 event_ptrs[1], &test_events[1]);
497 test_error(error, "clEnqueueCommandBufferKHR failed");
498
499 cl_event wait_list[] = { test_events[0], test_events[1] };
500 error = clWaitForEvents(2, wait_list);
501 test_error(error, "clWaitForEvents failed");
502
503 error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
504 output_data.data(), 0, nullptr, nullptr);
505 test_error(error, "clEnqueueReadBuffer failed");
506
507 error = clFinish(queue);
508 test_error(error, "clFinish failed");
509
510 // verify the result - result buffer must contain initial pattern
511 for (size_t i = 0; i < num_elements; i++)
512 {
513 CHECK_VERIFICATION_ERROR(pattern_sec, output_data[i], i);
514 }
515 return CL_SUCCESS;
516 }
517
518 //--------------------------------------------------------------------------
RunCombufWaitForRegular__anon7d9a26a30111::CommandBufferEventSync519 cl_int RunCombufWaitForRegular()
520 {
521 // if out-of-order queue requested it is necessary to secure proper
522 // order of commands
523 std::vector<cl_event *> event_ptrs = { nullptr };
524 InitInOrderEvents(event_ptrs);
525
526 cl_int error =
527 clEnqueueFillBuffer(queue, in_mem, &pattern_pri, sizeof(cl_int), 0,
528 data_size(), 0, nullptr, &test_event);
529 test_error(error, "clEnqueueFillBuffer failed");
530
531 error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 1,
532 &test_event, event_ptrs[0]);
533 test_error(error, "clEnqueueCommandBufferKHR failed");
534
535 std::vector<cl_int> output_data(num_elements);
536 error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
537 output_data.data(), wait_count,
538 event_ptrs[0], nullptr);
539 test_error(error, "clEnqueueReadBuffer failed");
540
541 error = clFinish(queue);
542 test_error(error, "clFinish failed");
543
544 // verify the result - result buffer must contain initial pattern
545 for (size_t i = 0; i < num_elements; i++)
546 {
547 CHECK_VERIFICATION_ERROR(pattern_pri, output_data[i], i);
548 }
549
550 return CL_SUCCESS;
551 }
552
553 //--------------------------------------------------------------------------
RunCombufWaitForSecQueueCombuf__anon7d9a26a30111::CommandBufferEventSync554 cl_int RunCombufWaitForSecQueueCombuf()
555 {
556 // if out-of-order queue requested it is necessary to secure proper
557 // order of all commands
558 std::vector<cl_event *> event_ptrs = { nullptr, nullptr };
559 InitInOrderEvents(event_ptrs);
560
561 cl_int error = CL_SUCCESS;
562
563 // create secondary command queue and command buffer
564 clCommandQueueWrapper queue_sec =
565 clCreateCommandQueue(context, device, 0, &error);
566 test_error(error, "Unable to create command queue to test with");
567
568 command_buffer_sec =
569 clCreateCommandBufferKHR(1, &queue_sec, nullptr, &error);
570 test_error(error, "clCreateCommandBufferKHR failed");
571
572 // record secondary command buffer
573 error = RecordCommandBuffer(command_buffer_sec, kernel);
574 test_error(error, "RecordCommandBuffer failed");
575
576 // process secondary queue
577 error =
578 clEnqueueFillBuffer(queue_sec, in_mem, &pattern_pri, sizeof(cl_int),
579 0, data_size(), 0, nullptr, nullptr);
580 test_error(error, "clEnqueueFillBuffer failed");
581
582 error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer_sec, 0,
583 nullptr, &test_event);
584 test_error(error,
585 "clEnqueueCommandBufferKHR in secondary queue failed");
586
587 // process primary queue
588 error = clEnqueueFillBuffer(queue, in_mem, &pattern_pri, sizeof(cl_int),
589 0, data_size(), 0, nullptr, event_ptrs[0]);
590 test_error(error, "clEnqueueFillBuffer failed");
591
592 cl_event wait_list[] = { test_event,
593 event_ptrs[0] != nullptr ? *event_ptrs[0]
594 : nullptr };
595 error =
596 clEnqueueCommandBufferKHR(0, nullptr, command_buffer,
597 1 + wait_count, wait_list, event_ptrs[1]);
598 test_error(error, "clEnqueueCommandBufferKHR failed");
599
600 std::vector<cl_int> output_data(num_elements);
601 error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
602 output_data.data(), wait_count,
603 event_ptrs[1], nullptr);
604 test_error(error, "clEnqueueReadBuffer failed");
605
606 error = clFlush(queue);
607 test_error(error, "clFlush failed");
608
609 error = clFinish(queue_sec);
610 test_error(error, "clFinish failed");
611
612 error = clFinish(queue);
613 test_error(error, "clFinish failed");
614
615 // verify the result - result buffer must contain initial pattern
616 for (size_t i = 0; i < num_elements; i++)
617 {
618 CHECK_VERIFICATION_ERROR(pattern_pri, output_data[i], i);
619 }
620 return CL_SUCCESS;
621 }
622
623
624 //--------------------------------------------------------------------------
RunUserEventWait__anon7d9a26a30111::CommandBufferEventSync625 cl_int RunUserEventWait()
626 {
627 // if out-of-order queue requested it is necessary to secure proper
628 // order of all commands
629 std::vector<cl_event *> event_ptrs = { nullptr, nullptr };
630 InitInOrderEvents(event_ptrs);
631
632 cl_int error = CL_SUCCESS;
633 clEventWrapper user_event = clCreateUserEvent(context, &error);
634 test_error(error, "clCreateUserEvent failed");
635
636 const cl_int pattern = 42;
637 error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
638 data_size(), 0, nullptr, event_ptrs[0]);
639 test_error(error, "clEnqueueFillBuffer failed");
640
641 cl_event wait_list[] = { user_event,
642 event_ptrs[0] != nullptr ? *event_ptrs[0]
643 : nullptr };
644 error =
645 clEnqueueCommandBufferKHR(0, nullptr, command_buffer,
646 wait_count + 1, wait_list, event_ptrs[1]);
647 test_error(error, "clEnqueueCommandBufferKHR failed");
648
649 std::vector<cl_int> output_data(num_elements);
650 error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
651 output_data.data(), wait_count,
652 event_ptrs[1], nullptr);
653 test_error(error, "clEnqueueReadBuffer failed");
654
655 error = clSetUserEventStatus(user_event, CL_COMPLETE);
656 test_error(error, "clSetUserEventStatus failed");
657
658 error = clFinish(queue);
659 test_error(error, "clFinish failed");
660
661 for (size_t i = 0; i < num_elements; i++)
662 {
663 CHECK_VERIFICATION_ERROR(pattern, output_data[i], i);
664 }
665
666 return CL_SUCCESS;
667 }
668
669 //--------------------------------------------------------------------------
RunUserEventsWait__anon7d9a26a30111::CommandBufferEventSync670 cl_int RunUserEventsWait()
671 {
672 // if out-of-order queue requested it is necessary to secure proper
673 // order of all commands
674 std::vector<cl_event *> event_ptrs = { nullptr, nullptr };
675 InitInOrderEvents(event_ptrs);
676
677 cl_int error = CL_SUCCESS;
678 std::vector<clEventWrapper> user_events(user_event_num);
679
680 for (size_t i = 0; i < user_event_num; i++)
681 {
682 user_events[i] = clCreateUserEvent(context, &error);
683 test_error(error, "clCreateUserEvent failed");
684 }
685
686 error = clEnqueueFillBuffer(queue, in_mem, &pattern_pri, sizeof(cl_int),
687 0, data_size(), 0, nullptr, event_ptrs[0]);
688 test_error(error, "clEnqueueFillBuffer failed");
689
690 std::vector<cl_event> wait_list(user_event_num + wait_count);
691 for (size_t i = 0; i < user_event_num; i++)
692 {
693 wait_list[i] = user_events[i];
694 }
695 if (out_of_order_requested) wait_list[user_event_num] = *event_ptrs[0];
696
697 error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer,
698 user_event_num + wait_count,
699 &wait_list.front(), event_ptrs[1]);
700 test_error(error, "clEnqueueCommandBufferKHR failed");
701
702 std::vector<cl_int> output_data(num_elements);
703 error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
704 output_data.data(), wait_count,
705 event_ptrs[1], nullptr);
706 test_error(error, "clEnqueueReadBuffer failed");
707
708 for (size_t i = 0; i < user_event_num; i++)
709 {
710 error = clSetUserEventStatus(user_events[i], CL_COMPLETE);
711 test_error(error, "clSetUserEventStatus failed");
712 }
713
714 error = clFinish(queue);
715 test_error(error, "clFinish failed");
716
717 for (size_t i = 0; i < num_elements; i++)
718 {
719 CHECK_VERIFICATION_ERROR(pattern_pri, output_data[i], i);
720 }
721 return CL_SUCCESS;
722 }
723
724 //--------------------------------------------------------------------------
RunUserEventCallback__anon7d9a26a30111::CommandBufferEventSync725 cl_int RunUserEventCallback()
726 {
727 // if out-of-order queue requested it is necessary to secure proper
728 // order of all commands
729 std::vector<cl_event *> event_ptrs = { nullptr, nullptr };
730 InitInOrderEvents(event_ptrs);
731
732 cl_int error = CL_SUCCESS;
733 clEventWrapper user_event = clCreateUserEvent(context, &error);
734 test_error(error, "clCreateUserEvent failed");
735
736 error = clEnqueueFillBuffer(queue, in_mem, &pattern_pri, sizeof(cl_int),
737 0, data_size(), 0, nullptr, event_ptrs[0]);
738 test_error(error, "clEnqueueFillBuffer failed");
739
740 cl_event wait_list[] = { user_event,
741 event_ptrs[0] != nullptr ? *event_ptrs[0]
742 : nullptr };
743 error =
744 clEnqueueCommandBufferKHR(0, nullptr, command_buffer,
745 wait_count + 1, wait_list, event_ptrs[1]);
746 test_error(error, "clEnqueueCommandBufferKHR failed");
747
748 bool confirmation = false;
749 error =
750 clSetEventCallback(user_event, CL_COMPLETE,
751 combuf_event_callback_function, &confirmation);
752 test_error(error, "clSetEventCallback failed");
753
754 error = clSetUserEventStatus(user_event, CL_COMPLETE);
755 test_error(error, "clSetUserEventStatus failed");
756
757 std::vector<cl_int> output_data(num_elements);
758 error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
759 output_data.data(), wait_count,
760 event_ptrs[1], nullptr);
761 test_error(error, "clEnqueueReadBuffer failed");
762
763 error = clFinish(queue);
764 test_error(error, "clFinish failed");
765
766 // verify the result
767 if (!confirmation)
768 {
769 log_error("combuf_event_callback_function invocation failure\n");
770 return TEST_FAIL;
771 }
772 return CL_SUCCESS;
773 }
774
775 //--------------------------------------------------------------------------
776
777 clCommandBufferWrapper command_buffer_sec;
778 clKernelWrapper kernel_sec;
779 clMemWrapper in_mem_sec, out_mem_sec, off_mem_sec;
780 clEventWrapper test_event;
781
782 std::vector<clEventWrapper> in_order_events;
783
784 const cl_int pattern_pri = 0xA;
785 const cl_int pattern_sec = 0xB;
786 const cl_int wait_count = out_of_order_requested ? 1 : 0;
787
788 const cl_int user_event_num = 3;
789 };
790
791 } // anonymous namespace
792
793 // helper macros
794 #define IN_ORDER_MSG(name) #name " test with in-order command queue"
795 #define OUT_OF_ORDER_MSG(name) #name " test with out-of-order command queue"
796 #define test_status_val(code, msg) \
797 { \
798 if (code == TEST_FAIL) \
799 { \
800 print_failure_error(code, TEST_PASS, msg " failed\n"); \
801 return TEST_FAIL; \
802 } \
803 else if (code == TEST_SKIP) \
804 { \
805 log_info(msg " skipped\n"); \
806 } \
807 }
808
809 //--------------------------------------------------------------------------
810 // return-events test cases for regular queue
test_regular_wait_for_command_buffer(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)811 int test_regular_wait_for_command_buffer(cl_device_id device,
812 cl_context context,
813 cl_command_queue queue,
814 int num_elements)
815 {
816 int status = TEST_PASS;
817 // The approach here is that test scenario which involves out-of-order
818 // command queue may be skipped without breaking in-order queue test.
819 // out-of-order command queue test
820 status = MakeAndRunTest<
821 CommandBufferEventSync<EventMode::RET_REGULAR_WAIT_FOR_COMBUF, true>>(
822 device, context, queue, num_elements);
823 test_status_val(status,
824 OUT_OF_ORDER_MSG(EventMode::RET_REGULAR_WAIT_FOR_COMBUF));
825
826 // in-order command queue test
827 status = MakeAndRunTest<
828 CommandBufferEventSync<EventMode::RET_REGULAR_WAIT_FOR_COMBUF, false>>(
829 device, context, queue, num_elements);
830 test_status_val(status,
831 IN_ORDER_MSG(EventMode::RET_REGULAR_WAIT_FOR_COMBUF));
832
833 return status;
834 }
835
test_command_buffer_wait_for_command_buffer(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)836 int test_command_buffer_wait_for_command_buffer(cl_device_id device,
837 cl_context context,
838 cl_command_queue queue,
839 int num_elements)
840 {
841 int status = TEST_PASS;
842 // out-of-order command queue test
843 status = MakeAndRunTest<
844 CommandBufferEventSync<EventMode::RET_COMBUF_WAIT_FOR_COMBUF, true>>(
845 device, context, queue, num_elements);
846 test_status_val(status,
847 OUT_OF_ORDER_MSG(EventMode::RET_COMBUF_WAIT_FOR_COMBUF));
848
849 // in-order command queue test
850 status = MakeAndRunTest<
851 CommandBufferEventSync<EventMode::RET_COMBUF_WAIT_FOR_COMBUF, false>>(
852 device, context, queue, num_elements);
853 test_status_val(status,
854 IN_ORDER_MSG(EventMode::RET_COMBUF_WAIT_FOR_COMBUF));
855
856 return status;
857 }
858
test_command_buffer_wait_for_sec_command_buffer(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)859 int test_command_buffer_wait_for_sec_command_buffer(cl_device_id device,
860 cl_context context,
861 cl_command_queue queue,
862 int num_elements)
863 {
864 int status = TEST_PASS;
865 // out-of-order command queue test
866 status = MakeAndRunTest<CommandBufferEventSync<
867 EventMode::RET_COMBUF_WAIT_FOR_SEC_COMBUF, true>>(device, context,
868 queue, num_elements);
869 test_status_val(
870 status, OUT_OF_ORDER_MSG(EventMode::RET_COMBUF_WAIT_FOR_SEC_COMBUF));
871
872 // in-order command queue test
873 status = MakeAndRunTest<CommandBufferEventSync<
874 EventMode::RET_COMBUF_WAIT_FOR_SEC_COMBUF, false>>(device, context,
875 queue, num_elements);
876 test_status_val(status,
877 IN_ORDER_MSG(EventMode::RET_COMBUF_WAIT_FOR_SEC_COMBUF));
878
879 return status;
880 }
881
test_return_event_callback(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)882 int test_return_event_callback(cl_device_id device, cl_context context,
883 cl_command_queue queue, int num_elements)
884 {
885 int status = TEST_PASS;
886 // out-of-order command queue test
887 status = MakeAndRunTest<
888 CommandBufferEventSync<EventMode::RET_EVENT_CALLBACK, true>>(
889 device, context, queue, num_elements);
890 test_status_val(status, OUT_OF_ORDER_MSG(EventMode::RET_EVENT_CALLBACK));
891
892 // in-order command queue test
893 status = MakeAndRunTest<
894 CommandBufferEventSync<EventMode::RET_EVENT_CALLBACK, false>>(
895 device, context, queue, num_elements);
896 test_status_val(status, IN_ORDER_MSG(EventMode::RET_EVENT_CALLBACK));
897
898 return status;
899 }
900
test_clwaitforevents_single(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)901 int test_clwaitforevents_single(cl_device_id device, cl_context context,
902 cl_command_queue queue, int num_elements)
903 {
904 int status = TEST_PASS;
905 // out-of-order command queue test
906 status = MakeAndRunTest<
907 CommandBufferEventSync<EventMode::RET_CLWAITFOREVENTS_SINGLE, true>>(
908 device, context, queue, num_elements);
909 test_status_val(status,
910 OUT_OF_ORDER_MSG(EventMode::RET_CLWAITFOREVENTS_SINGLE));
911
912 // in-order command queue test
913 status = MakeAndRunTest<
914 CommandBufferEventSync<EventMode::RET_CLWAITFOREVENTS_SINGLE, false>>(
915 device, context, queue, num_elements);
916 test_status_val(status,
917 IN_ORDER_MSG(EventMode::RET_CLWAITFOREVENTS_SINGLE));
918
919 return status;
920 }
921
test_clwaitforevents(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)922 int test_clwaitforevents(cl_device_id device, cl_context context,
923 cl_command_queue queue, int num_elements)
924 {
925 int status = TEST_PASS;
926 // out-of-order command queue test
927 status = MakeAndRunTest<
928 CommandBufferEventSync<EventMode::RET_CLWAITFOREVENTS, true>>(
929 device, context, queue, num_elements);
930 test_status_val(status, OUT_OF_ORDER_MSG(EventMode::RET_CLWAITFOREVENTS));
931
932 // in-order command queue test
933 status = MakeAndRunTest<
934 CommandBufferEventSync<EventMode::RET_CLWAITFOREVENTS, false>>(
935 device, context, queue, num_elements);
936 test_status_val(status, IN_ORDER_MSG(EventMode::RET_CLWAITFOREVENTS));
937
938 return status;
939 }
940
test_command_buffer_wait_for_regular(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)941 int test_command_buffer_wait_for_regular(cl_device_id device,
942 cl_context context,
943 cl_command_queue queue,
944 int num_elements)
945 {
946 int status = TEST_PASS;
947 // out-of-order command queue test
948 status = MakeAndRunTest<
949 CommandBufferEventSync<EventMode::RET_COMBUF_WAIT_FOR_REGULAR, true>>(
950 device, context, queue, num_elements);
951 test_status_val(status,
952 OUT_OF_ORDER_MSG(EventMode::RET_COMBUF_WAIT_FOR_REGULAR));
953
954 // in-order command queue test
955 status = MakeAndRunTest<
956 CommandBufferEventSync<EventMode::RET_COMBUF_WAIT_FOR_REGULAR, false>>(
957 device, context, queue, num_elements);
958 test_status_val(status,
959 IN_ORDER_MSG(EventMode::RET_COMBUF_WAIT_FOR_REGULAR));
960
961 return status;
962 }
963
test_wait_for_sec_queue_event(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)964 int test_wait_for_sec_queue_event(cl_device_id device, cl_context context,
965 cl_command_queue queue, int num_elements)
966 {
967 int status = TEST_PASS;
968 // out-of-order command queue test
969 status = MakeAndRunTest<
970 CommandBufferEventSync<EventMode::RET_WAIT_FOR_SEC_QUEUE_EVENT, true>>(
971 device, context, queue, num_elements);
972 test_status_val(status,
973 OUT_OF_ORDER_MSG(EventMode::RET_WAIT_FOR_SEC_QUEUE_EVENT));
974
975 // in-order command queue test
976 status = MakeAndRunTest<
977 CommandBufferEventSync<EventMode::RET_WAIT_FOR_SEC_QUEUE_EVENT, false>>(
978 device, context, queue, num_elements);
979 test_status_val(status,
980 IN_ORDER_MSG(EventMode::RET_WAIT_FOR_SEC_QUEUE_EVENT));
981
982 return status;
983 }
984
985 //--------------------------------------------------------------------------
986 // user-events test cases
987
test_user_event_wait(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)988 int test_user_event_wait(cl_device_id device, cl_context context,
989 cl_command_queue queue, int num_elements)
990 {
991 int status = TEST_PASS;
992 // out-of-order command queue test
993 status = MakeAndRunTest<
994 CommandBufferEventSync<EventMode::USER_EVENT_WAIT, true>>(
995 device, context, queue, num_elements);
996 test_status_val(status, OUT_OF_ORDER_MSG(EventMode::USER_EVENT_WAIT));
997
998 // in-order command queue test
999 status = MakeAndRunTest<
1000 CommandBufferEventSync<EventMode::USER_EVENT_WAIT, false>>(
1001 device, context, queue, num_elements);
1002 test_status_val(status, IN_ORDER_MSG(EventMode::USER_EVENT_WAIT));
1003
1004 return status;
1005 }
1006
test_user_events_wait(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)1007 int test_user_events_wait(cl_device_id device, cl_context context,
1008 cl_command_queue queue, int num_elements)
1009 {
1010 int status = TEST_PASS;
1011 // out-of-order command queue test
1012 status = MakeAndRunTest<
1013 CommandBufferEventSync<EventMode::USER_EVENTS_WAIT, true>>(
1014 device, context, queue, num_elements);
1015 test_status_val(status, OUT_OF_ORDER_MSG(EventMode::USER_EVENTS_WAIT));
1016
1017 // in-order command queue test
1018 status = MakeAndRunTest<
1019 CommandBufferEventSync<EventMode::USER_EVENTS_WAIT, false>>(
1020 device, context, queue, num_elements);
1021 test_status_val(status, IN_ORDER_MSG(EventMode::USER_EVENTS_WAIT));
1022
1023 return status;
1024 }
1025
test_user_event_callback(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)1026 int test_user_event_callback(cl_device_id device, cl_context context,
1027 cl_command_queue queue, int num_elements)
1028 {
1029 int status = TEST_PASS;
1030 // out-of-order command queue test
1031 status = MakeAndRunTest<
1032 CommandBufferEventSync<EventMode::USER_EVENT_CALLBACK, true>>(
1033 device, context, queue, num_elements);
1034 test_status_val(status, OUT_OF_ORDER_MSG(EventMode::USER_EVENT_CALLBACK));
1035
1036 // in-order command queue test
1037 status = MakeAndRunTest<
1038 CommandBufferEventSync<EventMode::USER_EVENT_CALLBACK, false>>(
1039 device, context, queue, num_elements);
1040 test_status_val(status, IN_ORDER_MSG(EventMode::USER_EVENT_CALLBACK));
1041
1042 return status;
1043 }
1044