From de299b9e6d12df9bde22042e7de5e72f6ac09190 Mon Sep 17 00:00:00 2001 From: ysh329 Date: Thu, 30 Jul 2020 11:19:47 +0800 Subject: [PATCH] [BugFix][OPENCL] Fix initalization sequence of opencl backend valid API. test=develop (#4003) * fix opencl backend. test=develop --- lite/api/paddle_api.cc | 16 +++++++++ lite/backends/opencl/cl_context.cc | 15 +++++++- lite/backends/opencl/cl_runtime.cc | 56 +++++++++++++++++++++++++++--- lite/backends/opencl/cl_runtime.h | 17 +++++---- lite/core/context.h | 13 ++++--- lite/core/program.cc | 19 +++++++--- 6 files changed, 112 insertions(+), 24 deletions(-) diff --git a/lite/api/paddle_api.cc b/lite/api/paddle_api.cc index 9e9176ea9d..5cd567b6e8 100644 --- a/lite/api/paddle_api.cc +++ b/lite/api/paddle_api.cc @@ -41,10 +41,26 @@ namespace lite_api { bool IsOpenCLBackendValid() { bool opencl_valid = false; + #ifdef LITE_WITH_OPENCL + bool opencl_lib_found = paddle::lite::CLWrapper::Global()->OpenclLibFound(); +#ifdef LITE_WITH_LOG + LOG(INFO) << "opencl_lib_found:" << opencl_lib_found; +#endif + if (opencl_lib_found == false) return false; + + bool dlsym_success = paddle::lite::CLWrapper::Global()->DlsymSuccess(); +#ifdef LITE_WITH_LOG + LOG(INFO) << "dlsym_success:" << dlsym_success; +#endif + if (dlsym_success == false) return false; + opencl_valid = paddle::lite::CLRuntime::Global()->OpenCLAvaliableForDevice(); #endif + +#ifdef LITE_WITH_LOG LOG(INFO) << "opencl_valid:" << opencl_valid; +#endif return opencl_valid; } diff --git a/lite/backends/opencl/cl_context.cc b/lite/backends/opencl/cl_context.cc index 002073517b..5fe19b0de5 100644 --- a/lite/backends/opencl/cl_context.cc +++ b/lite/backends/opencl/cl_context.cc @@ -34,15 +34,20 @@ cl::Program &CLContext::GetProgram(const std::string &file_name, std::string program_key = program_key_ss.str(); auto it = programs_.find(program_key); if (it != programs_.end()) { +#ifdef LITE_WITH_LOG VLOG(3) << " --- program -> " << program_key << " has been built --- "; +#endif return *(it->second); } auto program = CLRuntime::Global()->CreateProgram(GetContext(), file_name); - +#ifdef LITE_WITH_LOG VLOG(3) << " --- begin build program -> " << program_key << " --- "; +#endif CLRuntime::Global()->BuildProgram(program.get(), options); +#ifdef LITE_WITH_LOG VLOG(3) << " --- end build program -> " << program_key << " --- "; +#endif programs_[program_key] = std::move(program); @@ -54,14 +59,20 @@ void CLContext::AddKernel(const std::string &kernel_name, const std::string &options, const std::string &time_stamp) { cl_int status{CL_SUCCESS}; +#ifdef LITE_WITH_LOG VLOG(3) << " --- to get program " << file_name << " --- "; +#endif auto program = GetProgram(file_name, options); +#ifdef LITE_WITH_LOG VLOG(3) << " --- end get program --- "; VLOG(3) << " --- to create kernel: " << kernel_name << " --- "; +#endif std::shared_ptr kernel( new cl::Kernel(program, kernel_name.c_str(), &status)); CL_CHECK_FATAL(status); +#ifdef LITE_WITH_LOG VLOG(3) << " --- end create kernel --- "; +#endif kernels_.emplace_back(std::move(kernel)); STL::stringstream kernel_key; kernel_key << kernel_name << options << time_stamp; @@ -69,7 +80,9 @@ void CLContext::AddKernel(const std::string &kernel_name, } cl::Kernel &CLContext::GetKernel(const int index) { +#ifdef LITE_WITH_LOG VLOG(3) << " --- kernel count: " << kernels_.size() << " --- "; +#endif CHECK(static_cast(index) < kernels_.size()) << "The index must be less than the size of kernels."; CHECK(kernels_[index] != nullptr) diff --git a/lite/backends/opencl/cl_runtime.cc b/lite/backends/opencl/cl_runtime.cc index fe6b8fcd99..652ee9ca86 100644 --- a/lite/backends/opencl/cl_runtime.cc +++ b/lite/backends/opencl/cl_runtime.cc @@ -25,6 +25,13 @@ CLRuntime* CLRuntime::Global() { } CLRuntime::~CLRuntime() { +#ifdef LITE_WITH_LOG + LOG(INFO) << "is_cl_runtime_initialized_:" << is_cl_runtime_initialized_; +#endif + if (is_cl_runtime_initialized_ == false) { + return; + } + if (command_queue_ != nullptr) { command_queue_->flush(); command_queue_->finish(); @@ -38,18 +45,53 @@ CLRuntime::~CLRuntime() { } bool CLRuntime::Init() { +#ifdef LITE_WITH_LOG + LOG(INFO) << "is_cl_runtime_initialized_:" << is_cl_runtime_initialized_; +#endif if (is_cl_runtime_initialized_) { return true; } + + bool opencl_lib_found = paddle::lite::CLWrapper::Global()->OpenclLibFound(); +#ifdef LITE_WITH_LOG + LOG(INFO) << "opencl_lib_found:" << opencl_lib_found; +#endif + if (opencl_lib_found == false) { + return false; + } + + bool dlsym_success = paddle::lite::CLWrapper::Global()->DlsymSuccess(); +#ifdef LITE_WITH_LOG + LOG(INFO) << "dlsym_success:" << dlsym_success; +#endif + if (dlsym_success == false) { + return false; + } + bool is_platform_init = InitializePlatform(); - bool is_device_init = InitializeDevice(); +#ifdef LITE_WITH_LOG LOG(INFO) << "is_platform_init:" << is_platform_init; +#endif + if (is_platform_init == false) { + return false; + } + + bool is_device_init = InitializeDevice(); +#ifdef LITE_WITH_LOG LOG(INFO) << "is_device_init:" << is_device_init; +#endif + if (is_device_init == false) { + return false; + } + if ((is_platform_init == true) && (is_device_init == true)) { is_platform_device_init_success_ = true; context_ = CreateContext(); command_queue_ = CreateCommandQueue(context()); is_cl_runtime_initialized_ = true; +#ifdef LITE_WITH_LOG + LOG(INFO) << "set is_cl_runtime_initialized_ = true"; +#endif } return is_cl_runtime_initialized_; } @@ -138,20 +180,24 @@ GpuType CLRuntime::ParseGpuTypeFromDeviceName(std::string device_name) { const std::string kMALI_PATTERN_STR = "Mali"; const std::string kADRENO_PATTERN_STR = "QUALCOMM Adreno(TM)"; const std::string kPOWERVR_PATTERN_STR = "PowerVR"; + std::string gpu_type_str = ""; if (device_name == kADRENO_PATTERN_STR) { - LOG(INFO) << "adreno gpu"; + gpu_type_str = "adreno gpu"; return GpuType::QUALCOMM_ADRENO; } else if (device_name.find(kMALI_PATTERN_STR) != std::string::npos) { - LOG(INFO) << "mali gpu"; + gpu_type_str = "mali gpu"; return GpuType::ARM_MALI; } else if (device_name.find(kPOWERVR_PATTERN_STR) != std::string::npos) { - LOG(INFO) << "powerVR gpu"; + gpu_type_str = "powerVR gpu"; return GpuType::IMAGINATION_POWERVR; } else { - LOG(INFO) << "others gpu"; + gpu_type_str = "others gpu"; return GpuType::UNKNOWN; } +#ifdef LITE_WITH_LOG + LOG(INFO) << "gpu_type_str:" << gpu_type_str; +#endif } bool CLRuntime::InitializeDevice() { diff --git a/lite/backends/opencl/cl_runtime.h b/lite/backends/opencl/cl_runtime.h index 7a48989e37..22aaf83339 100644 --- a/lite/backends/opencl/cl_runtime.h +++ b/lite/backends/opencl/cl_runtime.h @@ -70,24 +70,23 @@ class CLRuntime { static CLRuntime* Global(); bool OpenCLAvaliableForDevice() { - bool opencl_lib_found = paddle::lite::CLWrapper::Global()->OpenclLibFound(); - LOG(INFO) << "opencl_lib_found:" << opencl_lib_found; - if (opencl_lib_found == false) return false; - - bool dlsym_success = paddle::lite::CLWrapper::Global()->DlsymSuccess(); - LOG(INFO) << "dlsym_success:" << dlsym_success; - if (opencl_lib_found == false) return false; + // note(ysh329): entered this func means: + // 1. opencl_lib_found must be true + // 2. dlsym_success must be true InitializeDevice(); bool support_fp16 = static_cast(device_info_["CL_DEVICE_EXTENSIONS_FP16"]); +#ifdef LITE_WITH_LOG LOG(INFO) << "support_fp16:" << support_fp16; +#endif if (support_fp16 == false) return false; - is_device_avaliable_for_opencl_ = - dlsym_success && opencl_lib_found && support_fp16; + is_device_avaliable_for_opencl_ = support_fp16; +#ifdef LITE_WITH_LOG LOG(INFO) << "is_device_avaliable_for_opencl_:" << is_device_avaliable_for_opencl_; +#endif return is_device_avaliable_for_opencl_; } diff --git a/lite/core/context.h b/lite/core/context.h index 69f6a4b9d6..5567eadbf8 100644 --- a/lite/core/context.h +++ b/lite/core/context.h @@ -347,18 +347,23 @@ class Context { #ifdef LITE_WITH_OPENCL template <> class Context { - std::shared_ptr cl_context_; + std::shared_ptr cl_context_{nullptr}; public: CLContext* cl_context() { return cl_context_.get(); } void InitOnce() { - // Init cl runtime. - CHECK(CLRuntime::Global()->IsInitSuccess()) << "OpenCL runtime init failed"; + if (CLRuntime::Global()->IsInitSuccess() == false) { + LOG(ERROR) << "OpenCL runtime init failed"; + } cl_context_ = std::make_shared(); } - void CopySharedTo(OpenCLContext* ctx) { ctx->cl_context_ = cl_context_; } + void CopySharedTo(OpenCLContext* ctx) { + if (ctx && cl_context_) { + ctx->cl_context_ = cl_context_; + } + } }; #endif diff --git a/lite/core/program.cc b/lite/core/program.cc index bd6dd09683..f83e685f4b 100644 --- a/lite/core/program.cc +++ b/lite/core/program.cc @@ -159,9 +159,12 @@ RuntimeProgram::RuntimeProgram( int block_idx) : exec_scope_(exec_scope) { #ifdef LITE_WITH_OPENCL + bool opencl_valid = CLRuntime::Global()->OpenCLAvaliableForDevice(); using OpenCLContext = Context; - std::unique_ptr local_ctx(new KernelContext()); - local_ctx->As().InitOnce(); + std::unique_ptr unique_opencl_ctx(new KernelContext()); + if (opencl_valid) { + unique_opencl_ctx->As().InitOnce(); + } #endif CHECK(program_desc); auto block_size = program_desc->BlocksSize(); @@ -227,9 +230,15 @@ RuntimeProgram::RuntimeProgram( } #ifdef LITE_WITH_OPENCL if (kernel->target() == TARGET(kOpenCL)) { - std::unique_ptr ctx(new KernelContext()); - (*local_ctx).As().CopySharedTo(&ctx->As()); - kernel->SetContext(std::move(ctx)); + if (opencl_valid) { + std::unique_ptr ctx(new KernelContext()); + (*unique_opencl_ctx) + .As() + .CopySharedTo(&ctx->As()); + kernel->SetContext(std::move(ctx)); + } else { + LOG(ERROR) << "opencl_valid:" << opencl_valid; + } } else { kernel->SetContext( ContextScheduler::Global().NewContext(kernel->target())); -- GitLab