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