updated gpu initialization functions, added compile-time error on CC 1.0
authorAlexey Spizhevoy <no@email>
Thu, 20 Jan 2011 14:13:07 +0000 (14:13 +0000)
committerAlexey Spizhevoy <no@email>
Thu, 20 Jan 2011 14:13:07 +0000 (14:13 +0000)
CMakeLists.txt
cvconfig.h.cmake
doc/gpu_image_processing.tex
doc/gpu_object_detection.tex
modules/gpu/src/initialization.cpp
modules/gpu/src/precomp.hpp

index 23b79ec..da82a9d 100644 (file)
@@ -708,47 +708,36 @@ if(WITH_CUDA)
         message(STATUS "CUDA detected: " ${CUDA_VERSION})\r
 \r
         set(CUDA_ARCH_GPU "1.3 2.0" CACHE STRING "Specify 'real' GPU architectures to build binaries for")\r
-        set(CUDA_ARCH_PTX "1.1 1.3" CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for")       \r
+        set(CUDA_ARCH_PTX "1.1 1.3" CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for")              \r
         \r
-        # Architectures to be searched for in user's input\r
-        set (CUDA_ARCH_ALL 1.0 1.1 1.2 1.3 2.0 2.1)\r
+        # These variables are used in config templates\r
+        string(REGEX REPLACE "\\." "" ARCH_GPU_NO_POINTS "${CUDA_ARCH_GPU}")\r
+        string(REGEX REPLACE "\\." "" ARCH_PTX_NO_POINTS "${CUDA_ARCH_PTX}")\r
         \r
-        # Parse user's input\r
-        foreach(ARCH IN LISTS CUDA_ARCH_ALL)            \r
-            string(REGEX MATCH ${ARCH} ARCH_GPU_MATCH "${CUDA_ARCH_GPU}") \r
-            string(REGEX MATCH ${ARCH} ARCH_PTX_MATCH "${CUDA_ARCH_PTX}") \r
-            string(REGEX REPLACE "\\." "" ARCH_GPU_AS_NUM "${ARCH_GPU_MATCH}")\r
-            string(REGEX REPLACE "\\." "" ARCH_PTX_AS_NUM "${ARCH_PTX_MATCH}")\r
-            \r
-            # Define variables indicating the architectures specified by user\r
-            if(NOT ${ARCH_GPU_AS_NUM} STREQUAL "")\r
-                set(OPENCV_ARCH_GPU_${ARCH_GPU_AS_NUM} 1)\r
-            endif()            \r
-            if(NOT ${ARCH_PTX_AS_NUM} STREQUAL "")\r
-                set(OPENCV_ARCH_PTX_${ARCH_PTX_AS_NUM} 1)\r
-            endif()\r
-        endforeach()       \r
+        # Ckeck if user specified 1.0 compute capability\r
+        string(REGEX MATCH "1.0" HAS_ARCH_10 "${CUDA_ARCH_GPU} ${CUDA_ARCH_PTX}")\r
+        if(NOT ${HAS_ARCH_10} STREQUAL "")\r
+            set(OPENCV_ARCH_GPU_OR_PTX_10 1)\r
+        endif()\r
         \r
         set(NVCC_FLAGS_EXTRA "")\r
         \r
         # Tell nvcc to add binaries for the specified GPUs\r
-        string(REGEX REPLACE "\\." "" CUDA_ARCH_GPU "${CUDA_ARCH_GPU}")\r
-        string(REGEX MATCHALL "[0-9]+" CUDA_ARCH_GPU_LIST "${CUDA_ARCH_GPU}")\r
-        foreach(ARCH_GPU IN LISTS CUDA_ARCH_GPU_LIST)\r
-            set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH_GPU},code=sm_${ARCH_GPU})\r
+        string(REGEX MATCHALL "[0-9]+" ARCH_LIST "${ARCH_GPU_NO_POINTS}")\r
+        foreach(ARCH IN LISTS ARCH_LIST)\r
+            set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=sm_${ARCH})\r
         endforeach()\r
         \r
         # Tell nvcc to add PTX intermediate code for the specified architectures\r
