Some comments. -----Original Message----- From: Beignet [mailto:[email protected]] On Behalf Of [email protected] Sent: Monday, May 05, 2014 6:09 AM To: [email protected] Cc: Luo, Xionghu Subject: [Beignet] [PATCH 2/2] add [opencl-1.2] API clEnqueueBarrierWithWaitList.
From: Luo <[email protected]> API clEnqueueMarkerWithWaitList patch didn't push the latest, update in this patch; the difference between clEnqueueMarkerWithWaitList and this API is that this API would block later enqueued calls, so added a barrier_events queue to manager barrier's wait list. Signed-off-by: Luo <[email protected]> --- src/cl_api.c | 22 +++++++- src/cl_command_queue.c | 66 +++++++++++++++++++++-- src/cl_command_queue.h | 9 ++-- src/cl_enqueue.h | 1 + src/cl_event.c | 144 +++++++++++++++++++++++++++++++++++++------------ src/cl_event.h | 6 +++ 6 files changed, 206 insertions(+), 42 deletions(-) diff --git a/src/cl_api.c b/src/cl_api.c index 9c22819..8902665 100644 --- a/src/cl_api.c +++ b/src/cl_api.c @@ -2753,8 +2753,28 @@ 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); + if(event == NULL) { + err = CL_INVALID_VALUE; + goto error; + } >>>>>>>>>>>event can be NULL per spec 1.2. + 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 6a699c0..c754ad5 100644 --- a/src/cl_command_queue.c +++ b/src/cl_command_queue.c @@ -492,18 +492,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 40c272c..b79d63a 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 cb612eb..0b22485 100644 --- a/src/cl_enqueue.h +++ b/src/cl_enqueue.h @@ -41,6 +41,7 @@ typedef enum { EnqueueNDRangeKernel, EnqueueNativeKernel, EnqueueMarker, + enqueueBarrier, >>>>>>>It is better use EnqueueBarrier. EnqueueFillBuffer, EnqueueInvalid } enqueue_type; diff --git a/src/cl_event.c b/src/cl_event.c index 1230581..079c98d 100644 --- a/src/cl_event.c +++ b/src/cl_event.c @@ -231,7 +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) { + 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; } @@ -259,6 +266,7 @@ void cl_event_new_enqueue_callback(cl_event event, user_event *user_events, *u_ev; cl_command_queue queue = event->queue; cl_int i; + cl_int err = CL_SUCCESS; GET_QUEUE_THREAD_GPGPU(data->queue); /* Allocate and initialize the structure itself */ @@ -271,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) @@ -286,10 +294,7 @@ void cl_event_new_enqueue_callback(cl_event event, } /* Insert the user event to enqueue_callback's wait_user_events */ - TRY_ALLOC_NO_ERR (u_ev, CALLOC(user_event)); - u_ev->event = queue->wait_events[i]; - u_ev->next = cb->wait_user_events; - cb->wait_user_events = u_ev; + TRY(cl_event_insert_user_event, &cb->wait_user_events, + queue->wait_events[i]); } } @@ -311,11 +316,11 @@ void cl_event_new_enqueue_callback(cl_event event, node->next = cb; } /* Insert the user event to enqueue_callback's wait_user_events */ - TRY_ALLOC_NO_ERR (u_ev, CALLOC(user_event)); - u_ev->event = event_wait_list[i]; - u_ev->next = cb->wait_user_events; - cb->wait_user_events = u_ev; + 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,11 +339,11 @@ void cl_event_new_enqueue_callback(cl_event event, } /* Insert the user event to enqueue_callback's wait_user_events */ - TRY_ALLOC_NO_ERR (u_ev, CALLOC(user_event)); - u_ev->event = user_events->event; - u_ev->next = cb->wait_user_events; - cb->wait_user_events = u_ev; + 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; } } @@ -458,6 +463,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, @@ -492,29 +498,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; @@ -528,6 +524,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; @@ -555,3 +586,50 @@ cl_int cl_event_get_timestamp(cl_event event, cl_profiling_info param_name) } return CL_INVALID_VALUE; } + +cl_int cl_event_insert_user_event(user_event** p_u_ev, cl_event event) +{ + user_event * u_iter = *p_u_ev; + user_event * u_ev; + + while(u_iter) + { + if(u_iter->event == event) + return CL_SUCCESS; + u_iter = u_iter->next; + } + + TRY_ALLOC_NO_ERR (u_ev, CALLOC(user_event)); u_ev->event = event; + u_ev->next = *p_u_ev; *p_u_ev = u_ev; + + + return CL_SUCCESS; +error: + return CL_FALSE; +} + +cl_int cl_event_remove_user_event(user_event** p_u_ev, cl_event event) +{ + user_event * u_iter = *p_u_ev; + user_event * u_prev = *p_u_ev; + + while(u_iter){ + if(u_iter->event == event ){ + if(u_iter == *p_u_ev){ + *p_u_ev = u_iter->next; + } + cl_free(u_iter); + break; + }else{ + u_prev->next = u_iter->next; + cl_free(u_iter); + break; >>>>>>Why do you also free and break when u_iter->event != event? + } + u_prev = u_iter; + u_iter = u_iter->next; + } + + return CL_SUCCESS; +} diff --git a/src/cl_event.h b/src/cl_event.h index 5a78a8d..bd8a5c7 100644 --- a/src/cl_event.h +++ b/src/cl_event.h @@ -91,7 +91,13 @@ 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*/ +cl_int cl_event_insert_user_event(user_event** p_u_ev, cl_event event); +/*remove the user event*/ cl_int +cl_event_remove_user_event(user_event** p_u_ev, cl_event event); #endif /* __CL_EVENT_H__ */ -- 1.8.1.2 _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
