add interfaces enable custom oclMat device memory type
authoryao <bitwangyaoyao@gmail.com>
Wed, 27 Feb 2013 09:32:32 +0000 (17:32 +0800)
committeryao <bitwangyaoyao@gmail.com>
Wed, 27 Feb 2013 09:32:32 +0000 (17:32 +0800)
modules/ocl/include/opencv2/ocl/ocl.hpp
modules/ocl/src/initialization.cpp
modules/ocl/src/matrix_operations.cpp
modules/ocl/src/precomp.hpp

index a60eb36..887d942 100644 (file)
@@ -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();
index c90b62b..0d3322b 100644 (file)
@@ -72,6 +72,15 @@ namespace cv
          */
         auto_ptr<ProgramCache> 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<cl_device_id> 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();
         }
 
index f0e65f9..f859193 100644 (file)
@@ -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)
index f65621f..f4cdae1 100644 (file)
@@ -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
         };
     }
 }