From e77abeef16a4214e3240dc5fb91cd2b0459b7a10 Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Mon, 10 Jun 2013 16:38:22 +0800 Subject: [PATCH 1/3] Add a new global function to control ocl binary storage Previously the feature is controlled by setBinpath implicitly. We add the function to cope with setBinpath and setBinpath is only useful when setBinaryDiskCache is set. Refer to the header to see more info. --- modules/ocl/include/opencv2/ocl/ocl.hpp | 20 ++++++-- modules/ocl/src/initialization.cpp | 62 ++++++++++++++++++------- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/modules/ocl/include/opencv2/ocl/ocl.hpp b/modules/ocl/include/opencv2/ocl/ocl.hpp index 01b0f72d2a..730c2e6b8f 100644 --- a/modules/ocl/include/opencv2/ocl/ocl.hpp +++ b/modules/ocl/include/opencv2/ocl/ocl.hpp @@ -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(); @@ -181,6 +178,23 @@ 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 program to be + // cached onto local disk automatically, which may accelerate subsequent runs. + // Caching mode is controlled by the following enum + // Note, the feature is by default enabled when OpenCV is built in release mode. + // enum BinaryDiskCacheMode + const int CACHE_NONE = 0; + const int CACHE_DEBUG = 0x1 << 0; + const int CACHE_RELEASE = 0x1 << 1; + const int CACHE_ALL = CACHE_DEBUG | CACHE_RELEASE; + const int 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 diff --git a/modules/ocl/src/initialization.cpp b/modules/ocl/src/initialization.cpp index a9cd08b9f4..9a0915ce55 100644 --- a/modules/ocl/src/initialization.cpp +++ b/modules/ocl/src/initialization.cpp @@ -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 = +#if !defined(NDEBUG) || defined(_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 From c8398c9fdc6641516d8e195e1ede2efd8a138b3c Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Tue, 11 Jun 2013 20:32:55 +0800 Subject: [PATCH 2/3] Use anonymous enumerations instead of constants --- modules/ocl/include/opencv2/ocl/ocl.hpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/modules/ocl/include/opencv2/ocl/ocl.hpp b/modules/ocl/include/opencv2/ocl/ocl.hpp index 730c2e6b8f..dc58f6f2e7 100644 --- a/modules/ocl/include/opencv2/ocl/ocl.hpp +++ b/modules/ocl/include/opencv2/ocl/ocl.hpp @@ -183,13 +183,14 @@ namespace cv // cached onto local disk automatically, which may accelerate subsequent runs. // Caching mode is controlled by the following enum // Note, the feature is by default enabled when OpenCV is built in release mode. - // enum BinaryDiskCacheMode - const int CACHE_NONE = 0; - const int CACHE_DEBUG = 0x1 << 0; - const int CACHE_RELEASE = 0x1 << 1; - const int CACHE_ALL = CACHE_DEBUG | CACHE_RELEASE; - const int CACHE_UPDATE = 0x1 << 2; // if the binary cache file with the same name is already on the disk, it will be updated. - + enum + { + CACHE_NONE = 0, + CACHE_DEBUG = 0x1 << 0, + CACHE_RELEASE = 0x1 << 1, + CACHE_ALL = CACHE_DEBUG | CACHE_RELEASE, + 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 From e6b18fc492e9115043b375c8b005687b24b84746 Mon Sep 17 00:00:00 2001 From: peng xiao Date: Fri, 14 Jun 2013 16:37:00 +0800 Subject: [PATCH 3/3] Fix a bug caused by NDEBUG macro; it is now removed. Revise some descriptions of the enums. --- modules/ocl/include/opencv2/ocl/ocl.hpp | 21 +++++++++++++-------- modules/ocl/src/initialization.cpp | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/modules/ocl/include/opencv2/ocl/ocl.hpp b/modules/ocl/include/opencv2/ocl/ocl.hpp index dc58f6f2e7..308383b61a 100644 --- a/modules/ocl/include/opencv2/ocl/ocl.hpp +++ b/modules/ocl/include/opencv2/ocl/ocl.hpp @@ -179,16 +179,21 @@ namespace cv 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 program to be - // cached onto local disk automatically, which may accelerate subsequent runs. - // Caching mode is controlled by the following enum - // Note, the feature is by default enabled when OpenCV is built in release mode. + // 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, - CACHE_DEBUG = 0x1 << 0, - CACHE_RELEASE = 0x1 << 1, - CACHE_ALL = CACHE_DEBUG | CACHE_RELEASE, + 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 = "./"); diff --git a/modules/ocl/src/initialization.cpp b/modules/ocl/src/initialization.cpp index 9a0915ce55..bdae7059ec 100644 --- a/modules/ocl/src/initialization.cpp +++ b/modules/ocl/src/initialization.cpp @@ -508,7 +508,7 @@ namespace cv { impl->update_disk_cache = (mode & CACHE_UPDATE) == CACHE_UPDATE; impl->enable_disk_cache = -#if !defined(NDEBUG) || defined(_DEBUG) +#ifdef _DEBUG (mode & CACHE_DEBUG) == CACHE_DEBUG; #else (mode & CACHE_RELEASE) == CACHE_RELEASE;