[Beignet] [PATCH] add the support of clGetProgramBuildInfo and clGetProgramInfo

He Junyan junyan.he at linux.intel.com
Tue Jun 18 01:44:49 PDT 2013


rebased


On 06/18/2013 04:44 PM, junyan.he at linux.intel.com wrote:
> From: Junyan He <junyan.he at linux.intel.com>
>
> 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 support
>
> Signed-off-by: Junyan He <junyan.he at linux.intel.com>
> ---
>   src/cl_api.c     |   97 +++++++++++++++++++++++++++++++++++++++++++++++++++---
>   src/cl_program.c |   32 ++++++++++++++++++
>   src/cl_program.h |    1 +
>   3 files changed, 126 insertions(+), 4 deletions(-)
>
> diff --git a/src/cl_api.c b/src/cl_api.c
> index d8787cd..65f06fa 100644
> --- a/src/cl_api.c
> +++ b/src/cl_api.c
> @@ -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,52 @@ 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) {
> +    int copyed = 0;
> +    int i = 0;
> +
> +    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 +801,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,
> diff --git a/src/cl_program.c b/src/cl_program.c
> index 3149219..16cb08c 100644
> --- a/src/cl_program.c
> +++ b/src/cl_program.c
> @@ -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;
> diff --git a/src/cl_program.h b/src/cl_program.h
> index 3e3edab..996a496 100644
> --- a/src/cl_program.h
> +++ b/src/cl_program.h
> @@ -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 */



More information about the Beignet mailing list