diff options
author | Denis Steckelmacher <steckdenis@yahoo.fr> | 2011-08-08 15:40:01 +0200 |
---|---|---|
committer | Denis Steckelmacher <steckdenis@yahoo.fr> | 2011-08-08 15:40:01 +0200 |
commit | fddcc53e44aecd16d284b9c3b8a4eb5a37e752e7 (patch) | |
tree | 239c696c3672f79d2a759ab5de31677c68e69934 | |
parent | 1a80d876947c922873b93a03e2d3b73f57d3468a (diff) |
Test clEnqueueWaitForEvents, Barrier and Marker. Fix bugs.
-rw-r--r-- | src/api/api_enqueue.cpp | 3 | ||||
-rw-r--r-- | src/core/commandqueue.cpp | 30 | ||||
-rw-r--r-- | tests/test_commandqueue.cpp | 144 |
3 files changed, 159 insertions, 18 deletions
diff --git a/src/api/api_enqueue.cpp b/src/api/api_enqueue.cpp index 589c3b6..81ffdd0 100644 --- a/src/api/api_enqueue.cpp +++ b/src/api/api_enqueue.cpp @@ -685,6 +685,9 @@ clEnqueueMarker(cl_command_queue command_queue, if (!command_queue->isA(Coal::Object::T_CommandQueue)) return CL_INVALID_COMMAND_QUEUE; + if (!event) + return CL_INVALID_VALUE; + // Get the events in command_queue unsigned int count; Coal::Event **events = command_queue->events(count); diff --git a/src/core/commandqueue.cpp b/src/core/commandqueue.cpp index 462e777..281e5e6 100644 --- a/src/core/commandqueue.cpp +++ b/src/core/commandqueue.cpp @@ -7,6 +7,7 @@ #include <cstring> #include <cstdlib> #include <ctime> +#include <iostream> using namespace Coal; @@ -146,6 +147,10 @@ void CommandQueue::flush() void CommandQueue::finish() { + // As pushEventsOnDevice doesn't remove SUCCESS events, we may need + // to do that here in order not to be stuck. + cleanEvents(); + // All the queued events must have completed. When they are, they get // deleted from the command queue, so simply wait for it to become empty. pthread_mutex_lock(&p_event_list_mutex); @@ -231,7 +236,7 @@ void CommandQueue::pushEventsOnDevice() // - If we are in-order, only the first event in Event::Queued state can // be pushed - std::list<Event *>::iterator it = p_events.begin(), oldit; + std::list<Event *>::iterator it = p_events.begin(); bool first = true; // We assume that we will flush the command queue (submit all the events) @@ -258,24 +263,12 @@ void CommandQueue::pushEventsOnDevice() break; } - // If we encounter a barrier, check if it's the first in the list - if (event->type() == Event::Barrier) + // Stop if we encounter a barrier that isn't the first event in the list. + if (event->type() == Event::Barrier && !first) { - if (first) - { - // Remove the barrier, we don't need it anymore - oldit = it; - ++it; - - p_events.erase(oldit); - continue; - } - else - { - // We have events to wait, stop - p_flushed = false; - break; - } + // We have events to wait, stop + p_flushed = false; + break; } // Completed events and first barriers are out, it remains real events @@ -490,6 +483,7 @@ bool Event::isDummy() const void Event::setStatus(Status status) { + // TODO: If status < 0, terminate all the events depending on us. pthread_mutex_lock(&p_state_mutex); p_status = status; diff --git a/tests/test_commandqueue.cpp b/tests/test_commandqueue.cpp index 1fac3eb..e361e41 100644 --- a/tests/test_commandqueue.cpp +++ b/tests/test_commandqueue.cpp @@ -809,6 +809,149 @@ START_TEST (test_copy_image_buffer) } END_TEST +START_TEST (test_misc_events) +{ + cl_platform_id platform = 0; + cl_device_id device; + cl_context ctx; + cl_command_queue queue; + cl_int result; + cl_event uevent1, uevent2, marker1, marker2; + + result = clGetDeviceIDs(platform, CL_DEVICE_TYPE_DEFAULT, 1, &device, 0); + fail_if( + result != CL_SUCCESS, + "unable to get the default device" + ); + + ctx = clCreateContext(0, 1, &device, 0, 0, &result); + fail_if( + result != CL_SUCCESS || ctx == 0, + "unable to create a valid context" + ); + + queue = clCreateCommandQueue(ctx, device, 0, &result); + fail_if( + result != CL_SUCCESS || queue == 0, + "cannot create a command queue" + ); + + /* + * This test will build a command queue blocked by an user event. The events + * will be in this order : + * + * -: UserEvent1 + * 0: WaitForEvents1 (wait=UserEvent1) + * 1: Marker1 + * -: UserEvent2 + * 2: WaitForEvents2 (wait=UserEvent2) + * 3: Barrier + * 4: Marker2 (to check the barrier worked) + * + * When the command queue is built, we : + * - Check that Marker1 is Queued (WaitForEvents waits) + * - Set UserEvent1 to Complete + * - Check that Marker1 is Complete (WaitForEvents stopped to wait) + * - Check that Marker2 is Queued (Barrier is there) + * - Set UserEvent2 to Complete + * - Check that Marker2 is Complete (no more barrier) + */ + uevent1 = clCreateUserEvent(ctx, &result); + fail_if( + result != CL_SUCCESS, + "unable to create UserEvent1" + ); + + uevent2 = clCreateUserEvent(ctx, &result); + fail_if( + result != CL_SUCCESS, + "unable to create UserEvent2" + ); + + result = clEnqueueWaitForEvents(queue, 1, &uevent1); + fail_if( + result != CL_SUCCESS, + "unable to enqueue WaitForEvents(UserEvent1)" + ); + + result = clEnqueueMarker(queue, &marker1); + fail_if( + result != CL_SUCCESS, + "unable to enqueue Marker1" + ); + + result = clEnqueueWaitForEvents(queue, 1, &uevent2); + fail_if( + result != CL_SUCCESS, + "unable to enqueue WaitForEvents(UserEvent2)" + ); + + result = clEnqueueBarrier(queue); + fail_if( + result != CL_SUCCESS, + "unable to enqueue Barrier" + ); + + result = clEnqueueMarker(queue, &marker2); + fail_if( + result != CL_SUCCESS, + "unable to enqueue Marker2" + ); + + // Now the checks + cl_int status; + + result = clGetEventInfo(marker1, CL_EVENT_COMMAND_EXECUTION_STATUS, + sizeof(cl_int), &status, 0); + fail_if( + result != CL_SUCCESS || status != CL_QUEUED, + "Marker1 must be Queued" + ); + + result = clSetUserEventStatus(uevent1, CL_COMPLETE); + fail_if( + result != CL_SUCCESS, + "unable to set UserEvent1 to Complete" + ); + + result = clGetEventInfo(marker1, CL_EVENT_COMMAND_EXECUTION_STATUS, + sizeof(cl_int), &status, 0); + fail_if( + result != CL_SUCCESS || status != CL_COMPLETE, + "Marker1 must be Complete" + ); + + result = clGetEventInfo(marker2, CL_EVENT_COMMAND_EXECUTION_STATUS, + sizeof(cl_int), &status, 0); + fail_if( + result != CL_SUCCESS || status != CL_QUEUED, + "Marker2 must be Queued" + ); + + result = clSetUserEventStatus(uevent2, CL_COMPLETE); + fail_if( + result != CL_SUCCESS, + "unable to set UserEvent2 to Complete" + ); + + result = clGetEventInfo(marker2, CL_EVENT_COMMAND_EXECUTION_STATUS, + sizeof(cl_int), &status, 0); + fail_if( + result != CL_SUCCESS || status != CL_COMPLETE, + "Marker2 must be Complete" + ); + + clFinish(queue); + + clReleaseEvent(uevent1); + clReleaseEvent(uevent2); + clReleaseEvent(marker1); + clReleaseEvent(marker2); + clReleaseCommandQueue(queue); + clReleaseContext(ctx); +} +END_TEST + TCase *cl_commandqueue_tcase_create(void) { TCase *tc = NULL; @@ -821,5 +964,6 @@ TCase *cl_commandqueue_tcase_create(void) tcase_add_test(tc, test_copy_buffer); tcase_add_test(tc, test_read_write_image); tcase_add_test(tc, test_copy_image_buffer); + tcase_add_test(tc, test_misc_events); return tc; } |