[Beignet] [PATCH OCL20 v2 1/4] Runtime: Add pipe related APIs
Xiuli Pan
xiuli.pan at intel.com
Tue Mar 1 04:47:55 UTC 2016
From: Pan Xiuli <xiuli.pan at intel.com>
Add clCreatePipe and clGetPipeInfo
Signed-off-by: Pan Xiuli <xiuli.pan at intel.com>
---
src/cl_api.c | 70 +++++++++++++++++++++++++++++++++++++
src/cl_device_id.c | 3 ++
src/cl_device_id.h | 3 ++
src/cl_gt_device.h | 3 ++
src/cl_khr_icd.c | 4 +--
src/cl_mem.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++
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 c5cb67a..840d57f 100644
--- a/src/cl_api.c
+++ b/src/cl_api.c
@@ -2857,6 +2857,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 b518d48..0652f4a 100644
--- a/src/cl_device_id.c
+++ b/src/cl_device_id.c
@@ -796,6 +796,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 6341362..e57e8e6 100644
--- a/src/cl_device_id.h
+++ b/src/cl_device_id.h
@@ -67,6 +67,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 cf48b6d..06d11db 100644
--- a/src/cl_gt_device.h
+++ b/src/cl_gt_device.h
@@ -55,6 +55,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 73d1924..a8dd3e0 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
(void *) NULL /* clCreateCommandQueueWithProperties */,
- (void *) NULL /* clCreatePipe */,
- (void *) NULL /* clGetPipeInfo */,
+ clCreatePipe,
+ clGetPipeInfo,
clSVMAlloc,
clSVMFree,
(void *) clEnqueueSVMFree,
diff --git a/src/cl_mem.c b/src/cl_mem.c
index 0458259..05aa70f 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 df23345..6e729ac 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,
--
2.5.0
More information about the Beignet
mailing list