// // 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) { 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 } /* 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) { 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) { 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