-        string(REGEX REPLACE "\\." "" CUDA_ARCH_PTX "${CUDA_ARCH_PTX}")\r
-        string(REGEX MATCHALL "[0-9]+" CUDA_ARCH_PTX_LIST "${CUDA_ARCH_PTX}")\r
-        foreach(ARCH_PTX IN LISTS CUDA_ARCH_PTX_LIST)\r
-            set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH_PTX},code=compute_${ARCH_PTX})\r
+        string(REGEX MATCHALL "[0-9]+" ARCH_LIST "${ARCH_PTX_NO_POINTS}")\r
+        foreach(ARCH IN LISTS ARCH_LIST)\r
+            set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=compute_${ARCH})\r
         endforeach()               \r
-             \r
-        set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ${NVCC_FLAGS_EXTRA})\r
-        message(STATUS "CUDA NVCC flags: ${CUDA_NVCC_FLAGS}")\r
         \r
+        set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ${NVCC_FLAGS_EXTRA})        \r
         set(OpenCV_CUDA_CC "${NVCC_FLAGS_EXTRA}")\r
+        \r
+        message(STATUS "CUDA NVCC flags: ${CUDA_NVCC_FLAGS}")\r
     endif()\r
 endif()\r
 \r
index 053fde1..27681a3 100644 (file)
 /* NVidia Cuda Runtime API*/
 #cmakedefine HAVE_CUDA
 
-/* Compile for 'real' NVIDIA GPU architecture */
-#cmakedefine OPENCV_ARCH_GPU_10
-#cmakedefine OPENCV_ARCH_GPU_11
-#cmakedefine OPENCV_ARCH_GPU_12
-#cmakedefine OPENCV_ARCH_GPU_13
-#cmakedefine OPENCV_ARCH_GPU_20
-#cmakedefine OPENCV_ARCH_GPU_21
-
-/* Compile for 'virtual' NVIDIA PTX architecture */
-#cmakedefine OPENCV_ARCH_PTX_10
-#cmakedefine OPENCV_ARCH_PTX_11
-#cmakedefine OPENCV_ARCH_PTX_12
-#cmakedefine OPENCV_ARCH_PTX_13
-#cmakedefine OPENCV_ARCH_PTX_20
-#cmakedefine OPENCV_ARCH_PTX_21
+/* Compile for 'real' NVIDIA GPU architectures */
+#define OPENCV_ARCH_GPU "${ARCH_GPU_NO_POINTS}"
+
+/* Compile for 'virtual' NVIDIA PTX architectures */
+#define OPENCV_ARCH_PTX "${ARCH_PTX_NO_POINTS}"
+
+/* Create PTX or CUBIN for 1.0 compute capability */
+#cmakedefine OPENCV_ARCH_GPU_OR_PTX_10
 
 /* VideoInput library */
 #cmakedefine HAVE_VIDEOINPUT
index 38e326b..fe6a69e 100644 (file)
@@ -232,10 +232,10 @@ private:
 \r
 \cvCppFunc{gpu::ConvolveBuf::ConvolveBuf}\r
 \r
-\cvdefCpp{ConvolveBuf();}\r
+\cvdefCpp{ConvolveBuf::ConvolveBuf();}\r
 Constructs an empty buffer which will be properly resized after first call of the convolve function.\r
 \r
-\cvdefCpp{ConvolveBuf(Size image\_size, Size templ\_size);}\r
+\cvdefCpp{ConvolveBuf::ConvolveBuf(Size image\_size, Size templ\_size);}\r
 Constructs a buffer for the convolve function with respectively arguments.\r
 \r
 \r
index e5cfb18..46cca72 100644 (file)
@@ -82,13 +82,13 @@ Creates HOG descriptor and detector.
 \cvCppFunc{gpu::HOGDescriptor::getDescriptorSize}\r
 Returns number of coefficients required for the classification.\r
 \r
-\cvdefCpp{size\_t getDescriptorSize() const;}\r
+\cvdefCpp{size\_t HOGDescriptor::getDescriptorSize() const;}\r
 \r
 \r
 \cvCppFunc{gpu::HOGDescriptor::getBlockHistogramSize}\r
 Returns block histogram size.\r
 \r
-\cvdefCpp{size\_t getBlockHistogramSize() const;}\r
+\cvdefCpp{size\_t HOGDescriptor::getBlockHistogramSize() const;}\r
 \r
 \r
 \cvCppFunc{gpu::HOGDescriptor::setSVMDetector}\r
