diff options
author | Pan Xiuli <xiuli.pan@intel.com> | 2015-11-19 12:51:48 +0800 |
---|---|---|
committer | Yang Rong <rong.r.yang@intel.com> | 2016-03-15 14:57:02 +0800 |
commit | 937dd2f345de430cfdf05aaa0232c415486d174c (patch) | |
tree | bab3856393076f7df90f1b517808243a16b1ce75 | |
parent | 26645f285cabbbf44c61a66606d5676399a2f662 (diff) | |
download | beignet-937dd2f345de430cfdf05aaa0232c415486d174c.tar.gz |
Runtime: Add pipe related APIs
Add clCreatePipe and clGetPipeInfo
Signed-off-by: Pan Xiuli <xiuli.pan@intel.com>
Reviewed-by: Yang Rong <rong.r.yang@intel.com>
-rw-r--r-- | src/cl_api.c | 70 | ||||
-rw-r--r-- | src/cl_device_id.c | 3 | ||||
-rw-r--r-- | src/cl_device_id.h | 3 | ||||
-rw-r--r-- | src/cl_gt_device.h | 3 | ||||
-rw-r--r-- | src/cl_khr_icd.c | 4 | ||||
-rw-r--r-- | src/cl_mem.c | 100 | ||||
-rw-r--r-- | src/cl_mem.h | 21 |
7 files changed, 197 insertions, 7 deletions
diff --git a/src/cl_api.c b/src/cl_api.c index ec5cf4d6..6712fa5c 100644 --- a/src/cl_api.c +++ b/src/cl_api.c @@ -3018,6 +3018,76 @@ error: return err; } +cl_mem clCreatePipe (cl_context context, + cl_mem_flags flags, + cl_uint pipe_packet_size, + cl_uint pipe_max_packets, + const cl_pipe_properties *properties, + cl_int *errcode_ret) +{ + cl_mem mem = NULL; + cl_int err = CL_SUCCESS; + cl_uint device_max_size = 0; + + CHECK_CONTEXT (context); + + if(UNLIKELY((flags & ~(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS)) != 0)) { + err = CL_INVALID_VALUE; + goto error; + } + + if(UNLIKELY(properties != NULL)) { + err = CL_INVALID_VALUE; + goto error; + } + + if(UNLIKELY(pipe_packet_size == 0 || pipe_max_packets == 0)) { + err = CL_INVALID_PIPE_SIZE; + goto error; + } + if ((err = cl_get_device_info(context->device, + CL_DEVICE_PIPE_MAX_PACKET_SIZE, + sizeof(device_max_size), + &device_max_size, + NULL)) != CL_SUCCESS) { + goto error; + } + + if(UNLIKELY(pipe_packet_size > device_max_size)) { + err = CL_INVALID_PIPE_SIZE; + goto error; + } + + if(flags == 0) + flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS; + + mem = cl_mem_new_pipe(context, flags, pipe_packet_size, pipe_max_packets, &err); + +error: + if (errcode_ret) + *errcode_ret = err; + return mem; +} + +cl_int clGetPipeInfo (cl_mem pipe, + cl_pipe_info param_name, + size_t param_value_size, + void *param_value, + size_t *param_value_size_ret) +{ + cl_int err = CL_SUCCESS; + CHECK_MEM(pipe); + + err = cl_get_pipe_info(pipe, + param_name, + param_value_size, + param_value, + param_value_size_ret); + +error: + return err; +} + void * clEnqueueMapBuffer(cl_command_queue command_queue, cl_mem buffer, diff --git a/src/cl_device_id.c b/src/cl_device_id.c index 90177692..a6436a43 100644 --- a/src/cl_device_id.c +++ b/src/cl_device_id.c @@ -797,6 +797,9 @@ cl_get_device_info(cl_device_id device, DECL_FIELD(MAX_PARAMETER_SIZE, max_parameter_size) DECL_FIELD(MEM_BASE_ADDR_ALIGN, mem_base_addr_align) DECL_FIELD(MIN_DATA_TYPE_ALIGN_SIZE, min_data_type_align_size) + DECL_FIELD(MAX_PIPE_ARGS, max_pipe_args) + DECL_FIELD(PIPE_MAX_ACTIVE_RESERVATIONS, pipe_max_active_reservations) + DECL_FIELD(PIPE_MAX_PACKET_SIZE, pipe_max_packet_siz) DECL_FIELD(SINGLE_FP_CONFIG, single_fp_config) DECL_FIELD(HALF_FP_CONFIG, half_fp_config) DECL_FIELD(DOUBLE_FP_CONFIG, double_fp_config) diff --git a/src/cl_device_id.h b/src/cl_device_id.h index 27ed5a5d..f05ab7dc 100644 --- a/src/cl_device_id.h +++ b/src/cl_device_id.h @@ -74,6 +74,9 @@ struct _cl_device_id { size_t max_parameter_size; cl_uint mem_base_addr_align; cl_uint min_data_type_align_size; + cl_uint max_pipe_args; + cl_uint pipe_max_active_reservations; + cl_uint pipe_max_packet_siz; cl_device_fp_config single_fp_config; cl_device_fp_config half_fp_config; cl_device_fp_config double_fp_config; diff --git a/src/cl_gt_device.h b/src/cl_gt_device.h index 7e66c140..041ddaad 100644 --- a/src/cl_gt_device.h +++ b/src/cl_gt_device.h @@ -59,6 +59,9 @@ .max_samplers = 16, .mem_base_addr_align = sizeof(cl_long) * 16 * 8, .min_data_type_align_size = sizeof(cl_long) * 16, +.max_pipe_args = 16, +.pipe_max_active_reservations = 1, +.pipe_max_packet_siz = 1024, .double_fp_config = 0, .global_mem_cache_type = CL_READ_WRITE_CACHE, .max_constant_buffer_size = 128 * 1024 * 1024, diff --git a/src/cl_khr_icd.c b/src/cl_khr_icd.c index 23d54bbc..49e9c47e 100644 --- a/src/cl_khr_icd.c +++ b/src/cl_khr_icd.c @@ -173,8 +173,8 @@ struct _cl_icd_dispatch const cl_khr_icd_dispatch = { #endif #ifdef CL_VERSION_2_0 clCreateCommandQueueWithProperties, - (void *) NULL /* clCreatePipe */, - (void *) NULL /* clGetPipeInfo */, + clCreatePipe, + clGetPipeInfo, clSVMAlloc, clSVMFree, clEnqueueSVMFree, diff --git a/src/cl_mem.c b/src/cl_mem.c index 07fb95e0..0922e0a6 100644 --- a/src/cl_mem.c +++ b/src/cl_mem.c @@ -139,6 +139,40 @@ cl_get_mem_object_info(cl_mem mem, return CL_SUCCESS; } +LOCAL cl_int +cl_get_pipe_info(cl_mem mem, + cl_mem_info param_name, + size_t param_value_size, + void *param_value, + size_t *param_value_size_ret) +{ + _cl_mem_pipe *pipe; + switch(param_name) + { + FIELD_SIZE(PIPE_PACKET_SIZE, cl_uint); + FIELD_SIZE(PIPE_MAX_PACKETS, cl_uint); + default: + return CL_INVALID_VALUE; + } + + if(mem->type != CL_MEM_PIPE_TYPE) + return CL_INVALID_MEM_OBJECT; + + pipe = cl_mem_pipe(mem); + + switch(param_name) + { + case CL_PIPE_PACKET_SIZE: + *((cl_uint *)param_value) = pipe->packet_size; + break; + case CL_PIPE_MAX_PACKETS: + *((cl_uint *)param_value) = pipe->max_packets; + break; + } + + return CL_SUCCESS; +} + #define IS_1D(image) (image->image_type == CL_MEM_OBJECT_IMAGE1D || \ image->image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY || \ image->image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER) @@ -259,6 +293,10 @@ cl_mem_allocate(enum cl_mem_type type, struct _cl_mem_buffer1d_image *buffer1d_image = NULL; TRY_ALLOC(buffer1d_image, CALLOC(struct _cl_mem_buffer1d_image)); mem = &buffer1d_image->base.base; + } else if (type == CL_MEM_PIPE_TYPE) { + _cl_mem_pipe *pipe = NULL; + TRY_ALLOC(pipe, CALLOC(struct _cl_mem_pipe)); + mem = &pipe->base; } else { struct _cl_mem_buffer *buffer = NULL; TRY_ALLOC (buffer, CALLOC(struct _cl_mem_buffer)); @@ -603,6 +641,68 @@ error: goto exit; } +cl_mem cl_mem_new_pipe(cl_context ctx, + cl_mem_flags flags, + cl_uint packet_size, + cl_uint max_packets, + cl_int *errcode_ret) +{ + _cl_mem_pipe* pipe = NULL; + cl_uint *ptr = NULL; + cl_mem mem = NULL; + cl_int err; + cl_uint sz; + if(UNLIKELY((pipe = CALLOC(_cl_mem_pipe)) == NULL)) { + err = CL_OUT_OF_RESOURCES; + goto error; + } + + sz = packet_size * max_packets; + assert(sz != 0); + + /* HSW: Byte scattered Read/Write has limitation that + the buffer size must be a multiple of 4 bytes. */ + sz = ALIGN(sz, 4); + + sz += 128; //The head of pipe is for data struct, and alignment to 128 byte for max data type double16 + + mem = cl_mem_allocate(CL_MEM_PIPE_TYPE, ctx, flags, sz, CL_FALSE,NULL , NULL, &err); + + if (mem == NULL || err != CL_SUCCESS) + goto error; + + ptr = cl_mem_map_auto(mem, 1); + if(ptr == NULL){ + err = CL_OUT_OF_RESOURCES; + goto error; + } + ptr[0] = max_packets; + ptr[1] = packet_size; + ptr[2] = 0; //write ptr + ptr[3] = 0; //read ptr + ptr[4] = 0; //reservation read ptr + ptr[5] = 0; //reservation write ptr + ptr[6] = 0; //packet num + cl_mem_unmap(mem); + + pipe = cl_mem_pipe(mem); + pipe->flags = flags; + pipe->packet_size = packet_size; + pipe->max_packets = max_packets; + + return mem; + +exit: + if (errcode_ret) + *errcode_ret = err; + return mem; +error: + cl_mem_delete(mem); + mem = NULL; + goto exit; + +} + void cl_mem_replace_buffer(cl_mem buffer, cl_buffer new_bo) { cl_buffer_unreference(buffer->bo); diff --git a/src/cl_mem.h b/src/cl_mem.h index df233457..6e729acc 100644 --- a/src/cl_mem.h +++ b/src/cl_mem.h @@ -70,6 +70,7 @@ typedef struct _cl_mem_dstr_cb { enum cl_mem_type { CL_MEM_BUFFER_TYPE, CL_MEM_SUBBUFFER_TYPE, + CL_MEM_PIPE_TYPE, CL_MEM_SVM_TYPE, CL_MEM_IMAGE_TYPE, CL_MEM_GL_IMAGE_TYPE, @@ -99,6 +100,13 @@ typedef struct _cl_mem { size_t offset; /* offset of host_ptr to the page beginning, only for CL_MEM_USE_HOST_PTR*/ } _cl_mem; +typedef struct _cl_mem_pipe { + _cl_mem base; + cl_svm_mem_flags flags; /* Flags specified at the creation time */ + uint32_t packet_size; + uint32_t max_packets; +} _cl_mem_pipe; + typedef struct _cl_mem_svm { _cl_mem base; cl_svm_mem_flags flags; /* Flags specified at the creation time */ @@ -180,11 +188,11 @@ cl_mem_gl_image(cl_mem mem) return (struct _cl_mem_gl_image*)mem; } -inline static struct _cl_mem_buffer * -cl_mem_buffer(cl_mem mem) +inline static struct _cl_mem_pipe * +cl_mem_pipe(cl_mem mem) { - assert(!IS_IMAGE(mem)); - return (struct _cl_mem_buffer *)mem; + assert(mem->type == CL_MEM_PIPE_TYPE); + return (struct _cl_mem_pipe *)mem; } /* Query information about a memory object */ @@ -202,10 +210,13 @@ extern cl_mem cl_mem_new_buffer(cl_context, cl_mem_flags, size_t, void*, cl_int* /* Create a new sub memory object */ extern cl_mem cl_mem_new_sub_buffer(cl_mem, cl_mem_flags, cl_buffer_create_type, const void *, cl_int *); +extern cl_mem cl_mem_new_pipe(cl_context, cl_mem_flags, cl_uint, cl_uint, cl_int *); +/* Query information about a pipe object */ +extern cl_int cl_get_pipe_info(cl_mem, cl_mem_info, size_t, void *, size_t *); + void* cl_mem_svm_allocate(cl_context, cl_svm_mem_flags, size_t, unsigned int); void cl_mem_svm_delete(cl_context, void *svm_pointer); - /* Idem but this is an image */ extern cl_mem cl_mem_new_image(cl_context context, |