Merge pull request #969 from pengx17:2.4_binary_cache

This commit is contained in:
Roman Donchenko 2013-06-14 15:47:23 +04:00 committed by OpenCV Buildbot
commit 47ea0614dc
2 changed files with 68 additions and 20 deletions

View File

@ -118,9 +118,6 @@ namespace cv
//the devnum is the index of the selected device in DeviceName vector of INfo
CV_EXPORTS void setDevice(Info &oclinfo, int devnum = 0);
//optional function, if you want save opencl binary kernel to the file, set its path
CV_EXPORTS void setBinpath(const char *path);
//The two functions below enable other opencl program to use ocl module's cl_context and cl_command_queue
//returns cl_context *
CV_EXPORTS void* getoclContext();
@ -184,6 +181,29 @@ namespace cv
bool finish = true, bool measureKernelTime = false,
bool cleanUp = true);
//! Enable or disable OpenCL program binary caching onto local disk
// After a program (*.cl files in opencl/ folder) is built at runtime, we allow the
// compiled OpenCL program to be cached to the path automatically as "path/*.clb"
// binary file, which will be reused when the OpenCV executable is started again.
//
// Caching mode is controlled by the following enums
// Notes
// 1. the feature is by default enabled when OpenCV is built in release mode.
// 2. the CACHE_DEBUG / CACHE_RELEASE flags only effectively work with MSVC compiler;
// for GNU compilers, the function always treats the build as release mode (enabled by default).
enum
{
CACHE_NONE = 0, // do not cache OpenCL binary
CACHE_DEBUG = 0x1 << 0, // cache OpenCL binary when built in debug mode (only work with MSVC)
CACHE_RELEASE = 0x1 << 1, // default behavior, only cache when built in release mode (only work with MSVC)
CACHE_ALL = CACHE_DEBUG | CACHE_RELEASE, // always cache opencl binary
CACHE_UPDATE = 0x1 << 2 // if the binary cache file with the same name is already on the disk, it will be updated.
};
CV_EXPORTS void setBinaryDiskCache(int mode = CACHE_RELEASE, cv::String path = "./");
//! set where binary cache to be saved to
CV_EXPORTS void setBinpath(const char *path);
class CV_EXPORTS oclMatExpr;
//////////////////////////////// oclMat ////////////////////////////////
class CV_EXPORTS oclMat

View File

@ -124,7 +124,8 @@ namespace cv
cacheSize = 0;
}
// not to be exported to dynamic lib
void setBinaryDiskCacheImpl(int mode, String path, Info::Impl * impl);
struct Info::Impl
{
cl_platform_id oclplatform;
@ -142,22 +143,12 @@ namespace cv
char extra_options[512];
int double_support;
int unified_memory; //1 means integrated GPU, otherwise this value is 0
bool enable_disk_cache;
bool update_disk_cache;
string binpath;
int refcounter;
Impl()
{
refcounter = 1;
oclplatform = 0;
oclcontext = 0;
clCmdQueue = 0;
devnum = -1;
maxComputeUnits = 0;
maxWorkGroupSize = 0;
memset(extra_options, 0, 512);
double_support = 0;
unified_memory = 0;
}
Impl();
void setDevice(void *ctx, void *q, int devnum);
@ -182,6 +173,25 @@ namespace cv
void releaseResources();
};
Info::Impl::Impl()
:oclplatform(0),
oclcontext(0),
clCmdQueue(0),
devnum(-1),
maxWorkGroupSize(0),
maxDimensions(0),
maxComputeUnits(0),
double_support(0),
unified_memory(0),
enable_disk_cache(false),
update_disk_cache(false),
binpath("./"),
refcounter(1)
{
memset(extra_options, 0, 512);
setBinaryDiskCacheImpl(CACHE_RELEASE, String("./"), this);
}
void Info::Impl::releaseResources()
{
devnum = -1;
@ -494,6 +504,24 @@ namespace cv
return openCLGetKernelFromSource(clCxt, source, kernelName, NULL);
}
void setBinaryDiskCacheImpl(int mode, String path, Info::Impl * impl)
{
impl->update_disk_cache = (mode & CACHE_UPDATE) == CACHE_UPDATE;
impl->enable_disk_cache =
#ifdef _DEBUG
(mode & CACHE_DEBUG) == CACHE_DEBUG;
#else
(mode & CACHE_RELEASE) == CACHE_RELEASE;
#endif
if(impl->enable_disk_cache && !path.empty())
{
impl->binpath = path;
}
}
void setBinaryDiskCache(int mode, cv::String path)
{
setBinaryDiskCacheImpl(mode, path, Context::getContext()->impl);
}
void setBinpath(const char *path)
{
@ -573,8 +601,8 @@ namespace cv
filename = clCxt->impl->binpath + kernelName + "_" + clCxt->impl->devName[clCxt->impl->devnum] + ".clb";
}
FILE *fp = fopen(filename.c_str(), "rb");
if(fp == NULL || clCxt->impl->binpath.size() == 0) //we should generate a binary file for the first time.
FILE *fp = clCxt->impl->enable_disk_cache ? fopen(filename.c_str(), "rb") : NULL;
if(fp == NULL || clCxt->impl->update_disk_cache)
{
if(fp != NULL)
fclose(fp);
@ -583,7 +611,7 @@ namespace cv
clCxt->impl->oclcontext, 1, source, NULL, &status);
openCLVerifyCall(status);
status = clBuildProgram(program, 1, &(clCxt->impl->devices[clCxt->impl->devnum]), all_build_options, NULL, NULL);
if(status == CL_SUCCESS && clCxt->impl->binpath.size())
if(status == CL_SUCCESS && clCxt->impl->enable_disk_cache)
savetofile(clCxt, program, filename.c_str());
}
else