The patchset LGTM. Thanks! Ruilng
> -----Original Message----- > From: Beignet [mailto:[email protected]] On Behalf Of > Yang Rong > Sent: Tuesday, November 10, 2015 3:52 PM > To: [email protected] > Cc: Yang, Rong R <[email protected]> > Subject: [Beignet] [Patch V2 3/3] OCL20: add svm enqueue apis and svm's > sub buffer support. > > Signed-off-by: Yang Rong <[email protected]> > --- > 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 > [email protected] > http://lists.freedesktop.org/mailman/listinfo/beignet _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
