add [opencl-1.2] API clCreateProgramWithBuiltInKernels.
authorLuo <xionghu.luo@intel.com>
Fri, 13 Jun 2014 00:58:16 +0000 (08:58 +0800)
committerZhigang Gong <zhigang.gong@intel.com>
Fri, 13 Jun 2014 05:50:46 +0000 (13:50 +0800)
This API creates a built-in program object for a context, and loads the
built-in kernels into this program object.

v2:
fix the image base index handling issue.

Signed-off-by: Zhigang Gong <zhigang.gong@intel.com>
src/cl_api.c
src/cl_context.c
src/cl_context.h
src/cl_gt_device.h
src/cl_program.c
src/cl_program.h

index b3e2fd5..e607a91 100644 (file)
@@ -826,6 +826,30 @@ error:
     *errcode_ret = err;
   return program;
 }
+
+cl_program
+clCreateProgramWithBuiltInKernels(cl_context           context,
+                                  cl_uint              num_devices,
+                                  const cl_device_id * device_list,
+                                  const char *         kernel_names,
+                                  cl_int *             errcode_ret)
+{
+  cl_program program = NULL;
+  cl_int err = CL_SUCCESS;
+
+  CHECK_CONTEXT (context);
+  INVALID_VALUE_IF (kernel_names == NULL);
+  program = cl_program_create_with_built_in_kernles(context,
+                                                    num_devices,
+                                                    device_list,
+                                                    kernel_names,
+                                                    &err);
+error:
+  if (errcode_ret)
+    *errcode_ret = err;
+  return program;
+}
+
 cl_int
 clRetainProgram(cl_program program)
 {
index a0da7b0..8f42a58 100644 (file)
@@ -206,8 +206,16 @@ cl_context_delete(cl_context ctx)
       cl_program_delete(ctx->internal_prgs[i]);
       ctx->internal_prgs[i] = NULL;
     }
+
+    if (ctx->internel_kernels[i]) {
+      cl_kernel_delete(ctx->built_in_kernels[i]);
+      ctx->built_in_kernels[i] = NULL;
+    }
   }
 
+  cl_program_delete(ctx->built_in_prgs);
+  ctx->built_in_prgs = NULL;
+
   /* All object lists should have been freed. Otherwise, the reference counter
    * of the context cannot be 0
    */
index 65b1728..cba0a0a 100644 (file)
@@ -102,6 +102,8 @@ struct _cl_context {
                                     /* All programs internal used, for example clEnqueuexxx api use */
   cl_kernel  internel_kernels[CL_INTERNAL_KERNEL_MAX];
                                     /* All kernels  for clenqueuexxx api, for example clEnqueuexxx api use */
+  cl_program built_in_prgs;  /*all built-in kernels belongs to this program only*/
+  cl_kernel  built_in_kernels[CL_INTERNAL_KERNEL_MAX];
   uint32_t ver;                     /* Gen version */
   struct _cl_context_prop props;
   cl_context_properties * prop_user; /* a copy of user passed context properties when create context */
index 7e45b4e..3e2502c 100644 (file)
@@ -75,7 +75,29 @@ DECL_INFO_STRING(version, LIBCL_VERSION_STRING)
 DECL_INFO_STRING(profile, "FULL_PROFILE")
 DECL_INFO_STRING(opencl_c_version, LIBCL_C_VERSION_STRING)
 DECL_INFO_STRING(extensions, "")
-DECL_INFO_STRING(built_in_kernels, "")
+DECL_INFO_STRING(built_in_kernels, "__cl_copy_region_align4;"
+                                   "__cl_copy_region_align16;"
+                                   "__cl_cpy_region_unalign_same_offset;"
+                                   "__cl_copy_region_unalign_dst_offset;"
+                                   "__cl_copy_region_unalign_src_offset;"
+                                   "__cl_copy_buffer_rect;"
+                                   "__cl_copy_image_2d_to_2d;"
+                                   "__cl_copy_image_3d_to_2d;"
+                                   "__cl_copy_image_2d_to_3d;"
+                                   "__cl_copy_image_3d_to_3d;"
+                                   "__cl_copy_image_2d_to_buffer;"
+                                   "__cl_copy_image_3d_to_buffer;"
+                                   "__cl_copy_buffer_to_image_2d;"
+                                   "__cl_copy_buffer_to_image_3d;"
+                                   "__cl_fill_region_unalign;"
+                                   "__cl_fill_region_align2;"
+                                   "__cl_fill_region_align4;"
+                                   "__cl_fill_region_align8_2;"
+                                   "__cl_fill_region_align8_4;"
+                                   "__cl_fill_region_align8_8;"
+                                   "__cl_fill_region_align8_16;"
+                                   "__cl_fill_region_align128;")
+
 DECL_INFO_STRING(driver_version, LIBCL_DRIVER_VERSION_STRING)
 #undef DECL_INFO_STRING
 
index 41bf67a..4a80ff5 100644 (file)
@@ -210,6 +210,80 @@ error:
 }
 
 LOCAL cl_program
