[Beignet] [PATCH V2] separate runtime(libcl.so) and compiler(libgbe.so)

Yang, Rong R rong.r.yang at intel.com
Tue May 27 01:27:24 PDT 2014


LGTM, thanks.

-----Original Message-----
From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of Guo Yejun
Sent: Tuesday, May 27, 2014 7:10 AM
To: beignet at lists.freedesktop.org
Cc: Guo, Yejun
Subject: [Beignet] [PATCH V2] separate runtime(libcl.so) and compiler(libgbe.so)

On embedded/handheld devices, storage and memory are scarce, it is necessary to provide only the OpenCL runtime library with small size, and only the executable binary kernel will be supported on such device.

At the beginning of process (before function main), OpenCL runtime
(libcl.so) will try to load the compiler (libgbe.so), the system's behavior is the same as before if successfully loaded, otherwise, the runtime assumes no OpenCL compiler in the system, and the device info will be changed as CL_DEVICE_COMPILER_AVAILABLE=false and CL_DEVICE_PROFILE="EMBEDDED_PROFILE", the clBuildProgram returns CL_COMPILER_NOT_AVAILABLE if the program is created with clCreateProgramWithSource, following the OpenCL spec.

To simulate the case without OpenCL compiler, just delete the file libgbe.so, or export OCL_NON_COMPILER=1.

Some explanation of the binary kernel interpreter (libinterp.a):

libinterp.a is used to interpret the binary kernel inside runtime, and the runtime library libcl.so is built against libinterp.a.

Since the code to interpret binary kernel is tightly integrated inside the compiler, to avoid code duplicate, a new file gbe_bin_interpreter.cpp is created to include some other .cpp files; to make libinterp.a small (the purpose to make libcl.so small), the macro GBE_COMPILER_AVAILABLE is used to make only the needed code active when build for libinterp.a.

V2: code base is changed to call function gbe_set_image_base_index in gbe_bin_generater, while this function is modified in this patch as gbe_set_image_base_index_compiler, fix it accordingly.

Signed-off-by: Guo Yejun <yejun.guo at intel.com>
---
 backend/CMakeLists.txt              |  3 ++
 backend/src/CMakeLists.txt          |  8 +++-
 backend/src/GBEConfig.h.in          |  1 +
 backend/src/backend/gen_program.cpp |  9 +++-
 backend/src/backend/program.cpp     | 12 ++++--
 backend/src/backend/program.h       |  3 +-
 backend/src/backend/program.hpp     |  2 +
 backend/src/gbe_bin_generater.cpp   |  2 +-
 backend/src/gbe_bin_interpreter.cpp | 71 ++++++++++++++++++++++++++++++++
 backend/src/ir/image.cpp            | 61 +++++++++++++--------------
 backend/src/ir/sampler.cpp          |  2 +
 backend/src/ocl_common_defines.h    |  5 ++-
 src/CMakeLists.txt                  |  5 ++-
 src/cl_device_id.c                  | 10 +++++
 src/cl_gbe_loader.cpp               | 82 +++++++++++++++++++++++++++++++++++++
 src/cl_gbe_loader.h                 | 32 +++++++++++++++
 src/cl_kernel.h                     |  2 +-
 src/cl_program.c                    |  6 +++
 src/cl_program.h                    |  2 +-
 src/intel/intel_driver.c            |  7 +++-
 utests/setenv.sh.in                 |  1 +
 21 files changed, 282 insertions(+), 44 deletions(-)  create mode 100644 backend/src/gbe_bin_interpreter.cpp
 create mode 100644 src/cl_gbe_loader.cpp  create mode 100644 src/cl_gbe_loader.h

diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt index dd55a4a..a20f423 100644
--- a/backend/CMakeLists.txt
+++ b/backend/CMakeLists.txt
@@ -36,6 +36,8 @@ endif (GBE_DEBUG_MEMORY)  # Hide all symbols and allows the symbols declared as visible to be exported  set (CMAKE_C_CXX_FLAGS "-fvisibility=hidden ${CMAKE_C_CXX_FLAGS}")
 
