Skip to content

[cherry-pick][BugFix][OPENCL] Fix initalization sequence of opencl backend valid A… #4021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions lite/api/paddle_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,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;
}

Expand Down
15 changes: 14 additions & 1 deletion lite/backends/opencl/cl_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -54,22 +59,30 @@ 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<cl::Kernel> 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;
kernel_offset_[kernel_key.str()] = kernels_.size() - 1;
}

cl::Kernel &CLContext::GetKernel(const int index) {
#ifdef LITE_WITH_LOG
VLOG(3) << " --- kernel count: " << kernels_.size() << " --- ";
#endif
CHECK(static_cast<size_t>(index) < kernels_.size())
<< "The index must be less than the size of kernels.";
CHECK(kernels_[index] != nullptr)
Expand Down
56 changes: 51 additions & 5 deletions lite/backends/opencl/cl_runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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_;
}
Expand Down Expand Up @@ -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() {
Expand Down
17 changes: 8 additions & 9 deletions lite/backends/opencl/cl_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<bool>(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_;
}

Expand Down
13 changes: 9 additions & 4 deletions lite/core/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,18 +364,23 @@ class Context<TargetType::kX86> {
#ifdef LITE_WITH_OPENCL
template <>
class Context<TargetType::kOpenCL> {
std::shared_ptr<CLContext> cl_context_;
std::shared_ptr<CLContext> 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<CLContext>();
}

void CopySharedTo(OpenCLContext* ctx) { ctx->cl_context_ = cl_context_; }
void CopySharedTo(OpenCLContext* ctx) {
if (ctx && cl_context_) {
ctx->cl_context_ = cl_context_;
}
}
};
#endif

Expand Down
19 changes: 14 additions & 5 deletions lite/core/program.cc
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,12 @@ RuntimeProgram::RuntimeProgram(
int block_idx)
: exec_scope_(exec_scope) {
#ifdef LITE_WITH_OPENCL
bool opencl_valid = CLRuntime::Global()->OpenCLAvaliableForDevice();
using OpenCLContext = Context<TargetType::kOpenCL>;
std::unique_ptr<KernelContext> local_ctx(new KernelContext());
local_ctx->As<OpenCLContext>().InitOnce();
std::unique_ptr<KernelContext> unique_opencl_ctx(new KernelContext());
if (opencl_valid) {
unique_opencl_ctx->As<OpenCLContext>().InitOnce();
}
#endif
CHECK(program_desc);
auto block_size = program_desc->BlocksSize();
Expand Down Expand Up @@ -229,9 +232,15 @@ RuntimeProgram::RuntimeProgram(
}
#ifdef LITE_WITH_OPENCL
if (kernel->target() == TARGET(kOpenCL)) {
std::unique_ptr<KernelContext> ctx(new KernelContext());
(*local_ctx).As<OpenCLContext>().CopySharedTo(&ctx->As<OpenCLContext>());
kernel->SetContext(std::move(ctx));
if (opencl_valid) {
std::unique_ptr<KernelContext> ctx(new KernelContext());
(*unique_opencl_ctx)
.As<OpenCLContext>()
.CopySharedTo(&ctx->As<OpenCLContext>());
kernel->SetContext(std::move(ctx));
} else {
LOG(ERROR) << "opencl_valid:" << opencl_valid;
}
} else {
kernel->SetContext(
ContextScheduler::Global().NewContext(kernel->target()));
Expand Down