xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/events/test_waitlists.cpp (revision 6467f958c7de8070b317fc65bcb0f6472e388d82)
1 //
2 // Copyright (c) 2017 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 #include "testBase.h"
17 #include "action_classes.h"
18 
19 
20 extern const char *IGetStatusString(cl_int status);
21 
22 #define PRINT_OPS 0
23 
test_waitlist(cl_device_id device,cl_context context,cl_command_queue queue,Action * actionToTest,bool multiple)24 int test_waitlist(cl_device_id device, cl_context context,
25                   cl_command_queue queue, Action *actionToTest, bool multiple)
26 {
27     NDRangeKernelAction actions[2];
28     clEventWrapper events[3];
29     cl_int status[3];
30     cl_int error;
31 
32     if (multiple)
33         log_info("\tExecuting reference event 0, then reference event 1 with "
34                  "reference event 0 in its waitlist, then test event 2 with "
35                  "reference events 0 and 1 in its waitlist.\n");
36     else
37         log_info("\tExecuting reference event 0, then test event 2 with "
38                  "reference event 0 in its waitlist.\n");
39 
40     // Set up the first base action to wait against
41     error = actions[0].Setup(device, context, queue);
42     test_error(error, "Unable to setup base event to wait against");
43 
44     if (multiple)
45     {
46         // Set up a second event to wait against
47         error = actions[1].Setup(device, context, queue);
48         test_error(error, "Unable to setup second base event to wait against");
49     }
50 
51     // Now set up the actual action to test
52     error = actionToTest->Setup(device, context, queue);
53     test_error(error, "Unable to set up test event");
54 
55     // Execute all events now
56     if (PRINT_OPS) log_info("\tExecuting action 0...\n");
57     error = actions[0].Execute(queue, 0, NULL, &events[0]);
58     test_error(error, "Unable to execute first event");
59 
60     if (multiple)
61     {
62         if (PRINT_OPS) log_info("\tExecuting action 1...\n");
63         error = actions[1].Execute(queue, 1, &events[0], &events[1]);
64         test_error(error, "Unable to execute second event");
65     }
66 
67     // Sanity check
68     if (multiple)
69     {
70         if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
71         error = clGetEventInfo(events[1], CL_EVENT_COMMAND_EXECUTION_STATUS,
72                                sizeof(status[1]), &status[1], NULL);
73         test_error(error, "Unable to get event status");
74     }
75     if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
76     error = clGetEventInfo(events[0], CL_EVENT_COMMAND_EXECUTION_STATUS,
77                            sizeof(status[0]), &status[0], NULL);
78     test_error(error, "Unable to get event status");
79 
80     log_info("\t\tEvent status after starting reference events: reference "
81              "event 0: %s, reference event 1: %s, test event 2: %s.\n",
82              IGetStatusString(status[0]),
83              (multiple ? IGetStatusString(status[1]) : "N/A"), "N/A");
84 
85     if ((status[0] == CL_COMPLETE) || (multiple && status[1] == CL_COMPLETE))
86     {
87         log_info("WARNING: Reference event(s) already completed before we "
88                  "could execute test event! Possible that the reference event "
89                  "blocked (implicitly passing)\n");
90         return 0;
91     }
92 
93     if (PRINT_OPS) log_info("\tExecuting action to test...\n");
94     error = actionToTest->Execute(queue, (multiple) ? 2 : 1, &events[0],
95                                   &events[2]);
96     test_error(error, "Unable to execute test event");
97 
98     // Hopefully, the first event is still running
99     if (PRINT_OPS) log_info("\tChecking status of action to test 2...\n");
100     error = clGetEventInfo(events[2], CL_EVENT_COMMAND_EXECUTION_STATUS,
101                            sizeof(status[2]), &status[2], NULL);
102     test_error(error, "Unable to get event status");
103     if (multiple)
104     {
105         if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
106         error = clGetEventInfo(events[1], CL_EVENT_COMMAND_EXECUTION_STATUS,
107                                sizeof(status[1]), &status[1], NULL);
108         test_error(error, "Unable to get event status");
109     }
110     if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
111     error = clGetEventInfo(events[0], CL_EVENT_COMMAND_EXECUTION_STATUS,
112                            sizeof(status[0]), &status[0], NULL);
113     test_error(error, "Unable to get event status");
114 
115     log_info("\t\tEvent status after starting test event: reference event 0: "
116              "%s, reference event 1: %s, test event 2: %s.\n",
117              IGetStatusString(status[0]),
118              (multiple ? IGetStatusString(status[1]) : "N/A"),
119              IGetStatusString(status[2]));
120 
121     if (multiple)
122     {
123         if (status[0] == CL_COMPLETE && status[1] == CL_COMPLETE)
124         {
125             log_info("WARNING: Both events completed, so unable to test "
126                      "further (implicitly passing).\n");
127             clFinish(queue);
128             return 0;
129         }
130 
131         if (status[1] == CL_COMPLETE && status[0] != CL_COMPLETE)
132         {
133             log_error(
134                 "ERROR: Test failed because the second wait event is complete "
135                 "and the first is not.(status: 0: %s and 1: %s)\n",
136                 IGetStatusString(status[0]), IGetStatusString(status[1]));
137             clFinish(queue);
138             return -1;
139         }
140     }
141     else
142     {
143         if (status[0] == CL_COMPLETE)
144         {
145             log_info("WARNING: Reference event completed, so unable to test "
146                      "further (implicitly passing).\n");
147             clFinish(queue);
148             return 0;
149         }
150         if (status[0] != CL_RUNNING && status[0] != CL_QUEUED
151             && status[0] != CL_SUBMITTED)
152         {
153             log_error(
154                 "ERROR: Test failed because first wait event is not currently "
155                 "running, queued, or submitted! (status: 0: %s)\n",
156                 IGetStatusString(status[0]));
157             clFinish(queue);
158             return -1;
159         }
160     }
161 
162     if (status[2] != CL_QUEUED && status[2] != CL_SUBMITTED)
163     {
164         log_error("ERROR: Test event is not waiting to run! (status: 2: %s)\n",
165                   IGetStatusString(status[2]));
166         clFinish(queue);
167         return -1;
168     }
169 
170     // Now wait for the first reference event
171     if (PRINT_OPS) log_info("\tWaiting for action 1 to finish...\n");
172     error = clWaitForEvents(1, &events[0]);
173     test_error(error, "Unable to wait for reference event");
174 
175     // Grab statuses again
176     if (PRINT_OPS) log_info("\tChecking status of action to test 2...\n");
177     error = clGetEventInfo(events[2], CL_EVENT_COMMAND_EXECUTION_STATUS,
178                            sizeof(status[2]), &status[2], NULL);
179     test_error(error, "Unable to get event status");
180     if (multiple)
181     {
182         if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
183         error = clGetEventInfo(events[1], CL_EVENT_COMMAND_EXECUTION_STATUS,
184                                sizeof(status[1]), &status[1], NULL);
185         test_error(error, "Unable to get event status");
186     }
187     if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
188     error = clGetEventInfo(events[0], CL_EVENT_COMMAND_EXECUTION_STATUS,
189                            sizeof(status[0]), &status[0], NULL);
190     test_error(error, "Unable to get event status");
191 
192     log_info("\t\tEvent status after waiting for reference event 0: reference "
193              "event 0: %s, reference event 1: %s, test event 2: %s.\n",
194              IGetStatusString(status[0]),
195              (multiple ? IGetStatusString(status[1]) : "N/A"),
196              IGetStatusString(status[2]));
197 
198     // Sanity
199     if (status[0] != CL_COMPLETE)
200     {
201         log_error("ERROR: Waited for first event but it's not complete "
202                   "(status: 0: %s)\n",
203                   IGetStatusString(status[0]));
204         clFinish(queue);
205         return -1;
206     }
207 
208     // If we're multiple, and the second event isn't complete, then our test
209     // event should still be queued
210     if (multiple && status[1] != CL_COMPLETE)
211     {
212         if (status[1] == CL_RUNNING && status[2] == CL_RUNNING)
213         {
214             log_error("ERROR: Test event and second event are both running.\n");
215             clFinish(queue);
216             return -1;
217         }
218         if (status[2] != CL_QUEUED && status[2] != CL_SUBMITTED)
219         {
220             log_error("ERROR: Test event did not wait for second event before "
221                       "starting! (status of ref: 1: %s, of test: 2: %s)\n",
222                       IGetStatusString(status[1]), IGetStatusString(status[2]));
223             clFinish(queue);
224             return -1;
225         }
226 
227         // Now wait for second event to complete, too
228         if (PRINT_OPS) log_info("\tWaiting for action 1 to finish...\n");
229         error = clWaitForEvents(1, &events[1]);
230         test_error(error, "Unable to wait for second reference event");
231 
232         // Grab statuses again
233         if (PRINT_OPS) log_info("\tChecking status of action to test 2...\n");
234         error = clGetEventInfo(events[2], CL_EVENT_COMMAND_EXECUTION_STATUS,
235                                sizeof(status[2]), &status[2], NULL);
236         test_error(error, "Unable to get event status");
237         if (multiple)
238         {
239             if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
240             error = clGetEventInfo(events[1], CL_EVENT_COMMAND_EXECUTION_STATUS,
241                                    sizeof(status[1]), &status[1], NULL);
242             test_error(error, "Unable to get event status");
243         }
244         if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
245         error = clGetEventInfo(events[0], CL_EVENT_COMMAND_EXECUTION_STATUS,
246                                sizeof(status[0]), &status[0], NULL);
247         test_error(error, "Unable to get event status");
248 
249         log_info(
250             "\t\tEvent status after waiting for reference event 1: reference "
251             "event 0: %s, reference event 1: %s, test event 2: %s.\n",
252             IGetStatusString(status[0]),
253             (multiple ? IGetStatusString(status[1]) : "N/A"),
254             IGetStatusString(status[2]));
255 
256         // Sanity
257         if (status[1] != CL_COMPLETE)
258         {
259             log_error("ERROR: Waited for second reference event but it didn't "
260                       "complete (status: 1: %s)\n",
261                       IGetStatusString(status[1]));
262             clFinish(queue);
263             return -1;
264         }
265     }
266 
267     // At this point, the test event SHOULD be running, but if it completed, we
268     // consider it a pass
269     if (status[2] == CL_COMPLETE)
270     {
271         log_info("WARNING: Test event already completed. Assumed valid.\n");
272         clFinish(queue);
273         return 0;
274     }
275     if (status[2] != CL_RUNNING && status[2] != CL_SUBMITTED
276         && status[2] != CL_QUEUED)
277     {
278         log_error("ERROR: Second event did not start running after reference "
279                   "event(s) completed! (status: 2: %s)\n",
280                   IGetStatusString(status[2]));
281         clFinish(queue);
282         return -1;
283     }
284 
285     // Wait for the test event, then return
286     if (PRINT_OPS) log_info("\tWaiting for action 2 to test to finish...\n");
287     error = clWaitForEvents(1, &events[2]);
288     test_error(error, "Unable to wait for test event");
289 
290     error |= clGetEventInfo(events[2], CL_EVENT_COMMAND_EXECUTION_STATUS,
291                             sizeof(status[2]), &status[2], NULL);
292     test_error(error, "Unable to get event status");
293 
294     log_info("\t\tEvent status after waiting for test event: reference event "
295              "0: %s, reference event 1: %s, test event 2: %s.\n",
296              IGetStatusString(status[0]),
297              (multiple ? IGetStatusString(status[1]) : "N/A"),
298              IGetStatusString(status[2]));
299 
300     // Sanity
301     if (status[2] != CL_COMPLETE)
302     {
303         log_error("ERROR: Test event didn't complete (status: 2: %s)\n",
304                   IGetStatusString(status[2]));
305         clFinish(queue);
306         return -1;
307     }
308 
309     clFinish(queue);
310     return 0;
311 }
312 
313 #define TEST_ACTION(name)                                                      \
314     {                                                                          \
315         name##Action action;                                                   \
316         log_info("-- Testing " #name " (waiting on 1 event)...\n");            \
317         if ((error = test_waitlist(deviceID, context, queue, &action, false))  \
318             != CL_SUCCESS)                                                     \
319             retVal++;                                                          \
320         clFinish(queue);                                                       \
321     }                                                                          \
322     if (error                                                                  \
323         == CL_SUCCESS) /* Only run multiples test if single test passed */     \
324     {                                                                          \
325         name##Action action;                                                   \
326         log_info("-- Testing " #name " (waiting on 2 events)...\n");           \
327         if ((error = test_waitlist(deviceID, context, queue, &action, true))   \
328             != CL_SUCCESS)                                                     \
329             retVal++;                                                          \
330         clFinish(queue);                                                       \
331     }
332 
test_waitlists(cl_device_id deviceID,cl_context context,cl_command_queue oldQueue,int num_elements)333 int test_waitlists(cl_device_id deviceID, cl_context context,
334                    cl_command_queue oldQueue, int num_elements)
335 {
336     cl_int error;
337     int retVal = 0;
338     cl_command_queue_properties props = CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE;
339 
340     if (!checkDeviceForQueueSupport(deviceID, props))
341     {
342         log_info("WARNING: Device does not support out-of-order exec mode; "
343                  "skipping test.\n");
344         return 0;
345     }
346 
347     clCommandQueueWrapper queue =
348         clCreateCommandQueue(context, deviceID, props, &error);
349     test_error(error, "Unable to create out-of-order queue");
350 
351     log_info("\n");
352 
353     TEST_ACTION(NDRangeKernel)
354 
355     TEST_ACTION(ReadBuffer)
356     TEST_ACTION(WriteBuffer)
357     TEST_ACTION(MapBuffer)
358     TEST_ACTION(UnmapBuffer)
359 
360     if (checkForImageSupport(deviceID) == CL_IMAGE_FORMAT_NOT_SUPPORTED)
361     {
362         log_info("\nNote: device does not support images. Skipping remainder "
363                  "of waitlist tests...\n");
364     }
365     else
366     {
367         TEST_ACTION(ReadImage2D)
368         TEST_ACTION(WriteImage2D)
369         TEST_ACTION(CopyImage2Dto2D)
370         TEST_ACTION(Copy2DImageToBuffer)
371         TEST_ACTION(CopyBufferTo2DImage)
372         TEST_ACTION(MapImage)
373 
374         if (checkFor3DImageSupport(deviceID) == CL_IMAGE_FORMAT_NOT_SUPPORTED)
375             log_info("Device does not support 3D images. Skipping remainder of "
376                      "waitlist tests...\n");
377         else
378         {
379             TEST_ACTION(ReadImage3D)
380             TEST_ACTION(WriteImage3D)
381             TEST_ACTION(CopyImage2Dto3D)
382             TEST_ACTION(CopyImage3Dto2D)
383             TEST_ACTION(CopyImage3Dto3D)
384             TEST_ACTION(Copy3DImageToBuffer)
385             TEST_ACTION(CopyBufferTo3DImage)
386         }
387     }
388 
389     return retVal;
390 }
391