// // Copyright (c) 2017 The Khronos Group Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "testBase.h" #if ! defined( _WIN32 ) #include "unistd.h" // for "sleep" used in the "while (1)" busy wait loop in #endif // test_event_flush const char *sample_long_test_kernel[] = { "__kernel void sample_test(__global float *src, __global int *dst)\n" "{\n" " int tid = get_global_id(0);\n" " int i;\n" "\n" " for( i = 0; i < 10000; i++ )\n" " {\n" " dst[tid] = (int)src[tid] * 3;\n" " }\n" "\n" "}\n" }; int create_and_execute_kernel( cl_context inContext, cl_command_queue inQueue, cl_program *outProgram, cl_kernel *outKernel, cl_mem *streams, unsigned int lineCount, const char **lines, const char *kernelName, cl_event *outEvent ) { size_t threads[1] = { 1000 }, localThreads[1]; int error; if( create_single_kernel_helper( inContext, outProgram, outKernel, lineCount, lines, kernelName ) ) { return -1; } error = get_max_common_work_group_size( inContext, *outKernel, threads[0], &localThreads[0] ); test_error( error, "Unable to get work group size to use" ); streams[0] = clCreateBuffer(inContext, CL_MEM_READ_WRITE, sizeof(cl_float) * 1000, NULL, &error); test_error( error, "Creating test array failed" ); streams[1] = clCreateBuffer(inContext, CL_MEM_READ_WRITE, sizeof(cl_int) * 1000, NULL, &error); test_error( error, "Creating test array failed" ); /* Set the arguments */ error = clSetKernelArg( *outKernel, 0, sizeof( streams[0] ), &streams[0] ); test_error( error, "Unable to set kernel arguments" ); error = clSetKernelArg( *outKernel, 1, sizeof( streams[1] ), &streams[1] ); test_error( error, "Unable to set kernel arguments" ); error = clEnqueueNDRangeKernel(inQueue, *outKernel, 1, NULL, threads, localThreads, 0, NULL, outEvent); test_error( error, "Unable to execute test kernel" ); return 0; } #define SETUP_EVENT( c, q ) \ clProgramWrapper program; \ clKernelWrapper kernel; \ clMemWrapper streams[2]; \ clEventWrapper event; \ int error; \ if( create_and_execute_kernel( c, q, &program, &kernel, &streams[0], 1, sample_long_test_kernel, "sample_test", &event ) ) return -1; #define FINISH_EVENT(_q) clFinish(_q) const char *IGetStatusString( cl_int status ) { static char tempString[ 128 ]; switch( status ) { case CL_COMPLETE: return "CL_COMPLETE"; case CL_RUNNING: return "CL_RUNNING"; case CL_QUEUED: return "CL_QUEUED"; case CL_SUBMITTED: return "CL_SUBMITTED"; default: sprintf( tempString, "", (int)status ); return tempString; } } /* Note: tests clGetEventStatus and clReleaseEvent (implicitly) */ int test_event_get_execute_status( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { cl_int status; SETUP_EVENT( context, queue ); /* Now wait for it to be done */ error = clWaitForEvents( 1, &event ); test_error( error, "Unable to wait for event" ); error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus to wait for event completion failed" ); if( status != CL_COMPLETE ) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus after event complete (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } FINISH_EVENT(queue); return 0; } int test_event_get_info( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { SETUP_EVENT( context, queue ); /* Verify parameters of clGetEventInfo not already tested by other tests */ cl_command_queue otherQueue; size_t size; error = clGetEventInfo( event, CL_EVENT_COMMAND_QUEUE, sizeof( otherQueue ), &otherQueue, &size ); test_error( error, "Unable to get event info!" ); // We can not check if this is the right queue because this is an opaque object. if( size != sizeof( queue ) ) { log_error( "ERROR: Returned command queue size does not validate (expected %d, got %d)\n", (int)sizeof( queue ), (int)size ); return -1; } cl_command_type type; error = clGetEventInfo( event, CL_EVENT_COMMAND_TYPE, sizeof( type ), &type, &size ); test_error( error, "Unable to get event info!" ); if( type != CL_COMMAND_NDRANGE_KERNEL ) { log_error( "ERROR: Returned command type does not validate (expected %d, got %d)\n", (int)CL_COMMAND_NDRANGE_KERNEL, (int)type ); return -1; } if( size != sizeof( type ) ) { log_error( "ERROR: Returned command type size does not validate (expected %d, got %d)\n", (int)sizeof( type ), (int)size ); return -1; } cl_uint count; error = clGetEventInfo( event, CL_EVENT_REFERENCE_COUNT, sizeof( count ), &count, &size ); test_error( error, "Unable to get event info for CL_EVENT_REFERENCE_COUNT!" ); if( size != sizeof( count ) ) { log_error( "ERROR: Returned command type size does not validate (expected %d, got %d)\n", (int)sizeof( type ), (int)size ); return -1; } cl_context testCtx; error = clGetEventInfo( event, CL_EVENT_CONTEXT, sizeof( testCtx ), &testCtx, &size ); test_error( error, "Unable to get event context info!" ); if( size != sizeof( context ) ) { log_error( "ERROR: Returned context size does not validate (expected %d, got %d)\n", (int)sizeof( context ), (int)size ); return -1; } if( testCtx != context ) { log_error( "ERROR: Returned context does not match (expected %p, got %p)\n", (void *)context, (void *)testCtx ); return -1; } FINISH_EVENT(queue); return 0; } int test_event_get_write_array_status( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { cl_mem stream; cl_float testArray[ 1024 * 32 ]; cl_event event; int error; cl_int status; stream = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_float) * 1024 * 32, NULL, &error); test_error( error, "Creating test array failed" ); error = clEnqueueWriteBuffer(queue, stream, CL_FALSE, 0, sizeof(cl_float)*1024*32, (void *)testArray, 0, NULL, &event); test_error( error, "Unable to set testing kernel data" ); /* Now wait for it to be done */ error = clWaitForEvents( 1, &event ); test_error( error, "Unable to wait for event" ); error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus to wait for event completion failed" ); if( status != CL_COMPLETE ) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus after array write complete (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } clReleaseMemObject( stream ); clReleaseEvent( event ); return 0; } int test_event_get_read_array_status( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { cl_mem stream; cl_float testArray[ 1024 * 32 ]; cl_event event; int error; cl_int status; stream = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_float) * 1024 * 32, NULL, &error); test_error( error, "Creating test array failed" ); error = clEnqueueReadBuffer(queue, stream, CL_FALSE, 0, sizeof(cl_float)*1024*32, (void *)testArray, 0, NULL, &event); test_error( error, "Unable to get testing kernel data" ); /* It should still be running... */ error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus didn't work!" ); if( status != CL_RUNNING && status != CL_QUEUED && status != CL_SUBMITTED && status != CL_COMPLETE) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus during array read (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } /* Now wait for it to be done */ error = clWaitForEvents( 1, &event ); test_error( error, "Unable to wait for event" ); error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus to wait for event completion failed" ); if( status != CL_COMPLETE ) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus after array read complete (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } clReleaseMemObject( stream ); clReleaseEvent( event ); return 0; } /* clGetEventStatus not implemented yet */ int test_event_wait_for_execute( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { cl_int status; SETUP_EVENT( context, queue ); /* Now we wait for it to be done, then test the status again */ error = clWaitForEvents( 1, &event ); test_error( error, "Unable to wait for execute event" ); /* Make sure it worked */ error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus didn't work!" ); if( status != CL_COMPLETE ) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus after event complete (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } FINISH_EVENT(queue); return 0; } int test_event_wait_for_array( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { cl_mem streams[2]; cl_float readArray[ 1024 * 32 ]; cl_float writeArray[ 1024 * 32 ]; cl_event events[2]; int error; cl_int status; streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_float) * 1024 * 32, NULL, &error); test_error( error, "Creating test array failed" ); streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_float) * 1024 * 32, NULL, &error); test_error( error, "Creating test array failed" ); error = clEnqueueReadBuffer(queue, streams[0], CL_FALSE, 0, sizeof(cl_float)*1024*32, (void *)readArray, 0, NULL, &events[0]); test_error( error, "Unable to read testing kernel data" ); error = clEnqueueWriteBuffer(queue, streams[1], CL_FALSE, 0, sizeof(cl_float)*1024*32, (void *)writeArray, 0, NULL, &events[1]); test_error( error, "Unable to write testing kernel data" ); /* Both should still be running */ error = clGetEventInfo( events[0], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus didn't work!" ); if( status != CL_RUNNING && status != CL_QUEUED && status != CL_SUBMITTED && status != CL_COMPLETE) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus during array read (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } error = clGetEventInfo( events[1], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus didn't work!" ); if( status != CL_RUNNING && status != CL_QUEUED && status != CL_SUBMITTED && status != CL_COMPLETE) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus during array write (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } /* Now try waiting for both */ error = clWaitForEvents( 2, events ); test_error( error, "Unable to wait for array events" ); /* Double check status on both */ error = clGetEventInfo( events[0], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus didn't work!" ); if( status != CL_COMPLETE ) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus after array read complete (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } error = clGetEventInfo( events[1], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus didn't work!" ); if( status != CL_COMPLETE ) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus after array write complete (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } clReleaseMemObject( streams[0] ); clReleaseMemObject( streams[1] ); clReleaseEvent( events[0] ); clReleaseEvent( events[1] ); return 0; } int test_event_flush( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { int loopCount = 0; cl_int status; SETUP_EVENT( context, queue ); /* Now flush. Note that we can't guarantee this actually lets the op finish, but we can guarantee it's no longer queued */ error = clFlush( queue ); test_error( error, "Unable to flush events" ); /* Make sure it worked */ while (1) { error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus didn't work!" ); if( status != CL_QUEUED ) break; #if ! defined( _WIN32 ) sleep(1); // give it some time here. #else // _WIN32 Sleep(1000); #endif ++loopCount; } /* CL_QUEUED (command has been enqueued in the command-queue), CL_SUBMITTED (enqueued command has been submitted by the host to the device associated with the command-queue), CL_RUNNING (device is currently executing this command), CL_COMPLETE (the command has completed), or Error code given by a negative integer value. (command was abnormally terminated – this may be caused by a bad memory access etc.). */ if(status != CL_COMPLETE && status != CL_SUBMITTED && status != CL_RUNNING && status != CL_COMPLETE) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus after event flush (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } /* Now wait */ error = clFinish( queue ); test_error( error, "Unable to finish events" ); FINISH_EVENT(queue); return 0; } int test_event_finish_execute( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { cl_int status; SETUP_EVENT( context, queue ); /* Now flush and finish all ops */ error = clFinish( queue ); test_error( error, "Unable to finish all events" ); /* Make sure it worked */ error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus didn't work!" ); if( status != CL_COMPLETE ) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus after event complete (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } FINISH_EVENT(queue); return 0; } int test_event_finish_array( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { cl_mem streams[2]; cl_float readArray[ 1024 * 32 ]; cl_float writeArray[ 1024 * 32 ]; cl_event events[2]; int error; cl_int status; streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_float) * 1024 * 32, NULL, &error); test_error( error, "Creating test array failed" ); streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_float) * 1024 * 32, NULL, &error); test_error( error, "Creating test array failed" ); error = clEnqueueReadBuffer(queue, streams[0], CL_FALSE, 0, sizeof(cl_float)*1024*32, (void *)readArray, 0, NULL, &events[0]); test_error( error, "Unable to read testing kernel data" ); error = clEnqueueWriteBuffer(queue, streams[1], CL_FALSE, 0, sizeof(cl_float)*1024*32, (void *)writeArray, 0, NULL, &events[1]); test_error( error, "Unable to write testing kernel data" ); /* Both should still be running */ error = clGetEventInfo( events[0], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus didn't work!" ); if( status != CL_RUNNING && status != CL_QUEUED && status != CL_SUBMITTED && status != CL_COMPLETE) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus during array read (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } error = clGetEventInfo( events[1], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus didn't work!" ); if( status != CL_RUNNING && status != CL_QUEUED && status != CL_SUBMITTED && status != CL_COMPLETE) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus during array write (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } /* Now try finishing all ops */ error = clFinish( queue ); test_error( error, "Unable to finish all events" ); /* Double check status on both */ error = clGetEventInfo( events[0], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus didn't work!" ); if( status != CL_COMPLETE ) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus after array read complete (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } error = clGetEventInfo( events[1], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventStatus didn't work!" ); if( status != CL_COMPLETE ) { log_error( "ERROR: Incorrect status returned from clGetErrorStatus after array write complete (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } clReleaseMemObject( streams[0] ); clReleaseMemObject( streams[1] ); clReleaseEvent( events[0] ); clReleaseEvent( events[1] ); return 0; } #define NUM_EVENT_RUNS 100 int test_event_release_before_done( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { // Create a kernel to run clProgramWrapper program; clKernelWrapper kernel[NUM_EVENT_RUNS]; size_t threads[1] = { 1000 }; cl_event events[NUM_EVENT_RUNS]; cl_int status; clMemWrapper streams[NUM_EVENT_RUNS][2]; int error, i; // Create a kernel if( create_single_kernel_helper( context, &program, &kernel[0], 1, sample_long_test_kernel, "sample_test" ) ) { return -1; } for( i = 1; i < NUM_EVENT_RUNS; i++ ) { kernel[i] = clCreateKernel(program, "sample_test", &error); test_error(error, "Unable to create kernel"); } error = get_max_common_work_group_size( context, kernel[0], 1024, &threads[0] ); test_error( error, "Unable to get work group size to use" ); // Create a set of streams to use as arguments for( i = 0; i < NUM_EVENT_RUNS; i++ ) { streams[i][0] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_float) * threads[0], NULL, &error); streams[i][1] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_int) * threads[0], NULL, &error); if( ( streams[i][0] == NULL ) || ( streams[i][1] == NULL ) ) { log_error( "ERROR: Unable to allocate testing streams" ); return -1; } } // Execute the kernels one by one, hopefully making sure they won't be done by the time we get to the end for( i = 0; i < NUM_EVENT_RUNS; i++ ) { error = clSetKernelArg( kernel[i], 0, sizeof( cl_mem ), &streams[i][0] ); error |= clSetKernelArg( kernel[i], 1, sizeof( cl_mem ), &streams[i][1] ); test_error( error, "Unable to set kernel arguments" ); error = clEnqueueNDRangeKernel( queue, kernel[i], 1, NULL, threads, threads, 0, NULL, &events[i]); test_error( error, "Unable to execute test kernel" ); } // Free all but the last event for( i = 0; i < NUM_EVENT_RUNS - 1; i++ ) { clReleaseEvent( events[ i ] ); } // Get status on the last one, then free it error = clGetEventInfo( events[ NUM_EVENT_RUNS - 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Unable to get event status" ); clReleaseEvent( events[ NUM_EVENT_RUNS - 1 ] ); // Was the status still-running? if( status == CL_COMPLETE ) { log_info( "WARNING: Events completed before they could be released, so test is a null-op. Increase workload and try again." ); } else if( status == CL_RUNNING || status == CL_QUEUED || status == CL_SUBMITTED ) { log_info( "Note: Event status was running or queued when released, so test was good.\n" ); } // If we didn't crash by now, the test succeeded clFinish( queue ); return 0; } int test_event_enqueue_marker( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { cl_int status; SETUP_EVENT( context, queue ); /* Now we queue a marker and wait for that, which--since it queues afterwards--should guarantee the execute finishes too */ clEventWrapper markerEvent; //error = clEnqueueMarker( queue, &markerEvent ); #ifdef CL_VERSION_1_2 error = clEnqueueMarkerWithWaitList(queue, 0, NULL, &markerEvent ); #else error = clEnqueueMarker( queue, &markerEvent ); #endif test_error( error, "Unable to queue marker" ); /* Now we wait for it to be done, then test the status again */ error = clWaitForEvents( 1, &markerEvent ); test_error( error, "Unable to wait for marker event" ); /* Check the status of the first event */ error = clGetEventInfo( event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status ), &status, NULL ); test_error( error, "Calling clGetEventInfo didn't work!" ); if( status != CL_COMPLETE ) { log_error( "ERROR: Incorrect status returned from clGetEventInfo after event complete (%d:%s)\n", status, IGetStatusString( status ) ); return -1; } FINISH_EVENT(queue); return 0; } #ifdef CL_VERSION_1_2 int test_event_enqueue_marker_with_event_list( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { cl_int status; SETUP_EVENT( context, queue ); cl_event event_list[3]={ NULL, NULL, NULL}; size_t threads[1] = { 10 }, localThreads[1]={1}; cl_uint event_count=2; error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[0]); test_error( error, " clEnqueueMarkerWithWaitList 1 " ); error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[1]); test_error( error, " clEnqueueMarkerWithWaitList 2" ); error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, NULL); test_error( error, " clEnqueueMarkerWithWaitList 3" ); // test the case event returned error =clEnqueueMarkerWithWaitList(queue, event_count, event_list, &event_list[2]); test_error( error, " clEnqueueMarkerWithWaitList " ); error = clReleaseEvent(event_list[0]); error |= clReleaseEvent(event_list[1]); test_error( error, "clReleaseEvent" ); error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[0]); test_error( error, " clEnqueueMarkerWithWaitList 1 -1 " ); error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[1]); test_error( error, " clEnqueueMarkerWithWaitList 2-2" ); // test the case event =NULL, caused [CL_INVALID_VALUE] : OpenCL Error : clEnqueueMarkerWithWaitList failed: event is a NULL value error =clEnqueueMarkerWithWaitList(queue, event_count, event_list, NULL); test_error( error, " clEnqueueMarkerWithWaitList " ); error = clReleaseEvent(event_list[0]); error |= clReleaseEvent(event_list[1]); error |= clReleaseEvent(event_list[2]); test_error( error, "clReleaseEvent" ); FINISH_EVENT(queue); return 0; } int test_event_enqueue_barrier_with_event_list( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { cl_int status; SETUP_EVENT( context, queue ); cl_event event_list[3]={ NULL, NULL, NULL}; size_t threads[1] = { 10 }, localThreads[1]={1}; cl_uint event_count=2; error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[0]); test_error( error, " clEnqueueBarrierWithWaitList 1 " ); error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[1]); test_error( error, " clEnqueueBarrierWithWaitList 2" ); error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, NULL); test_error( error, " clEnqueueBarrierWithWaitList 20" ); // test the case event returned error =clEnqueueBarrierWithWaitList(queue, event_count, event_list, &event_list[2]); test_error( error, " clEnqueueBarrierWithWaitList " ); clReleaseEvent(event_list[0]); clReleaseEvent(event_list[1]); error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[0]); test_error( error, " clEnqueueBarrierWithWaitList 1 " ); error= clEnqueueNDRangeKernel( queue,kernel,1,NULL, threads, localThreads, 0, NULL, &event_list[1]); test_error( error, " clEnqueueBarrierWithWaitList 2" ); // test the case event =NULL, caused [CL_INVALID_VALUE] : OpenCL Error : clEnqueueMarkerWithWaitList failed: event is a NULL value error = clEnqueueBarrierWithWaitList(queue, event_count, event_list, NULL); test_error( error, " clEnqueueBarrierWithWaitList " ); clReleaseEvent(event_list[0]); clReleaseEvent(event_list[1]); clReleaseEvent(event_list[2]); FINISH_EVENT(queue); return 0; } #endif