[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