diff options
author | Luo <xionghu.luo@intel.com> | 2014-06-13 11:17:34 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2014-06-13 16:58:40 +0800 |
commit | f01bbc99fb4e26a4a923bea80f9e78dc5542b9aa (patch) | |
tree | 6f23daa3a2b22730e07549a41e5c43b7c58bf8a8 | |
parent | 6caeef0ebb89cd97a88baf7c06ab28c1df37e0fa (diff) |
add [opencl-1.2] API clEnqueueBarrierWithWaitList.
This command blocks command execution, that is, any following commands
enqueued after it do not execute until it completes;
API clEnqueueMarkerWithWaitList patch didn't push the latest, update in
this patch.
Reviewed-by: "Yang, Rong R" <rong.r.yang@intel.com>
Signed-off-by: Luo <xionghu.luo@intel.com>
Conflicts:
src/cl_event.c
-rw-r--r-- | src/cl_api.c | 19 | ||||
-rw-r--r-- | src/cl_command_queue.c | 66 | ||||
-rw-r--r-- | src/cl_command_queue.h | 9 | ||||
-rw-r--r-- | src/cl_enqueue.h | 1 | ||||
-rw-r--r-- | src/cl_event.c | 84 | ||||
-rw-r--r-- | src/cl_event.h | 2 |
6 files changed, 148 insertions, 33 deletions
diff --git a/src/cl_api.c b/src/cl_api.c index 5ca83749..705e6002 100644 --- a/src/cl_api.c +++ b/src/cl_api.c @@ -2837,8 +2837,25 @@ clEnqueueBarrier(cl_command_queue command_queue) { cl_int err = CL_SUCCESS; CHECK_QUEUE(command_queue); - cl_command_queue_set_barrier(command_queue); + cl_event_barrier_with_wait_list(command_queue, 0, NULL, NULL); + +error: + return err; +} + +cl_int +clEnqueueBarrierWithWaitList(cl_command_queue command_queue, + cl_uint num_events_in_wait_list, + const cl_event *event_wait_list, + cl_event *event) +{ + cl_int err = CL_SUCCESS; + CHECK_QUEUE(command_queue); + + TRY(cl_event_check_waitlist, num_events_in_wait_list, event_wait_list, event, command_queue->ctx); + + cl_event_barrier_with_wait_list(command_queue, num_events_in_wait_list, event_wait_list, event); error: return err; } diff --git a/src/cl_command_queue.c b/src/cl_command_queue.c index 15b0ead1..1bc97ac6 100644 --- a/src/cl_command_queue.c +++ b/src/cl_command_queue.c @@ -506,18 +506,74 @@ cl_command_queue_remove_event(cl_command_queue queue, cl_event event) if(i == queue->wait_events_num) return; - if(queue->barrier_index >= i) - queue->barrier_index -= 1; - for(; i<queue->wait_events_num-1; i++) { queue->wait_events[i] = queue->wait_events[i+1]; } queue->wait_events_num -= 1; } +#define DEFAULT_WAIT_EVENTS_SIZE 16 LOCAL void -cl_command_queue_set_barrier(cl_command_queue queue) +cl_command_queue_insert_barrier_event(cl_command_queue queue, cl_event event) { - queue->barrier_index = queue->wait_events_num; + cl_int i=0; + cl_event *new_list; + + assert(queue != NULL); + if(queue->barrier_events == NULL) { + queue->barrier_events_size = DEFAULT_WAIT_EVENTS_SIZE; + TRY_ALLOC_NO_ERR (queue->barrier_events, CALLOC_ARRAY(cl_event, queue->barrier_events_size)); + } + + for(i=0; i<queue->barrier_events_num; i++) { + if(queue->barrier_events[i] == event) + return; //is in the barrier_events, need to insert + } + + if(queue->barrier_events_num < queue->barrier_events_size) { + queue->barrier_events[queue->barrier_events_num++] = event; + return; + } + + //barrier_events_num == barrier_events_size, array is full + queue->barrier_events_size *= 2; + TRY_ALLOC_NO_ERR (new_list, CALLOC_ARRAY(cl_event, queue->barrier_events_size)); + memcpy(new_list, queue->barrier_events, sizeof(cl_event)*queue->barrier_events_num); + cl_free(queue->barrier_events); + queue->barrier_events = new_list; + queue->barrier_events[queue->barrier_events_num++] = event; + return; + +exit: + return; +error: + if(queue->barrier_events) + cl_free(queue->barrier_events); + queue->barrier_events = NULL; + queue->barrier_events_size = 0; + queue->barrier_events_num = 0; + goto exit; + } +LOCAL void +cl_command_queue_remove_barrier_event(cl_command_queue queue, cl_event event) +{ + cl_int i=0; + + if(queue->barrier_events_num == 0) + return; + + for(i=0; i<queue->barrier_events_num; i++) { + if(queue->barrier_events[i] == event) + break; + } + + if(i == queue->barrier_events_num) + return; + + for(; i<queue->barrier_events_num-1; i++) { + queue->barrier_events[i] = queue->barrier_events[i+1]; + } + queue->barrier_events_num -= 1; +} diff --git a/src/cl_command_queue.h b/src/cl_command_queue.h index 40c272c5..b79d63ad 100644 --- a/src/cl_command_queue.h +++ b/src/cl_command_queue.h @@ -34,10 +34,12 @@ struct _cl_command_queue { uint64_t magic; /* To identify it as a command queue */ volatile int ref_n; /* We reference count this object */ cl_context ctx; /* Its parent context */ + cl_event* barrier_events; /* Point to array of non-complete user events that block this command queue */ + cl_int barrier_events_num; /* Number of Non-complete user events */ + cl_int barrier_events_size; /* The size of array that wait_events point to */ cl_event* wait_events; /* Point to array of non-complete user events that block this command queue */ cl_int wait_events_num; /* Number of Non-complete user events */ cl_int wait_events_size; /* The size of array that wait_events point to */ - cl_int barrier_index; /* Indicate event count in wait_events as barrier events */ cl_event last_event; /* The last event in the queue, for enqueue mark used */ cl_command_queue_properties props; /* Queue properties */ cl_command_queue prev, next; /* We chain the command queues together */ @@ -95,8 +97,9 @@ extern void cl_command_queue_insert_event(cl_command_queue, cl_event); /* Remove a user event from command's wait_events */ extern void cl_command_queue_remove_event(cl_command_queue, cl_event); -/* Set the barrier index */ -extern void cl_command_queue_set_barrier(cl_command_queue); +extern void cl_command_queue_insert_barrier_event(cl_command_queue queue, cl_event event); + +extern void cl_command_queue_remove_barrier_event(cl_command_queue queue, cl_event event); #endif /* __CL_COMMAND_QUEUE_H__ */ diff --git a/src/cl_enqueue.h b/src/cl_enqueue.h index 99c75ecc..1960cc27 100644 --- a/src/cl_enqueue.h +++ b/src/cl_enqueue.h @@ -41,6 +41,7 @@ typedef enum { EnqueueNDRangeKernel, EnqueueNativeKernel, EnqueueMarker, + EnqueueBarrier, EnqueueFillBuffer, EnqueueInvalid } enqueue_type; diff --git a/src/cl_event.c b/src/cl_event.c index 26756ece..5dccfd9b 100644 --- a/src/cl_event.c +++ b/src/cl_event.c @@ -231,10 +231,14 @@ cl_int cl_event_wait_events(cl_uint num_events_in_wait_list, const cl_event *eve } } - if(queue && queue->barrier_index > 0) { - for(j=0; j<queue->wait_events_num; j++){ - cl_event_add_ref(queue->wait_events[j]); //add defer enqueue's wait event reference - } + if(queue && queue->barrier_events_num ) { + if(num_events_in_wait_list == 0){ + for(j=0; j<queue->wait_events_num; j++) + cl_event_add_ref(queue->wait_events[j]); //add defer enqueue's wait event reference + }else{ + for(j=0; j<num_events_in_wait_list; j++) + cl_event_add_ref(event_wait_list[j]); //add defer enqueue's wait event reference + } return CL_ENQUEUE_EXECUTE_DEFER; } @@ -275,8 +279,8 @@ void cl_event_new_enqueue_callback(cl_event event, cb->next = NULL; cb->wait_user_events = NULL; - if(queue && queue->barrier_index > 0) { - for(i=0; i<queue->barrier_index; i++) { + if(queue && queue->barrier_events_num > 0) { + for(i=0; i<queue->barrier_events_num; i++) { /* Insert the enqueue_callback to user event list */ node = queue->wait_events[i]->waits_head; if(node == NULL) @@ -314,6 +318,9 @@ void cl_event_new_enqueue_callback(cl_event event, /* Insert the user event to enqueue_callback's wait_user_events */ TRY(cl_event_insert_user_event, &cb->wait_user_events, event_wait_list[i]); cl_command_queue_insert_event(event->queue, event_wait_list[i]); + if(data->type == EnqueueBarrier){ + cl_command_queue_insert_barrier_event(event->queue, event_wait_list[i]); + } } else if(event_wait_list[i]->enqueue_cb != NULL) { user_events = event_wait_list[i]->enqueue_cb->wait_user_events; while(user_events != NULL) { @@ -334,6 +341,9 @@ void cl_event_new_enqueue_callback(cl_event event, /* Insert the user event to enqueue_callback's wait_user_events */ TRY(cl_event_insert_user_event, &cb->wait_user_events, user_events->event); cl_command_queue_insert_event(event->queue, user_events->event); + if(data->type == EnqueueBarrier){ + cl_command_queue_insert_barrier_event(event->queue, user_events->event); + } user_events = user_events->next; } } @@ -430,6 +440,7 @@ void cl_event_set_status(cl_event event, cl_int status) //remove user event frome enqueue_cb's ctx cl_command_queue_remove_event(enqueue_cb->event->queue, event); + cl_command_queue_remove_barrier_event(enqueue_cb->event->queue, event); /* All user events complete, now wait enqueue events */ ret = cl_event_wait_events(enqueue_cb->num_events, enqueue_cb->wait_list, @@ -464,29 +475,19 @@ cl_int cl_event_marker_with_wait_list(cl_command_queue queue, const cl_event *event_wait_list, cl_event* event) { - enqueue_data data; - cl_uint i = 0; + enqueue_data data = { 0 }; *event = cl_event_new(queue->ctx, queue, CL_COMMAND_MARKER, CL_TRUE); if(event == NULL) return CL_OUT_OF_HOST_MEMORY; - //insert the input events to queue - for(i=0; i<num_events_in_wait_list; i++) { - if(event_wait_list[i]->type==CL_COMMAND_USER) { - cl_command_queue_insert_event(queue, event_wait_list[i]); - }else if(event_wait_list[i]->enqueue_cb != NULL) { - user_event* user_events = event_wait_list[i]->enqueue_cb->wait_user_events; - - while(user_events != NULL) { - cl_command_queue_insert_event(queue, user_events->event); - user_events = user_events->next; - } - } - } - - //if wait_events_num>0, the marker event need wait queue->wait_events - if(queue->wait_events_num > 0) { +//enqueues a marker command which waits for either a list of events to complete, or if the list is +//empty it waits for all commands previously enqueued in command_queue to complete before it completes. + if(num_events_in_wait_list > 0){ + data.type = EnqueueMarker; + cl_event_new_enqueue_callback(*event, &data, num_events_in_wait_list, event_wait_list); + return CL_SUCCESS; + } else if(queue->wait_events_num > 0) { data.type = EnqueueMarker; cl_event_new_enqueue_callback(*event, &data, queue->wait_events_num, queue->wait_events); return CL_SUCCESS; @@ -500,6 +501,41 @@ cl_int cl_event_marker_with_wait_list(cl_command_queue queue, return CL_SUCCESS; } +cl_int cl_event_barrier_with_wait_list(cl_command_queue queue, + cl_uint num_events_in_wait_list, + const cl_event *event_wait_list, + cl_event* event) +{ + enqueue_data data = { 0 }; + cl_event e; + + e = cl_event_new(queue->ctx, queue, CL_COMMAND_BARRIER, CL_TRUE); + if(e == NULL) + return CL_OUT_OF_HOST_MEMORY; + + if(event != NULL ){ + *event = e; + } +//enqueues a barrier command which waits for either a list of events to complete, or if the list is +//empty it waits for all commands previously enqueued in command_queue to complete before it completes. + if(num_events_in_wait_list > 0){ + data.type = EnqueueBarrier; + cl_event_new_enqueue_callback(e, &data, num_events_in_wait_list, event_wait_list); + return CL_SUCCESS; + } else if(queue->wait_events_num > 0) { + data.type = EnqueueBarrier; + cl_event_new_enqueue_callback(e, &data, queue->wait_events_num, queue->wait_events); + return CL_SUCCESS; + } + + if(queue->last_event && queue->last_event->gpgpu_event) { + cl_gpgpu_event_update_status(queue->last_event->gpgpu_event, 1); + } + + cl_event_set_status(e, CL_COMPLETE); + return CL_SUCCESS; +} + cl_int cl_event_get_timestamp(cl_event event, cl_profiling_info param_name) { cl_ulong ret_val = 0; diff --git a/src/cl_event.h b/src/cl_event.h index 63ff9832..bd8a5c7e 100644 --- a/src/cl_event.h +++ b/src/cl_event.h @@ -91,6 +91,8 @@ void cl_event_set_status(cl_event, cl_int); void cl_event_update_status(cl_event); /* Create the marker event */ cl_int cl_event_marker_with_wait_list(cl_command_queue, cl_uint, const cl_event *, cl_event*); +/* Create the barrier event */ +cl_int cl_event_barrier_with_wait_list(cl_command_queue, cl_uint, const cl_event *, cl_event*); /* Do the event profiling */ cl_int cl_event_get_timestamp(cl_event event, cl_profiling_info param_name); /*insert the user event*/ |