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

He Junyan junyan.he at linux.intel.com
Tue Jun 18 21:05:32 PDT 2013


OK, forget to delete when do the source logic change.
I will send  a test case later



On 06/19/2013 11:56 AM, Zhigang Gong wrote:
> On Tue, Jun 18, 2013 at 04:44:49PM +0800, 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;
> Compiler complains the above two variables are unused. I will remove them,
> no need for new version of patch.
> The other part LGTM. Will pushed latter. Thanks.
>
>> +
>> +    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 */
>> -- 
>> 1.7.9.5
>>
>> _______________________________________________
>> Beignet mailing list
>> Beignet at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/beignet



More information about the Beignet mailing list