|
|
|
@@ -17,12 +17,14 @@ |
|
|
|
#include "src/runtime/opencl/opencl_runtime.h" |
|
|
|
#include <vector> |
|
|
|
#include <numeric> |
|
|
|
#include <utility> |
|
|
|
#ifdef SHARING_MEM_WITH_OPENGL |
|
|
|
#include <EGL/egl.h> |
|
|
|
#endif |
|
|
|
#include "include/errorcode.h" |
|
|
|
#include "src/runtime/kernel/opencl/utils.h" |
|
|
|
#include "src/runtime/opencl/opencl_allocator.h" |
|
|
|
#include "src/common/file_utils.h" |
|
|
|
#ifdef PROGRAM_WITH_IL |
|
|
|
#include "src/backend/opencl/cl/program.inc" |
|
|
|
#endif |
|
|
|
@@ -254,6 +256,9 @@ int OpenCLRuntime::Init() { |
|
|
|
std::string flag = ""; |
|
|
|
binary_program_ = CreateProgramFromIL(g_program_binary, flag); |
|
|
|
#endif |
|
|
|
if (enable_cache_) { |
|
|
|
InitGpuCache(); |
|
|
|
} |
|
|
|
init_done_ = true; |
|
|
|
MS_LOG(INFO) << "OpenCLRuntime init done!"; |
|
|
|
|
|
|
|
@@ -261,6 +266,10 @@ int OpenCLRuntime::Init() { |
|
|
|
} |
|
|
|
|
|
|
|
int OpenCLRuntime::Uninit() { |
|
|
|
if (enable_cache_) { |
|
|
|
StoreCache(); |
|
|
|
} |
|
|
|
binary_map_.clear(); |
|
|
|
program_map_.clear(); |
|
|
|
delete allocator_; |
|
|
|
delete default_command_queue_; |
|
|
|
@@ -374,6 +383,12 @@ int OpenCLRuntime::BuildKernel(cl::Kernel &kernel, const std::string &program_na |
|
|
|
MS_LOG(ERROR) << program_name << " build failed!"; |
|
|
|
return RET_ERROR; |
|
|
|
} |
|
|
|
if (enable_cache_) { |
|
|
|
need_write_ = true; |
|
|
|
auto bin = GetProgramBinaries(program); |
|
|
|
MS_ASSERT(bin.size() >= 1); |
|
|
|
binary_map_.emplace(build_program_key, bin[0]); |
|
|
|
} |
|
|
|
program_map_.emplace(build_program_key, program); |
|
|
|
} |
|
|
|
|
|
|
|
@@ -673,9 +688,8 @@ cl::Program OpenCLRuntime::CreateProgramFromIL(const std::vector<char> &binary, |
|
|
|
} |
|
|
|
|
|
|
|
// build program with binary |
|
|
|
cl::Program OpenCLRuntime::CreateProgramFromBinary(const std::vector<std::vector<unsigned char>> &binary, |
|
|
|
const std::string &flag) { |
|
|
|
cl::Program program = cl::Program(*context_, {*device_}, binary); |
|
|
|
cl::Program OpenCLRuntime::CreateProgramFromBinary(const std::vector<unsigned char> &binary, const std::string &flag) { |
|
|
|
cl::Program program = cl::Program(*context_, {*device_}, {binary}); |
|
|
|
bool status = BuildProgram(default_build_opts_, program); |
|
|
|
if (!status) { |
|
|
|
MS_LOG(ERROR) << "Build program with binary failed!"; |
|
|
|
@@ -691,4 +705,75 @@ std::vector<std::vector<unsigned char>> OpenCLRuntime::GetProgramBinaries(const |
|
|
|
} |
|
|
|
return binary; |
|
|
|
} |
|
|
|
void OpenCLRuntime::InitGpuCache() { |
|
|
|
size_t len; |
|
|
|
char *buf = lite::ReadFile(cache_path_.c_str(), &len); |
|
|
|
if (LoadCache(buf) != RET_OK) { |
|
|
|
MS_LOG(ERROR) << "Load opencl cache fail"; |
|
|
|
} |
|
|
|
delete buf; |
|
|
|
MS_LOG(INFO) << "Init opencl cache success"; |
|
|
|
} |
|
|
|
int OpenCLRuntime::LoadCache(const void *buf) { |
|
|
|
if (buf == nullptr) { |
|
|
|
return RET_ERROR; |
|
|
|
} |
|
|
|
auto gpu_cache = schema::GetGpuCache(buf); |
|
|
|
if (gpu_cache == nullptr) { |
|
|
|
return RET_ERROR; |
|
|
|
} |
|
|
|
auto *bins = gpu_cache->allBins(); |
|
|
|
if (bins == nullptr) { |
|
|
|
return RET_ERROR; |
|
|
|
} |
|
|
|
auto n = bins->size(); |
|
|
|
for (auto i = 0; i < n; ++i) { |
|
|
|
auto *kernel_bin = bins->template GetAs<schema::KernelBin>(i); |
|
|
|
if (kernel_bin == nullptr) { |
|
|
|
MS_LOG(ERROR) << "kernel_bin[" << i << "] null"; |
|
|
|
return RET_ERROR; |
|
|
|
} |
|
|
|
auto *pdata = kernel_bin->data(); |
|
|
|
MS_ASSERT(pdata); |
|
|
|
if (pdata->size() == 0) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
std::vector<unsigned char> bin(pdata->begin(), pdata->end()); |
|
|
|
auto program = CreateProgramFromBinary(bin, kernel_bin->name()->str()); |
|
|
|
program_map_.emplace(kernel_bin->name()->str(), program); |
|
|
|
binary_map_.emplace(kernel_bin->name()->str(), bin); |
|
|
|
MS_LOG(INFO) << "LoadCache " << kernel_bin->name()->str() << " success, size=" << pdata->size(); |
|
|
|
} |
|
|
|
return RET_OK; |
|
|
|
} |
|
|
|
void OpenCLRuntime::StoreCache() { |
|
|
|
if (need_write_) { |
|
|
|
auto fbb_ = new (std::nothrow) flatbuffers::FlatBufferBuilder; |
|
|
|
if (fbb_ == nullptr) { |
|
|
|
MS_LOG(ERROR) << "new opencl FlatBufferBuilder fail"; |
|
|
|
return; |
|
|
|
} |
|
|
|
std::vector<flatbuffers::Offset<schema::KernelBin>> vec_kernel_bin; |
|
|
|
for (auto iv : binary_map_) { |
|
|
|
auto name = fbb_->CreateString(iv.first); |
|
|
|
auto data = fbb_->CreateVector<uint8_t>(iv.second); |
|
|
|
std::vector<int32_t> shape; |
|
|
|
auto tune = schema::CreateTuneParam(*fbb_, fbb_->CreateVector<int32_t>(shape), fbb_->CreateVector<int32_t>(shape), |
|
|
|
fbb_->CreateVector<int32_t>(shape), fbb_->CreateVector<int32_t>(shape)); |
|
|
|
auto kbin = schema::CreateKernelBin(*fbb_, name, tune, data); |
|
|
|
vec_kernel_bin.emplace_back(kbin); |
|
|
|
MS_LOG(INFO) << "StoreCache " << iv.first << " success, size=" << iv.second.size(); |
|
|
|
} |
|
|
|
|
|
|
|
auto data = fbb_->CreateVector<flatbuffers::Offset<schema::KernelBin>>(vec_kernel_bin); |
|
|
|
auto name = fbb_->CreateString("OpenCLCache"); |
|
|
|
auto version = fbb_->CreateString(version_); |
|
|
|
auto gpu_cache = schema::CreateGpuCache(*fbb_, name, version, data); |
|
|
|
fbb_->Finish(gpu_cache); |
|
|
|
uint8_t *buf = fbb_->GetBufferPointer(); |
|
|
|
lite::WriteToBin(cache_path_, reinterpret_cast<void *>(buf), fbb_->GetSize()); |
|
|
|
MS_LOG(INFO) << "store opencl cache ok, size=" << fbb_->GetSize(); |
|
|
|
delete fbb_; |
|
|
|
} |
|
|
|
} |
|
|
|
} // namespace mindspore::lite::opencl |