@@ -100,25 +100,25 @@ Sets coefficients for the linear SVM classifier.
 \cvCppFunc{gpu::HOGDescriptor::getDefaultPeopleDetector}\r
 Returns coefficients of the classifier trained for people detection (for default window size).\r
 \r
-\cvdefCpp{static vector<float> getDefaultPeopleDetector();}\r
+\cvdefCpp{static vector<float> HOGDescriptor::getDefaultPeopleDetector();}\r
 \r
 \r
 \cvCppFunc{gpu::HOGDescriptor::getPeopleDetector48x96}\r
 Returns coefficients of the classifier trained for people detection (for 48x96 windows).\r
 \r
-\cvdefCpp{static vector<float> getPeopleDetector48x96();}\r
+\cvdefCpp{static vector<float> HOGDescriptor::getPeopleDetector48x96();}\r
 \r
 \r
 \cvCppFunc{gpu::HOGDescriptor::getPeopleDetector64x128}\r
 Returns coefficients of the classifier trained for people detection (for 64x128 windows).\r
 \r
-\cvdefCpp{static vector<float> getPeopleDetector64x128();}\r
+\cvdefCpp{static vector<float> HOGDescriptor::getPeopleDetector64x128();}\r
 \r
 \r
 \cvCppFunc{gpu::HOGDescriptor::detect}\r
 Perfroms object detection without multiscale window.\r
 \r
