From f9074f9ff4e24da2ee92fc84a8dcff0604346d28 Mon Sep 17 00:00:00 2001 From: Guo Yejun Date: Fri, 30 May 2014 06:29:09 +0800 Subject: [PATCH] extract libgbeinterp.so from runtime (libcl.so) currently, there are same symbol names in libinterp.a (inside libcl.so) and libgbe.so (compiler), and so have to dlopen libgbe.so with RTLD_DEEPBIND, this flag makes std::cerr inside libgbe crash. extract the interp part from libcl.so as libgbeinterp.so, therefore, first dlopen libgbe.so without RTLD_DEEPBIND, then dlopen libgbeinterp.so with RTLD_DEEPBIND, to fix the std:cerr crash issue. Signed-off-by: Guo Yejun Reviewed-by: Zhigang Gong --- backend/CMakeLists.txt | 2 + backend/src/CMakeLists.txt | 5 +- backend/src/GBEConfig.h.in | 1 + src/CMakeLists.txt | 1 - src/cl_api.c | 4 +- src/cl_gbe_loader.cpp | 229 ++++++++++++++++++++++++++++++++++++++++----- src/cl_gbe_loader.h | 5 + src/cl_program.c | 4 +- src/intel/intel_driver.c | 2 +- utests/setenv.sh.in | 1 + 10 files changed, 226 insertions(+), 28 deletions(-) diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt index a20f423..d25255e 100644 --- a/backend/CMakeLists.txt +++ b/backend/CMakeLists.txt @@ -102,6 +102,8 @@ 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(LOCAL_INTERP_OBJECT_DIR ${LOCAL_INTERP_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 528595f..02c6404 100644 --- a/backend/src/CMakeLists.txt +++ b/backend/src/CMakeLists.txt @@ -195,7 +195,7 @@ target_link_libraries( ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) -add_library(interp STATIC gbe_bin_interpreter.cpp) +add_library(gbeinterp SHARED gbe_bin_interpreter.cpp) if (LLVM_VERSION_NODOT VERSION_EQUAL 34) find_library(TERMINFO NAMES tinfo ncurses) @@ -212,6 +212,7 @@ ADD_EXECUTABLE(gbe_bin_generater gbe_bin_generater.cpp) TARGET_LINK_LIBRARIES(gbe_bin_generater gbe) install (TARGETS gbe LIBRARY DESTINATION ${LIB_INSTALL_DIR}/beignet) +install (TARGETS gbeinterp 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) @@ -221,10 +222,12 @@ install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${pcm_lib} DESTINATION ${LIB_INSTALL_ 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 (LOCAL_INTERP_OBJECT_DIR "${CMAKE_CURRENT_BINARY_DIR}/libgbeinterp.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") +set (INTERP_OBJECT_DIR "${beignet_install_path}/libgbeinterp.so") configure_file ( "GBEConfig.h.in" "GBEConfig.h" diff --git a/backend/src/GBEConfig.h.in b/backend/src/GBEConfig.h.in index ad24390..f5c69c6 100644 --- a/backend/src/GBEConfig.h.in +++ b/backend/src/GBEConfig.h.in @@ -4,3 +4,4 @@ #define PCH_OBJECT_DIR "@PCH_OBJECT_DIR@" #define PCM_OBJECT_DIR "@PCM_OBJECT_DIR@" #define GBE_OBJECT_DIR "@GBE_OBJECT_DIR@" +#define INTERP_OBJECT_DIR "@INTERP_OBJECT_DIR@" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4c2b027..a8d35d6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -99,7 +99,6 @@ link_directories (${LLVM_LIBRARY_DIR}) add_library(cl SHARED ${OPENCL_SRC}) target_link_libraries( cl - interp ${XLIB_LIBRARY} ${XEXT_LIBRARIES} ${XFIXES_LIBRARIES} diff --git a/src/cl_api.c b/src/cl_api.c index 0800c09..6206e10 100644 --- a/src/cl_api.c +++ b/src/cl_api.c @@ -920,7 +920,7 @@ clGetProgramInfo(cl_program program, program->source, CL_SUCCESS); } else if (param_name == CL_PROGRAM_BINARY_SIZES) { if (program->binary == NULL) { - program->binary_sz = gbe_program_serialize_to_binary(program->opaque, &program->binary); + program->binary_sz = compiler_program_serialize_to_binary(program->opaque, &program->binary); } if (program->binary == NULL || program->binary_sz == 0) { @@ -936,7 +936,7 @@ clGetProgramInfo(cl_program program, /* param_value points to an array of n pointers allocated by the caller */ if (program->binary == NULL) { - program->binary_sz = gbe_program_serialize_to_binary(program->opaque, &program->binary); + program->binary_sz = compiler_program_serialize_to_binary(program->opaque, &program->binary); } if (program->binary == NULL || program->binary_sz == 0) { diff --git a/src/cl_gbe_loader.cpp b/src/cl_gbe_loader.cpp index da83c9a..794b12b 100644 --- a/src/cl_gbe_loader.cpp +++ b/src/cl_gbe_loader.cpp @@ -15,15 +15,197 @@ * License along with this library. If not, see . * */ +#include #include #include +#include #include "cl_gbe_loader.h" #include "backend/src/GBEConfig.h" +//function pointer from libgbe.so +gbe_program_new_from_source_cb *compiler_program_new_from_source = NULL; +gbe_program_serialize_to_binary_cb *compiler_program_serialize_to_binary = NULL; +gbe_program_new_from_llvm_cb *compiler_program_new_from_llvm = NULL; +gbe_kernel_set_const_buffer_size_cb *compiler_kernel_set_const_buffer_size = NULL; +gbe_set_image_base_index_cb *compiler_set_image_base_index_compiler = NULL; + +//function pointer from libgbeinterp.so +gbe_program_new_from_binary_cb *gbe_program_new_from_binary = NULL; +gbe_program_get_global_constant_size_cb *gbe_program_get_global_constant_size = NULL; +gbe_program_get_global_constant_data_cb *gbe_program_get_global_constant_data = NULL; +gbe_program_delete_cb *gbe_program_delete = NULL; +gbe_program_get_kernel_num_cb *gbe_program_get_kernel_num = NULL; +gbe_program_get_kernel_by_name_cb *gbe_program_get_kernel_by_name = NULL; +gbe_program_get_kernel_cb *gbe_program_get_kernel = NULL; +gbe_kernel_get_name_cb *gbe_kernel_get_name = NULL; +gbe_kernel_get_code_cb *gbe_kernel_get_code = NULL; +gbe_kernel_get_code_size_cb *gbe_kernel_get_code_size = NULL; +gbe_kernel_get_arg_num_cb *gbe_kernel_get_arg_num = NULL; +gbe_kernel_get_arg_size_cb *gbe_kernel_get_arg_size = NULL; +gbe_kernel_get_arg_type_cb *gbe_kernel_get_arg_type = NULL; +gbe_kernel_get_arg_align_cb *gbe_kernel_get_arg_align = NULL; +gbe_kernel_get_simd_width_cb *gbe_kernel_get_simd_width = NULL; +gbe_kernel_get_curbe_offset_cb *gbe_kernel_get_curbe_offset = NULL; +gbe_kernel_get_curbe_size_cb *gbe_kernel_get_curbe_size = NULL; +gbe_kernel_get_stack_size_cb *gbe_kernel_get_stack_size = NULL; +gbe_kernel_get_scratch_size_cb *gbe_kernel_get_scratch_size = NULL; +gbe_kernel_get_required_work_group_size_cb *gbe_kernel_get_required_work_group_size = NULL; +gbe_kernel_use_slm_cb *gbe_kernel_use_slm = NULL; +gbe_kernel_get_slm_size_cb *gbe_kernel_get_slm_size = NULL; +gbe_kernel_get_sampler_size_cb *gbe_kernel_get_sampler_size = NULL; +gbe_kernel_get_sampler_data_cb *gbe_kernel_get_sampler_data = NULL; +gbe_kernel_get_compile_wg_size_cb *gbe_kernel_get_compile_wg_size = NULL; +gbe_kernel_get_image_size_cb *gbe_kernel_get_image_size = NULL; +gbe_kernel_get_image_data_cb *gbe_kernel_get_image_data = NULL; +gbe_set_image_base_index_cb *gbe_set_image_base_index_interp = NULL; +gbe_get_image_base_index_cb *gbe_get_image_base_index = NULL; + struct GbeLoaderInitializer { - GbeLoaderInitializer() { - inited = false; + GbeLoaderInitializer() + { + LoadCompiler(); + + const char* path; + if (!LoadInterp(path)) + std::cerr << "unable to load " << path << " which is part of the driver, please check!" << std::endl; + } + + bool LoadInterp(const char*& path) + { + const char* interpPath = getenv("OCL_INTERP_PATH"); + if (interpPath == NULL) + interpPath = INTERP_OBJECT_DIR; + + path = interpPath; + + dlhInterp = dlopen(interpPath, RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND); + if (dlhInterp == NULL) { + return false; + } + + gbe_program_new_from_binary = *(gbe_program_new_from_binary_cb**)dlsym(dlhInterp, "gbe_program_new_from_binary"); + if (gbe_program_new_from_binary == NULL) + return false; + + gbe_program_get_global_constant_size = *(gbe_program_get_global_constant_size_cb**)dlsym(dlhInterp, "gbe_program_get_global_constant_size"); + if (gbe_program_get_global_constant_size == NULL) + return false; + + gbe_program_get_global_constant_data = *(gbe_program_get_global_constant_data_cb**)dlsym(dlhInterp, "gbe_program_get_global_constant_data"); + if (gbe_program_get_global_constant_data == NULL) + return false; + + gbe_program_delete = *(gbe_program_delete_cb**)dlsym(dlhInterp, "gbe_program_delete"); + if (gbe_program_delete == NULL) + return false; + + gbe_program_get_kernel_num = *(gbe_program_get_kernel_num_cb**)dlsym(dlhInterp, "gbe_program_get_kernel_num"); + if (gbe_program_get_kernel_num == NULL) + return false; + + gbe_program_get_kernel_by_name = *(gbe_program_get_kernel_by_name_cb**)dlsym(dlhInterp, "gbe_program_get_kernel_by_name"); + if (gbe_program_get_kernel_by_name == NULL) + return false; + + gbe_program_get_kernel = *(gbe_program_get_kernel_cb**)dlsym(dlhInterp, "gbe_program_get_kernel"); + if (gbe_program_get_kernel == NULL) + return false; + + gbe_kernel_get_name = *(gbe_kernel_get_name_cb**)dlsym(dlhInterp, "gbe_kernel_get_name"); + if (gbe_kernel_get_name == NULL) + return false; + + gbe_kernel_get_code = *(gbe_kernel_get_code_cb**)dlsym(dlhInterp, "gbe_kernel_get_code"); + if (gbe_kernel_get_code == NULL) + return false; + + gbe_kernel_get_code_size = *(gbe_kernel_get_code_size_cb**)dlsym(dlhInterp, "gbe_kernel_get_code_size"); + if (gbe_kernel_get_code_size == NULL) + return false; + + gbe_kernel_get_arg_num = *(gbe_kernel_get_arg_num_cb**)dlsym(dlhInterp, "gbe_kernel_get_arg_num"); + if (gbe_kernel_get_arg_num == NULL) + return false; + + gbe_kernel_get_arg_size = *(gbe_kernel_get_arg_size_cb**)dlsym(dlhInterp, "gbe_kernel_get_arg_size"); + if (gbe_kernel_get_arg_size == NULL) + return false; + + gbe_kernel_get_arg_type = *(gbe_kernel_get_arg_type_cb**)dlsym(dlhInterp, "gbe_kernel_get_arg_type"); + if (gbe_kernel_get_arg_type == NULL) + return false; + + gbe_kernel_get_arg_align = *(gbe_kernel_get_arg_align_cb**)dlsym(dlhInterp, "gbe_kernel_get_arg_align"); + if (gbe_kernel_get_arg_align == NULL) + return false; + + gbe_kernel_get_simd_width = *(gbe_kernel_get_simd_width_cb**)dlsym(dlhInterp, "gbe_kernel_get_simd_width"); + if (gbe_kernel_get_simd_width == NULL) + return false; + + gbe_kernel_get_curbe_offset = *(gbe_kernel_get_curbe_offset_cb**)dlsym(dlhInterp, "gbe_kernel_get_curbe_offset"); + if (gbe_kernel_get_curbe_offset == NULL) + return false; + + gbe_kernel_get_curbe_size = *(gbe_kernel_get_curbe_size_cb**)dlsym(dlhInterp, "gbe_kernel_get_curbe_size"); + if (gbe_kernel_get_curbe_size == NULL) + return false; + + gbe_kernel_get_stack_size = *(gbe_kernel_get_stack_size_cb**)dlsym(dlhInterp, "gbe_kernel_get_stack_size"); + if (gbe_kernel_get_stack_size == NULL) + return false; + + gbe_kernel_get_scratch_size = *(gbe_kernel_get_scratch_size_cb**)dlsym(dlhInterp, "gbe_kernel_get_scratch_size"); + if (gbe_kernel_get_scratch_size == NULL) + return false; + + gbe_kernel_get_required_work_group_size = *(gbe_kernel_get_required_work_group_size_cb**)dlsym(dlhInterp, "gbe_kernel_get_required_work_group_size"); + if (gbe_kernel_get_required_work_group_size == NULL) + return false; + + gbe_kernel_use_slm = *(gbe_kernel_use_slm_cb**)dlsym(dlhInterp, "gbe_kernel_use_slm"); + if (gbe_kernel_use_slm == NULL) + return false; + + gbe_kernel_get_slm_size = *(gbe_kernel_get_slm_size_cb**)dlsym(dlhInterp, "gbe_kernel_get_slm_size"); + if (gbe_kernel_get_slm_size == NULL) + return false; + + gbe_kernel_get_sampler_size = *(gbe_kernel_get_sampler_size_cb**)dlsym(dlhInterp, "gbe_kernel_get_sampler_size"); + if (gbe_kernel_get_sampler_size == NULL) + return false; + + gbe_kernel_get_sampler_data = *(gbe_kernel_get_sampler_data_cb**)dlsym(dlhInterp, "gbe_kernel_get_sampler_data"); + if (gbe_kernel_get_sampler_data == NULL) + return false; + + gbe_kernel_get_compile_wg_size = *(gbe_kernel_get_compile_wg_size_cb**)dlsym(dlhInterp, "gbe_kernel_get_compile_wg_size"); + if (gbe_kernel_get_compile_wg_size == NULL) + return false; + + gbe_kernel_get_image_size = *(gbe_kernel_get_image_size_cb**)dlsym(dlhInterp, "gbe_kernel_get_image_size"); + if (gbe_kernel_get_image_size == NULL) + return false; + + gbe_kernel_get_image_data = *(gbe_kernel_get_image_data_cb**)dlsym(dlhInterp, "gbe_kernel_get_image_data"); + if (gbe_kernel_get_image_data == NULL) + return false; + + gbe_set_image_base_index_interp = *(gbe_set_image_base_index_cb**)dlsym(dlhInterp, "gbe_set_image_base_index_interp"); + if (gbe_set_image_base_index_interp == NULL) + return false; + + gbe_get_image_base_index = *(gbe_get_image_base_index_cb**)dlsym(dlhInterp, "gbe_get_image_base_index"); + if (gbe_get_image_base_index == NULL) + return false; + + return true; + } + + void LoadCompiler() + { + compilerLoaded = false; const char* nonCompiler = getenv("OCL_NON_COMPILER"); if (nonCompiler != NULL) { @@ -35,47 +217,52 @@ struct GbeLoaderInitializer 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) + dlhCompiler = dlopen(gbePath, RTLD_LAZY | RTLD_LOCAL); + if (dlhCompiler != NULL) { + compiler_program_new_from_source = *(gbe_program_new_from_source_cb **)dlsym(dlhCompiler, "gbe_program_new_from_source"); + if (compiler_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) + compiler_program_serialize_to_binary = *(gbe_program_serialize_to_binary_cb **)dlsym(dlhCompiler, "gbe_program_serialize_to_binary"); + if (compiler_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) + compiler_program_new_from_llvm = *(gbe_program_new_from_llvm_cb **)dlsym(dlhCompiler, "gbe_program_new_from_llvm"); + if (compiler_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) + compiler_kernel_set_const_buffer_size = *(gbe_kernel_set_const_buffer_size_cb **)dlsym(dlhCompiler, "gbe_kernel_set_const_buffer_size"); + if (compiler_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) + compiler_set_image_base_index_compiler = *(gbe_set_image_base_index_cb **)dlsym(dlhCompiler, "gbe_set_image_base_index_compiler"); + if (compiler_set_image_base_index_compiler == NULL) return; - inited = true; + compilerLoaded = true; } } - ~GbeLoaderInitializer() { - if (dlh != NULL) - dlclose(dlh); + ~GbeLoaderInitializer() + { + if (dlhCompiler != NULL) + dlclose(dlhCompiler); + + if (dlhInterp != NULL) + dlclose(dlhInterp); } - bool inited; - void *dlh; + bool compilerLoaded; + void *dlhCompiler; + void *dlhInterp; }; static struct GbeLoaderInitializer gbeLoader; int CompilerSupported() { - if (gbeLoader.inited) + if (gbeLoader.compilerLoaded) return 1; else return 0; diff --git a/src/cl_gbe_loader.h b/src/cl_gbe_loader.h index 50ec55b..be088f4 100644 --- a/src/cl_gbe_loader.h +++ b/src/cl_gbe_loader.h @@ -24,6 +24,11 @@ #ifdef __cplusplus extern "C" { #endif +extern gbe_program_new_from_source_cb *compiler_program_new_from_source; +extern gbe_program_serialize_to_binary_cb *compiler_program_serialize_to_binary; +extern gbe_program_new_from_llvm_cb *compiler_program_new_from_llvm; +extern gbe_kernel_set_const_buffer_size_cb *compiler_kernel_set_const_buffer_size; +extern gbe_set_image_base_index_cb *compiler_set_image_base_index_compiler; int CompilerSupported(); #ifdef __cplusplus } diff --git a/src/cl_program.c b/src/cl_program.c index c4e85d1..af9d21e 100644 --- a/src/cl_program.c +++ b/src/cl_program.c @@ -226,7 +226,7 @@ cl_program_create_from_llvm(cl_context ctx, INVALID_VALUE_IF (file_name == NULL); program = cl_program_new(ctx); - program->opaque = gbe_program_new_from_llvm(ctx->device->vendor_id, file_name, program->build_log_max_sz, program->build_log, &program->build_log_sz, 1); + program->opaque = compiler_program_new_from_llvm(ctx->device->vendor_id, file_name, program->build_log_max_sz, program->build_log, &program->build_log_sz, 1); if (UNLIKELY(program->opaque == NULL)) { err = CL_INVALID_PROGRAM; goto error; @@ -332,7 +332,7 @@ cl_program_build(cl_program p, const char *options) 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); + p->opaque = compiler_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'")) err = CL_INVALID_BUILD_OPTIONS; diff --git a/src/intel/intel_driver.c b/src/intel/intel_driver.c index d2a477d..dcd19ac 100644 --- a/src/intel/intel_driver.c +++ b/src/intel/intel_driver.c @@ -411,7 +411,7 @@ cl_intel_driver_new(cl_context_prop props) * Notify the gbe this base index, thus gbe can avoid conflicts * when it allocates slots for images*/ if (CompilerSupported()) - gbe_set_image_base_index_compiler(3); + compiler_set_image_base_index_compiler(3); gbe_set_image_base_index_interp(3); exit: return driver; diff --git a/utests/setenv.sh.in b/utests/setenv.sh.in index 95f468b..b0f575f 100644 --- a/utests/setenv.sh.in +++ b/utests/setenv.sh.in @@ -4,3 +4,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@ +export OCL_INTERP_PATH=@LOCAL_INTERP_OBJECT_DIR@ -- 2.7.4