+cl_program_create_with_built_in_kernles(cl_context     ctx,
+                                  cl_uint              num_devices,
+                                  const cl_device_id * devices,
+                                  const char *         kernel_names,
+                                  cl_int *             errcode_ret)
+{
+  cl_int err = CL_SUCCESS;
+
+  assert(ctx);
+  INVALID_DEVICE_IF (num_devices != 1);
+  INVALID_DEVICE_IF (devices == NULL);
+  INVALID_DEVICE_IF (devices[0] != ctx->device);
+
+  extern char cl_internal_built_in_kernel_str[];
+  extern int cl_internal_built_in_kernel_str_size;
+  char* p_built_in_kernel_str =cl_internal_built_in_kernel_str;
+  cl_int binary_status = CL_SUCCESS;
+
+  ctx->built_in_prgs = cl_program_create_from_binary(ctx, 1,
+                                                          &ctx->device,
+                                                          (size_t*)&cl_internal_built_in_kernel_str_size,
+                                                          (const unsigned char **)&p_built_in_kernel_str,
+                                                          &binary_status, &err);
+
+  if (!ctx->built_in_prgs)
+    return NULL;
+
+  err = cl_program_build(ctx->built_in_prgs, NULL);
+  if (err != CL_SUCCESS)
+    return NULL;
+
+  ctx->built_in_prgs->is_built = 1;
+
+  char delims[] = ";";
+  char* saveptr = NULL;
+  char* local_kernel_names;
+  char* kernel = NULL;
+  char* matched_kernel;
+  int i = 0;
+
+  //copy the content to local_kernel_names to protect the kernel_names.
+  TRY_ALLOC(local_kernel_names, cl_calloc(strlen(kernel_names)+1, sizeof(char) ) );
+  memcpy(local_kernel_names, kernel_names, strlen(kernel_names)+1);
+
+  kernel = strtok_r( local_kernel_names, delims , &saveptr);
+  while( kernel != NULL ) {
+    matched_kernel = strstr(ctx->device->built_in_kernels, kernel);
+    if(matched_kernel){
+      for (i = 0; i < ctx->built_in_prgs->ker_n; ++i) {
+        assert(ctx->built_in_prgs->ker[i]);
+        const char *ker_name = cl_kernel_get_name(ctx->built_in_prgs->ker[i]);
+        if (strcmp(ker_name, kernel) == 0) {
+          break;
+        }
+      }
+
+      ctx->built_in_kernels[i] = cl_program_create_kernel(ctx->built_in_prgs, kernel, NULL);
+    }
+    kernel = strtok_r((char*)saveptr , delims, &saveptr );
+  }
+
+  cl_free(local_kernel_names);
+
+exit:
+  if (errcode_ret)
+    *errcode_ret = err;
+  return ctx->built_in_prgs;
+error:
+  goto exit;
+
+  return CL_SUCCESS;
+}
+
+LOCAL cl_program
 cl_program_create_from_llvm(cl_context ctx,
                             cl_uint num_devices,
                             const cl_device_id *devices,
index 4218efd..b9bf395 100644 (file)
@@ -92,6 +92,13 @@ cl_program_create_from_binary(cl_context             context,
                               cl_int *               binary_status,
                               cl_int *               errcode_ret);
 
+/* Create a program with built-in kernels*/
+extern cl_program
+cl_program_create_with_built_in_kernles(cl_context     context,
+                                  cl_uint              num_devices,
+                                  const cl_device_id * device_list,
+                                  const char *         kernel_names,
+                                  cl_int *             errcode_ret);
 /* Directly create a program from a LLVM source file */
 extern cl_program
 cl_program_create_from_llvm(cl_context             context,