-\cvdefCpp{void detect(const GpuMat\& img, vector<Point>\& found\_locations,\par\r
+\cvdefCpp{void HOGDescriptor::detect(const GpuMat\& img, vector<Point>\& found\_locations,\par\r
              double hit\_threshold=0, Size win\_stride=Size(),\par\r
              Size padding=Size());}\r
 \r
@@ -134,10 +134,10 @@ Perfroms object detection without multiscale window.
 \cvCppFunc{gpu::HOGDescriptor::detectMultiScale}\r
 Perfroms object detection with multiscale window.\r
 \r
-\cvdefCpp{void detectMultiScale(const GpuMat\& img, vector<Rect>\& found\_locations,\par\r
-                      double hit\_threshold=0, Size win\_stride=Size(),\par\r
-                      Size padding=Size(), double scale0=1.05,\par\r
-                      int group\_threshold=2);}\r
+\cvdefCpp{void HOGDescriptor::detectMultiScale(const GpuMat\& img,\par\r
+  vector<Rect>\& found\_locations, double hit\_threshold=0,\par\r
+  Size win\_stride=Size(), Size padding=Size(),\par\r
+  double scale0=1.05, int group\_threshold=2);}\r
 \r
 \begin{description}\r
 \cvarg{img}{Source image. See \cvCppCross{gpu::HOGDescriptor::detect} for type limitations.}\r
@@ -154,9 +154,9 @@ See \cvCppCross{groupRectangles}.}
 \cvCppFunc{gpu::HOGDescriptor::getDescriptors}\r
 Returns block descriptors computed for the whole image. It's mainly used for classifier learning purposes.\r
 \r
-\cvdefCpp{void getDescriptors(const GpuMat\& img, Size win\_stride,\par\r
-                    GpuMat\& descriptors,\par\r
-                    int descr\_format=DESCR\_FORMAT\_COL\_BY\_COL);}\r
+\cvdefCpp{void HOGDescriptor::getDescriptors(const GpuMat\& img,\par\r
+  Size win\_stride, GpuMat\& descriptors,\par\r
+  int descr\_format=DESCR\_FORMAT\_COL\_BY\_COL);}\r
 \r
 \begin{description}\r
 \cvarg{img}{Source image. See \cvCppCross{gpu::HOGDescriptor::detect} for type limitations.}\r
index 10ee3b5..d754c87 100644 (file)
@@ -41,6 +41,7 @@
 //M*/\r
 \r
 #include "precomp.hpp"\r
+#include <functional>\r
 \r
 using namespace cv;\r
 using namespace cv::gpu;\r
@@ -58,12 +59,12 @@ CV_EXPORTS void cv::gpu::getGpuMemInfo(size_t& /*free*/, size_t& /*total*/)  { t
 CV_EXPORTS bool cv::gpu::hasNativeDoubleSupport(int /*device*/) { throw_nogpu(); return false; }\r
 CV_EXPORTS bool cv::gpu::hasAtomicsSupport(int /*device*/) { throw_nogpu(); return false; }\r
 CV_EXPORTS bool cv::gpu::hasPtxVersion(int major, int minor) { throw_nogpu(); return false; }\r
-CV_EXPORTS bool cv::gpu::hasLessOrEqualPtxVersion(int major, int minor) { throw_nogpu(); return false; }\r
-CV_EXPORTS bool cv::gpu::hasGreaterOrEqualPtxVersion(int major, int minor) { throw_nogpu(); return false; }\r
-CV_EXPORTS bool cv::gpu::hasCubinVersion(int major, int minor) { throw_nogpu(); return false; }\r
-CV_EXPORTS bool cv::gpu::hasGreaterOrEqualCubinVersion(int major, int minor) { throw_nogpu(); return false; }\r
-CV_EXPORTS bool cv::gpu::hasVersion(int major, int minor) { throw_nogpu(); return false; }\r
-CV_EXPORTS bool cv::gpu::hasGreaterOrEqualVersion(int major, int minor) { throw_nogpu(); return false; }\r
+CV_EXPORTS bool cv::gpu::hasLessOrEqualPtxVersion(int major, int minor) { return false; }\r
+CV_EXPORTS bool cv::gpu::hasGreaterOrEqualPtxVersion(int major, int minor) { return false; }\r
+CV_EXPORTS bool cv::gpu::hasCubinVersion(int major, int minor) { return false; }\r
+CV_EXPORTS bool cv::gpu::hasGreaterOrEqualCubinVersion(int major, int minor) { return false; }\r
+CV_EXPORTS bool cv::gpu::hasVersion(int major, int minor) { return false; }\r
+CV_EXPORTS bool cv::gpu::hasGreaterOrEqualVersion(int major, int minor) { return false; }\r
 CV_EXPORTS bool cv::gpu::isCompatibleWith(int device) { throw_nogpu(); return false; }\r
 \r
 \r
@@ -142,118 +143,55 @@ CV_EXPORTS bool cv::gpu::hasAtomicsSupport(int device)
 namespace \r
 {\r
     template <typename Comparer>\r
-    bool checkPtxVersion(int major, int minor, Comparer cmp) \r
+    bool compare(const std::string& str, int x, Comparer cmp)\r
     {\r
-#ifdef OPENCV_ARCH_PTX_10\r
-        if (cmp(1, 0, major, minor)) return true;\r
-#endif\r
-\r
-#ifdef OPENCV_ARCH_PTX_11\r
-        if (cmp(1, 1, major, minor)) return true;\r
-#endif\r
-\r
-#ifdef OPENCV_ARCH_PTX_12\r
-        if (cmp(1, 2, major, minor)) return true;\r
-#endif\r
-\r
-#ifdef OPENCV_ARCH_PTX_13\r
-        if (cmp(1, 3, major, minor)) return true;\r
-#endif\r
-\r
-#ifdef OPENCV_ARCH_PTX_20\r
-        if (cmp(2, 0, major, minor)) return true;\r
-#endif\r
-\r
-#ifdef OPENCV_ARCH_PTX_21\r
-        if (cmp(2, 1, major, minor)) return true;\r
-#endif\r
-\r
-        return false;\r
-    }\r
-\r
-    template <typename Comparer>\r
-    bool checkCubinVersion(int major, int minor, Comparer cmp) \r
-    {\r
-#ifdef OPENCV_ARCH_GPU_10\r
-        if (cmp(1, 0, major, minor)) return true;\r
-#endif\r
-\r
-#ifdef OPENCV_ARCH_GPU_11\r
-        if (cmp(1, 1, major, minor)) return true;\r
-#endif\r
+        std::stringstream stream(str);\r
 \r
-#ifdef OPENCV_ARCH_GPU_12\r
-        if (cmp(1, 2, major, minor)) return true;\r
-#endif\r
-\r
-#ifdef OPENCV_ARCH_GPU_13\r
-        if (cmp(1, 3, major, minor)) return true;\r
-#endif\r
-\r
-#ifdef OPENCV_ARCH_GPU_20\r
-        if (cmp(2, 0, major, minor)) return true;\r
-#endif\r
-\r
-#ifdef OPENCV_ARCH_GPU_21\r
-        if (cmp(2, 1, major, minor)) return true;\r
-#endif\r
-\r
-        return false;\r
-    }\r
+        int val;\r
+        stream >> val;\r
 \r
-    struct ComparerEqual \r
-    {\r
-        bool operator()(int lhs1, int lhs2, int rhs1, int rhs2) const\r
-        {\r
-            return lhs1 == rhs1 && lhs2 == rhs2;\r
-        }\r
-    };\r
-\r
-    struct ComparerLessOrEqual\r
-    {\r
-        bool operator()(int lhs1, int lhs2, int rhs1, int rhs2) const\r
+        while (!stream.eof() && !stream.fail())\r
         {\r
-            return lhs1 < rhs1 || (lhs1 == rhs1 && lhs2 <= rhs2);\r
+            if (cmp(val, x))\r
+                return true;\r
+            stream >> val;\r
         }\r
-    };\r
 \r
-    struct ComparerGreaterOrEqual\r
-    {\r
-        bool operator()(int lhs1, int lhs2, int rhs1, int rhs2) const\r
-        {\r
-            return lhs1 > rhs1 || (lhs1 == rhs1 && lhs2 >= rhs2);\r
-        }\r
-    };\r
+        return false;\r
+    }\r
 }\r
 \r
 \r
 CV_EXPORTS bool cv::gpu::hasPtxVersion(int major, int minor)\r
 {\r
-    return checkPtxVersion(major, minor, ComparerEqual());\r
+    return ::compare(OPENCV_ARCH_PTX, major * 10 + minor, std::equal_to<int>());\r
 }\r
 \r
 \r
 CV_EXPORTS bool cv::gpu::hasLessOrEqualPtxVersion(int major, int minor)\r
 {\r
-    return checkPtxVersion(major, minor, ComparerLessOrEqual());\r
+    return ::compare(OPENCV_ARCH_PTX, major * 10 + minor, \r
+                     std::less_equal<int>());\r
 }\r
 \r
 \r
 CV_EXPORTS bool cv::gpu::hasGreaterOrEqualPtxVersion(int major, int minor)\r
 {\r
-    return checkPtxVersion(major, minor, ComparerGreaterOrEqual());\r
+    return ::compare(OPENCV_ARCH_PTX, major * 10 + minor, \r
+                     std::greater_equal<int>());\r
 }\r
 \r
 \r
 CV_EXPORTS bool cv::gpu::hasCubinVersion(int major, int minor)\r
 {\r
-    return checkCubinVersion(major, minor, ComparerEqual());\r
+    return ::compare(OPENCV_ARCH_GPU, major * 10 + minor, std::equal_to<int>());\r
 }\r
 \r
 \r
 CV_EXPORTS bool cv::gpu::hasGreaterOrEqualCubinVersion(int major, int minor)\r
 {\r
-    return checkCubinVersion(major, minor, ComparerGreaterOrEqual());\r
+    return ::compare(OPENCV_ARCH_GPU, major * 10 + minor, \r
+                     std::greater_equal<int>());\r
 }\r
 \r
 \r
@@ -284,7 +222,7 @@ CV_EXPORTS bool cv::gpu::isCompatibleWith(int device)
         return true;\r
 \r
     // Check CUBIN compatibilty\r
-    for (int i = 0; i <= minor; ++i)\r
+    for (int i = minor; i >= 0; --i)\r
         if (hasCubinVersion(major, i))\r
             return true;\r
 \r
index a7ba6ff..03acb4a 100644 (file)
     #error "Insufficient NPP version, please update it."\r
 #endif\r
 \r
+#if defined(OPENCV_ARCH_GPU_OR_PTX_10)\r
+    #error "OpenCV GPU module doesn't support NVIDIA compute capability 1.0"\r
+#endif\r
+\r
     static inline void throw_nogpu() { CV_Error(CV_GpuNotSupported, "The called functionality is disabled for current build or platform"); }\r
 \r
 #else /* defined(HAVE_CUDA) */\r