• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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