[Beignet] [PATCH V1 1/2] add [opencl-1.2] API clEnqueueBarrierWithWaitList.

Zhigang Gong zhigang.gong at linux.intel.com
Wed May 28 00:19:53 PDT 2014


Just pushed, thanks.

On Wed, May 28, 2014 at 03:01:23AM +0000, Luo, Xionghu wrote:
> Hi Zhigang,
> Just found this patchset is missing. 
> Please push it to opencl-1.2, thanks.
> 
> Luo Xionghu
> Best Regards
> 
> -----Original Message-----
> From: Yang, Rong R 
> Sent: Tuesday, May 06, 2014 4:33 PM
> To: Luo, Xionghu; beignet at lists.freedesktop.org
> Cc: Luo, Xionghu
> Subject: RE: [Beignet] [PATCH V1 1/2] add [opencl-1.2] API clEnqueueBarrierWithWaitList.
> 
> The patchset LGTM. Thanks.
> 
> -----Original Message-----
> From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of xionghu.luo at intel.com
> Sent: Tuesday, May 06, 2014 11:23 AM
> To: beignet at lists.freedesktop.org
> Cc: Luo, Xionghu
> Subject: [Beignet] [PATCH V1 1/2] add [opencl-1.2] API clEnqueueBarrierWithWaitList.
> 
> From: Luo <xionghu.luo at intel.com>
> 
> 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.
> ---
>  src/cl_api.c           |  19 +++++-
>  src/cl_command_queue.c |  66 +++++++++++++++++--
>  src/cl_command_queue.h |   9 ++-
>  src/cl_enqueue.h       |   1 +
>  src/cl_event.c         | 167 ++++++++++++++++++++++++++++++++-----------------
>  src/cl_event.h         |   6 ++
>  6 files changed, 202 insertions(+), 66 deletions(-)
> 
> diff --git a/src/cl_api.c b/src/cl_api.c index 9c22819..ad70b65 100644
> --- a/src/cl_api.c
> +++ b/src/cl_api.c
> @@ -2753,8 +2753,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 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..3593f01 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 1230581..a94541a 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;
>        }
>      }
> @@ -369,7 +374,6 @@ error:
>  void cl_event_set_status(cl_event event, cl_int status)  {
>    user_callback *user_cb;
> -  user_event    *u_ev;
>    cl_int ret, i;
>    cl_event evt;
>  
> @@ -426,29 +430,7 @@ void cl_event_set_status(cl_event event, cl_int status)
>    enqueue_callback *cb, *enqueue_cb = event->waits_head;
>    while(enqueue_cb) {
>      /* Remove this user event in enqueue_cb, update the header if needed. */
> -    u_ev = enqueue_cb->wait_user_events;
> -    user_event * u_prev = NULL;
> -    user_event *tmp =NULL;
> -    while(u_ev) {
> -      if(u_ev && u_ev->event == event) {
> -        if(u_prev){
> -          u_prev->next = u_ev->next;
> -        }
> -        tmp = u_ev;
> -        u_ev = u_ev->next;
> -        cl_free(tmp);
> -      }else{
> -        if(!u_prev){
> -          enqueue_cb->wait_user_events = u_ev;
> -        }
> -        u_prev=u_ev;
> -        u_ev = u_ev->next;
> -      }
> -    }
> -
> -    if(!u_prev){
> -      enqueue_cb->wait_user_events = NULL;
> -    }
> +    cl_event_remove_user_event(&enqueue_cb->wait_user_events, event);
>  
>      /* Still wait on other user events */
>      if(enqueue_cb->wait_user_events != NULL) { @@ -458,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, @@ -492,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;
> @@ -528,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;
> @@ -555,3 +563,48 @@ 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;
> +      }else{
> +        u_prev->next = u_iter->next;
> +      }
> +      cl_free(u_iter);
> +      break;
> +    }
> +    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
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list