[Beignet] [PATCH] Fixup the problem of CL_PROGRAM_BINARIES in clGetProgramInfo API

junyan.he at inbox.com junyan.he at inbox.com
Thu Nov 7 21:44:42 PST 2013


From: Junyan He <junyan.he at linux.intel.com>

clGetProgramInfo using CL_PROGRAM_BINARIES to get the binary will
not be right because the binary got is not the serilization one.
Add the serilization there to fix this bug.

Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 backend/src/backend/gen_program.cpp |   17 +++++++++++++++++
 backend/src/backend/program.cpp     |    1 +
 backend/src/backend/program.h       |    4 ++++
 src/cl_api.c                        |   20 +++++++++++++++-----
 4 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp
index 40ab176..67d4cab 100644
--- a/backend/src/backend/gen_program.cpp
+++ b/backend/src/backend/gen_program.cpp
@@ -131,6 +131,22 @@ namespace gbe {
     return reinterpret_cast<gbe_program>(program);
   }
 
+  static size_t genProgramSerializeToBinary(gbe_program program, char **binary) {
+    using namespace gbe;
+    size_t sz;
+    std::ostringstream oss;
+    GenProgram *prog = (GenProgram*)program;
+
+    if ((sz = prog->serializeToBin(oss)) == 0) {
+      *binary = 0;
+      return 0;
+    }
+
+    *binary = (char *)malloc(sizeof(char) * sz);
+    memcpy(*binary, oss.str().c_str(), sz*sizeof(char));
+    return sz;
+  }
+
   static gbe_program genProgramNewFromLLVM(const char *fileName,
                                            size_t stringSize,
                                            char *err,
@@ -157,5 +173,6 @@ namespace gbe {
 void genSetupCallBacks(void)
 {
   gbe_program_new_from_binary = gbe::genProgramNewFromBinary;
+  gbe_program_serialize_to_binary = gbe::genProgramSerializeToBinary;
   gbe_program_new_from_llvm = gbe::genProgramNewFromLLVM;
 }
diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp
index 25be484..f2ddae9 100644
--- a/backend/src/backend/program.cpp
+++ b/backend/src/backend/program.cpp
@@ -790,6 +790,7 @@ namespace gbe {
 
 GBE_EXPORT_SYMBOL gbe_program_new_from_source_cb *gbe_program_new_from_source = NULL;
 GBE_EXPORT_SYMBOL gbe_program_new_from_binary_cb *gbe_program_new_from_binary = NULL;
+GBE_EXPORT_SYMBOL gbe_program_serialize_to_binary_cb *gbe_program_serialize_to_binary = NULL;
 GBE_EXPORT_SYMBOL gbe_program_new_from_llvm_cb *gbe_program_new_from_llvm = NULL;
 GBE_EXPORT_SYMBOL gbe_program_get_global_constant_size_cb *gbe_program_get_global_constant_size = NULL;
 GBE_EXPORT_SYMBOL gbe_program_get_global_constant_data_cb *gbe_program_get_global_constant_data = NULL;
diff --git a/backend/src/backend/program.h b/backend/src/backend/program.h
index 10fcc49..b79b4dd 100644
--- a/backend/src/backend/program.h
+++ b/backend/src/backend/program.h
@@ -122,6 +122,10 @@ extern gbe_program_new_from_source_cb *gbe_program_new_from_source;
 typedef gbe_program (gbe_program_new_from_binary_cb)(const char *binary, size_t size);
 extern gbe_program_new_from_binary_cb *gbe_program_new_from_binary;
 
+/*! Serialize a program to a bin */
+typedef size_t (gbe_program_serialize_to_binary_cb)(gbe_program program, char **binary);
+extern gbe_program_serialize_to_binary_cb *gbe_program_serialize_to_binary;
+
 /*! Create a new program from the given LLVM file */
 typedef gbe_program (gbe_program_new_from_llvm_cb)(const char *fileName,
                                                    size_t string_size,
diff --git a/src/cl_api.c b/src/cl_api.c
index 6acc1a2..d04ff00 100644
--- a/src/cl_api.c
+++ b/src/cl_api.c
@@ -909,7 +909,14 @@ clGetProgramInfo(cl_program       program,
     FILL_GETINFO_RET (char, (strlen(program->source) + 1),
                    program->source, CL_SUCCESS);
   } else if (param_name == CL_PROGRAM_BINARY_SIZES) {
-    FILL_GETINFO_RET (size_t, 1, (&program->bin_sz), CL_SUCCESS);
+    if (program->binary == NULL) {
+      program->binary_sz = gbe_program_serialize_to_binary(program->opaque, &program->binary);
+    }
+
+    if (program->binary == NULL || program->binary_sz == 0) {
+      return CL_OUT_OF_RESOURCES;
+    }
+    FILL_GETINFO_RET (size_t, 1, (&program->binary_sz), CL_SUCCESS);
   } else if (param_name == CL_PROGRAM_BINARIES) {
     if (param_value_size_ret)
       *param_value_size_ret = sizeof(void*);
@@ -918,12 +925,15 @@ clGetProgramInfo(cl_program       program,
 
     /* 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);
+    if (program->binary == NULL) {
+      program->binary_sz = gbe_program_serialize_to_binary(program->opaque, &program->binary);
+    }
+
+    if (program->binary == NULL || program->binary_sz == 0) {
+      return CL_OUT_OF_RESOURCES;
     }
 
+    memcpy(*((void **)param_value), program->binary, program->binary_sz);
     return CL_SUCCESS;
   } else {
     return CL_INVALID_VALUE;
-- 
1.7.9.5



More information about the Beignet mailing list