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