[Beignet] [V2 PATCH 3/4] Implement the clCreateProgramWithBinary to deseralize the binary

junyan.he at inbox.com junyan.he at inbox.com
Thu Sep 5 03:48:38 PDT 2013


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

We now do not check the format of the binary. We need to
check the binary file format to handle the internal binary,
the LLVM binary or the invalid format differently.

Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 backend/src/backend/gen_program.cpp |   16 +++++++++++++--
 src/cl_api.c                        |    3 ++-
 src/cl_program.c                    |   37 ++++++++++++++++++++++++++++++-----
 src/cl_program.h                    |    2 ++
 4 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp
index bdd3441..a699889 100644
--- a/backend/src/backend/gen_program.cpp
+++ b/backend/src/backend/gen_program.cpp
@@ -33,6 +33,7 @@
 #include "llvm/llvm_to_gen.hpp"
 
 #include <cstring>
+#include <sstream>  
 #include <memory>
 #include <iostream>
 #include <fstream>
@@ -115,8 +116,19 @@ namespace gbe {
   }
 
   static gbe_program genProgramNewFromBinary(const char *binary, size_t size) {
-    NOT_IMPLEMENTED;
-    return NULL;
+    using namespace gbe;
+    std::string binary_content;
+    binary_content.assign(binary, size);
+    GenProgram *program = GBE_NEW_NO_ARG(GenProgram);
+    std::istringstream ifs(binary_content, std::ostringstream::binary);
+
+    if (!program->deserializeFromBin(ifs)) {
+      delete program;
+      return NULL;
+    }
+
+    //program->printStatus(0, std::cout);
+    return reinterpret_cast<gbe_program>(program);
   }
 
   static gbe_program genProgramNewFromLLVM(const char *fileName,
diff --git a/src/cl_api.c b/src/cl_api.c
index 30d0b11..50a0042 100644
--- a/src/cl_api.c
+++ b/src/cl_api.c
@@ -777,7 +777,8 @@ clBuildProgram(cl_program            program,
 
   /* TODO support create program from binary */
   assert(program->source_type == FROM_LLVM ||
-         program->source_type == FROM_SOURCE);
+         program->source_type == FROM_SOURCE ||
+         program->source_type == FROM_BINARY);
   if((err = cl_program_build(program, options)) != CL_SUCCESS) {
     goto error;
   }
diff --git a/src/cl_program.c b/src/cl_program.c
index 7870514..a0e0104 100644
--- a/src/cl_program.c
+++ b/src/cl_program.c
@@ -42,6 +42,15 @@ cl_program_release_sources(cl_program p)
   }
 }
 
+static void
+cl_program_release_binary(cl_program p)
+{
+  if (p->binary) {
+    cl_free(p->binary);
+    p->binary = NULL;
+  }
+}
+
 LOCAL void
 cl_program_delete(cl_program p)
 {
@@ -53,8 +62,9 @@ cl_program_delete(cl_program p)
   /* We are not done with it yet */
   if ((ref = atomic_dec(&p->ref_n)) > 1) return;
 
-  /* Destroy the sources if still allocated */
+  /* Destroy the sources and binary if still allocated */
   cl_program_release_sources(p);
+  cl_program_release_binary(p);
 
   /* Release the build options. */
   if (p->build_opts) {
@@ -149,7 +159,6 @@ cl_program_create_from_binary(cl_context             ctx,
                               cl_int *               binary_status,
                               cl_int *               errcode_ret)
 {
-#if 0
   cl_program program = NULL;
   cl_int err = CL_SUCCESS;
 
@@ -174,7 +183,16 @@ cl_program_create_from_binary(cl_context             ctx,
     goto error;
   }
 
-  // TRY_ALLOC (program, cl_program_new(ctx, (const char *) binaries[0], lengths[0]));
+  program = cl_program_new(ctx);
+
+  // TODO:  Need to check the binary format here to return CL_INVALID_BINARY.
+  TRY_ALLOC(program->binary, cl_calloc(lengths[0], sizeof(char)));
+  memcpy(program->binary, binaries[0], lengths[0]);
+  program->binary_sz = lengths[0];
+  program->source_type = FROM_BINARY;
+
+  if (binary_status)
+    binary_status[0] = CL_SUCCESS;
 
 exit:
   if (errcode_ret)
@@ -184,8 +202,7 @@ error:
   cl_program_delete(program);
   program = NULL;
   goto exit;
-#endif
-  NOT_IMPLEMENTED;
+
   return CL_SUCCESS;
 }
 
@@ -303,6 +320,16 @@ cl_program_build(cl_program p, const char *options)
     /* Create all the kernels */
     TRY (cl_program_load_gen_program, p);
     p->source_type = FROM_LLVM;
+  } else if (p->source_type == FROM_BINARY) {
+    p->opaque = gbe_program_new_from_binary(p->binary, p->binary_sz);
+    if (UNLIKELY(p->opaque == NULL)) {
+      err = CL_INVALID_PROGRAM;
+      goto error;
+    }
+
+    /* Create all the kernels */
+    TRY (cl_program_load_gen_program, p);
+    p->source_type = FROM_LLVM;
   }
 
   for (i = 0; i < p->ker_n; i ++) {
diff --git a/src/cl_program.h b/src/cl_program.h
index 996a496..de82fd5 100644
--- a/src/cl_program.h
+++ b/src/cl_program.h
@@ -48,6 +48,8 @@ struct _cl_program {
   char *bin;              /* The program copied verbatim */
   size_t bin_sz;          /* Its size in memory */
   char *source;           /* Program sources */
+  char *binary;           /* Program binary. */
+  size_t binary_sz;       /* The binary size. */
   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? */
-- 
1.7.9.5



More information about the Beignet mailing list