1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Copyright (C) 2015, Itseez Inc., all rights reserved.
16 // Third party copyrights are property of their respective owners.
18 // Redistribution and use in source and binary forms, with or without modification,
19 // are permitted provided that the following conditions are met:
21 // * Redistribution's of source code must retain the above copyright notice,
22 // this list of conditions and the following disclaimer.
24 // * Redistribution's in binary form must reproduce the above copyright notice,
25 // this list of conditions and the following disclaimer in the documentation
26 // and/or other materials provided with the distribution.
28 // * The name of the copyright holders may not be used to endorse or promote products
29 // derived from this software without specific prior written permission.
31 // This software is provided by the copyright holders and contributors "as is" and
32 // any express or implied warranties, including, but not limited to, the implied
33 // warranties of merchantability and fitness for a particular purpose are disclaimed.
34 // In no event shall the Intel Corporation or contributors be liable for any direct,
35 // indirect, incidental, special, exemplary, or consequential damages
36 // (including, but not limited to, procurement of substitute goods or services;
37 // loss of use, data, or profits; or business interruption) however caused
38 // and on any theory of liability, whether in contract, strict liability,
39 // or tort (including negligence or otherwise) arising in any way out of
40 // the use of this software, even if advised of the possibility of such damage.
44 #include "precomp.hpp"
47 #include <opencv2/core/utils/configuration.private.hpp>
48 #include <opencv2/core/utils/trace.private.hpp>
50 #include <opencv2/core/utils/logger.hpp>
54 static Mutex* __initialization_mutex = NULL;
55 Mutex& getInitializationMutex()
57 if (__initialization_mutex == NULL)
58 __initialization_mutex = new Mutex();
59 return *__initialization_mutex;
61 // force initialization (single-threaded environment)
62 Mutex* __initialization_mutex_initializer = &getInitializationMutex();
64 static bool param_dumpErrors = utils::getConfigurationParameterBool("OPENCV_DUMP_ERRORS",
65 #if defined(_DEBUG) || defined(__ANDROID__) || (defined(__GNUC__) && !defined(__EXCEPTIONS))
74 #ifndef CV_ERROR_SET_TERMINATE_HANDLER // build config option
76 # define CV_ERROR_SET_TERMINATE_HANDLER 1
79 #if defined(CV_ERROR_SET_TERMINATE_HANDLER) && !CV_ERROR_SET_TERMINATE_HANDLER
80 # undef CV_ERROR_SET_TERMINATE_HANDLER
85 # pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
89 #ifdef CV_ERROR_SET_TERMINATE_HANDLER
90 #include <exception> // std::set_terminate
91 #include <cstdlib> // std::abort
94 #if defined __ANDROID__ || defined __linux__ || defined __FreeBSD__ || defined __HAIKU__
98 #if defined __ANDROID__ || defined __linux__
99 # include <linux/auxvec.h>
103 #if defined __ANDROID__ && defined HAVE_CPUFEATURES
104 # include <cpu-features.h>
108 # if defined __PPC64__ && defined __linux__
109 # include "sys/auxv.h"
111 # define AT_HWCAP2 26
113 # ifndef PPC_FEATURE2_ARCH_2_07
114 # define PPC_FEATURE2_ARCH_2_07 0x80000000
119 #if defined _WIN32 || defined WINCE
120 #ifndef _WIN32_WINNT // This is needed for the declaration of TryEnterCriticalSection in winbase.h with Visual Studio 2005 (and older?)
121 #define _WIN32_WINNT 0x0400 // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx
124 #if (_WIN32_WINNT >= 0x0602)
125 #include <synchapi.h>
134 #include <wrl/client.h>
135 #ifndef __cplusplus_winrt
136 #include <windows.storage.h>
137 #pragma comment(lib, "runtimeobject.lib")
140 std::wstring GetTempPathWinRT()
142 #ifdef __cplusplus_winrt
143 return std::wstring(Windows::Storage::ApplicationData::Current->TemporaryFolder->Path->Data());
145 Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationDataStatics> appdataFactory;
146 Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationData> appdataRef;
147 Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> storagefolderRef;
148 Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageItem> storageitemRef;
150 HSTRING_HEADER hstrHead;
152 if (FAILED(WindowsCreateStringReference(RuntimeClass_Windows_Storage_ApplicationData,
153 (UINT32)wcslen(RuntimeClass_Windows_Storage_ApplicationData), &hstrHead, &str)))
155 if (FAILED(RoGetActivationFactory(str, IID_PPV_ARGS(appdataFactory.ReleaseAndGetAddressOf()))))
157 if (FAILED(appdataFactory->get_Current(appdataRef.ReleaseAndGetAddressOf())))
159 if (FAILED(appdataRef->get_TemporaryFolder(storagefolderRef.ReleaseAndGetAddressOf())))
161 if (FAILED(storagefolderRef.As(&storageitemRef)))
164 if (FAILED(storageitemRef->get_Path(&str)))
166 wstr = WindowsGetStringRawBuffer(str, NULL);
167 WindowsDeleteString(str);
172 std::wstring GetTempFileNameWinRT(std::wstring prefix)
177 wchar_t* mask = L"%08x_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x";
178 swprintf(&guidStr[0], sizeof(guidStr)/sizeof(wchar_t), mask,
179 g.Data1, g.Data2, g.Data3, UINT(g.Data4[0]), UINT(g.Data4[1]),
180 UINT(g.Data4[2]), UINT(g.Data4[3]), UINT(g.Data4[4]),
181 UINT(g.Data4[5]), UINT(g.Data4[6]), UINT(g.Data4[7]));
183 return prefix.append(std::wstring(guidStr));
189 #include <sys/time.h>
192 #if defined __MACH__ && defined __APPLE__
193 #include <mach/mach.h>
194 #include <mach/mach_time.h>
203 #if defined __linux__ || defined __APPLE__ || defined __EMSCRIPTEN__ || defined __FreeBSD__ || defined __GLIBC__ || defined __HAIKU__
206 #include <sys/types.h>
207 #if defined __ANDROID__
208 #include <sys/sysconf.h>
213 # include <android/log.h>
216 #ifdef DECLARE_CV_CPUID_X86
220 #if defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
221 #if _MSC_VER >= 1400 // MSVS 2005
222 #include <intrin.h> // __cpuidex()
223 #define CV_CPUID_X86 __cpuidex
225 #error "Required MSVS 2005+"
227 #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
228 static void cv_cpuid(int* cpuid_data, int reg_eax, int reg_ecx)
230 int __eax = reg_eax, __ebx = 0, __ecx = reg_ecx, __edx = 0;
231 // tested with available compilers (-fPIC -O2 -m32/-m64): https://godbolt.org/
232 #if !defined(__PIC__) \
233 || defined(__x86_64__) || __GNUC__ >= 5 \
234 || defined(__clang__) || defined(__INTEL_COMPILER)
236 : "+a" (__eax), "=b" (__ebx), "+c" (__ecx), "=d" (__edx)
238 #elif defined(__i386__) // ebx may be reserved as the PIC register
239 __asm__("xchg{l}\t{%%}ebx, %1\n\t"
241 "xchg{l}\t{%%}ebx, %1\n\t"
242 : "+a" (__eax), "=&r" (__ebx), "+c" (__ecx), "=d" (__edx)
245 #error "Configuration error"
247 cpuid_data[0] = __eax; cpuid_data[1] = __ebx; cpuid_data[2] = __ecx; cpuid_data[3] = __edx;
249 #define CV_CPUID_X86 cv_cpuid
257 Exception::Exception() { code = 0; line = 0; }
259 Exception::Exception(int _code, const String& _err, const String& _func, const String& _file, int _line)
260 : code(_code), err(_err), func(_func), file(_file), line(_line)
265 Exception::~Exception() throw() {}
268 \return the error description and the context as a text string.
270 const char* Exception::what() const throw() { return msg.c_str(); }
272 void Exception::formatMessage()
274 size_t pos = err.find('\n');
275 bool multiline = pos != cv::String::npos;
278 std::stringstream ss;
280 while (pos != cv::String::npos)
282 ss << "> " << err.substr(prev_pos, pos - prev_pos) << std::endl;
284 pos = err.find('\n', prev_pos);
286 ss << "> " << err.substr(prev_pos);
287 if (err[err.size() - 1] != '\n')
294 msg = format("OpenCV(%s) %s:%d: error: (%d:%s) in function '%s'\n%s", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), func.c_str(), err.c_str());
296 msg = format("OpenCV(%s) %s:%d: error: (%d:%s) %s in function '%s'\n", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), err.c_str(), func.c_str());
300 msg = format("OpenCV(%s) %s:%d: error: (%d:%s) %s%s", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), err.c_str(), multiline ? "" : "\n");
304 static const char* g_hwFeatureNames[CV_HARDWARE_MAX_FEATURE] = { NULL };
306 static const char* getHWFeatureName(int id)
308 return (id < CV_HARDWARE_MAX_FEATURE) ? g_hwFeatureNames[id] : NULL;
310 static const char* getHWFeatureNameSafe(int id)
312 const char* name = getHWFeatureName(id);
313 return name ? name : "Unknown feature";
318 enum { MAX_FEATURE = CV_HARDWARE_MAX_FEATURE };
320 HWFeatures(bool run_initialize = false)
322 memset( have, 0, sizeof(have[0]) * MAX_FEATURE );
327 static void initializeNames()
329 for (int i = 0; i < CV_HARDWARE_MAX_FEATURE; i++)
331 g_hwFeatureNames[i] = 0;
333 g_hwFeatureNames[CPU_MMX] = "MMX";
334 g_hwFeatureNames[CPU_SSE] = "SSE";
335 g_hwFeatureNames[CPU_SSE2] = "SSE2";
336 g_hwFeatureNames[CPU_SSE3] = "SSE3";
337 g_hwFeatureNames[CPU_SSSE3] = "SSSE3";
338 g_hwFeatureNames[CPU_SSE4_1] = "SSE4.1";
339 g_hwFeatureNames[CPU_SSE4_2] = "SSE4.2";
340 g_hwFeatureNames[CPU_POPCNT] = "POPCNT";
341 g_hwFeatureNames[CPU_FP16] = "FP16";
342 g_hwFeatureNames[CPU_AVX] = "AVX";
343 g_hwFeatureNames[CPU_AVX2] = "AVX2";
344 g_hwFeatureNames[CPU_FMA3] = "FMA3";
346 g_hwFeatureNames[CPU_AVX_512F] = "AVX512F";
347 g_hwFeatureNames[CPU_AVX_512BW] = "AVX512BW";
348 g_hwFeatureNames[CPU_AVX_512CD] = "AVX512CD";
349 g_hwFeatureNames[CPU_AVX_512DQ] = "AVX512DQ";
350 g_hwFeatureNames[CPU_AVX_512ER] = "AVX512ER";
351 g_hwFeatureNames[CPU_AVX_512IFMA] = "AVX512IFMA";
352 g_hwFeatureNames[CPU_AVX_512PF] = "AVX512PF";
353 g_hwFeatureNames[CPU_AVX_512VBMI] = "AVX512VBMI";
354 g_hwFeatureNames[CPU_AVX_512VL] = "AVX512VL";
356 g_hwFeatureNames[CPU_NEON] = "NEON";
358 g_hwFeatureNames[CPU_VSX] = "VSX";
360 g_hwFeatureNames[CPU_AVX512_SKX] = "AVX512-SKX";
363 void initialize(void)
366 if (getenv("OPENCV_DUMP_CONFIG"))
368 fprintf(stderr, "\nOpenCV build configuration is:\n%s\n",
369 cv::getBuildInformation().c_str());
376 int cpuid_data[4] = { 0, 0, 0, 0 };
377 int cpuid_data_ex[4] = { 0, 0, 0, 0 };
379 CV_CPUID_X86(cpuid_data, 1, 0/*unused*/);
381 int x86_family = (cpuid_data[0] >> 8) & 15;
382 if( x86_family >= 6 )
384 have[CV_CPU_MMX] = (cpuid_data[3] & (1<<23)) != 0;
385 have[CV_CPU_SSE] = (cpuid_data[3] & (1<<25)) != 0;
386 have[CV_CPU_SSE2] = (cpuid_data[3] & (1<<26)) != 0;
387 have[CV_CPU_SSE3] = (cpuid_data[2] & (1<<0)) != 0;
388 have[CV_CPU_SSSE3] = (cpuid_data[2] & (1<<9)) != 0;
389 have[CV_CPU_FMA3] = (cpuid_data[2] & (1<<12)) != 0;
390 have[CV_CPU_SSE4_1] = (cpuid_data[2] & (1<<19)) != 0;
391 have[CV_CPU_SSE4_2] = (cpuid_data[2] & (1<<20)) != 0;
392 have[CV_CPU_POPCNT] = (cpuid_data[2] & (1<<23)) != 0;
393 have[CV_CPU_AVX] = (cpuid_data[2] & (1<<28)) != 0;
394 have[CV_CPU_FP16] = (cpuid_data[2] & (1<<29)) != 0;
396 // make the second call to the cpuid command in order to get
397 // information about extended features like AVX2
398 CV_CPUID_X86(cpuid_data_ex, 7, 0);
400 have[CV_CPU_AVX2] = (cpuid_data_ex[1] & (1<<5)) != 0;
402 have[CV_CPU_AVX_512F] = (cpuid_data_ex[1] & (1<<16)) != 0;
403 have[CV_CPU_AVX_512DQ] = (cpuid_data_ex[1] & (1<<17)) != 0;
404 have[CV_CPU_AVX_512IFMA512] = (cpuid_data_ex[1] & (1<<21)) != 0;
405 have[CV_CPU_AVX_512PF] = (cpuid_data_ex[1] & (1<<26)) != 0;
406 have[CV_CPU_AVX_512ER] = (cpuid_data_ex[1] & (1<<27)) != 0;
407 have[CV_CPU_AVX_512CD] = (cpuid_data_ex[1] & (1<<28)) != 0;
408 have[CV_CPU_AVX_512BW] = (cpuid_data_ex[1] & (1<<30)) != 0;
409 have[CV_CPU_AVX_512VL] = (cpuid_data_ex[1] & (1<<31)) != 0;
410 have[CV_CPU_AVX_512VBMI] = (cpuid_data_ex[2] & (1<<1)) != 0;
412 bool have_AVX_OS_support = true;
413 bool have_AVX512_OS_support = true;
414 if (!(cpuid_data[2] & (1<<27)))
415 have_AVX_OS_support = false; // OS uses XSAVE_XRSTORE and CPU support AVX
419 #ifdef _XCR_XFEATURE_ENABLED_MASK // requires immintrin.h
420 xcr0 = (int)_xgetbv(_XCR_XFEATURE_ENABLED_MASK);
421 #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
422 __asm__ ("xgetbv\n\t" : "=a" (xcr0) : "c" (0) : "%edx" );
424 if ((xcr0 & 0x6) != 0x6)
425 have_AVX_OS_support = false; // YMM registers
426 if ((xcr0 & 0xe6) != 0xe6)
427 have_AVX512_OS_support = false; // ZMM registers
430 if (!have_AVX_OS_support)
432 have[CV_CPU_AVX] = false;
433 have[CV_CPU_FP16] = false;
434 have[CV_CPU_AVX2] = false;
435 have[CV_CPU_FMA3] = false;
437 if (!have_AVX_OS_support || !have_AVX512_OS_support)
439 have[CV_CPU_AVX_512F] = false;
440 have[CV_CPU_AVX_512BW] = false;
441 have[CV_CPU_AVX_512CD] = false;
442 have[CV_CPU_AVX_512DQ] = false;
443 have[CV_CPU_AVX_512ER] = false;
444 have[CV_CPU_AVX_512IFMA512] = false;
445 have[CV_CPU_AVX_512PF] = false;
446 have[CV_CPU_AVX_512VBMI] = false;
447 have[CV_CPU_AVX_512VL] = false;
450 if (have[CV_CPU_AVX_512F])
452 have[CV_CPU_AVX512_SKX] = have[CV_CPU_AVX_512F] & have[CV_CPU_AVX_512CD] & have[CV_CPU_AVX_512BW] & have[CV_CPU_AVX_512DQ] & have[CV_CPU_AVX_512VL];
455 #endif // CV_CPUID_X86
457 #if defined __ANDROID__ || defined __linux__
459 have[CV_CPU_NEON] = true;
460 have[CV_CPU_FP16] = true;
461 #elif defined __arm__ && defined __ANDROID__
462 #if defined HAVE_CPUFEATURES
463 CV_LOG_INFO(NULL, "calling android_getCpuFeatures() ...");
464 uint64_t features = android_getCpuFeatures();
465 CV_LOG_INFO(NULL, cv::format("calling android_getCpuFeatures() ... Done (%llx)", (long long)features));
466 have[CV_CPU_NEON] = (features & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
467 have[CV_CPU_FP16] = (features & ANDROID_CPU_ARM_FEATURE_VFP_FP16) != 0;
469 CV_LOG_INFO(NULL, "cpufeatures library is not available for CPU detection");
471 CV_LOG_INFO(NULL, "- NEON instructions is enabled via build flags");
472 have[CV_CPU_NEON] = true;
474 CV_LOG_INFO(NULL, "- NEON instructions is NOT enabled via build flags");
477 CV_LOG_INFO(NULL, "- FP16 instructions is enabled via build flags");
478 have[CV_CPU_FP16] = true;
480 CV_LOG_INFO(NULL, "- FP16 instructions is NOT enabled via build flags");
483 #elif defined __arm__
484 int cpufile = open("/proc/self/auxv", O_RDONLY);
489 const size_t size_auxv_t = sizeof(auxv);
491 while ((size_t)read(cpufile, &auxv, size_auxv_t) == size_auxv_t)
493 if (auxv.a_type == AT_HWCAP)
495 have[CV_CPU_NEON] = (auxv.a_un.a_val & 4096) != 0;
496 have[CV_CPU_FP16] = (auxv.a_un.a_val & 2) != 0;
504 #elif (defined __clang__ || defined __APPLE__)
505 #if (defined __ARM_NEON__ || (defined __ARM_NEON && defined __aarch64__))
506 have[CV_CPU_NEON] = true;
508 #if (defined __ARM_FP && (((__ARM_FP & 0x2) != 0) && defined __ARM_NEON__))
509 have[CV_CPU_FP16] = true;
514 have[CV_CPU_VSX] = true;
515 #elif (defined __PPC64__ && defined __linux__)
516 uint64 hwcaps = getauxval(AT_HWCAP);
517 uint64 hwcap2 = getauxval(AT_HWCAP2);
518 have[CV_CPU_VSX] = (hwcaps & PPC_FEATURE_PPC_LE && hwcaps & PPC_FEATURE_HAS_VSX && hwcap2 & PPC_FEATURE2_ARCH_2_07);
520 have[CV_CPU_VSX] = false;
523 int baseline_features[] = { CV_CPU_BASELINE_FEATURES };
524 if (!checkFeatures(baseline_features, sizeof(baseline_features) / sizeof(baseline_features[0])))
527 "******************************************************************\n"
529 "* This OpenCV build doesn't support current CPU/HW configuration *\n"
531 "* Use OPENCV_DUMP_CONFIG=1 environment variable for details *\n"
532 "******************************************************************\n");
533 fprintf(stderr, "\nRequired baseline features:\n");
534 checkFeatures(baseline_features, sizeof(baseline_features) / sizeof(baseline_features[0]), true);
535 CV_Error(cv::Error::StsAssert, "Missing support for required CPU baseline features. Check OpenCV build configuration and required CPU/HW setup.");
538 readSettings(baseline_features, sizeof(baseline_features) / sizeof(baseline_features[0]));
541 bool checkFeatures(const int* features, int count, bool dump = false)
544 for (int i = 0; i < count; i++)
546 int feature = features[i];
551 if (dump) fprintf(stderr, "%s - OK\n", getHWFeatureNameSafe(feature));
556 if (dump) fprintf(stderr, "%s - NOT AVAILABLE\n", getHWFeatureNameSafe(feature));
563 static inline bool isSymbolSeparator(char c)
565 return c == ',' || c == ';';
568 void readSettings(const int* baseline_features, int baseline_count)
571 const char* disabled_features =
573 getenv("OPENCV_CPU_DISABLE");
577 if (disabled_features && disabled_features[0] != 0)
579 const char* start = disabled_features;
582 while (start[0] != 0 && isSymbolSeparator(start[0]))
588 const char* end = start;
589 while (end[0] != 0 && !isSymbolSeparator(end[0]))
595 cv::String feature(start, end);
598 CV_Assert(feature.size() > 0);
601 for (int i = 0; i < CV_HARDWARE_MAX_FEATURE; i++)
603 if (!g_hwFeatureNames[i]) continue;
604 size_t len = strlen(g_hwFeatureNames[i]);
605 if (len != feature.size()) continue;
606 if (feature.compare(g_hwFeatureNames[i]) == 0)
608 bool isBaseline = false;
609 for (int k = 0; k < baseline_count; k++)
611 if (baseline_features[k] == i)
619 if (dump) fprintf(stderr, "OPENCV: Trying to disable baseline CPU feature: '%s'. This has very limited effect, because code optimizations for this feature are executed unconditionally in the most cases.\n", getHWFeatureNameSafe(i));
623 if (dump) fprintf(stderr, "OPENCV: Trying to disable unavailable CPU feature on the current platform: '%s'.\n", getHWFeatureNameSafe(i));
633 if (dump) fprintf(stderr, "OPENCV: Trying to disable unknown CPU feature: '%s'.\n", feature.c_str());
639 bool have[MAX_FEATURE+1];
642 static HWFeatures featuresEnabled(true), featuresDisabled = HWFeatures(false);
643 static HWFeatures* currentFeatures = &featuresEnabled;
645 bool checkHardwareSupport(int feature)
647 CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
648 return currentFeatures->have[feature];
651 String getHardwareFeatureName(int feature)
653 const char* name = getHWFeatureName(feature);
654 return name ? String(name) : String();
657 volatile bool useOptimizedFlag = true;
659 void setUseOptimized( bool flag )
661 useOptimizedFlag = flag;
662 currentFeatures = flag ? &featuresEnabled : &featuresDisabled;
664 ipp::setUseIPP(flag);
666 ocl::setUseOpenCL(flag);
668 #ifdef HAVE_TEGRA_OPTIMIZATION
669 ::tegra::setUseTegra(flag);
673 bool useOptimized(void)
675 return useOptimizedFlag;
678 int64 getTickCount(void)
680 #if defined _WIN32 || defined WINCE
681 LARGE_INTEGER counter;
682 QueryPerformanceCounter( &counter );
683 return (int64)counter.QuadPart;
684 #elif defined __linux || defined __linux__
686 clock_gettime(CLOCK_MONOTONIC, &tp);
687 return (int64)tp.tv_sec*1000000000 + tp.tv_nsec;
688 #elif defined __MACH__ && defined __APPLE__
689 return (int64)mach_absolute_time();
693 gettimeofday( &tv, &tz );
694 return (int64)tv.tv_sec*1000000 + tv.tv_usec;
698 double getTickFrequency(void)
700 #if defined _WIN32 || defined WINCE
702 QueryPerformanceFrequency(&freq);
703 return (double)freq.QuadPart;
704 #elif defined __linux || defined __linux__
706 #elif defined __MACH__ && defined __APPLE__
707 static double freq = 0;
710 mach_timebase_info_data_t sTimebaseInfo;
711 mach_timebase_info(&sTimebaseInfo);
712 freq = sTimebaseInfo.denom*1e9/sTimebaseInfo.numer;
720 #if defined __GNUC__ && (defined __i386__ || defined __x86_64__ || defined __ppc__)
721 #if defined(__i386__)
723 int64 getCPUTickCount(void)
726 __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
729 #elif defined(__x86_64__)
731 int64 getCPUTickCount(void)
734 __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
735 return (int64)lo | ((int64)hi << 32);
738 #elif defined(__ppc__)
740 int64 getCPUTickCount(void)
742 unsigned upper, lower, tmp;
750 : "=r"(upper),"=r"(lower),"=r"(tmp)
752 return lower | ((int64)upper << 32);
757 #error "RDTSC not defined"
761 #elif defined _MSC_VER && defined _WIN32 && defined _M_IX86
763 int64 getCPUTickCount(void)
772 //int64 getCPUTickCount(void)
774 // return ippGetCpuClocks();
777 int64 getCPUTickCount(void)
779 return getTickCount();
785 const String& getBuildInformation()
787 static String build_info =
788 #include "version_string.inc"
793 String getVersionString() { return String(CV_VERSION); }
795 int getVersionMajor() { return CV_VERSION_MAJOR; }
797 int getVersionMinor() { return CV_VERSION_MINOR; }
799 int getVersionRevision() { return CV_VERSION_REVISION; }
801 String format( const char* fmt, ... )
803 AutoBuffer<char, 1024> buf;
809 int bsize = static_cast<int>(buf.size());
810 int len = cv_vsnprintf((char *)buf, bsize, fmt, va);
813 CV_Assert(len >= 0 && "Check format string for errors");
820 return String((char *)buf, len);
824 String tempfile( const char* suffix )
828 const char *temp_dir = getenv("OPENCV_TEMP_PATH");
833 RoInitialize(RO_INIT_MULTITHREADED);
834 std::wstring temp_dir = GetTempPathWinRT();
836 std::wstring temp_file = GetTempFileNameWinRT(L"ocv");
837 if (temp_file.empty())
840 temp_file = temp_dir.append(std::wstring(L"\\")).append(temp_file);
841 DeleteFileW(temp_file.c_str());
843 char aname[MAX_PATH];
844 size_t copied = wcstombs(aname, temp_file.c_str(), MAX_PATH);
845 CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
846 fname = String(aname);
849 char temp_dir2[MAX_PATH] = { 0 };
850 char temp_file[MAX_PATH] = { 0 };
852 if (temp_dir == 0 || temp_dir[0] == 0)
854 ::GetTempPathA(sizeof(temp_dir2), temp_dir2);
855 temp_dir = temp_dir2;
857 if(0 == ::GetTempFileNameA(temp_dir, "ocv", 0, temp_file))
860 DeleteFileA(temp_file);
866 //char defaultTemplate[] = "/mnt/sdcard/__opencv_temp.XXXXXX";
867 char defaultTemplate[] = "/data/local/tmp/__opencv_temp.XXXXXX";
869 char defaultTemplate[] = "/tmp/__opencv_temp.XXXXXX";
872 if (temp_dir == 0 || temp_dir[0] == 0)
873 fname = defaultTemplate;
877 char ech = fname[fname.size() - 1];
878 if(ech != '/' && ech != '\\')
880 fname = fname + "__opencv_temp.XXXXXX";
883 const int fd = mkstemp((char*)fname.c_str());
884 if (fd == -1) return String();
887 remove(fname.c_str());
892 if (suffix[0] != '.')
893 return fname + "." + suffix;
895 return fname + suffix;
900 static ErrorCallback customErrorCallback = 0;
901 static void* customErrorCallbackData = 0;
902 static bool breakOnError = false;
904 bool setBreakOnError(bool value)
906 bool prevVal = breakOnError;
907 breakOnError = value;
911 int cv_snprintf(char* buf, int len, const char* fmt, ...)
915 int res = cv_vsnprintf(buf, len, fmt, va);
920 int cv_vsnprintf(char* buf, int len, const char* fmt, va_list args)
923 if (len <= 0) return len == 0 ? 1024 : -1;
924 int res = _vsnprintf_s(buf, len, _TRUNCATE, fmt, args);
925 // ensure null terminating on VS
926 if (res >= 0 && res < len)
933 buf[len - 1] = 0; // truncate happened
934 return res >= len ? res : (len * 2);
937 return vsnprintf(buf, len, fmt, args);
941 static void dumpException(const Exception& exc)
943 const char* errorStr = cvErrorStr(exc.code);
946 cv_snprintf(buf, sizeof(buf),
947 "OpenCV(%s) Error: %s (%s) in %s, file %s, line %d",
949 errorStr, exc.err.c_str(), exc.func.size() > 0 ?
950 exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line);
952 __android_log_print(ANDROID_LOG_ERROR, "cv::error()", "%s", buf);
954 fflush(stdout); fflush(stderr);
955 fprintf(stderr, "%s\n", buf);
960 #ifdef CV_ERROR_SET_TERMINATE_HANDLER
961 static bool cv_terminate_handler_installed = false;
962 static std::terminate_handler cv_old_terminate_handler;
963 static cv::Exception cv_terminate_handler_exception;
964 static bool param_setupTerminateHandler = utils::getConfigurationParameterBool("OPENCV_SETUP_TERMINATE_HANDLER", true);
965 static void cv_terminate_handler() {
966 std::cerr << "OpenCV: terminate handler is called! The last OpenCV error is:\n";
967 dumpException(cv_terminate_handler_exception);
968 if (false /*cv_old_terminate_handler*/) // buggy behavior is observed with doubled "abort/retry/ignore" windows
969 cv_old_terminate_handler();
975 void error( const Exception& exc )
977 #ifdef CV_ERROR_SET_TERMINATE_HANDLER
979 cv::AutoLock lock(getInitializationMutex());
980 if (!cv_terminate_handler_installed)
982 if (param_setupTerminateHandler)
983 cv_old_terminate_handler = std::set_terminate(cv_terminate_handler);
984 cv_terminate_handler_installed = true;
986 cv_terminate_handler_exception = exc;
990 if (customErrorCallback != 0)
991 customErrorCallback(exc.code, exc.func.c_str(), exc.err.c_str(),
992 exc.file.c_str(), exc.line, customErrorCallbackData);
993 else if (param_dumpErrors)
1000 static volatile int* p = 0;
1007 void error(int _code, const String& _err, const char* _func, const char* _file, int _line)
1009 error(cv::Exception(_code, _err, _func, _file, _line));
1014 redirectError( ErrorCallback errCallback, void* userdata, void** prevUserdata)
1017 *prevUserdata = customErrorCallbackData;
1019 ErrorCallback prevCallback = customErrorCallback;
1021 customErrorCallback = errCallback;
1022 customErrorCallbackData = userdata;
1024 return prevCallback;
1029 CV_IMPL int cvCheckHardwareSupport(int feature)
1031 CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
1032 return cv::currentFeatures->have[feature];
1035 CV_IMPL int cvUseOptimized( int flag )
1037 int prevMode = cv::useOptimizedFlag;
1038 cv::setUseOptimized( flag != 0 );
1042 CV_IMPL int64 cvGetTickCount(void)
1044 return cv::getTickCount();
1047 CV_IMPL double cvGetTickFrequency(void)
1049 return cv::getTickFrequency()*1e-6;
1052 CV_IMPL CvErrorCallback
1053 cvRedirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
1055 return cv::redirectError(errCallback, userdata, prevUserdata);
1058 CV_IMPL int cvNulDevReport( int, const char*, const char*,
1059 const char*, int, void* )
1064 CV_IMPL int cvStdErrReport( int, const char*, const char*,
1065 const char*, int, void* )
1070 CV_IMPL int cvGuiBoxReport( int, const char*, const char*,
1071 const char*, int, void* )
1076 CV_IMPL int cvGetErrInfo( const char**, const char**, const char**, int* )
1082 CV_IMPL const char* cvErrorStr( int status )
1084 static char buf[256];
1088 case CV_StsOk : return "No Error";
1089 case CV_StsBackTrace : return "Backtrace";
1090 case CV_StsError : return "Unspecified error";
1091 case CV_StsInternal : return "Internal error";
1092 case CV_StsNoMem : return "Insufficient memory";
1093 case CV_StsBadArg : return "Bad argument";
1094 case CV_StsNoConv : return "Iterations do not converge";
1095 case CV_StsAutoTrace : return "Autotrace call";
1096 case CV_StsBadSize : return "Incorrect size of input array";
1097 case CV_StsNullPtr : return "Null pointer";
1098 case CV_StsDivByZero : return "Division by zero occurred";
1099 case CV_BadStep : return "Image step is wrong";
1100 case CV_StsInplaceNotSupported : return "Inplace operation is not supported";
1101 case CV_StsObjectNotFound : return "Requested object was not found";
1102 case CV_BadDepth : return "Input image depth is not supported by function";
1103 case CV_StsUnmatchedFormats : return "Formats of input arguments do not match";
1104 case CV_StsUnmatchedSizes : return "Sizes of input arguments do not match";
1105 case CV_StsOutOfRange : return "One of arguments\' values is out of range";
1106 case CV_StsUnsupportedFormat : return "Unsupported format or combination of formats";
1107 case CV_BadCOI : return "Input COI is not supported";
1108 case CV_BadNumChannels : return "Bad number of channels";
1109 case CV_StsBadFlag : return "Bad flag (parameter or structure field)";
1110 case CV_StsBadPoint : return "Bad parameter of type CvPoint";
1111 case CV_StsBadMask : return "Bad type of mask argument";
1112 case CV_StsParseError : return "Parsing error";
1113 case CV_StsNotImplemented : return "The function/feature is not implemented";
1114 case CV_StsBadMemBlock : return "Memory block has been corrupted";
1115 case CV_StsAssert : return "Assertion failed";
1116 case CV_GpuNotSupported : return "No CUDA support";
1117 case CV_GpuApiCallError : return "Gpu API call";
1118 case CV_OpenGlNotSupported : return "No OpenGL support";
1119 case CV_OpenGlApiCallError : return "OpenGL API call";
1122 sprintf(buf, "Unknown %s code %d", status >= 0 ? "status":"error", status);
1126 CV_IMPL int cvGetErrMode(void)
1131 CV_IMPL int cvSetErrMode(int)
1136 CV_IMPL int cvGetErrStatus(void)
1141 CV_IMPL void cvSetErrStatus(int)
1146 CV_IMPL void cvError( int code, const char* func_name,
1147 const char* err_msg,
1148 const char* file_name, int line )
1150 cv::error(cv::Exception(code, err_msg, func_name, file_name, line));
1153 /* function, which converts int to int */
1155 cvErrorFromIppStatus( int status )
1159 case CV_BADSIZE_ERR: return CV_StsBadSize;
1160 case CV_BADMEMBLOCK_ERR: return CV_StsBadMemBlock;
1161 case CV_NULLPTR_ERR: return CV_StsNullPtr;
1162 case CV_DIV_BY_ZERO_ERR: return CV_StsDivByZero;
1163 case CV_BADSTEP_ERR: return CV_BadStep;
1164 case CV_OUTOFMEM_ERR: return CV_StsNoMem;
1165 case CV_BADARG_ERR: return CV_StsBadArg;
1166 case CV_NOTDEFINED_ERR: return CV_StsError;
1167 case CV_INPLACE_NOT_SUPPORTED_ERR: return CV_StsInplaceNotSupported;
1168 case CV_NOTFOUND_ERR: return CV_StsObjectNotFound;
1169 case CV_BADCONVERGENCE_ERR: return CV_StsNoConv;
1170 case CV_BADDEPTH_ERR: return CV_BadDepth;
1171 case CV_UNMATCHED_FORMATS_ERR: return CV_StsUnmatchedFormats;
1172 case CV_UNSUPPORTED_COI_ERR: return CV_BadCOI;
1173 case CV_UNSUPPORTED_CHANNELS_ERR: return CV_BadNumChannels;
1174 case CV_BADFLAG_ERR: return CV_StsBadFlag;
1175 case CV_BADRANGE_ERR: return CV_StsBadArg;
1176 case CV_BADCOEF_ERR: return CV_StsBadArg;
1177 case CV_BADFACTOR_ERR: return CV_StsBadArg;
1178 case CV_BADPOINT_ERR: return CV_StsBadPoint;
1186 bool __termination = false;
1192 #if defined _WIN32 || defined WINCE
1198 #if (_WIN32_WINNT >= 0x0600)
1199 ::InitializeCriticalSectionEx(&cs, 1000, 0);
1201 ::InitializeCriticalSection(&cs);
1205 ~Impl() { DeleteCriticalSection(&cs); }
1207 void lock() { EnterCriticalSection(&cs); }
1208 bool trylock() { return TryEnterCriticalSection(&cs) != 0; }
1209 void unlock() { LeaveCriticalSection(&cs); }
1211 CRITICAL_SECTION cs;
1221 pthread_mutexattr_t attr;
1222 pthread_mutexattr_init(&attr);
1223 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
1224 pthread_mutex_init(&mt, &attr);
1225 pthread_mutexattr_destroy(&attr);
1229 ~Impl() { pthread_mutex_destroy(&mt); }
1231 void lock() { pthread_mutex_lock(&mt); }
1232 bool trylock() { return pthread_mutex_trylock(&mt) == 0; }
1233 void unlock() { pthread_mutex_unlock(&mt); }
1243 impl = new Mutex::Impl;
1248 if( CV_XADD(&impl->refcount, -1) == 1 )
1253 Mutex::Mutex(const Mutex& m)
1256 CV_XADD(&impl->refcount, 1);
1259 Mutex& Mutex::operator = (const Mutex& m)
1263 CV_XADD(&m.impl->refcount, 1);
1264 if( CV_XADD(&impl->refcount, -1) == 1 )
1271 void Mutex::lock() { impl->lock(); }
1272 void Mutex::unlock() { impl->unlock(); }
1273 bool Mutex::trylock() { return impl->trylock(); }
1276 //////////////////////////////// thread-local storage ////////////////////////////////
1280 #pragma warning(disable:4505) // unreferenced local function has been removed
1282 #ifndef TLS_OUT_OF_INDEXES
1283 #define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
1287 // TLS platform abstraction layer
1288 class TlsAbstraction
1293 void* GetData() const;
1294 void SetData(void *pData);
1302 pthread_key_t tlsKey;
1308 static __declspec( thread ) void* tlsData = NULL; // using C++11 thread attribute for local thread data
1309 TlsAbstraction::TlsAbstraction() {}
1310 TlsAbstraction::~TlsAbstraction() {}
1311 void* TlsAbstraction::GetData() const
1315 void TlsAbstraction::SetData(void *pData)
1320 TlsAbstraction::TlsAbstraction()
1322 tlsKey = TlsAlloc();
1323 CV_Assert(tlsKey != TLS_OUT_OF_INDEXES);
1325 TlsAbstraction::~TlsAbstraction()
1329 void* TlsAbstraction::GetData() const
1331 return TlsGetValue(tlsKey);
1333 void TlsAbstraction::SetData(void *pData)
1335 CV_Assert(TlsSetValue(tlsKey, pData) == TRUE);
1339 TlsAbstraction::TlsAbstraction()
1341 CV_Assert(pthread_key_create(&tlsKey, NULL) == 0);
1343 TlsAbstraction::~TlsAbstraction()
1345 CV_Assert(pthread_key_delete(tlsKey) == 0);
1347 void* TlsAbstraction::GetData() const
1349 return pthread_getspecific(tlsKey);
1351 void TlsAbstraction::SetData(void *pData)
1353 CV_Assert(pthread_setspecific(tlsKey, pData) == 0);
1357 // Per-thread data structure
1366 std::vector<void*> slots; // Data array for a thread
1367 size_t idx; // Thread index in TLS storage. This is not OS thread ID!
1370 // Main TLS storage class
1377 tlsSlots.reserve(32);
1378 threads.reserve(32);
1382 for(size_t i = 0; i < threads.size(); i++)
1386 /* Current architecture doesn't allow proper global objects release, so this check can cause crashes
1388 // Check if all slots were properly cleared
1389 for(size_t j = 0; j < threads[i]->slots.size(); j++)
1391 CV_Assert(threads[i]->slots[j] == 0);
1400 void releaseThread()
1402 AutoLock guard(mtxGlobalAccess);
1403 ThreadData *pTD = (ThreadData*)tls.GetData();
1404 for(size_t i = 0; i < threads.size(); i++)
1406 if(pTD == threads[i])
1416 // Reserve TLS storage index
1417 size_t reserveSlot()
1419 AutoLock guard(mtxGlobalAccess);
1420 CV_Assert(tlsSlotsSize == tlsSlots.size());
1422 // Find unused slots
1423 for(size_t slot = 0; slot < tlsSlotsSize; slot++)
1433 tlsSlots.push_back(1); tlsSlotsSize++;
1434 return tlsSlotsSize - 1;
1437 // Release TLS storage index and pass associated data to caller
1438 void releaseSlot(size_t slotIdx, std::vector<void*> &dataVec, bool keepSlot = false)
1440 AutoLock guard(mtxGlobalAccess);
1441 CV_Assert(tlsSlotsSize == tlsSlots.size());
1442 CV_Assert(tlsSlotsSize > slotIdx);
1444 for(size_t i = 0; i < threads.size(); i++)
1448 std::vector<void*>& thread_slots = threads[i]->slots;
1449 if (thread_slots.size() > slotIdx && thread_slots[slotIdx])
1451 dataVec.push_back(thread_slots[slotIdx]);
1452 thread_slots[slotIdx] = NULL;
1458 tlsSlots[slotIdx] = 0;
1461 // Get data by TLS storage index
1462 void* getData(size_t slotIdx) const
1464 #ifndef CV_THREAD_SANITIZER
1465 CV_Assert(tlsSlotsSize > slotIdx);
1468 ThreadData* threadData = (ThreadData*)tls.GetData();
1469 if(threadData && threadData->slots.size() > slotIdx)
1470 return threadData->slots[slotIdx];
1475 // Gather data from threads by TLS storage index
1476 void gather(size_t slotIdx, std::vector<void*> &dataVec)
1478 AutoLock guard(mtxGlobalAccess);
1479 CV_Assert(tlsSlotsSize == tlsSlots.size());
1480 CV_Assert(tlsSlotsSize > slotIdx);
1482 for(size_t i = 0; i < threads.size(); i++)
1486 std::vector<void*>& thread_slots = threads[i]->slots;
1487 if (thread_slots.size() > slotIdx && thread_slots[slotIdx])
1488 dataVec.push_back(thread_slots[slotIdx]);
1493 // Set data to storage index
1494 void setData(size_t slotIdx, void* pData)
1496 #ifndef CV_THREAD_SANITIZER
1497 CV_Assert(tlsSlotsSize > slotIdx);
1500 ThreadData* threadData = (ThreadData*)tls.GetData();
1503 threadData = new ThreadData;
1504 tls.SetData((void*)threadData);
1506 AutoLock guard(mtxGlobalAccess);
1507 threadData->idx = threads.size();
1508 threads.push_back(threadData);
1512 if(slotIdx >= threadData->slots.size())
1514 AutoLock guard(mtxGlobalAccess); // keep synchronization with gather() calls
1515 threadData->slots.resize(slotIdx + 1, NULL);
1517 threadData->slots[slotIdx] = pData;
1521 TlsAbstraction tls; // TLS abstraction layer instance
1523 Mutex mtxGlobalAccess; // Shared objects operation guard
1524 size_t tlsSlotsSize; // equal to tlsSlots.size() in synchronized sections
1525 // without synchronization this counter doesn't desrease - it is used for slotIdx sanity checks
1526 std::vector<int> tlsSlots; // TLS keys state
1527 std::vector<ThreadData*> threads; // Array for all allocated data. Thread data pointers are placed here to allow data cleanup
1530 // Create global TLS storage object
1531 static TlsStorage &getTlsStorage()
1533 CV_SINGLETON_LAZY_INIT_REF(TlsStorage, new TlsStorage())
1536 TLSDataContainer::TLSDataContainer()
1538 key_ = (int)getTlsStorage().reserveSlot(); // Reserve key from TLS storage
1541 TLSDataContainer::~TLSDataContainer()
1543 CV_Assert(key_ == -1); // Key must be released in child object
1546 void TLSDataContainer::gatherData(std::vector<void*> &data) const
1548 getTlsStorage().gather(key_, data);
1551 void TLSDataContainer::release()
1553 std::vector<void*> data;
1555 getTlsStorage().releaseSlot(key_, data); // Release key and get stored data for proper destruction
1557 for(size_t i = 0; i < data.size(); i++) // Delete all associated data
1558 deleteDataInstance(data[i]);
1561 void TLSDataContainer::cleanup()
1563 std::vector<void*> data;
1565 getTlsStorage().releaseSlot(key_, data, true); // Extract stored data with removal from TLS tables
1566 for(size_t i = 0; i < data.size(); i++) // Delete all associated data
1567 deleteDataInstance(data[i]);
1570 void* TLSDataContainer::getData() const
1572 CV_Assert(key_ != -1 && "Can't fetch data from terminated TLS container.");
1573 void* pData = getTlsStorage().getData(key_); // Check if data was already allocated
1576 // Create new data instance and save it to TLS storage
1577 pData = createDataInstance();
1578 getTlsStorage().setData(key_, pData);
1583 TLSData<CoreTLSData>& getCoreTlsData()
1585 CV_SINGLETON_LAZY_INIT_REF(TLSData<CoreTLSData>, new TLSData<CoreTLSData>())
1588 #if defined CVAPI_EXPORTS && defined _WIN32 && !defined WINCE
1590 #pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
1594 BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID lpReserved);
1597 BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID lpReserved)
1599 if (fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH)
1601 if (lpReserved != NULL) // called after ExitProcess() call
1603 cv::__termination = true;
1607 // Not allowed to free resources if lpReserved is non-null
1608 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583.aspx
1609 cv::getTlsStorage().releaseThread();
1618 static int g_threadNum = 0;
1623 id(CV_XADD(&g_threadNum, 1))
1625 #ifdef OPENCV_WITH_ITT
1626 __itt_thread_set_name(cv::format("OpenCVThread-%03d", id).c_str());
1631 static TLSData<ThreadID>& getThreadIDTLS()
1633 CV_SINGLETON_LAZY_INIT_REF(TLSData<ThreadID>, new TLSData<ThreadID>());
1637 int utils::getThreadID() { return getThreadIDTLS().get()->id; }
1639 bool utils::getConfigurationParameterBool(const char* name, bool defaultValue)
1642 const char* envValue = NULL;
1644 const char* envValue = getenv(name);
1646 if (envValue == NULL)
1648 return defaultValue;
1650 cv::String value = envValue;
1651 if (value == "1" || value == "True" || value == "true" || value == "TRUE")
1655 if (value == "0" || value == "False" || value == "false" || value == "FALSE")
1659 CV_Error(cv::Error::StsBadArg, cv::format("Invalid value for %s parameter: %s", name, value.c_str()));
1663 size_t utils::getConfigurationParameterSizeT(const char* name, size_t defaultValue)
1666 const char* envValue = NULL;
1668 const char* envValue = getenv(name);
1670 if (envValue == NULL)
1672 return defaultValue;
1674 cv::String value = envValue;
1676 for (; pos < value.size(); pos++)
1678 if (!isdigit(value[pos]))
1681 cv::String valueStr = value.substr(0, pos);
1682 cv::String suffixStr = value.substr(pos, value.length() - pos);
1683 int v = atoi(valueStr.c_str());
1684 if (suffixStr.length() == 0)
1686 else if (suffixStr == "MB" || suffixStr == "Mb" || suffixStr == "mb")
1687 return v * 1024 * 1024;
1688 else if (suffixStr == "KB" || suffixStr == "Kb" || suffixStr == "kb")
1690 CV_Error(cv::Error::StsBadArg, cv::format("Invalid value for %s parameter: %s", name, value.c_str()));
1693 cv::String utils::getConfigurationParameterString(const char* name, const char* defaultValue)
1696 const char* envValue = NULL;
1698 const char* envValue = getenv(name);
1700 if (envValue == NULL)
1702 return defaultValue;
1704 cv::String value = envValue;
1709 #ifdef CV_COLLECT_IMPL_DATA
1710 ImplCollector& getImplData()
1712 CV_SINGLETON_LAZY_INIT_REF(ImplCollector, new ImplCollector())
1715 void setImpl(int flags)
1717 cv::AutoLock lock(getImplData().mutex);
1719 getImplData().implFlags = flags;
1720 getImplData().implCode.clear();
1721 getImplData().implFun.clear();
1724 void addImpl(int flag, const char* func)
1726 cv::AutoLock lock(getImplData().mutex);
1728 getImplData().implFlags |= flag;
1729 if(func) // use lazy collection if name was not specified
1731 size_t index = getImplData().implCode.size();
1732 if(!index || (getImplData().implCode[index-1] != flag || getImplData().implFun[index-1].compare(func))) // avoid duplicates
1734 getImplData().implCode.push_back(flag);
1735 getImplData().implFun.push_back(func);
1740 int getImpl(std::vector<int> &impl, std::vector<String> &funName)
1742 cv::AutoLock lock(getImplData().mutex);
1744 impl = getImplData().implCode;
1745 funName = getImplData().implFun;
1746 return getImplData().implFlags; // return actual flags for lazy collection
1749 bool useCollection()
1751 return getImplData().useCollection;
1754 void setUseCollection(bool flag)
1756 cv::AutoLock lock(getImplData().mutex);
1758 getImplData().useCollection = flag;
1764 bool useInstrumentation()
1766 #ifdef ENABLE_INSTRUMENTATION
1767 return getInstrumentStruct().useInstr;
1773 void setUseInstrumentation(bool flag)
1775 #ifdef ENABLE_INSTRUMENTATION
1776 getInstrumentStruct().useInstr = flag;
1782 InstrNode* getTrace()
1784 #ifdef ENABLE_INSTRUMENTATION
1785 return &getInstrumentStruct().rootNode;
1793 #ifdef ENABLE_INSTRUMENTATION
1794 getInstrumentStruct().rootNode.removeChilds();
1795 getInstrumentTLSStruct().pCurrentNode = &getInstrumentStruct().rootNode;
1799 void setFlags(FLAGS modeFlags)
1801 #ifdef ENABLE_INSTRUMENTATION
1802 getInstrumentStruct().flags = modeFlags;
1804 CV_UNUSED(modeFlags);
1809 #ifdef ENABLE_INSTRUMENTATION
1810 return (FLAGS)getInstrumentStruct().flags;
1816 NodeData::NodeData(const char* funName, const char* fileName, int lineNum, void* retAddress, bool alwaysExpand, cv::instr::TYPE instrType, cv::instr::IMPL implType)
1818 m_funName = funName;
1819 m_instrType = instrType;
1820 m_implType = implType;
1821 m_fileName = fileName;
1822 m_lineNum = lineNum;
1823 m_retAddress = retAddress;
1824 m_alwaysExpand = alwaysExpand;
1832 NodeData::NodeData(NodeData &ref)
1836 NodeData& NodeData::operator=(const NodeData &right)
1838 this->m_funName = right.m_funName;
1839 this->m_instrType = right.m_instrType;
1840 this->m_implType = right.m_implType;
1841 this->m_fileName = right.m_fileName;
1842 this->m_lineNum = right.m_lineNum;
1843 this->m_retAddress = right.m_retAddress;
1844 this->m_alwaysExpand = right.m_alwaysExpand;
1846 this->m_threads = right.m_threads;
1847 this->m_counter = right.m_counter;
1848 this->m_ticksTotal = right.m_ticksTotal;
1850 this->m_funError = right.m_funError;
1854 NodeData::~NodeData()
1857 bool operator==(const NodeData& left, const NodeData& right)
1859 if(left.m_lineNum == right.m_lineNum && left.m_funName == right.m_funName && left.m_fileName == right.m_fileName)
1861 if(left.m_retAddress == right.m_retAddress || !(cv::instr::getFlags()&cv::instr::FLAGS_EXPAND_SAME_NAMES || left.m_alwaysExpand))
1867 #ifdef ENABLE_INSTRUMENTATION
1868 InstrStruct& getInstrumentStruct()
1870 static InstrStruct instr;
1874 InstrTLSStruct& getInstrumentTLSStruct()
1876 return *getInstrumentStruct().tlsStruct.get();
1879 InstrNode* getCurrentNode()
1881 return getInstrumentTLSStruct().pCurrentNode;
1884 IntrumentationRegion::IntrumentationRegion(const char* funName, const char* fileName, int lineNum, void *retAddress, bool alwaysExpand, TYPE instrType, IMPL implType)
1889 InstrStruct *pStruct = &getInstrumentStruct();
1890 if(pStruct->useInstr)
1892 InstrTLSStruct *pTLS = &getInstrumentTLSStruct();
1894 // Disable in case of failure
1895 if(!pTLS->pCurrentNode)
1901 int depth = pTLS->pCurrentNode->getDepth();
1902 if(pStruct->maxDepth && pStruct->maxDepth <= depth)
1908 NodeData payload(funName, fileName, lineNum, retAddress, alwaysExpand, instrType, implType);
1909 Node<NodeData>* pChild = NULL;
1911 if(pStruct->flags&FLAGS_MAPPING)
1914 cv::AutoLock guard(pStruct->mutexCreate); // Guard from concurrent child creation
1915 pChild = pTLS->pCurrentNode->findChild(payload);
1918 pChild = new Node<NodeData>(payload);
1919 pTLS->pCurrentNode->addChild(pChild);
1924 pChild = pTLS->pCurrentNode->findChild(payload);
1931 pTLS->pCurrentNode = pChild;
1933 m_regionTicks = getTickCount();
1937 IntrumentationRegion::~IntrumentationRegion()
1939 InstrStruct *pStruct = &getInstrumentStruct();
1940 if(pStruct->useInstr)
1944 InstrTLSStruct *pTLS = &getInstrumentTLSStruct();
1946 if (pTLS->pCurrentNode->m_payload.m_implType == cv::instr::IMPL_OPENCL &&
1947 (pTLS->pCurrentNode->m_payload.m_instrType == cv::instr::TYPE_FUN ||
1948 pTLS->pCurrentNode->m_payload.m_instrType == cv::instr::TYPE_WRAPPER))
1950 cv::ocl::finish(); // TODO Support "async" OpenCL instrumentation
1953 uint64 ticks = (getTickCount() - m_regionTicks);
1955 cv::AutoLock guard(pStruct->mutexCount); // Concurrent ticks accumulation
1956 pTLS->pCurrentNode->m_payload.m_counter++;
1957 pTLS->pCurrentNode->m_payload.m_ticksTotal += ticks;
1958 pTLS->pCurrentNode->m_payload.m_tls.get()->m_ticksTotal += ticks;
1961 pTLS->pCurrentNode = pTLS->pCurrentNode->m_pParent;
1972 struct IPPInitSingleton
1988 ippStatus = ippGetCpuFeatures(&cpuFeatures, NULL);
1991 std::cerr << "ERROR: IPP cannot detect CPU features, IPP was disabled " << std::endl;
1995 ippFeatures = cpuFeatures;
1997 const char* pIppEnv = getenv("OPENCV_IPP");
1998 cv::String env = pIppEnv;
2001 #if IPP_VERSION_X100 >= 201703
2002 const Ipp64u minorFeatures = ippCPUID_MOVBE|ippCPUID_AES|ippCPUID_CLMUL|ippCPUID_ABR|ippCPUID_RDRAND|ippCPUID_F16C|
2003 ippCPUID_ADCOX|ippCPUID_RDSEED|ippCPUID_PREFETCHW|ippCPUID_SHA|ippCPUID_MPX|ippCPUID_AVX512CD|ippCPUID_AVX512ER|
2004 ippCPUID_AVX512PF|ippCPUID_AVX512BW|ippCPUID_AVX512DQ|ippCPUID_AVX512VL|ippCPUID_AVX512VBMI;
2005 #elif IPP_VERSION_X100 >= 201700
2006 const Ipp64u minorFeatures = ippCPUID_MOVBE|ippCPUID_AES|ippCPUID_CLMUL|ippCPUID_ABR|ippCPUID_RDRAND|ippCPUID_F16C|
2007 ippCPUID_ADCOX|ippCPUID_RDSEED|ippCPUID_PREFETCHW|ippCPUID_SHA|ippCPUID_AVX512CD|ippCPUID_AVX512ER|
2008 ippCPUID_AVX512PF|ippCPUID_AVX512BW|ippCPUID_AVX512DQ|ippCPUID_AVX512VL|ippCPUID_AVX512VBMI;
2010 const Ipp64u minorFeatures = 0;
2013 env = env.toLowerCase();
2014 if(env.substr(0, 2) == "ne")
2017 env = env.substr(3, env.size());
2020 if(env == "disabled")
2022 std::cerr << "WARNING: IPP was disabled by OPENCV_IPP environment variable" << std::endl;
2025 else if(env == "sse42")
2026 ippFeatures = minorFeatures|ippCPUID_SSE2|ippCPUID_SSE3|ippCPUID_SSSE3|ippCPUID_SSE41|ippCPUID_SSE42;
2027 else if(env == "avx2")
2028 ippFeatures = minorFeatures|ippCPUID_SSE2|ippCPUID_SSE3|ippCPUID_SSSE3|ippCPUID_SSE41|ippCPUID_SSE42|ippCPUID_AVX|ippCPUID_AVX2;
2029 #if IPP_VERSION_X100 >= 201700
2030 #if defined (_M_AMD64) || defined (__x86_64__)
2031 else if(env == "avx512")
2032 ippFeatures = minorFeatures|ippCPUID_SSE2|ippCPUID_SSE3|ippCPUID_SSSE3|ippCPUID_SSE41|ippCPUID_SSE42|ippCPUID_AVX|ippCPUID_AVX2|ippCPUID_AVX512F;
2036 std::cerr << "ERROR: Improper value of OPENCV_IPP: " << env.c_str() << ". Correct values are: disabled, sse42, avx2, avx512 (Intel64 only)" << std::endl;
2038 // Trim unsupported features
2039 ippFeatures &= cpuFeatures;
2042 // Disable AVX1 since we don't track regressions for it. SSE42 will be used instead
2043 if(cpuFeatures&ippCPUID_AVX && !(cpuFeatures&ippCPUID_AVX2))
2044 ippFeatures &= ~((Ipp64u)ippCPUID_AVX);
2046 // IPP integrations in OpenCV support only SSE4.2, AVX2 and AVX-512 optimizations.
2048 #if IPP_VERSION_X100 >= 201700
2049 cpuFeatures&ippCPUID_AVX512F ||
2051 cpuFeatures&ippCPUID_AVX2 ||
2052 cpuFeatures&ippCPUID_SSE42
2059 if(ippFeatures == cpuFeatures)
2062 IPP_INITIALIZER(ippFeatures)
2063 ippFeatures = ippGetEnabledCpuFeatures();
2065 // Detect top level optimizations to make comparison easier for optimizations dependent conditions
2066 #if IPP_VERSION_X100 >= 201700
2067 if(ippFeatures&ippCPUID_AVX512F)
2069 if((ippFeatures&ippCPUID_AVX512_SKX) == ippCPUID_AVX512_SKX)
2070 ippTopFeatures = ippCPUID_AVX512_SKX;
2071 else if((ippFeatures&ippCPUID_AVX512_KNL) == ippCPUID_AVX512_KNL)
2072 ippTopFeatures = ippCPUID_AVX512_KNL;
2074 ippTopFeatures = ippCPUID_AVX512F; // Unknown AVX512 configuration
2078 if(ippFeatures&ippCPUID_AVX2)
2079 ippTopFeatures = ippCPUID_AVX2;
2080 else if(ippFeatures&ippCPUID_SSE42)
2081 ippTopFeatures = ippCPUID_SSE42;
2083 pIppLibInfo = ippiGetLibVersion();
2090 int ippStatus; // 0 - all is ok, -1 - IPP functions failed
2091 const char *funcname;
2092 const char *filename;
2096 Ipp64u ippTopFeatures;
2097 const IppLibraryVersion *pIppLibInfo;
2100 static IPPInitSingleton& getIPPSingleton()
2102 CV_SINGLETON_LAZY_INIT_REF(IPPInitSingleton, new IPPInitSingleton())
2106 #if OPENCV_ABI_COMPATIBILITY > 300
2107 unsigned long long getIppFeatures()
2109 int getIppFeatures()
2113 #if OPENCV_ABI_COMPATIBILITY > 300
2114 return getIPPSingleton().ippFeatures;
2116 return (int)getIPPSingleton().ippFeatures;
2123 unsigned long long getIppTopFeatures();
2125 unsigned long long getIppTopFeatures()
2128 return getIPPSingleton().ippTopFeatures;
2134 void setIppStatus(int status, const char * const _funcname, const char * const _filename, int _line)
2137 getIPPSingleton().ippStatus = status;
2138 getIPPSingleton().funcname = _funcname;
2139 getIPPSingleton().filename = _filename;
2140 getIPPSingleton().linen = _line;
2142 CV_UNUSED(status); CV_UNUSED(_funcname); CV_UNUSED(_filename); CV_UNUSED(_line);
2149 return getIPPSingleton().ippStatus;
2155 String getIppErrorLocation()
2158 return format("%s:%d %s", getIPPSingleton().filename ? getIPPSingleton().filename : "", getIPPSingleton().linen, getIPPSingleton().funcname ? getIPPSingleton().funcname : "");
2164 String getIppVersion()
2167 const IppLibraryVersion *pInfo = getIPPSingleton().pIppLibInfo;
2169 return format("%s %s %s", pInfo->Name, pInfo->Version, pInfo->BuildDate);
2171 return String("error");
2173 return String("disabled");
2180 CoreTLSData* data = getCoreTlsData().get();
2181 if(data->useIPP < 0)
2183 data->useIPP = getIPPSingleton().useIPP;
2185 return (data->useIPP > 0);
2191 void setUseIPP(bool flag)
2193 CoreTLSData* data = getCoreTlsData().get();
2195 data->useIPP = (getIPPSingleton().useIPP)?flag:false;
2198 data->useIPP = false;
2205 CoreTLSData* data = getCoreTlsData().get();
2206 if(data->useIPP_NE < 0)
2208 data->useIPP_NE = getIPPSingleton().useIPP_NE;
2210 return (data->useIPP_NE > 0);
2216 void setUseIPP_NE(bool flag)
2218 CoreTLSData* data = getCoreTlsData().get();
2220 data->useIPP_NE = (getIPPSingleton().useIPP_NE)?flag:false;
2223 data->useIPP_NE = false;
2231 #ifdef HAVE_TEGRA_OPTIMIZATION
2237 cv::CoreTLSData* data = cv::getCoreTlsData().get();
2239 if (data->useTegra < 0)
2241 const char* pTegraEnv = getenv("OPENCV_TEGRA");
2242 if (pTegraEnv && (cv::String(pTegraEnv) == "disabled"))
2243 data->useTegra = false;
2245 data->useTegra = true;
2248 return (data->useTegra > 0);
2251 void setUseTegra(bool flag)
2253 cv::CoreTLSData* data = cv::getCoreTlsData().get();
2254 data->useTegra = flag;
2257 } // namespace tegra