[Beignet] [PATCH OCL2.0 1/4] Runtime: Add pipe related APIs

Xiuli Pan xiuli.pan at intel.com
Wed Feb 24 02:58:16 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