[Beignet] [Patch V2 3/3] OCL20: add svm enqueue apis and svm's sub buffer support.

Song, Ruiling ruiling.song at intel.com
Mon Nov 16 23:15:13 PST 2015


The patchset LGTM.

Thanks!
Ruilng

> -----Original Message-----
> From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of
> Yang Rong
> Sent: Tuesday, November 10, 2015 3:52 PM
> To: beignet at lists.freedesktop.org
> Cc: Yang, Rong R <rong.r.yang at intel.com>
> Subject: [Beignet] [Patch V2 3/3] OCL20: add svm enqueue apis and svm's
> sub buffer support.
> 
> Signed-off-by: Yang Rong <rong.r.yang at intel.com>
> ---
>  src/cl_api.c     | 154
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/cl_context.c |   5 +-
>  src/cl_context.h |   2 +-
>  src/cl_enqueue.c |  65 +++++++++++++++++++++++
>  src/cl_enqueue.h |   9 ++++
>  src/cl_khr_icd.c |   6 +--
>  6 files changed, 235 insertions(+), 6 deletions(-)
> 
> diff --git a/src/cl_api.c b/src/cl_api.c
> index 134870d..c5cb67a 100644
> --- a/src/cl_api.c
> +++ b/src/cl_api.c
> @@ -599,6 +599,63 @@ error:
>  }
> 
>  cl_int
> +clEnqueueSVMFree (cl_command_queue command_queue,
> +                  cl_uint num_svm_pointers,
> +                  void *svm_pointers[],
> +                  void (CL_CALLBACK *pfn_free_func)( cl_command_queue queue,
> +                                                     cl_uint num_svm_pointers,
> +                                                     void *svm_pointers[],
> +                                                     void *user_data),
> +                  void *user_data,
> +                  cl_uint num_events_in_wait_list,
> +                  const cl_event *event_wait_list,
> +                  cl_event *event)
> +{
> +  cl_int err = CL_SUCCESS;
> +  cl_int i = 0;
> +  void** pointers = NULL;
> +  enqueue_data *data, defer_enqueue_data = { 0 };
> +  CHECK_QUEUE(command_queue);
> +
> +  if(num_svm_pointers == 0 || svm_pointers == NULL) {
> +    err = CL_INVALID_VALUE;
> +    goto error;
> +  }
> +  for(i=0; i<num_svm_pointers; i++) {
> +    if(svm_pointers[i] == NULL) {
> +      err = CL_INVALID_VALUE;
> +      goto error;
> +    }
> +  }
> +
> +  TRY(cl_event_check_waitlist, num_events_in_wait_list, event_wait_list,
> event, command_queue->ctx);
> +
> +  pointers = malloc(num_svm_pointers * sizeof(void *));
> +  if(UNLIKELY(pointers == NULL)) {
> +    err = CL_OUT_OF_HOST_MEMORY;
> +    goto error;
> +  }
> +  memcpy(pointers, svm_pointers, num_svm_pointers * sizeof(void *));
> +
> +  data = &defer_enqueue_data;
> +  data->type      = EnqueueSVMFree;
> +  data->queue     = command_queue;
> +  data->pointers  = pointers;
> +  data->free_func = pfn_free_func;
> +  data->size      = num_svm_pointers;
> +  data->ptr       = user_data;
> +
> +  if(handle_events(command_queue, num_events_in_wait_list,
> event_wait_list,
> +                   event, data, CL_COMMAND_SVM_FREE) ==
> CL_ENQUEUE_EXECUTE_IMM) {
> +    err = cl_enqueue_handle(event ? *event : NULL, data);
> +    if(event) cl_event_set_status(*event, CL_COMPLETE);
> +  }
> +
> +error:
> +  return err;
> +}
> +
> +cl_int
>  clEnqueueSVMMap (cl_command_queue command_queue,
>                   cl_bool blocking_map,
>                   cl_map_flags map_flags,
> @@ -620,6 +677,8 @@ clEnqueueSVMMap (cl_command_queue
> command_queue,
> 
>    clEnqueueMapBuffer(command_queue, buffer, blocking_map, map_flags,
> 0, size,
>                       num_events_in_wait_list, event_wait_list, event, &err);
> +  if(event)
> +    (*event)->type = CL_COMMAND_SVM_MAP;
>  error:
>    return err;
>  }
> @@ -643,11 +702,106 @@ clEnqueueSVMUnmap (cl_command_queue
> command_queue,
> 
>    err = clEnqueueUnmapMemObject(command_queue, buffer, svm_ptr,
>                                  num_events_in_wait_list, event_wait_list, event);
> +  if(event)
> +    (*event)->type = CL_COMMAND_SVM_UNMAP;
> +
> +error:
> +  return err;
> +}
> +
> +cl_int clEnqueueSVMMemcpy (cl_command_queue command_queue,
> +                           cl_bool blocking_copy,
> +                           void *dst_ptr,
> +                           const void *src_ptr,
> +                           size_t size,
> +                           cl_uint num_events_in_wait_list,
> +                           const cl_event *event_wait_list,
> +                           cl_event *event)
> +{
> +  cl_int err = CL_SUCCESS;
> +  enqueue_data *data, defer_enqueue_data = { 0 };
> +
> +  if(UNLIKELY(dst_ptr == NULL || src_ptr == NULL || size == 0 )) {
> +    err = CL_INVALID_VALUE;
> +    goto error;
> +  }
> +
> +  if(((size_t)src_ptr < (size_t)dst_ptr && ((size_t)src_ptr + size >
> (size_t)dst_ptr)) ||
> +     ((size_t)dst_ptr < (size_t)src_ptr && ((size_t)dst_ptr + size >
> (size_t)src_ptr))) {
> +    err = CL_MEM_COPY_OVERLAP;
> +    goto error;
> +  }
> +
> +  TRY(cl_event_check_waitlist, num_events_in_wait_list, event_wait_list,
> event, command_queue->ctx);
> +
> +  data = &defer_enqueue_data;
> +  data->type         = EnqueueSVMMemCopy;
> +  data->queue        = command_queue;
> +  data->ptr          = dst_ptr;
> +  data->const_ptr    = src_ptr;
> +  data->size         = size;
> +
> +  if(handle_events(command_queue, num_events_in_wait_list,
> event_wait_list,
> +                   event, data, CL_COMMAND_SVM_MEMCPY) ==
> CL_ENQUEUE_EXECUTE_IMM) {
> +    err = cl_enqueue_handle(event ? *event : NULL, data);
> +    if(event) cl_event_set_status(*event, CL_COMPLETE);
> +  }
> 
>  error:
>    return err;
>  }
> 
> +cl_int clEnqueueSVMMemFill (cl_command_queue command_queue,
> +                            void *svm_ptr,
> +                            const void *pattern,
> +                            size_t pattern_size,
> +                            size_t size,
> +                            cl_uint num_events_in_wait_list,
> +                            const cl_event *event_wait_list,
> +                            cl_event *event)
> +{
> +  cl_int err = CL_SUCCESS;
> +  enqueue_data *data, defer_enqueue_data = { 0 };
> +
> +  CHECK_QUEUE(command_queue);
> +  if(UNLIKELY(svm_ptr == NULL ||
> +             ((size_t)svm_ptr & (pattern_size - 1)) != 0)) {
> +    err = CL_INVALID_VALUE;
> +    goto error;
> +  }
> +
> +  if(UNLIKELY(pattern == NULL ||
> +             (pattern_size & (pattern_size - 1)) != 0 ||
> +              pattern_size > 128)) {
> +    err = CL_INVALID_VALUE;
> +    goto error;
> +  }
> +
> +  if(UNLIKELY(size == 0 ||
> +             (size % pattern_size) != 0)) {
> +    err = CL_INVALID_VALUE;
> +    goto error;
> +  }
> +
> +  TRY(cl_event_check_waitlist, num_events_in_wait_list, event_wait_list,
> event, command_queue->ctx);
> +
> +  data = &defer_enqueue_data;
> +  data->type         = EnqueueSVMMemFill;
> +  data->queue        = command_queue;
> +  data->ptr          = svm_ptr;
> +  data->const_ptr    = pattern;
> +  data->pattern_size = pattern_size;
> +  data->size         = size;
> +
> +  if(handle_events(command_queue, num_events_in_wait_list,
> event_wait_list,
> +                   event, data, CL_COMMAND_SVM_MEMFILL) ==
> CL_ENQUEUE_EXECUTE_IMM) {
> +    err = cl_enqueue_handle(event ? *event : NULL, data);
> +    if(event) cl_event_set_status(*event, CL_COMPLETE);
> +  }
> +
> +error:
> +  return err;
> +}
> 
>  cl_mem
>  clCreateImage2D(cl_context              context,
> diff --git a/src/cl_context.c b/src/cl_context.c
> index 3fcdb63..6bdf272 100644
> --- a/src/cl_context.c
> +++ b/src/cl_context.c
> @@ -330,12 +330,13 @@ unlock:
>  }
> 
>  cl_mem
> -cl_context_get_svm_from_ptr(cl_context ctx, void * p)
> +cl_context_get_svm_from_ptr(cl_context ctx, const void * p)
>  {
>    cl_mem buf = ctx->svm_buffers;
>    while(buf) {
>      assert(buf->host_ptr && buf->is_svm);
> -    if(buf->host_ptr == p)
> +    if((size_t)buf->host_ptr <= (size_t)p &&
> +       (size_t)p < ((size_t)buf->host_ptr + buf->size))
>        return buf;
>      buf = buf->next;
>    }
> diff --git a/src/cl_context.h b/src/cl_context.h
> index 365ec32..8c462b1 100644
> --- a/src/cl_context.h
> +++ b/src/cl_context.h
> @@ -171,6 +171,6 @@ extern cl_kernel
> cl_context_get_static_kernel_from_bin(cl_context ctx, cl_int in
>                    const char * str_kernel, size_t size, const char * str_option);
> 
>  /* Get the SVM from pointer, return NULL if pointer is not from SVM */
> -extern cl_mem cl_context_get_svm_from_ptr(cl_context ctx, void *p);
> +extern cl_mem cl_context_get_svm_from_ptr(cl_context ctx, const void
> *p);
>  #endif /* __CL_CONTEXT_H__ */
> 
> diff --git a/src/cl_enqueue.c b/src/cl_enqueue.c
> index 371b2d4..4fea6f9 100644
> --- a/src/cl_enqueue.c
> +++ b/src/cl_enqueue.c
> @@ -443,6 +443,65 @@ error:
>    return err;
>  }
> 
> +cl_int cl_enqueue_svm_free(enqueue_data *data) {
> +  int i;
> +  void **pointers = data->pointers;
> +  uint num_svm_ptrs = data->size;
> +
> +  if(data->free_func) {
> +    data->free_func(data->queue, num_svm_ptrs, pointers, data->ptr);
> +  } else {
> +    for(i=0; i<num_svm_ptrs; i++)
> +      cl_mem_svm_delete(data->queue->ctx, pointers[i]);
> +  }
> +
> +  free(pointers);
> +  return CL_SUCCESS;
> +}
> +
> +cl_int cl_enqueue_svm_mem_copy(enqueue_data *data) {
> +  cl_mem mem;
> +  size_t size = data->size;
> +  const char* src_ptr = (const char *)data->const_ptr;
> +  char *dst_ptr = (char *)data->ptr;
> +  int i;
> +
> +  if((mem = cl_context_get_svm_from_ptr(data->queue->ctx, data-
> >ptr)) != NULL) {
> +      dst_ptr = (char *)cl_mem_map_auto(mem, 1);
> +  }
> +
> +  if((mem = cl_context_get_svm_from_ptr(data->queue->ctx, data-
> >const_ptr)) != NULL) {
> +      src_ptr = (const char *)cl_mem_map_auto(mem, 0);
> +  }
> +
> +  for(i=0; i<size; i++) {
> +    dst_ptr[i] = src_ptr[i];
> +  }
> +
> +  return CL_SUCCESS;
> +}
> +
> +cl_int cl_enqueue_svm_mem_fill(enqueue_data *data) {
> +  cl_mem mem;
> +  size_t size = data->size;
> +  size_t pattern_size = data->pattern_size;
> +  const char* pattern = (const char *)data->const_ptr;
> +  char *ptr = (char *)data->ptr;
> +  int i, j;
> +
> +  if((mem = cl_context_get_svm_from_ptr(data->queue->ctx, data-
> >ptr)) != NULL) {
> +      ptr = (char *)cl_mem_map_auto(mem, 1);
> +  }
> +
> +  for(i=0; i<size; ) {
> +    for(j=0; j<pattern_size; j++) {
> +      ptr[i++] = pattern[j];
> +    }
> +  }
> +
> +  return CL_SUCCESS;
> +}
> +
>  cl_int cl_enqueue_handle(cl_event event, enqueue_data* data)
>  {
>    /* if need profiling, add the submit timestamp here. */
> @@ -481,6 +540,12 @@ cl_int cl_enqueue_handle(cl_event event,
> enqueue_data* data)
>        return cl_event_flush(event);
>      case EnqueueNativeKernel:
>        return cl_enqueue_native_kernel(data);
> +    case EnqueueSVMFree:
> +      return cl_enqueue_svm_free(data);
> +    case EnqueueSVMMemCopy:
> +      return cl_enqueue_svm_mem_copy(data);
> +    case EnqueueSVMMemFill:
> +      return cl_enqueue_svm_mem_fill(data);
>      case EnqueueMigrateMemObj:
>      default:
>        return CL_SUCCESS;
> diff --git a/src/cl_enqueue.h b/src/cl_enqueue.h
> index 09305af..faa85d2 100644
> --- a/src/cl_enqueue.h
> +++ b/src/cl_enqueue.h
> @@ -45,6 +45,9 @@ typedef enum {
>    EnqueueFillBuffer,
>    EnqueueFillImage,
>    EnqueueMigrateMemObj,
> +  EnqueueSVMFree,
> +  EnqueueSVMMemCopy,
> +  EnqueueSVMMemFill,
>    EnqueueInvalid
>  } enqueue_type;
> 
> @@ -66,7 +69,13 @@ typedef struct _enqueue_data {
>    const cl_mem*     mem_list;         /* mem_list of clEnqueueNativeKernel */
>    uint8_t           unsync_map;       /* Indicate the clEnqueueMapBuffer/Image is
> unsync map */
>    uint8_t           write_map;        /* Indicate if the clEnqueueMapBuffer is write
> enable */
> +  void **           pointers;         /* The svm_pointers of clEnqueueSVMFree  */
> +  size_t            pattern_size;     /* the pattern_size of clEnqueueSVMMemFill
> */
>    void (*user_func)(void *);          /* pointer to a host-callable user function */
> +  void (CL_CALLBACK *free_func)( cl_command_queue queue,
> +                                 cl_uint num_svm_pointers,
> +                                 void *svm_pointers[],
> +                                 void *user_data);  /* pointer to pfn_free_func of
> clEnqueueSVMFree */
>  } enqueue_data;
> 
>  /* Do real enqueue commands */
> diff --git a/src/cl_khr_icd.c b/src/cl_khr_icd.c
> index 0894d61..73d1924 100644
> --- a/src/cl_khr_icd.c
> +++ b/src/cl_khr_icd.c
> @@ -177,9 +177,9 @@ struct _cl_icd_dispatch const cl_khr_icd_dispatch = {
>    (void *) NULL /* clGetPipeInfo */,
>    clSVMAlloc,
>    clSVMFree,
> -  (void *) NULL /* clEnqueueSVMFree */,
> -  (void *) NULL /* clEnqueueSVMMemcpy */,
> -  (void *) NULL /* clEnqueueSVMMemFill */,
> +  (void *) clEnqueueSVMFree,
> +  (void *) clEnqueueSVMMemcpy,
> +  (void *) clEnqueueSVMMemFill,
>    (void *) clEnqueueSVMMap,
>    (void *) clEnqueueSVMUnmap,
>    (void *) NULL /* clCreateSamplerWithProperties */,
> --
> 2.1.4
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list