+set (CMAKE_C_CXX_FLAGS -DGBE_COMPILER_AVAILABLE=1)
+
 if (COMPILER STREQUAL "GCC")
   set (CMAKE_C_CXX_FLAGS "${CMAKE_C_CXX_FLAGS} -funroll-loops -Wstrict-aliasing=2 -fstrict-aliasing -msse2 -msse3 -mssse3 -msse4.1 -fPIC -Wall")
   set (CMAKE_C_CXX_FLAGS "${CMAKE_C_CXX_FLAGS}  ${LLVM_CFLAGS}") @@ -99,6 +101,7 @@ include_directories (${CMAKE_CURRENT_BINARY_DIR})  add_subdirectory (src)  set(LOCAL_PCH_OBJECT_DIR ${LOCAL_PCH_OBJECT_DIR} PARENT_SCOPE)  set(LOCAL_PCM_OBJECT_DIR ${LOCAL_PCM_OBJECT_DIR} PARENT_SCOPE)
+set(LOCAL_GBE_OBJECT_DIR ${LOCAL_GBE_OBJECT_DIR} PARENT_SCOPE)
 set (GBE_BIN_GENERATER
      OCL_PCM_PATH=${LOCAL_PCM_OBJECT_DIR} OCL_PCH_PATH=${LOCAL_PCH_OBJECT_DIR} ${CMAKE_CURRENT_BINARY_DIR}/src/gbe_bin_generater
      PARENT_SCOPE)
diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt index 1dfbcf6..528595f 100644
--- a/backend/src/CMakeLists.txt
+++ b/backend/src/CMakeLists.txt
@@ -177,7 +177,7 @@ endif (GBE_USE_BLOB)  include_directories (.)  link_directories (${LLVM_LIBRARY_DIRS})
 include_directories(${LLVM_INCLUDE_DIRS})
-add_library (gbe STATIC ${GBE_SRC})
+add_library (gbe SHARED ${GBE_SRC})
 
 # for pre compiled module library.
 set (pcm_lib "beignet.bc")
@@ -195,6 +195,8 @@ target_link_libraries(
                       ${CMAKE_THREAD_LIBS_INIT}
                       ${CMAKE_DL_LIBS})
 
+add_library(interp STATIC gbe_bin_interpreter.cpp)
+
 if (LLVM_VERSION_NODOT VERSION_EQUAL 34)
   find_library(TERMINFO NAMES tinfo ncurses)
   if (${TERMINFO} STREQUAL TERMINFO-NOTFOUND) @@ -209,7 +211,7 @@ link_directories (${LLVM_LIBRARY_DIR})  ADD_EXECUTABLE(gbe_bin_generater gbe_bin_generater.cpp)  TARGET_LINK_LIBRARIES(gbe_bin_generater gbe)
 
