add the support of clGetProgramBuildInfo and clGetProgramInfo
authorJunyan He <junyan.he@linux.intel.com>
Tue, 18 Jun 2013 08:44:49 +0000 (16:44 +0800)
committerZhigang Gong <zhigang.gong@linux.intel.com>
Wed, 19 Jun 2013 05:14:45 +0000 (13:14 +0800)
For clGetProgramBuildInfo,
CL_BUILD_IN_PROGRESS not support now
and CL_PROGRAM_BUILD_LOG need do add the info collection
logic in backend and not support too, just return null
string now.
clGetProgramInfo all are fully supported.

Signed-off-by: Junyan He <junyan.he@linux.intel.com>
Reviewed-by: Ruiling Song <ruiling.song@intel.com>
src/cl_api.c
src/cl_program.c
src/cl_program.h

index d8787cd..223ba9b 100644 (file)
@@ -725,6 +725,19 @@ clUnloadCompiler(void)
   return 0;
 }
 
+#define FILL_AND_RET(TYPE, ELT, VAL, RET) \
+       do { \
+         if (param_value && param_value_size < sizeof(TYPE)*ELT) \
+             return CL_INVALID_VALUE;  \
+         if (param_value) { \
+             memcpy(param_value, (VAL), sizeof(TYPE)*ELT); \
+         } \
+          \
+         if (param_value_size_ret) \
+             *param_value_size_ret = sizeof(TYPE)*ELT; \
+         return RET; \
+       } while(0)
+
 cl_int
 clGetProgramInfo(cl_program       program,
                  cl_program_info  param_name,
@@ -732,8 +745,50 @@ clGetProgramInfo(cl_program       program,
                  void *           param_value,
                  size_t *         param_value_size_ret)
 {
-  NOT_IMPLEMENTED;
-  return 0;
+  cl_int err = CL_SUCCESS;
+  char * ret_str = "";
+
+  CHECK_PROGRAM (program);
+
+  if (param_name == CL_PROGRAM_REFERENCE_COUNT) {
+    cl_uint ref = program->ref_n;
+    FILL_AND_RET (cl_uint, 1, (&ref), CL_SUCCESS);
+  } else if (param_name == CL_PROGRAM_CONTEXT) {
+    cl_context context = program->ctx;
+    FILL_AND_RET (cl_context, 1, &context, CL_SUCCESS);
+  } else if (param_name == CL_PROGRAM_NUM_DEVICES) {
+    cl_uint num_dev = 1; // Just 1 dev now.
+    FILL_AND_RET (cl_uint, 1, &num_dev, CL_SUCCESS);
+  } else if (param_name == CL_PROGRAM_DEVICES) {
+    cl_device_id dev_id = program->ctx->device;
+    FILL_AND_RET (cl_device_id, 1, &dev_id, CL_SUCCESS);
+  } else if (param_name == CL_PROGRAM_SOURCE) {
+
+    if (!program->source)
+      FILL_AND_RET (char, 1, &ret_str, CL_SUCCESS);
+    FILL_AND_RET (char, (strlen(program->source) + 1),
+                   program->source, CL_SUCCESS);
+  } else if (param_name == CL_PROGRAM_BINARY_SIZES) {
+    FILL_AND_RET (size_t, 1, (&program->bin_sz), CL_SUCCESS);
+  } else if (param_name == CL_PROGRAM_BINARIES) {
+    if (!param_value)
+      return CL_SUCCESS;
+
+    /* param_value points to an array of n
+       pointers allocated by the caller */
+    if (program->bin_sz > 0) {
+      memcpy(*((void **)param_value), program->bin, program->bin_sz);
+    } else {
+      memcpy(*((void **)param_value), ret_str, 1);
+    }
+
+    return CL_SUCCESS;
+  } else {
+    return CL_INVALID_VALUE;
+  }
+
+error:
+    return err;
 }
 
 cl_int
@@ -744,10 +799,42 @@ clGetProgramBuildInfo(cl_program             program,
                       void *                 param_value,
                       size_t *               param_value_size_ret)
 {
-  NOT_IMPLEMENTED;
-  return 0;
+  cl_int err = CL_SUCCESS;
+  char * ret_str = "";
+
+  CHECK_PROGRAM (program);
+  INVALID_DEVICE_IF (device != program->ctx->device);
+
+  if (param_name == CL_PROGRAM_BUILD_STATUS) {
+    cl_build_status status;
+
+    if (!program->is_built)
+      status = CL_BUILD_NONE;
+    else if (program->ker_n > 0)
+      status = CL_BUILD_SUCCESS;
+    else
+      status = CL_BUILD_ERROR;
+    // TODO: Support CL_BUILD_IN_PROGRESS ?
+
+    FILL_AND_RET (cl_build_status, 1, &status, CL_SUCCESS);
+  } else if (param_name == CL_PROGRAM_BUILD_OPTIONS) {
+    if (program->is_built && program->build_opts)
+      ret_str = program->build_opts;
+
+    FILL_AND_RET (char, (strlen(ret_str)+1), ret_str, CL_SUCCESS);
+  } else if (param_name == CL_PROGRAM_BUILD_LOG) {
+    // TODO: need to add logs in backend when compiling.
+    FILL_AND_RET (char, (strlen(ret_str)+1), ret_str, CL_SUCCESS);
+  } else {
+    return CL_INVALID_VALUE;
+  }
+
+error:
+    return err;
 }
 
+#undef FILL_AND_RET
+
 cl_kernel
 clCreateKernel(cl_program   program,
                const char * kernel_name,
index 1b49b84..7870514 100644 (file)
@@ -56,6 +56,12 @@ cl_program_delete(cl_program p)
   /* Destroy the sources if still allocated */
   cl_program_release_sources(p);
 
+  /* Release the build options. */
+  if (p->build_opts) {
+    cl_free(p->build_opts);
+    p->build_opts = NULL;
+  }
+
   /* Remove it from the list */
   assert(p->ctx);
   pthread_mutex_lock(&p->ctx->program_lock);
@@ -274,6 +280,18 @@ LOCAL cl_int
 cl_program_build(cl_program p, const char *options)
 {
   cl_int err = CL_SUCCESS;
+  int i = 0;
+  int copyed = 0;
+
+  if (options) {
+    if(p->build_opts) {
+      cl_free(p->build_opts);
+      p->build_opts = NULL;
+    }
+
+    TRY_ALLOC (p->build_opts, cl_calloc(strlen(options) + 1, sizeof(char)));
+    memcpy(p->build_opts, options, strlen(options));
+  }
 
   if (p->source_type == FROM_SOURCE) {
     p->opaque = gbe_program_new_from_source(p->source, 0, options, NULL, NULL);
@@ -287,6 +305,20 @@ cl_program_build(cl_program p, const char *options)
     p->source_type = FROM_LLVM;
   }
 
+  for (i = 0; i < p->ker_n; i ++) {
+    const gbe_kernel opaque = gbe_program_get_kernel(p->opaque, i);
+    p->bin_sz += gbe_kernel_get_code_size(opaque);
+  }
+
+  TRY_ALLOC (p->bin, cl_calloc(p->bin_sz, sizeof(char)));
+  for (i = 0; i < p->ker_n; i ++) {
+    const gbe_kernel opaque = gbe_program_get_kernel(p->opaque, i);
+    size_t sz = gbe_kernel_get_code_size(opaque);
+
+    memcpy(p->bin + copyed, gbe_kernel_get_code(opaque), sz);
+    copyed += sz;
+  }
+
   p->is_built = 1;
 error:
   return err;
index 3e3edab..996a496 100644 (file)
@@ -51,6 +51,7 @@ struct _cl_program {
   uint32_t ker_n;         /* Number of declared kernels */
   uint32_t source_type:2; /* Built from binary, source or LLVM */
   uint32_t is_built:1;    /* Did we call clBuildProgram on it? */
+  char *build_opts;       /* The build options for this program */
 };
 
 /* Create a empty program */