[Beignet] [PATCH 4/6] Add the API of clCreateProgramFromBinaryIntel to deserializate the program.

junyan.he at inbox.com junyan.he at inbox.com
Thu Aug 22 01:18:49 PDT 2013


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

Because the serialization format is just for intel's gen platfom,
we do not use the clCreateProgramWithBinary API of OpenCL.
clCreateProgramWithBinary will be used when the binary ABI format comply
with the LLVM or other binary standard.

Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 backend/src/backend/gen_program.cpp |   19 +++++++++++++++++
 backend/src/backend/program.cpp     |    1 +
 backend/src/backend/program.h       |    4 ++++
 include/CL/cl_intel.h               |    8 +++++++
 src/cl_api.c                        |   13 ++++++++++++
 src/cl_program.c                    |   39 +++++++++++++++++++++++++++++++++++
 src/cl_program.h                    |    8 +++++++
 7 files changed, 92 insertions(+)

diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp
index 9429158..a0d1e4d 100644
--- a/backend/src/backend/gen_program.cpp
+++ b/backend/src/backend/gen_program.cpp
@@ -35,6 +35,7 @@
 #include <cstring>
 #include <memory>
 #include <iostream>
+#include <fstream>
 
 namespace gbe {
 
@@ -125,11 +126,29 @@ namespace gbe {
     // Everything run fine
     return (gbe_program) program;
   }
+
+  static gbe_program genProgramNewFromBinFile(const char *binFile)
+  {
+    using namespace gbe;
+    GenProgram *program = GBE_NEW_NO_ARG(GenProgram);
+    std::ifstream ifs(binFile, std::ifstream::out | std::ifstream::binary);
+
+    if (!ifs.is_open()) {
+      return NULL;
+    }
+
+    if (!program->deserializeFromBin(ifs)) {
+      return NULL;
+    }
+
+    return reinterpret_cast<gbe_program>(program);
+  }
 } /* namespace gbe */
 
 void genSetupCallBacks(void)
 {
   gbe_program_new_from_binary = gbe::genProgramNewFromBinary;
   gbe_program_new_from_llvm = gbe::genProgramNewFromLLVM;
+  gbe_program_new_from_binfile = gbe::genProgramNewFromBinFile;
 }
 
diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp
index 2485fdb..1069b91 100644
--- a/backend/src/backend/program.cpp
+++ b/backend/src/backend/program.cpp
@@ -928,6 +928,7 @@ GBE_EXPORT_SYMBOL gbe_kernel_get_image_size_cb *gbe_kernel_get_image_size = NULL
 GBE_EXPORT_SYMBOL gbe_kernel_get_image_data_cb *gbe_kernel_get_image_data = NULL;
 GBE_EXPORT_SYMBOL gbe_set_image_base_index_cb *gbe_set_image_base_index = NULL;
 GBE_EXPORT_SYMBOL gbe_get_image_base_index_cb *gbe_get_image_base_index = NULL;
+GBE_EXPORT_SYMBOL gbe_program_new_from_binfile_cb *gbe_program_new_from_binfile = NULL;
 
 namespace gbe
 {
diff --git a/backend/src/backend/program.h b/backend/src/backend/program.h
index d20e7af..a011735 100644
--- a/backend/src/backend/program.h
+++ b/backend/src/backend/program.h
@@ -220,6 +220,10 @@ extern gbe_kernel_get_required_work_group_size_cb *gbe_kernel_get_required_work_
 typedef int32_t (gbe_kernel_use_slm_cb)(gbe_kernel);
 extern gbe_kernel_use_slm_cb *gbe_kernel_use_slm;
 
+/*! re-build the program from bin file. */
+typedef gbe_program (gbe_program_new_from_binfile_cb)(const char* bin_path);
+extern gbe_program_new_from_binfile_cb *gbe_program_new_from_binfile;
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/include/CL/cl_intel.h b/include/CL/cl_intel.h
index 135e340..1dd1c77 100644
--- a/include/CL/cl_intel.h
+++ b/include/CL/cl_intel.h
@@ -90,6 +90,14 @@ typedef CL_API_ENTRY cl_program (CL_API_CALL *clCreateProgramWithLLVMIntel_fn)(
                                  const char *            /* file */,
                                  cl_int *                /* errcode_ret */);
 
+extern CL_API_ENTRY cl_program CL_API_CALL
+clCreateProgramFromBinaryIntel(cl_context              context,
+                               cl_uint                 num_devices,
+                               const cl_device_id *    devices,
+                               const char *            filename,
+                               cl_int *                errcode_ret);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/cl_api.c b/src/cl_api.c
index 4f048ee..23820e6 100644
--- a/src/cl_api.c
+++ b/src/cl_api.c
@@ -2007,3 +2007,16 @@ clCreateProgramWithLLVMIntel(cl_context              context,
                                      errcode_ret);
 }
 
+cl_program
+clCreateProgramFromBinaryIntel(cl_context              context,
+                               cl_uint                 num_devices,
+                               const cl_device_id *    devices,
+                               const char *            filename,
+                               cl_int *                errcode_ret)
+{
+  return cl_program_create_from_binfile(context,
+                                        num_devices,
+                                        devices,
+                                        filename,
+                                        errcode_ret);
+}
diff --git a/src/cl_program.c b/src/cl_program.c
index 7870514..b0c5d5f 100644
--- a/src/cl_program.c
+++ b/src/cl_program.c
@@ -227,6 +227,45 @@ error:
 }
 
 LOCAL cl_program
+cl_program_create_from_binfile(cl_context ctx,
+                               cl_uint num_devices,
+                               const cl_device_id *devices,
+                               const char *file_name,
+                               cl_int *errcode_ret)
+{
+  cl_program program = NULL;
+  cl_int err = CL_SUCCESS;
+
+  assert(ctx);
+  INVALID_DEVICE_IF (num_devices != 1);
+  INVALID_DEVICE_IF (devices == NULL);
+  INVALID_DEVICE_IF (devices[0] != ctx->device);
+  INVALID_VALUE_IF (file_name == NULL);
+
+  program = cl_program_new(ctx);
+  program->opaque = gbe_program_new_from_binfile(file_name);
+  if (UNLIKELY(program->opaque == NULL)) {
+    err = CL_INVALID_PROGRAM;
+    goto error;
+  }
+
+  /* Create all the kernels */
+  TRY (cl_program_load_gen_program, program);
+  program->source_type = FROM_BINARY;
+
+  program->is_built = 1;
+
+exit:
+  if (errcode_ret)
+    *errcode_ret = err;
+  return program;
+error:
+  cl_program_delete(program);
+  program = NULL;
+  goto exit;
+}
+
+LOCAL cl_program
 cl_program_create_from_source(cl_context ctx,
                               cl_uint count,
                               const char **strings,
diff --git a/src/cl_program.h b/src/cl_program.h
index 996a496..197d999 100644
--- a/src/cl_program.h
+++ b/src/cl_program.h
@@ -92,6 +92,14 @@ cl_program_create_from_llvm(cl_context             context,
                             const char *           fileName,
                             cl_int *               errcode_ret);
 
+/* Directly create a program from a pre-compiled binary file*/
+extern cl_program
+cl_program_create_from_binfile(cl_context             context,
+                               cl_uint                num_devices,
+                               const cl_device_id *   devices,
+                               const char *           fileName,
+                               cl_int *               errcode_ret);
+
 /* Build the program as specified by OCL */
 extern cl_int
 cl_program_build(cl_program p, const char* options);
-- 
1.7.9.5



More information about the Beignet mailing list