[Beignet] [PATCH] add the support of clGetProgramBuildInfo and clGetProgramInfo
junyan.he at linux.intel.com
junyan.he at linux.intel.com
Tue Jun 18 01:44:49 PDT 2013
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 */
--
1.7.9.5
More information about the Beignet
mailing list