From 01f4a173aba2882eaec6b6249ae2895bc3624dcc Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Sat, 27 Jan 2018 13:09:28 +0000 Subject: [PATCH 1/2] opencv_version: dump OpenCL information via opencv_version fix missing "opencv2/core/opencl" headers from core module (updated install list) --- apps/version/opencv_version.cpp | 14 +- cmake/templates/opencv_abi.xml.in | 1 + modules/core/CMakeLists.txt | 3 +- .../opencv2/core/opencl/opencl_info.hpp | 198 ++++++++++++++++++ modules/python/bindings/CMakeLists.txt | 1 + modules/ts/src/ocl_test.cpp | 184 +--------------- 6 files changed, 225 insertions(+), 176 deletions(-) create mode 100644 modules/core/include/opencv2/core/opencl/opencl_info.hpp diff --git a/apps/version/opencv_version.cpp b/apps/version/opencv_version.cpp index 9ad4baceaf..ecb602c171 100644 --- a/apps/version/opencv_version.cpp +++ b/apps/version/opencv_version.cpp @@ -7,6 +7,8 @@ #include #include +#include + int main(int argc, const char** argv) { CV_TRACE_FUNCTION(); @@ -17,12 +19,16 @@ int main(int argc, const char** argv) cv::CommandLineParser parser(argc, argv, "{ help h usage ? | | show this help message }" "{ verbose v | | show build configuration log }" + "{ opencl | | show information about OpenCL (available platforms/devices, default selected device) }" ); + if (parser.has("help")) { parser.printMessage(); + return 0; } - else if (parser.has("verbose")) + + if (parser.has("verbose")) { std::cout << cv::getBuildInformation().c_str() << std::endl; } @@ -30,5 +36,11 @@ int main(int argc, const char** argv) { std::cout << CV_VERSION << std::endl; } + + if (parser.has("opencl")) + { + cv::dumpOpenCLInformation(); + } + return 0; } diff --git a/cmake/templates/opencv_abi.xml.in b/cmake/templates/opencv_abi.xml.in index 99128451bf..ed142d8917 100644 --- a/cmake/templates/opencv_abi.xml.in +++ b/cmake/templates/opencv_abi.xml.in @@ -23,6 +23,7 @@ opencv2/core/hal/intrin* opencv2/core/cuda* + opencv2/core/opencl* opencv2/core/private* opencv/cxeigen.hpp opencv2/core/eigen.hpp diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index a9ed1f157b..adb2013bb0 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -27,6 +27,7 @@ endif() file(GLOB lib_cuda_hdrs "include/opencv2/${name}/cuda/*.hpp" "include/opencv2/${name}/cuda/*.h") file(GLOB lib_cuda_hdrs_detail "include/opencv2/${name}/cuda/detail/*.hpp" "include/opencv2/${name}/cuda/detail/*.h") +file(GLOB_RECURSE module_opencl_hdrs "include/opencv2/${name}/opencl/*") source_group("Include\\Cuda Headers" FILES ${lib_cuda_hdrs}) source_group("Include\\Cuda Headers\\Detail" FILES ${lib_cuda_hdrs_detail}) @@ -34,7 +35,7 @@ source_group("Include\\Cuda Headers\\Detail" FILES ${lib_cuda_hdrs_detail}) source_group("Src" FILES "${OPENCV_MODULE_opencv_core_BINARY_DIR}/version_string.inc") ocv_glob_module_sources(SOURCES "${OPENCV_MODULE_opencv_core_BINARY_DIR}/version_string.inc" - HEADERS ${lib_cuda_hdrs} ${lib_cuda_hdrs_detail}) + HEADERS ${module_opencl_hdrs} ${lib_cuda_hdrs} ${lib_cuda_hdrs_detail}) ocv_module_include_directories(${the_module} ${ZLIB_INCLUDE_DIRS} ${OPENCL_INCLUDE_DIRS}) if(ANDROID AND HAVE_CPUFEATURES) diff --git a/modules/core/include/opencv2/core/opencl/opencl_info.hpp b/modules/core/include/opencv2/core/opencl/opencl_info.hpp new file mode 100644 index 0000000000..fdd27039e2 --- /dev/null +++ b/modules/core/include/opencv2/core/opencl/opencl_info.hpp @@ -0,0 +1,198 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#include + +#include +#include + +#ifndef DUMP_CONFIG_PROPERTY +#define DUMP_CONFIG_PROPERTY(...) +#endif + +#ifndef DUMP_MESSAGE_STDOUT +#define DUMP_MESSAGE_STDOUT(...) do { std::cout << __VA_ARGS__ << std::endl; } while (false) +#endif + +namespace cv { + +namespace { +static std::string bytesToStringRepr(size_t value) +{ + size_t b = value % 1024; + value /= 1024; + + size_t kb = value % 1024; + value /= 1024; + + size_t mb = value % 1024; + value /= 1024; + + size_t gb = value; + + std::ostringstream stream; + + if (gb > 0) + stream << gb << " GB "; + if (mb > 0) + stream << mb << " MB "; + if (kb > 0) + stream << kb << " KB "; + if (b > 0) + stream << b << " B"; + + std::string s = stream.str(); + if (s[s.size() - 1] == ' ') + s = s.substr(0, s.size() - 1); + return s; +} +} // namespace + +static void dumpOpenCLInformation() +{ + using namespace cv::ocl; + + try + { + if (!haveOpenCL() || !useOpenCL()) + { + DUMP_MESSAGE_STDOUT("OpenCL is disabled"); + DUMP_CONFIG_PROPERTY("cv_ocl", "disabled"); + return; + } + + std::vector platforms; + cv::ocl::getPlatfomsInfo(platforms); + if (platforms.size() > 0) + { + DUMP_MESSAGE_STDOUT("OpenCL Platforms: "); + for (size_t i = 0; i < platforms.size(); i++) + { + const PlatformInfo* platform = &platforms[i]; + DUMP_MESSAGE_STDOUT(" " << platform->name().c_str()); + Device current_device; + for (int j = 0; j < platform->deviceNumber(); j++) + { + platform->getDevice(current_device, j); + const char* deviceTypeStr = current_device.type() == Device::TYPE_CPU + ? ("CPU") : (current_device.type() == Device::TYPE_GPU ? current_device.hostUnifiedMemory() ? "iGPU" : "dGPU" : "unknown"); + DUMP_MESSAGE_STDOUT( " " << deviceTypeStr << ": " << current_device.name().c_str() << " (" << current_device.version().c_str() << ")"); + DUMP_CONFIG_PROPERTY( cv::format("cv_ocl_platform_%d_device_%d", (int)i, (int)j ), + cv::format("(Platform=%s)(Type=%s)(Name=%s)(Version=%s)", + platform->name().c_str(), deviceTypeStr, current_device.name().c_str(), current_device.version().c_str()) ); + } + } + } + else + { + DUMP_MESSAGE_STDOUT("OpenCL is not available"); + DUMP_CONFIG_PROPERTY("cv_ocl", "not available"); + return; + } + + const Device& device = Device::getDefault(); + if (!device.available()) + CV_ErrorNoReturn(Error::OpenCLInitError, "OpenCL device is not available"); + + DUMP_MESSAGE_STDOUT("Current OpenCL device: "); + +#if 0 + DUMP_MESSAGE_STDOUT(" Platform = " << device.getPlatform().name()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_platformName", device.getPlatform().name()); +#endif + + const char* deviceTypeStr = device.type() == Device::TYPE_CPU + ? ("CPU") : (device.type() == Device::TYPE_GPU ? device.hostUnifiedMemory() ? "iGPU" : "dGPU" : "unknown"); + DUMP_MESSAGE_STDOUT(" Type = " << deviceTypeStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_deviceType", deviceTypeStr); + + DUMP_MESSAGE_STDOUT(" Name = " << device.name()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_deviceName", device.name()); + + DUMP_MESSAGE_STDOUT(" Version = " << device.version()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_deviceVersion", device.version()); + + DUMP_MESSAGE_STDOUT(" Driver version = " << device.driverVersion()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_driverVersion", device.driverVersion()); + + DUMP_MESSAGE_STDOUT(" Address bits = " << device.addressBits()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_addressBits", device.addressBits()); + + DUMP_MESSAGE_STDOUT(" Compute units = " << device.maxComputeUnits()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_maxComputeUnits", device.maxComputeUnits()); + + DUMP_MESSAGE_STDOUT(" Max work group size = " << device.maxWorkGroupSize()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_maxWorkGroupSize", device.maxWorkGroupSize()); + + std::string localMemorySizeStr = bytesToStringRepr(device.localMemSize()); + DUMP_MESSAGE_STDOUT(" Local memory size = " << localMemorySizeStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_localMemSize", device.localMemSize()); + + std::string maxMemAllocSizeStr = bytesToStringRepr(device.maxMemAllocSize()); + DUMP_MESSAGE_STDOUT(" Max memory allocation size = " << maxMemAllocSizeStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_maxMemAllocSize", device.maxMemAllocSize()); + + const char* doubleSupportStr = device.doubleFPConfig() > 0 ? "Yes" : "No"; + DUMP_MESSAGE_STDOUT(" Double support = " << doubleSupportStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_haveDoubleSupport", device.doubleFPConfig() > 0); + + const char* isUnifiedMemoryStr = device.hostUnifiedMemory() ? "Yes" : "No"; + DUMP_MESSAGE_STDOUT(" Host unified memory = " << isUnifiedMemoryStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_hostUnifiedMemory", device.hostUnifiedMemory()); + + DUMP_MESSAGE_STDOUT(" Device extensions:"); + String extensionsStr = device.extensions(); + size_t pos = 0; + while (pos < extensionsStr.size()) + { + size_t pos2 = extensionsStr.find(' ', pos); + if (pos2 == String::npos) + pos2 = extensionsStr.size(); + if (pos2 > pos) + { + String extensionName = extensionsStr.substr(pos, pos2 - pos); + DUMP_MESSAGE_STDOUT(" " << extensionName); + } + pos = pos2 + 1; + } + DUMP_CONFIG_PROPERTY("cv_ocl_current_extensions", extensionsStr.c_str()); + + const char* haveAmdBlasStr = haveAmdBlas() ? "Yes" : "No"; + DUMP_MESSAGE_STDOUT(" Has AMD Blas = " << haveAmdBlasStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_AmdBlas", haveAmdBlas()); + + const char* haveAmdFftStr = haveAmdFft() ? "Yes" : "No"; + DUMP_MESSAGE_STDOUT(" Has AMD Fft = " << haveAmdFftStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_AmdFft", haveAmdFft()); + + + DUMP_MESSAGE_STDOUT(" Preferred vector width char = " << device.preferredVectorWidthChar()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthChar", device.preferredVectorWidthChar()); + + DUMP_MESSAGE_STDOUT(" Preferred vector width short = " << device.preferredVectorWidthShort()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthShort", device.preferredVectorWidthShort()); + + DUMP_MESSAGE_STDOUT(" Preferred vector width int = " << device.preferredVectorWidthInt()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthInt", device.preferredVectorWidthInt()); + + DUMP_MESSAGE_STDOUT(" Preferred vector width long = " << device.preferredVectorWidthLong()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthLong", device.preferredVectorWidthLong()); + + DUMP_MESSAGE_STDOUT(" Preferred vector width float = " << device.preferredVectorWidthFloat()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthFloat", device.preferredVectorWidthFloat()); + + DUMP_MESSAGE_STDOUT(" Preferred vector width double = " << device.preferredVectorWidthDouble()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthDouble", device.preferredVectorWidthDouble()); + } + catch (...) + { + DUMP_MESSAGE_STDOUT("Exception. Can't dump OpenCL info"); + DUMP_MESSAGE_STDOUT("OpenCL device not available"); + DUMP_CONFIG_PROPERTY("cv_ocl", "not available"); + } +} +#undef DUMP_MESSAGE_STDOUT +#undef DUMP_CONFIG_PROPERTY + +} // namespace diff --git a/modules/python/bindings/CMakeLists.txt b/modules/python/bindings/CMakeLists.txt index 4226dd853e..73c67aa3ce 100644 --- a/modules/python/bindings/CMakeLists.txt +++ b/modules/python/bindings/CMakeLists.txt @@ -32,6 +32,7 @@ ocv_list_filterout(opencv_hdrs "modules/core/.*/cuda") ocv_list_filterout(opencv_hdrs "modules/cuda.*") ocv_list_filterout(opencv_hdrs "modules/cudev") ocv_list_filterout(opencv_hdrs "modules/core/.*/hal/") +ocv_list_filterout(opencv_hdrs "modules/core/.*/opencl/") ocv_list_filterout(opencv_hdrs "modules/.+/utils/.*") ocv_list_filterout(opencv_hdrs "modules/.*\\\\.inl\\\\.h*") ocv_list_filterout(opencv_hdrs "modules/.*_inl\\\\.h*") diff --git a/modules/ts/src/ocl_test.cpp b/modules/ts/src/ocl_test.cpp index 6e25468c2e..8eaa7e637d 100644 --- a/modules/ts/src/ocl_test.cpp +++ b/modules/ts/src/ocl_test.cpp @@ -43,16 +43,9 @@ #include "opencv2/ts/ocl_test.hpp" -namespace cvtest { -namespace ocl { - -using namespace cv; - -int test_loop_times = 1; // TODO Read from command line / environment - #ifdef HAVE_OPENCL -#define DUMP_PROPERTY_XML(propertyName, propertyValue) \ +#define DUMP_CONFIG_PROPERTY(propertyName, propertyValue) \ do { \ std::stringstream ssName, ssValue;\ ssName << propertyName;\ @@ -65,180 +58,23 @@ int test_loop_times = 1; // TODO Read from command line / environment std::cout << msg << std::endl; \ } while (false) -static std::string bytesToStringRepr(size_t value) -{ - size_t b = value % 1024; - value /= 1024; +#include - size_t kb = value % 1024; - value /= 1024; +#endif // HAVE_OPENCL - size_t mb = value % 1024; - value /= 1024; - - size_t gb = value; - - std::ostringstream stream; +namespace cvtest { +namespace ocl { - if (gb > 0) - stream << gb << " GB "; - if (mb > 0) - stream << mb << " MB "; - if (kb > 0) - stream << kb << " kB "; - if (b > 0) - stream << b << " B"; +using namespace cv; - return stream.str(); -} +int test_loop_times = 1; // TODO Read from command line / environment +#ifdef HAVE_OPENCL void dumpOpenCLDevice() { - using namespace cv::ocl; - - try - { - if (!useOpenCL()) - { - DUMP_MESSAGE_STDOUT("OpenCL is disabled"); - DUMP_PROPERTY_XML("cv_ocl", "disabled"); - return; - } - - std::vector platforms; - cv::ocl::getPlatfomsInfo(platforms); - if (platforms.size() > 0) - { - DUMP_MESSAGE_STDOUT("OpenCL Platforms: "); - for (size_t i = 0; i < platforms.size(); i++) - { - const PlatformInfo* platform = &platforms[i]; - DUMP_MESSAGE_STDOUT(" " << platform->name().c_str()); - Device current_device; - for (int j = 0; j < platform->deviceNumber(); j++) - { - platform->getDevice(current_device, j); - const char* deviceTypeStr = current_device.type() == Device::TYPE_CPU - ? ("CPU") : (current_device.type() == Device::TYPE_GPU ? current_device.hostUnifiedMemory() ? "iGPU" : "dGPU" : "unknown"); - DUMP_MESSAGE_STDOUT( " " << deviceTypeStr << ": " << current_device.name().c_str() << " (" << current_device.version().c_str() << ")"); - DUMP_PROPERTY_XML( cv::format("cv_ocl_platform_%d_device_%d", (int)i, (int)j ), - cv::format("(Platform=%s)(Type=%s)(Name=%s)(Version=%s)", - platform->name().c_str(), deviceTypeStr, current_device.name().c_str(), current_device.version().c_str()) ); - } - } - } - else - { - DUMP_MESSAGE_STDOUT("OpenCL is not available"); - DUMP_PROPERTY_XML("cv_ocl", "not available"); - return; - } - - const Device& device = Device::getDefault(); - if (!device.available()) - CV_ErrorNoReturn(CV_OpenCLInitError, "OpenCL device is not available"); - - DUMP_MESSAGE_STDOUT("Current OpenCL device: "); - -#if 0 - DUMP_MESSAGE_STDOUT(" Platform = "<< device.getPlatform().name()); - DUMP_PROPERTY_XML("cv_ocl_current_platformName", device.getPlatform().name()); -#endif - - const char* deviceTypeStr = device.type() == Device::TYPE_CPU - ? ("CPU") : (device.type() == Device::TYPE_GPU ? device.hostUnifiedMemory() ? "iGPU" : "dGPU" : "unknown"); - DUMP_MESSAGE_STDOUT(" Type = "<< deviceTypeStr); - DUMP_PROPERTY_XML("cv_ocl_current_deviceType", deviceTypeStr); - - DUMP_MESSAGE_STDOUT(" Name = "<< device.name()); - DUMP_PROPERTY_XML("cv_ocl_current_deviceName", device.name()); - - DUMP_MESSAGE_STDOUT(" Version = " << device.version()); - DUMP_PROPERTY_XML("cv_ocl_current_deviceVersion", device.version()); - - DUMP_MESSAGE_STDOUT(" Driver version = " << device.driverVersion()); - DUMP_PROPERTY_XML("cv_ocl_current_driverVersion", device.driverVersion()); - - DUMP_MESSAGE_STDOUT(" Address bits = " << device.addressBits()); - DUMP_PROPERTY_XML("cv_ocl_current_addressBits", device.addressBits()); - - DUMP_MESSAGE_STDOUT(" Compute units = "<< device.maxComputeUnits()); - DUMP_PROPERTY_XML("cv_ocl_current_maxComputeUnits", device.maxComputeUnits()); - - DUMP_MESSAGE_STDOUT(" Max work group size = "<< device.maxWorkGroupSize()); - DUMP_PROPERTY_XML("cv_ocl_current_maxWorkGroupSize", device.maxWorkGroupSize()); - - std::string localMemorySizeStr = bytesToStringRepr(device.localMemSize()); - DUMP_MESSAGE_STDOUT(" Local memory size = " << localMemorySizeStr); - DUMP_PROPERTY_XML("cv_ocl_current_localMemSize", device.localMemSize()); - - std::string maxMemAllocSizeStr = bytesToStringRepr(device.maxMemAllocSize()); - DUMP_MESSAGE_STDOUT(" Max memory allocation size = "<< maxMemAllocSizeStr); - DUMP_PROPERTY_XML("cv_ocl_current_maxMemAllocSize", device.maxMemAllocSize()); - - const char* doubleSupportStr = device.doubleFPConfig() > 0 ? "Yes" : "No"; - DUMP_MESSAGE_STDOUT(" Double support = "<< doubleSupportStr); - DUMP_PROPERTY_XML("cv_ocl_current_haveDoubleSupport", device.doubleFPConfig() > 0); - - const char* isUnifiedMemoryStr = device.hostUnifiedMemory() ? "Yes" : "No"; - DUMP_MESSAGE_STDOUT(" Host unified memory = "<< isUnifiedMemoryStr); - DUMP_PROPERTY_XML("cv_ocl_current_hostUnifiedMemory", device.hostUnifiedMemory()); - - DUMP_MESSAGE_STDOUT(" Device extensions:"); - String extensionsStr = device.extensions(); - size_t pos = 0; - while (pos < extensionsStr.size()) - { - size_t pos2 = extensionsStr.find(' ', pos); - if (pos2 == String::npos) - pos2 = extensionsStr.size(); - if (pos2 > pos) - { - String extensionName = extensionsStr.substr(pos, pos2 - pos); - DUMP_MESSAGE_STDOUT(" " << extensionName); - } - pos = pos2 + 1; - } - DUMP_PROPERTY_XML("cv_ocl_current_extensions", extensionsStr.c_str()); - - const char* haveAmdBlasStr = haveAmdBlas() ? "Yes" : "No"; - DUMP_MESSAGE_STDOUT(" Has AMD Blas = "<< haveAmdBlasStr); - DUMP_PROPERTY_XML("cv_ocl_current_AmdBlas", haveAmdBlas()); - - const char* haveAmdFftStr = haveAmdFft() ? "Yes" : "No"; - DUMP_MESSAGE_STDOUT(" Has AMD Fft = "<< haveAmdFftStr); - DUMP_PROPERTY_XML("cv_ocl_current_AmdFft", haveAmdFft()); - - - DUMP_MESSAGE_STDOUT(" Preferred vector width char = "<< device.preferredVectorWidthChar()); - DUMP_PROPERTY_XML("cv_ocl_current_preferredVectorWidthChar", device.preferredVectorWidthChar()); - - DUMP_MESSAGE_STDOUT(" Preferred vector width short = "<< device.preferredVectorWidthShort()); - DUMP_PROPERTY_XML("cv_ocl_current_preferredVectorWidthShort", device.preferredVectorWidthShort()); - - DUMP_MESSAGE_STDOUT(" Preferred vector width int = "<< device.preferredVectorWidthInt()); - DUMP_PROPERTY_XML("cv_ocl_current_preferredVectorWidthInt", device.preferredVectorWidthInt()); - - DUMP_MESSAGE_STDOUT(" Preferred vector width long = "<< device.preferredVectorWidthLong()); - DUMP_PROPERTY_XML("cv_ocl_current_preferredVectorWidthLong", device.preferredVectorWidthLong()); - - DUMP_MESSAGE_STDOUT(" Preferred vector width float = "<< device.preferredVectorWidthFloat()); - DUMP_PROPERTY_XML("cv_ocl_current_preferredVectorWidthFloat", device.preferredVectorWidthFloat()); - - DUMP_MESSAGE_STDOUT(" Preferred vector width double = "<< device.preferredVectorWidthDouble()); - DUMP_PROPERTY_XML("cv_ocl_current_preferredVectorWidthDouble", device.preferredVectorWidthDouble()); - } - catch (...) - { - DUMP_MESSAGE_STDOUT("Exception. Can't dump OpenCL info"); - DUMP_MESSAGE_STDOUT("OpenCL device not available"); - DUMP_PROPERTY_XML("cv_ocl", "not available"); - } + cv::dumpOpenCLInformation(); } -#undef DUMP_MESSAGE_STDOUT -#undef DUMP_PROPERTY_XML - -#endif +#endif // HAVE_OPENCL Mat TestUtils::readImage(const String &fileName, int flags) { From c8930cc27964680b0df97aaed2250347c449ad07 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Sat, 27 Jan 2018 13:37:38 +0000 Subject: [PATCH 2/2] opencv_version: dump detected HW features --- apps/version/opencv_version.cpp | 22 +++++++++++++++++++ modules/core/include/opencv2/core/utility.hpp | 6 +++++ modules/core/src/system.cpp | 5 +++++ 3 files changed, 33 insertions(+) diff --git a/apps/version/opencv_version.cpp b/apps/version/opencv_version.cpp index ecb602c171..04aa25917f 100644 --- a/apps/version/opencv_version.cpp +++ b/apps/version/opencv_version.cpp @@ -20,6 +20,7 @@ int main(int argc, const char** argv) "{ help h usage ? | | show this help message }" "{ verbose v | | show build configuration log }" "{ opencl | | show information about OpenCL (available platforms/devices, default selected device) }" + "{ hw | | show detected HW features (see cv::checkHardwareSupport() function). Use --hw=0 to show available features only }" ); if (parser.has("help")) @@ -42,5 +43,26 @@ int main(int argc, const char** argv) cv::dumpOpenCLInformation(); } + if (parser.has("hw")) + { + bool showAll = parser.get("hw"); + std::cout << "OpenCV's HW features list:" << std::endl; + int count = 0; + for (int i = 0; i < CV_HARDWARE_MAX_FEATURE; i++) + { + cv::String name = cv::getHardwareFeatureName(i); + if (name.empty()) + continue; + bool enabled = cv::checkHardwareSupport(i); + if (enabled) + count++; + if (enabled || showAll) + { + printf(" ID=%3d (%s) -> %s\n", i, name.c_str(), enabled ? "ON" : "N/A"); + } + } + std::cout << "Total available: " << count << std::endl; + } + return 0; } diff --git a/modules/core/include/opencv2/core/utility.hpp b/modules/core/include/opencv2/core/utility.hpp index 69d114e156..863012710c 100644 --- a/modules/core/include/opencv2/core/utility.hpp +++ b/modules/core/include/opencv2/core/utility.hpp @@ -427,6 +427,12 @@ in OpenCV. */ CV_EXPORTS_W bool checkHardwareSupport(int feature); +/** @brief Returns feature name by ID + +Returns empty string if feature is not defined +*/ +CV_EXPORTS_W String getHardwareFeatureName(int feature); + /** @brief Returns the number of logical CPUs available for the process. */ CV_EXPORTS_W int getNumberOfCPUs(); diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index ccf2ca0e28..ceca01f82e 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -663,6 +663,11 @@ bool checkHardwareSupport(int feature) return currentFeatures->have[feature]; } +String getHardwareFeatureName(int feature) +{ + const char* name = getHWFeatureName(feature); + return name ? String(name) : String(); +} volatile bool useOptimizedFlag = true;