From bfb82e4985717ff64e50e36f6d6174e4eefa60bc Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 17 Apr 2014 14:56:08 +0800 Subject: [PATCH] GBE/Runtime: pass the device id to the compiler backend. For some reason, we need to know current target device id at the code generation stage. This patch introduces such a mechanism. This is the preparation for the baytrail werid hang issue fixing. Signed-off-by: Zhigang Gong Reviewed-by: He Junyan --- backend/src/backend/gen_context.cpp | 5 +++-- backend/src/backend/gen_context.hpp | 4 +++- backend/src/backend/gen_encoder.cpp | 4 ++-- backend/src/backend/gen_encoder.hpp | 5 ++++- backend/src/backend/gen_program.cpp | 14 ++++++++------ backend/src/backend/gen_program.hpp | 4 +++- backend/src/backend/program.cpp | 5 +++-- backend/src/backend/program.h | 8 +++++--- backend/src/gbe_bin_generater.cpp | 4 +++- src/cl_program.c | 6 +++--- 10 files changed, 37 insertions(+), 22 deletions(-) diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp index ea673b6..3ee38dd 100644 --- a/backend/src/backend/gen_context.cpp +++ b/backend/src/backend/gen_context.cpp @@ -44,11 +44,12 @@ namespace gbe /////////////////////////////////////////////////////////////////////////// GenContext::GenContext(const ir::Unit &unit, const std::string &name, + uint32_t deviceID, bool limitRegisterPressure, bool relaxMath) : - Context(unit, name), limitRegisterPressure(limitRegisterPressure), relaxMath(relaxMath) + Context(unit, name), deviceID(deviceID), limitRegisterPressure(limitRegisterPressure), relaxMath(relaxMath) { - this->p = GBE_NEW(GenEncoder, simdWidth, 7); // XXX handle more than Gen7 + this->p = GBE_NEW(GenEncoder, simdWidth, 7, deviceID); // XXX handle more than Gen7 this->sel = GBE_NEW(Selection, *this); this->ra = GBE_NEW(GenRegAllocator, *this); } diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp index d24d05b..1154796 100644 --- a/backend/src/backend/gen_context.hpp +++ b/backend/src/backend/gen_context.hpp @@ -52,9 +52,11 @@ namespace gbe /*! Create a new context. name is the name of the function we want to * compile */ - GenContext(const ir::Unit &unit, const std::string &name, bool limitRegisterPressure = false, bool relaxMath = false); + GenContext(const ir::Unit &unit, const std::string &name, uint32_t deviceID, bool limitRegisterPressure = false, bool relaxMath = false); /*! Release everything needed */ ~GenContext(void); + /*! Target device ID*/ + uint32_t deviceID; /*! Implements base class */ virtual bool emitCode(void); /*! Function we emit code for */ diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp index ce9be09..0de4504 100644 --- a/backend/src/backend/gen_encoder.cpp +++ b/backend/src/backend/gen_encoder.cpp @@ -216,8 +216,8 @@ namespace gbe ////////////////////////////////////////////////////////////////////////// // Gen Emitter encoding class ////////////////////////////////////////////////////////////////////////// - GenEncoder::GenEncoder(uint32_t simdWidth, uint32_t gen) : - stateNum(0), gen(gen) + GenEncoder::GenEncoder(uint32_t simdWidth, uint32_t gen, uint32_t deviceID) : + stateNum(0), gen(gen), deviceID(deviceID) { this->curr.execWidth = simdWidth; this->curr.quarterControl = GEN_COMPRESSION_Q1; diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp index 321c8c1..9a8d47e 100644 --- a/backend/src/backend/gen_encoder.hpp +++ b/backend/src/backend/gen_encoder.hpp @@ -56,6 +56,7 @@ #include "sys/platform.hpp" #include "sys/vector.hpp" #include +#include "src/cl_device_data.h" namespace gbe { @@ -64,7 +65,7 @@ namespace gbe { public: /*! simdWidth is the default width for the instructions */ - GenEncoder(uint32_t simdWidth, uint32_t gen); + GenEncoder(uint32_t simdWidth, uint32_t gen, uint32_t deviceID); /*! Size of the stack (should be large enough) */ enum { MAX_STATE_NUM = 16 }; /*! Push the current instruction state */ @@ -81,6 +82,8 @@ namespace gbe uint32_t stateNum; /*! Gen generation to encode */ uint32_t gen; + /*! Device ID */ + uint32_t deviceID; //////////////////////////////////////////////////////////////////////// // Encoding functions diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp index 1f157e0..240ae4f 100644 --- a/backend/src/backend/gen_program.cpp +++ b/backend/src/backend/gen_program.cpp @@ -71,7 +71,6 @@ namespace gbe { fclose(f); } - GenProgram::GenProgram(void) {} GenProgram::~GenProgram(void) {} /*! We must avoid spilling at all cost with Gen */ @@ -102,7 +101,7 @@ namespace gbe { // Force the SIMD width now and try to compile unit.getFunction(name)->setSimdWidth(simdWidth); - Context *ctx = GBE_NEW(GenContext, unit, name, limitRegisterPressure, relaxMath); + Context *ctx = GBE_NEW(GenContext, unit, name, deviceID, limitRegisterPressure, relaxMath); kernel = ctx->compileKernel(); if (kernel != NULL) { break; @@ -116,12 +115,14 @@ namespace gbe { return kernel; } - static gbe_program genProgramNewFromBinary(const char *binary, size_t size) { + static gbe_program genProgramNewFromBinary(uint32_t deviceID, const char *binary, size_t size) { using namespace gbe; std::string binary_content; binary_content.assign(binary, size); - GenProgram *program = GBE_NEW_NO_ARG(GenProgram); + GenProgram *program = GBE_NEW(GenProgram, deviceID); std::istringstream ifs(binary_content, std::ostringstream::binary); + // FIXME we need to check the whether the current device ID match the binary file's. + deviceID = deviceID; if (!program->deserializeFromBin(ifs)) { delete program; @@ -148,14 +149,15 @@ namespace gbe { return sz; } - static gbe_program genProgramNewFromLLVM(const char *fileName, + static gbe_program genProgramNewFromLLVM(uint32_t deviceID, + const char *fileName, size_t stringSize, char *err, size_t *errSize, int optLevel) { using namespace gbe; - GenProgram *program = GBE_NEW_NO_ARG(GenProgram); + GenProgram *program = GBE_NEW(GenProgram, deviceID); std::string error; // Try to compile the program if (program->buildFromLLVMFile(fileName, error, optLevel) == false) { diff --git a/backend/src/backend/gen_program.hpp b/backend/src/backend/gen_program.hpp index 189c262..ea54b49 100644 --- a/backend/src/backend/gen_program.hpp +++ b/backend/src/backend/gen_program.hpp @@ -58,7 +58,9 @@ namespace gbe { public: /*! Create an empty program */ - GenProgram(void); + GenProgram(uint32_t deviceID) : deviceID(deviceID) {} + /*! Current device ID*/ + uint32_t deviceID; /*! Destroy the program */ virtual ~GenProgram(void); /*! Implements base class */ diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp index 91abbae..79622e0 100644 --- a/backend/src/backend/program.cpp +++ b/backend/src/backend/program.cpp @@ -690,7 +690,8 @@ namespace gbe { extern std::string ocl_stdlib_str; BVAR(OCL_USE_PCH, true); - static gbe_program programNewFromSource(const char *source, + static gbe_program programNewFromSource(uint32_t deviceID, + const char *source, size_t stringSize, const char *options, char *err, @@ -829,7 +830,7 @@ namespace gbe { err += *errSize; clangErrSize = *errSize; } - p = gbe_program_new_from_llvm(llName.c_str(), stringSize, + p = gbe_program_new_from_llvm(deviceID, llName.c_str(), stringSize, err, errSize, optLevel); if (err != NULL) *errSize += clangErrSize; diff --git a/backend/src/backend/program.h b/backend/src/backend/program.h index c22793e..d90ada3 100644 --- a/backend/src/backend/program.h +++ b/backend/src/backend/program.h @@ -112,7 +112,8 @@ typedef void (gbe_kernel_get_image_data_cb)(gbe_kernel gbeKernel, ImageInfo *ima extern gbe_kernel_get_image_data_cb *gbe_kernel_get_image_data; /*! Create a new program from the given source code (zero terminated string) */ -typedef gbe_program (gbe_program_new_from_source_cb)(const char *source, +typedef gbe_program (gbe_program_new_from_source_cb)(uint32_t deviceID, + const char *source, size_t stringSize, const char *options, char *err, @@ -120,7 +121,7 @@ typedef gbe_program (gbe_program_new_from_source_cb)(const char *source, extern gbe_program_new_from_source_cb *gbe_program_new_from_source; /*! Create a new program from the given blob */ -typedef gbe_program (gbe_program_new_from_binary_cb)(const char *binary, size_t size); +typedef gbe_program (gbe_program_new_from_binary_cb)(uint32_t deviceID, const char *binary, size_t size); extern gbe_program_new_from_binary_cb *gbe_program_new_from_binary; /*! Serialize a program to a bin */ @@ -128,7 +129,8 @@ typedef size_t (gbe_program_serialize_to_binary_cb)(gbe_program program, char ** 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, +typedef gbe_program (gbe_program_new_from_llvm_cb)(uint32_t deviceID, + const char *fileName, size_t string_size, char *err, size_t *err_size, diff --git a/backend/src/gbe_bin_generater.cpp b/backend/src/gbe_bin_generater.cpp index f813775..1d97f01 100644 --- a/backend/src/gbe_bin_generater.cpp +++ b/backend/src/gbe_bin_generater.cpp @@ -192,7 +192,9 @@ void program_build_instance::serialize_program(void) throw(int) void program_build_instance::build_program(void) throw(int) { - gbe_program opaque = gbe_program_new_from_source(code, 0, build_opt.c_str(), NULL, NULL); + // FIXME, we need to find a graceful way to generate internal binaries for difference + // devices. + gbe_program opaque = gbe_program_new_from_source(0, code, 0, build_opt.c_str(), NULL, NULL); if (!opaque) throw FILE_BUILD_FAILED; diff --git a/src/cl_program.c b/src/cl_program.c index 8ae3aa7..184d6b5 100644 --- a/src/cl_program.c +++ b/src/cl_program.c @@ -225,7 +225,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(file_name, program->build_log_max_sz, program->build_log, &program->build_log_sz, 1); + 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); if (UNLIKELY(program->opaque == NULL)) { err = CL_INVALID_PROGRAM; goto error; @@ -326,7 +326,7 @@ cl_program_build(cl_program p, const char *options) } if (p->source_type == FROM_SOURCE) { - p->opaque = gbe_program_new_from_source(p->source, p->build_log_max_sz, options, p->build_log, &p->build_log_sz); + 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'")) err = CL_INVALID_BUILD_OPTIONS; @@ -339,7 +339,7 @@ cl_program_build(cl_program p, const char *options) 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); + p->opaque = gbe_program_new_from_binary(p->ctx->device->vendor_id, p->binary, p->binary_sz); if (UNLIKELY(p->opaque == NULL)) { err = CL_BUILD_PROGRAM_FAILURE; goto error; -- 2.7.4