From 9ccf27c7f578cf672b7e544f4bfe41160878f8b2 Mon Sep 17 00:00:00 2001 From: yao Date: Wed, 27 Feb 2013 17:32:32 +0800 Subject: [PATCH] add interfaces enable custom oclMat device memory type --- modules/ocl/include/opencv2/ocl/ocl.hpp | 31 +++++++++++++++ modules/ocl/src/initialization.cpp | 69 ++++++++++++++++++++------------- modules/ocl/src/matrix_operations.cpp | 14 ++++++- modules/ocl/src/precomp.hpp | 3 ++ 4 files changed, 88 insertions(+), 29 deletions(-) diff --git a/modules/ocl/include/opencv2/ocl/ocl.hpp b/modules/ocl/include/opencv2/ocl/ocl.hpp index a60eb36..887d942 100644 --- a/modules/ocl/include/opencv2/ocl/ocl.hpp +++ b/modules/ocl/include/opencv2/ocl/ocl.hpp @@ -66,6 +66,32 @@ namespace cv //CVCL_DEVICE_TYPE_CUSTOM = (1 << 4) CVCL_DEVICE_TYPE_ALL = 0xFFFFFFFF }; + + enum DevMemRW + { + DEVICE_MEM_R_W = 0, + DEVICE_MEM_R_ONLY, + DEVICE_MEM_W_ONLY + }; + + enum DevMemType + { + DEVICE_MEM_DEFAULT = 0, + DEVICE_MEM_AHP, //alloc host pointer + DEVICE_MEM_UHP, //use host pointer + DEVICE_MEM_CHP, //copy host pointer + DEVICE_MEM_PM //persistent memory + }; + + //Get the global device memory and read/write type + //return 1 if unified memory system supported, otherwise return 0 + CV_EXPORTS int getDevMemType(DevMemRW& rw_type, DevMemType& mem_type); + + //Set the global device memory and read/write type, + //the newly generated oclMat will all use this type + //return -1 if the target type is unsupported, otherwise return 0 + CV_EXPORTS int setDevMemType(DevMemRW rw_type = DEVICE_MEM_R_W, DevMemType mem_type = DEVICE_MEM_DEFAULT); + //this class contains ocl runtime information class CV_EXPORTS Info { @@ -228,6 +254,11 @@ namespace cv // previous data is unreferenced if needed. void create(int rows, int cols, int type); void create(Size size, int type); + + //! allocates new oclMatrix with specified device memory type. + void createEx(int rows, int cols, int type, DevMemRW rw_type, DevMemType mem_type); + void createEx(Size size, int type, DevMemRW rw_type, DevMemType mem_type); + //! decreases reference counter; // deallocate the data when reference counter reaches 0. void release(); diff --git a/modules/ocl/src/initialization.cpp b/modules/ocl/src/initialization.cpp index c90b62b..0d3322b 100644 --- a/modules/ocl/src/initialization.cpp +++ b/modules/ocl/src/initialization.cpp @@ -72,6 +72,15 @@ namespace cv */ auto_ptr ProgramCache::programCache; ProgramCache *programCache = NULL; + DevMemType gDeviceMemType = DEVICE_MEM_DEFAULT; + DevMemRW gDeviceMemRW = DEVICE_MEM_R_W; + int gDevMemTypeValueMap[5] = {0, + CL_MEM_ALLOC_HOST_PTR, + CL_MEM_USE_HOST_PTR, + CL_MEM_COPY_HOST_PTR, + CL_MEM_USE_PERSISTENT_MEM_AMD}; + int gDevMemRWValueMap[3] = {CL_MEM_READ_WRITE, CL_MEM_READ_ONLY, CL_MEM_WRITE_ONLY}; + ProgramCache::ProgramCache() { codeCache.clear(); @@ -113,30 +122,25 @@ namespace cv } ////////////////////////Common OpenCL specific calls/////////////// - //Info::Info() - //{ - // oclplatform = 0; - // oclcontext = 0; - // devnum = 0; - //} - //Info::~Info() - //{ - // release(); - //} - //void Info::release() - //{ - // if(oclplatform) - // { - // oclplatform = 0; - // } - // if(oclcontext) - // { - // openCLSafeCall(clReleaseContext(oclcontext)); - // } - // devices.empty(); - // devName.empty(); - //} - struct Info::Impl + int getDevMemType(DevMemRW& rw_type, DevMemType& mem_type) + { + rw_type = gDeviceMemRW; + mem_type = gDeviceMemType; + return Context::getContext()->impl->unified_memory; + } + + int setDevMemType(DevMemRW rw_type, DevMemType mem_type) + { + if( (mem_type == DEVICE_MEM_PM && Context::getContext()->impl->unified_memory == 0) || + mem_type == DEVICE_MEM_UHP || + mem_type == DEVICE_MEM_CHP ) + return -1; + gDeviceMemRW = rw_type; + gDeviceMemType = mem_type; + return 0; + } + + struct Info::Impl { cl_platform_id oclplatform; std::vector devices; @@ -290,11 +294,8 @@ namespace cv } void *getoclContext() - { - return &(Context::getContext()->impl->clContext); - } void *getoclCommandQueue() @@ -320,9 +321,15 @@ namespace cv void openCLMallocPitch(Context *clCxt, void **dev_ptr, size_t *pitch, size_t widthInBytes, size_t height) { + openCLMallocPitchEx(clCxt, dev_ptr, pitch, widthInBytes, height, gDeviceMemRW, gDeviceMemType); + } + + void openCLMallocPitchEx(Context *clCxt, void **dev_ptr, size_t *pitch, + size_t widthInBytes, size_t height, DevMemRW rw_type, DevMemType mem_type) + { cl_int status; - *dev_ptr = clCreateBuffer(clCxt->impl->clContext, CL_MEM_READ_WRITE, + *dev_ptr = clCreateBuffer(clCxt->impl->clContext, gDevMemRWValueMap[rw_type]|gDevMemTypeValueMap[mem_type], widthInBytes * height, 0, &status); openCLVerifyCall(status); *pitch = widthInBytes; @@ -837,6 +844,11 @@ namespace cv clcxt->impl->double_support = oclinfo.impl->double_support; //extra options to recognize compiler options memcpy(clcxt->impl->extra_options, oclinfo.impl->extra_options, 512); + cl_bool unfymem = false; + openCLSafeCall(clGetDeviceInfo(clcxt->impl->devices, CL_DEVICE_HOST_UNIFIED_MEMORY, + sizeof(cl_bool), (void *)&unfymem, NULL)); + if(unfymem) + clcxt->impl->unified_memory = 1; } Context::Context() { @@ -853,6 +865,7 @@ namespace cv impl->double_support = 0; //extra options to recognize vendor specific fp64 extensions memset(impl->extra_options, 0, 512); + impl->unified_memory = 0; programCache = ProgramCache::getProgramCache(); } diff --git a/modules/ocl/src/matrix_operations.cpp b/modules/ocl/src/matrix_operations.cpp index f0e65f9..f859193 100644 --- a/modules/ocl/src/matrix_operations.cpp +++ b/modules/ocl/src/matrix_operations.cpp @@ -69,6 +69,8 @@ namespace cv extern const char *operator_setTo; extern const char *operator_setToM; extern const char *convertC3C4; + extern DevMemType gDeviceMemType; + extern DevMemRW gDeviceMemRW; } } @@ -912,8 +914,18 @@ oclMat cv::ocl::oclMat::reshape(int new_cn, int new_rows) const } +void cv::ocl::oclMat::createEx(Size size, int type, DevMemRW rw_type, DevMemType mem_type) +{ + createEx(size.height, size.width, type, rw_type, mem_type); +} + void cv::ocl::oclMat::create(int _rows, int _cols, int _type) { + createEx(_rows, _cols, _type, gDeviceMemRW, gDeviceMemType); +} + +void cv::ocl::oclMat::createEx(int _rows, int _cols, int _type, DevMemRW rw_type, DevMemType mem_type) +{ clCxt = Context::getContext(); /* core logic */ _type &= TYPE_MASK; @@ -937,7 +949,7 @@ void cv::ocl::oclMat::create(int _rows, int _cols, int _type) size_t esz = elemSize(); void *dev_ptr; - openCLMallocPitch(clCxt, &dev_ptr, &step, GPU_MATRIX_MALLOC_STEP(esz * cols), rows); + openCLMallocPitchEx(clCxt, &dev_ptr, &step, GPU_MATRIX_MALLOC_STEP(esz * cols), rows, rw_type, mem_type); //openCLMallocPitch(clCxt,&dev_ptr, &step, esz * cols, rows); if (esz * cols == step) diff --git a/modules/ocl/src/precomp.hpp b/modules/ocl/src/precomp.hpp index f65621f..f4cdae1 100644 --- a/modules/ocl/src/precomp.hpp +++ b/modules/ocl/src/precomp.hpp @@ -95,6 +95,8 @@ namespace cv ///////////////////////////OpenCL call wrappers//////////////////////////// void openCLMallocPitch(Context *clCxt, void **dev_ptr, size_t *pitch, size_t widthInBytes, size_t height); + void openCLMallocPitchEx(Context *clCxt, void **dev_ptr, size_t *pitch, + size_t widthInBytes, size_t height, DevMemRW rw_type, DevMemType mem_type); void openCLMemcpy2D(Context *clCxt, void *dst, size_t dpitch, const void *src, size_t spitch, size_t width, size_t height, enum openCLMemcpyKind kind, int channels = -1); @@ -143,6 +145,7 @@ namespace cv //extra options to recognize vendor specific fp64 extensions char extra_options[512]; string Binpath; + int unified_memory; //1 means integrated GPU, otherwise this value is 0 }; } } -- 2.7.4