From: Vladislav Vinogradov Date: Fri, 23 Nov 2012 14:36:15 +0000 (+0400) Subject: added optimized deviceSupports function X-Git-Tag: accepted/tizen/6.0/unified/20201030.111113~4052^2~56^2~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f00efcfc593b361f875b1b85c2684850cd192974;p=platform%2Fupstream%2Fopencv.git added optimized deviceSupports function --- diff --git a/modules/core/include/opencv2/core/gpumat.hpp b/modules/core/include/opencv2/core/gpumat.hpp index 73da7e7..6bf4e5d 100644 --- a/modules/core/include/opencv2/core/gpumat.hpp +++ b/modules/core/include/opencv2/core/gpumat.hpp @@ -79,6 +79,8 @@ namespace cv { namespace gpu WARP_SHUFFLE_FUNCTIONS = FEATURE_SET_COMPUTE_30 }; + CV_EXPORTS bool deviceSupports(FeatureSet feature_set); + // Gives information about what GPU archs this OpenCV GPU module was // compiled for class CV_EXPORTS TargetArchs diff --git a/modules/core/src/gpumat.cpp b/modules/core/src/gpumat.cpp index afd7115..6b5b076 100644 --- a/modules/core/src/gpumat.cpp +++ b/modules/core/src/gpumat.cpp @@ -69,33 +69,89 @@ using namespace cv::gpu; namespace { - // Compares value to set using the given comparator. Returns true if - // there is at least one element x in the set satisfying to: x cmp value - // predicate. - template - bool compareToSet(const std::string& set_as_str, int value, Comparer cmp) + class CudaArch + { + public: + CudaArch(); + + bool builtWith(FeatureSet feature_set) const; + bool hasPtx(int major, int minor) const; + bool hasBin(int major, int minor) const; + bool hasEqualOrLessPtx(int major, int minor) const; + bool hasEqualOrGreaterPtx(int major, int minor) const; + bool hasEqualOrGreaterBin(int major, int minor) const; + + private: + static void fromStr(const string& set_as_str, vector& arr); + + vector bin; + vector ptx; + vector features; + }; + + const CudaArch cudaArch; + + CudaArch::CudaArch() + { + #ifdef HAVE_CUDA + fromStr(CUDA_ARCH_BIN, bin); + fromStr(CUDA_ARCH_PTX, ptx); + fromStr(CUDA_ARCH_FEATURES, features); + #endif + } + + bool CudaArch::builtWith(FeatureSet feature_set) const + { + return !features.empty() && (features.back() >= feature_set); + } + + bool CudaArch::hasPtx(int major, int minor) const + { + return find(ptx.begin(), ptx.end(), major * 10 + minor) != ptx.end(); + } + + bool CudaArch::hasBin(int major, int minor) const + { + return find(bin.begin(), bin.end(), major * 10 + minor) != bin.end(); + } + + bool CudaArch::hasEqualOrLessPtx(int major, int minor) const + { + return !ptx.empty() && (ptx.front() <= major * 10 + minor); + } + + bool CudaArch::hasEqualOrGreaterPtx(int major, int minor) const + { + return !ptx.empty() && (ptx.back() >= major * 10 + minor); + } + + bool CudaArch::hasEqualOrGreaterBin(int major, int minor) const + { + return !bin.empty() && (bin.back() >= major * 10 + minor); + } + + void CudaArch::fromStr(const string& set_as_str, vector& arr) { if (set_as_str.find_first_not_of(" ") == string::npos) - return false; + return; - std::stringstream stream(set_as_str); + istringstream stream(set_as_str); int cur_value; while (!stream.eof()) { stream >> cur_value; - if (cmp(cur_value, value)) - return true; + arr.push_back(cur_value); } - return false; + sort(arr.begin(), arr.end()); } } bool cv::gpu::TargetArchs::builtWith(cv::gpu::FeatureSet feature_set) { #if defined (HAVE_CUDA) - return ::compareToSet(CUDA_ARCH_FEATURES, feature_set, std::greater_equal()); + return cudaArch.builtWith(feature_set); #else (void)feature_set; return false; @@ -110,7 +166,7 @@ bool cv::gpu::TargetArchs::has(int major, int minor) bool cv::gpu::TargetArchs::hasPtx(int major, int minor) { #if defined (HAVE_CUDA) - return ::compareToSet(CUDA_ARCH_PTX, major * 10 + minor, std::equal_to()); + return cudaArch.hasPtx(major, minor); #else (void)major; (void)minor; @@ -121,7 +177,7 @@ bool cv::gpu::TargetArchs::hasPtx(int major, int minor) bool cv::gpu::TargetArchs::hasBin(int major, int minor) { #if defined (HAVE_CUDA) - return ::compareToSet(CUDA_ARCH_BIN, major * 10 + minor, std::equal_to()); + return cudaArch.hasBin(major, minor); #else (void)major; (void)minor; @@ -132,8 +188,7 @@ bool cv::gpu::TargetArchs::hasBin(int major, int minor) bool cv::gpu::TargetArchs::hasEqualOrLessPtx(int major, int minor) { #if defined (HAVE_CUDA) - return ::compareToSet(CUDA_ARCH_PTX, major * 10 + minor, - std::less_equal()); + return cudaArch.hasEqualOrLessPtx(major, minor); #else (void)major; (void)minor; @@ -143,14 +198,13 @@ bool cv::gpu::TargetArchs::hasEqualOrLessPtx(int major, int minor) bool cv::gpu::TargetArchs::hasEqualOrGreater(int major, int minor) { - return hasEqualOrGreaterPtx(major, minor) || - hasEqualOrGreaterBin(major, minor); + return hasEqualOrGreaterPtx(major, minor) || hasEqualOrGreaterBin(major, minor); } bool cv::gpu::TargetArchs::hasEqualOrGreaterPtx(int major, int minor) { #if defined (HAVE_CUDA) - return ::compareToSet(CUDA_ARCH_PTX, major * 10 + minor, std::greater_equal()); + return cudaArch.hasEqualOrGreaterPtx(major, minor); #else (void)major; (void)minor; @@ -161,8 +215,7 @@ bool cv::gpu::TargetArchs::hasEqualOrGreaterPtx(int major, int minor) bool cv::gpu::TargetArchs::hasEqualOrGreaterBin(int major, int minor) { #if defined (HAVE_CUDA) - return ::compareToSet(CUDA_ARCH_BIN, major * 10 + minor, - std::greater_equal()); + return cudaArch.hasEqualOrGreaterBin(major, minor); #else (void)major; (void)minor; @@ -170,6 +223,31 @@ bool cv::gpu::TargetArchs::hasEqualOrGreaterBin(int major, int minor) #endif } +bool cv::gpu::deviceSupports(FeatureSet feature_set) +{ + static int versions[] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + static const int cache_size = static_cast(sizeof(versions) / sizeof(versions[0])); + + const int devId = getDevice(); + + int version; + + if (devId < cache_size && versions[devId] >= 0) + version = versions[devId]; + else + { + DeviceInfo dev(devId); + version = dev.majorVersion() * 10 + dev.minorVersion(); + if (devId < cache_size) + versions[devId] = version; + } + + return TargetArchs::builtWith(feature_set) && (version >= feature_set); +} + #if !defined (HAVE_CUDA) #define throw_nogpu CV_Error(CV_GpuNotSupported, "The library is compiled without CUDA support")