-#install (TARGETS gbe LIBRARY DESTINATION lib)
+install (TARGETS gbe LIBRARY DESTINATION ${LIB_INSTALL_DIR}/beignet)
 #install (FILES backend/program.h DESTINATION include/gen)  install (FILES ${ocl_blob_file} DESTINATION ${LIB_INSTALL_DIR}/beignet)  install (FILES ${pch_object} DESTINATION ${LIB_INSTALL_DIR}/beignet) @@ -218,9 +220,11 @@ install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${pcm_lib} DESTINATION ${LIB_INSTALL_  # file to libcl and utests.
 set (LOCAL_PCH_OBJECT_DIR "${local_pch_object}:${beignet_install_path}/ocl_stdlib.h.pch" PARENT_SCOPE)  set (LOCAL_PCM_OBJECT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${pcm_lib}:${beignet_install_path}/${pcm_lib}" PARENT_SCOPE)
+set (LOCAL_GBE_OBJECT_DIR "${CMAKE_CURRENT_BINARY_DIR}/libgbe.so" 
+PARENT_SCOPE)
 
 set (PCH_OBJECT_DIR "${beignet_install_path}/ocl_stdlib.h.pch")
 set (PCM_OBJECT_DIR "${beignet_install_path}/${pcm_lib}")
+set (GBE_OBJECT_DIR "${beignet_install_path}/libgbe.so")
 configure_file (
   "GBEConfig.h.in"
   "GBEConfig.h"
diff --git a/backend/src/GBEConfig.h.in b/backend/src/GBEConfig.h.in index 5bc09b8..ad24390 100644
--- a/backend/src/GBEConfig.h.in
+++ b/backend/src/GBEConfig.h.in
@@ -3,3 +3,4 @@
 #define LIBGBE_VERSION_MINOR @LIBGBE_VERSION_MINOR@  #define PCH_OBJECT_DIR "@PCH_OBJECT_DIR@"
 #define PCM_OBJECT_DIR "@PCM_OBJECT_DIR@"
+#define GBE_OBJECT_DIR "@GBE_OBJECT_DIR@"
diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp
index 52db904..d2e95d4 100644
--- a/backend/src/backend/gen_program.cpp
+++ b/backend/src/backend/gen_program.cpp
@@ -53,6 +53,7 @@ namespace gbe {
   size_t GenKernel::getCodeSize(void) const { return insnNum * sizeof(GenInstruction); }
 
   void GenKernel::printStatus(int indent, std::ostream& outs) {
+#ifdef GBE_COMPILER_AVAILABLE
     Kernel::printStatus(indent, outs);
 
     FILE *f = fopen("/dev/null", "w");
@@ -70,6 +71,7 @@ namespace gbe {
     setbuffer(f, NULL, 0);
     delete [] buf;
     fclose(f);
+#endif
   }
 
   GenProgram::~GenProgram(void) {}
@@ -88,7 +90,7 @@ namespace gbe {
   };
 
   Kernel *GenProgram::compileKernel(const ir::Unit &unit, const std::string &name, bool relaxMath) {
-
+#ifdef GBE_COMPILER_AVAILABLE
     // Be careful when the simdWidth is forced by the programmer. We can see it
     // when the function already provides the simd width we need to use (i.e.
     // non zero)
@@ -139,6 +141,9 @@ namespace gbe {
 
     GBE_ASSERTM(kernel != NULL, "Fail to compile kernel, may need to increase reserved registers for spilling.");
     return kernel;
+#else
+    return NULL;
+#endif
   }
 
   static gbe_program genProgramNewFromBinary(uint32_t deviceID, const char *binary, size_t size) { @@ -184,6 +189,7 @@ namespace gbe {
   {
     using namespace gbe;
     GenProgram *program = GBE_NEW(GenProgram, deviceID);
+#ifdef GBE_COMPILER_AVAILABLE
     std::string error;
     // Try to compile the program
     if (program->buildFromLLVMFile(fileName, error, optLevel) == false) { @@ -195,6 +201,7 @@ namespace gbe {
       GBE_DELETE(program);
       return NULL;
     }
+#endif
     // Everything run fine
     return (gbe_program) program;
   }
diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp index bdc7d34..121e237 100644
--- a/backend/src/backend/program.cpp
+++ b/backend/src/backend/program.cpp
@@ -100,6 +100,7 @@ namespace gbe {
     if (constantSet) delete constantSet;
   }
 
+#ifdef GBE_COMPILER_AVAILABLE
   BVAR(OCL_OUTPUT_GEN_IR, false);
 
   bool Program::buildFromLLVMFile(const char *fileName, std::string &error, int optLevel) { @@ -139,6 +140,7 @@ namespace gbe {
     }
     return true;
   }
+#endif
 
 #define OUT_UPDATE_SZ(elt) SERIALIZE_OUT(elt, outs, ret_size)  #define IN_UPDATE_SZ(elt) DESERIALIZE_IN(elt, ins, total_size) @@ -511,6 +513,7 @@ namespace gbe {
     GBE_SAFE_DELETE(program);
   }
 
+#ifdef GBE_COMPILER_AVAILABLE
   BVAR(OCL_OUTPUT_BUILD_LOG, false);
   SVAR(OCL_PCH_PATH, PCH_OBJECT_DIR);
   SVAR(OCL_PCM_PATH, PCM_OBJECT_DIR);
@@ -847,6 +850,7 @@ namespace gbe {
     remove(clName.c_str());
     return p;
   }
+#endif
 
   static size_t programGetGlobalConstantSize(gbe_program gbeProgram) {
     if (gbeProgram == NULL) return 0;
@@ -1042,9 +1046,11 @@ GBE_EXPORT_SYMBOL gbe_kernel_get_sampler_data_cb *gbe_kernel_get_sampler_data =  GBE_EXPORT_SYMBOL gbe_kernel_get_compile_wg_size_cb *gbe_kernel_get_compile_wg_size = NULL;  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_set_image_base_index_cb 
+*gbe_set_image_base_index_compiler = NULL; GBE_EXPORT_SYMBOL 
+gbe_set_image_base_index_cb *gbe_set_image_base_index_interp = NULL;
 GBE_EXPORT_SYMBOL gbe_get_image_base_index_cb *gbe_get_image_base_index = NULL;
 
+#ifdef GBE_COMPILER_AVAILABLE
 namespace gbe
 {
   /* Use pre-main to setup the call backs */ @@ -1080,7 +1086,7 @@ namespace gbe
       gbe_kernel_get_image_size = gbe::kernelGetImageSize;
       gbe_kernel_get_image_data = gbe::kernelGetImageData;
       gbe_get_image_base_index = gbe::getImageBaseIndex;
-      gbe_set_image_base_index = gbe::setImageBaseIndex;
+      gbe_set_image_base_index_compiler = gbe::setImageBaseIndex;
       genSetupCallBacks();
       llvm::llvm_start_multithreaded();
     }
@@ -1095,4 +1101,4 @@ namespace gbe
 
   static CallBackInitializer cbInitializer;  } /* namespace gbe */
-
+#endif
diff --git a/backend/src/backend/program.h b/backend/src/backend/program.h index 8727966..e23f4db 100644
--- a/backend/src/backend/program.h
+++ b/backend/src/backend/program.h
@@ -99,7 +99,8 @@ typedef struct ImageInfo {  } ImageInfo;
 
 typedef void (gbe_set_image_base_index_cb)(uint32_t base_idx); -extern gbe_set_image_base_index_cb *gbe_set_image_base_index;
+extern gbe_set_image_base_index_cb *gbe_set_image_base_index_compiler;
+extern gbe_set_image_base_index_cb *gbe_set_image_base_index_interp;
 
 typedef uint32_t (gbe_get_image_base_index_cb)();  extern gbe_get_image_base_index_cb *gbe_get_image_base_index; diff --git a/backend/src/backend/program.hpp b/backend/src/backend/program.hpp index fe945a6..6bb1529 100644
--- a/backend/src/backend/program.hpp
+++ b/backend/src/backend/program.hpp
@@ -112,12 +112,14 @@ namespace gbe {
     INLINE uint32_t getSLMSize(void) const { return this->slmSize; }
     /*! set constant buffer size and return the cb curbe offset */
     int32_t setConstBufSize(uint32_t argID, size_t sz) {
+#ifdef GBE_COMPILER_AVAILABLE
       if(argID >= argNum) return -1;
       if(args[argID].type != GBE_ARG_CONSTANT_PTR) return -1;
       if(args[argID].bufSize != sz) {
         args[argID].bufSize = sz;
         return ctx->allocConstBuf(argID);
       }
+#endif
       return -1;
     }
     /*! Set sampler set. */
diff --git a/backend/src/gbe_bin_generater.cpp b/backend/src/gbe_bin_generater.cpp
index dce0792..0295b1a 100644
--- a/backend/src/gbe_bin_generater.cpp
+++ b/backend/src/gbe_bin_generater.cpp
@@ -301,7 +301,7 @@ int main (int argc, const char **argv)
 
             used_index[optind-1] = 1;
             // We must set the image base index here, as we invoke the backend in a non-standard way.
-            gbe_set_image_base_index(3);
+            gbe_set_image_base_index_compiler(3);
             break;
         }
 
diff --git a/backend/src/gbe_bin_interpreter.cpp b/backend/src/gbe_bin_interpreter.cpp
new file mode 100644
index 0000000..bd160c3
--- /dev/null
+++ b/backend/src/gbe_bin_interpreter.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or modify 
+it
+ * under the terms of the GNU Lesser General Public License as 
+published by the
+ * Free Software Foundation; either version 2 of the License, or (at 
+your
+ * option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but 
+WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
+or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
+License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public 
+License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "sys/alloc.cpp"
+#include "sys/cvar.cpp"
+#include "sys/assert.cpp"
+#include "sys/platform.cpp"
+#include "ir/constant.cpp"
+
+#pragma GCC diagnostic ignored "-Wunused-function"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#undef GBE_COMPILER_AVAILABLE
+#include "backend/program.cpp"
+#include "backend/gen_program.cpp"
+#include "ir/sampler.cpp"
+#include "ir/image.cpp"
+
+struct BinInterpCallBackInitializer
+{
+  BinInterpCallBackInitializer() {
+    gbe_program_new_from_binary = gbe::genProgramNewFromBinary;
+    gbe_program_get_kernel_num = gbe::programGetKernelNum;
+    gbe_program_get_kernel_by_name = gbe::programGetKernelByName;
+    gbe_program_get_kernel = gbe::programGetKernel;
+    gbe_kernel_get_code_size = gbe::kernelGetCodeSize;
+    gbe_kernel_get_code = gbe::kernelGetCode;
+    gbe_kernel_get_arg_num = gbe::kernelGetArgNum;
+    gbe_kernel_get_curbe_size = gbe::kernelGetCurbeSize;
+    gbe_kernel_get_sampler_size = gbe::kernelGetSamplerSize;
+    gbe_kernel_get_compile_wg_size = gbe::kernelGetCompileWorkGroupSize;
+    gbe_kernel_get_stack_size = gbe::kernelGetStackSize;
+    gbe_kernel_get_image_size = gbe::kernelGetImageSize;
+    gbe_kernel_get_name = gbe::kernelGetName;
+    gbe_kernel_get_arg_type = gbe::kernelGetArgType;
+    gbe_kernel_get_arg_size = gbe::kernelGetArgSize;
+    gbe_kernel_get_simd_width = gbe::kernelGetSIMDWidth;
+    gbe_kernel_get_scratch_size = gbe::kernelGetScratchSize;
+    gbe_kernel_use_slm = gbe::kernelUseSLM;
+    gbe_kernel_get_required_work_group_size = gbe::kernelGetRequiredWorkGroupSize;
+    gbe_kernel_get_curbe_offset = gbe::kernelGetCurbeOffset;
+    gbe_kernel_get_slm_size = gbe::kernelGetSLMSize;
+    gbe_kernel_get_arg_align = gbe::kernelGetArgAlign;
+    gbe_program_get_global_constant_size = gbe::programGetGlobalConstantSize;
+    gbe_program_delete = gbe::programDelete;
+    gbe_program_get_global_constant_data = gbe::programGetGlobalConstantData;
+    gbe_kernel_get_sampler_data = gbe::kernelGetSamplerData;
+    gbe_kernel_get_image_data = gbe::kernelGetImageData;
+    gbe_get_image_base_index = gbe::getImageBaseIndex;
+    gbe_set_image_base_index_interp = gbe::setImageBaseIndex;
+  }
+
+  ~BinInterpCallBackInitializer() {
+  }
+};
+
+static struct BinInterpCallBackInitializer binInterpCB;
diff --git a/backend/src/ir/image.cpp b/backend/src/ir/image.cpp index 8c34d70..ee80a3d 100644
--- a/backend/src/ir/image.cpp
+++ b/backend/src/ir/image.cpp
@@ -64,16 +64,6 @@ namespace ir {
     setInfoOffset4Type(imageInfo, key.type, offset);
   }
 
-  Register ImageSet::appendInfo(ImageInfoKey key, Context *ctx)
-  {
-    auto it = infoRegMap.find(key.data);
-    if (it != infoRegMap.end())
-      return it->second;
-    Register reg = ctx->reg(FAMILY_DWORD);
-    infoRegMap.insert(std::make_pair(key.data, reg));
-    return reg;
-  }
-
   void ImageSet::clearInfo()
   {
     struct ImageInfo *imageInfo;
@@ -87,26 +77,6 @@ namespace ir {
     }
   }
 
-  void ImageSet::append(Register imageReg, Context *ctx)
-  {
-    ir::FunctionArgument *arg =  ctx->getFunction().getArg(imageReg);
-    GBE_ASSERTM(arg && arg->type == ir::FunctionArgument::IMAGE, "Append an invalid reg to image set.");
-    GBE_ASSERTM(regMap.find(imageReg) == regMap.end(), "Append the same image reg twice.");
-
-    int32_t id = ctx->getFunction().getArgID(arg);
-    struct ImageInfo *imageInfo = GBE_NEW(struct ImageInfo);
-    imageInfo->arg_idx = id;
-    imageInfo->idx = regMap.size() + gbe_get_image_base_index();
-    imageInfo->wSlot = -1;
-    imageInfo->hSlot = -1;
-    imageInfo->depthSlot = -1;
-    imageInfo->dataTypeSlot = -1;
-    imageInfo->channelOrderSlot = -1;
-    imageInfo->dimOrderSlot = -1;
-    regMap.insert(std::make_pair(imageReg, imageInfo));
-    indexMap.insert(std::make_pair(imageInfo->idx, imageInfo));
-  }
-
   const int32_t ImageSet::getInfoOffset(ImageInfoKey key) const
   {
     auto it = indexMap.find(key.index); @@ -271,6 +241,37 @@ namespace ir {
    outs << spaces << "------------- End ImageSet -------------" << "\n";
   }
 
+#ifdef GBE_COMPILER_AVAILABLE
+  Register ImageSet::appendInfo(ImageInfoKey key, Context *ctx)
+  {
+    auto it = infoRegMap.find(key.data);
+    if (it != infoRegMap.end())
+      return it->second;
+    Register reg = ctx->reg(FAMILY_DWORD);
+    infoRegMap.insert(std::make_pair(key.data, reg));
+    return reg;
+  }
+
+  void ImageSet::append(Register imageReg, Context *ctx)  {
+    ir::FunctionArgument *arg =  ctx->getFunction().getArg(imageReg);
+    GBE_ASSERTM(arg && arg->type == ir::FunctionArgument::IMAGE, "Append an invalid reg to image set.");
+    GBE_ASSERTM(regMap.find(imageReg) == regMap.end(), "Append the same 
+ image reg twice.");
+
+    int32_t id = ctx->getFunction().getArgID(arg);
+    struct ImageInfo *imageInfo = GBE_NEW(struct ImageInfo);
+    imageInfo->arg_idx = id;
+    imageInfo->idx = regMap.size() + gbe_get_image_base_index();
+    imageInfo->wSlot = -1;
+    imageInfo->hSlot = -1;
+    imageInfo->depthSlot = -1;
+    imageInfo->dataTypeSlot = -1;
+    imageInfo->channelOrderSlot = -1;
+    imageInfo->dimOrderSlot = -1;
+    regMap.insert(std::make_pair(imageReg, imageInfo));
+    indexMap.insert(std::make_pair(imageInfo->idx, imageInfo));
+  }
+#endif
 
 } /* namespace ir */
 } /* namespace gbe */
diff --git a/backend/src/ir/sampler.cpp b/backend/src/ir/sampler.cpp index b67c1b7..1406ff6 100644
--- a/backend/src/ir/sampler.cpp
+++ b/backend/src/ir/sampler.cpp
@@ -27,6 +27,7 @@
 namespace gbe {
 namespace ir {
 
+#ifdef GBE_COMPILER_AVAILABLE
   uint8_t SamplerSet::appendReg(uint32_t key, Context *ctx) {
     uint8_t samplerSlot = samplerMap.size();
     samplerMap.insert(std::make_pair(key, samplerSlot)); @@ -61,6 +62,7 @@ namespace ir {
     }
     return appendReg(SAMPLER_ID(id), ctx);
   }
+#endif
 
 #define OUT_UPDATE_SZ(elt) SERIALIZE_OUT(elt, outs, ret_size)  #define IN_UPDATE_SZ(elt) DESERIALIZE_IN(elt, ins, total_size) diff --git a/backend/src/ocl_common_defines.h b/backend/src/ocl_common_defines.h
index b736a88..52f5365 100644
--- a/backend/src/ocl_common_defines.h
+++ b/backend/src/ocl_common_defines.h
@@ -1,6 +1,7 @@
 // This file includes defines that are common to both kernel code and  // the NVPTX back-end.
-
+#ifndef __OCL_COMMON_DEFINES__
+#define __OCL_COMMON_DEFINES__
 //
 // Common defines for Image intrinsics
 // Channel order
@@ -121,3 +122,5 @@ typedef enum clk_sampler_type {  // Memory synchronization
 #define CLK_LOCAL_MEM_FENCE     (1 << 0)
 #define CLK_GLOBAL_MEM_FENCE    (1 << 1)
+
+#endif   /* __OCL_COMMON_DEFINES__ */
\ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 20e1a4c..4c2b027 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -54,6 +54,7 @@ set(OPENCL_SRC
     cl_alloc.c
     cl_kernel.c
     cl_program.c
+    cl_gbe_loader.cpp
     cl_sampler.c
     cl_event.c
     cl_enqueue.c
@@ -98,12 +99,14 @@ link_directories (${LLVM_LIBRARY_DIR})  add_library(cl SHARED ${OPENCL_SRC})  target_link_libraries(
                       cl
-                      gbe
+                      interp
                       ${XLIB_LIBRARY}
                       ${XEXT_LIBRARIES}
                       ${XFIXES_LIBRARIES}
                       ${DRM_INTEL_LIBRARIES}
                       ${DRM_LIBRARIES}
+                      ${CMAKE_THREAD_LIBS_INIT}
+                      ${CMAKE_DL_LIBS}
                       ${OPENGL_LIBRARIES}
                       ${OPTIONAL_EGL_LIBRARY})  install (TARGETS cl LIBRARY DESTINATION ${LIB_INSTALL_DIR}/beignet) diff --git a/src/cl_device_id.c b/src/cl_device_id.c index 4dc74cd..427c50e 100644
--- a/src/cl_device_id.c
+++ b/src/cl_device_id.c
@@ -26,6 +26,7 @@
 #include "cl_khr_icd.h"
 #include "cl_thread.h"
 #include "CL/cl.h"
+#include "cl_gbe_loader.h"
 
 #include <assert.h>
 #include <stdio.h>
@@ -252,6 +253,15 @@ baytrail_t_device_break:
       printf("cl_get_gt_device(): error, unknown device: %x\n", device_id);
   }
 
+  if (!CompilerSupported()) {
+    if (ret != NULL) {
+      ret->compiler_available = CL_FALSE;
+      //ret->linker_available = CL_FALSE;
+      ret->profile = "EMBEDDED_PROFILE";
+      ret->profile_sz = strlen(ret->profile) + 1;
+    }
+  }
+
   return ret;
 }
 
diff --git a/src/cl_gbe_loader.cpp b/src/cl_gbe_loader.cpp new file mode 100644 index 0000000..da83c9a
--- /dev/null
+++ b/src/cl_gbe_loader.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <dlfcn.h>
+#include <string.h>
+#include "cl_gbe_loader.h"
+#include "backend/src/GBEConfig.h"
+
+struct GbeLoaderInitializer
+{
+  GbeLoaderInitializer() {
+    inited = false;
+
+    const char* nonCompiler = getenv("OCL_NON_COMPILER");
+    if (nonCompiler != NULL) {
+      if (strcmp(nonCompiler, "1") == 0)
+        return;
+    }
+
+    const char* gbePath = getenv("OCL_GBE_PATH");
+    if (gbePath == NULL)
+      gbePath = GBE_OBJECT_DIR;
+
+    dlh = dlopen(gbePath, RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND);
+    if (dlh != NULL) {
+      gbe_program_new_from_source = *(gbe_program_new_from_source_cb **)dlsym(dlh, "gbe_program_new_from_source");
+      if (gbe_program_new_from_source == NULL)
+        return;
+
+      gbe_program_serialize_to_binary = *(gbe_program_serialize_to_binary_cb **)dlsym(dlh, "gbe_program_serialize_to_binary");
+      if (gbe_program_serialize_to_binary == NULL)
+        return;
+
+      gbe_program_new_from_llvm = *(gbe_program_new_from_llvm_cb **)dlsym(dlh, "gbe_program_new_from_llvm");
+      if (gbe_program_new_from_llvm == NULL)
+        return;
+
+      //gbe_kernel_set_const_buffer_size is not used by runttime
+      gbe_kernel_set_const_buffer_size = *(gbe_kernel_set_const_buffer_size_cb **)dlsym(dlh, "gbe_kernel_set_const_buffer_size");
+      if (gbe_kernel_set_const_buffer_size == NULL)
+        return;
+
+      gbe_set_image_base_index_compiler = *(gbe_set_image_base_index_cb **)dlsym(dlh, "gbe_set_image_base_index_compiler");
+      if (gbe_set_image_base_index_compiler == NULL)
+        return;
+
+      inited = true;
+    }
+  }
+
+  ~GbeLoaderInitializer() {
+    if (dlh != NULL)
+      dlclose(dlh);
+  }
+
+  bool inited;
+  void *dlh;
+};
+
+static struct GbeLoaderInitializer gbeLoader;
+
+int CompilerSupported()
+{
+  if (gbeLoader.inited)
+    return 1;
+  else
+    return 0;
+}
diff --git a/src/cl_gbe_loader.h b/src/cl_gbe_loader.h new file mode 100644 index 0000000..50ec55b
--- /dev/null
+++ b/src/cl_gbe_loader.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __CL_GBE_LOADER_H__
+#define __CL_GBE_LOADER_H__
+
+#include "program.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+int CompilerSupported();
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CL_GBE_LOADER_H__ */
diff --git a/src/cl_kernel.h b/src/cl_kernel.h index fb509a2..8d0e566 100644
--- a/src/cl_kernel.h
+++ b/src/cl_kernel.h
@@ -22,7 +22,7 @@
 
 #include "cl_internals.h"
 #include "cl_driver.h"
-#include "program.h"
+#include "cl_gbe_loader.h"
 #include "CL/cl.h"
 
 #include <stdint.h>
diff --git a/src/cl_program.c b/src/cl_program.c index 184d6b5..c4e85d1 100644
--- a/src/cl_program.c
+++ b/src/cl_program.c
@@ -24,6 +24,7 @@
 #include "cl_alloc.h"
 #include "cl_utils.h"
 #include "cl_khr_icd.h"
+#include "cl_gbe_loader.h"
 #include "CL/cl.h"
 #include "CL/cl_intel.h"
 
@@ -326,6 +327,11 @@ cl_program_build(cl_program p, const char *options)
   }
 
   if (p->source_type == FROM_SOURCE) {
+    if (!CompilerSupported()) {
+      err = CL_COMPILER_NOT_AVAILABLE;
+      goto error;
+    }
+
     p->opaque = gbe_program_new_from_source(p->ctx->device->vendor_id, p->source, p->build_log_max_sz, options, p->build_log, &p->build_log_sz);
     if (UNLIKELY(p->opaque == NULL)) {
       if (p->build_log_sz > 0 && strstr(p->build_log, "error: error reading 'options'")) diff --git a/src/cl_program.h b/src/cl_program.h index a6d75da..4218efd 100644
--- a/src/cl_program.h
+++ b/src/cl_program.h
@@ -21,7 +21,7 @@
 #define __CL_PROGRAM_H__
 
 #include "cl_internals.h"
-#include "program.h"
+#include "cl_gbe_loader.h"
 #include "CL/cl.h"
 
 #include <stdint.h>
diff --git a/src/intel/intel_driver.c b/src/intel/intel_driver.c index 08d6bc0..aa31344 100644
--- a/src/intel/intel_driver.c
+++ b/src/intel/intel_driver.c
@@ -399,7 +399,8 @@ cl_intel_driver_delete(intel_driver_t *driver)
   intel_driver_terminate(driver);
   intel_driver_delete(driver);
 }
-#include "program.h"
+
+#include "cl_gbe_loader.h"
 static intel_driver_t*
 cl_intel_driver_new(cl_context_prop props)  { @@ -409,7 +410,9 @@ cl_intel_driver_new(cl_context_prop props)
   /* We use the first 2 slots(0,1) for all the bufs.
    * Notify the gbe this base index, thus gbe can avoid conflicts
    * when it allocates slots for images*/
-  gbe_set_image_base_index(3);
+  if (CompilerSupported())
+    gbe_set_image_base_index_compiler(3);
+  gbe_set_image_base_index_interp(3);
 exit:
   return driver;
 error:
diff --git a/utests/setenv.sh.in b/utests/setenv.sh.in index ad77369..95f468b 100644
--- a/utests/setenv.sh.in
+++ b/utests/setenv.sh.in
@@ -3,3 +3,4 @@
 export OCL_PCM_PATH=@LOCAL_PCM_OBJECT_DIR@
 export OCL_PCH_PATH=@LOCAL_PCH_OBJECT_DIR@
 export OCL_KERNEL_PATH=@CMAKE_CURRENT_SOURCE_DIR@/../kernels
+export OCL_GBE_PATH=@LOCAL_GBE_OBJECT_DIR@
--
1.8.3.2

_______________________________________________
Beignet mailing list
Beignet at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list