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))
76 # pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
80 #if defined __ANDROID__ || defined __linux__ || defined __FreeBSD__ || defined __HAIKU__
84 #if defined __ANDROID__ || defined __linux__
85 # include <linux/auxvec.h>
89 #if defined __ANDROID__ && defined HAVE_CPUFEATURES
90 # include <cpu-features.h>
94 # if defined __PPC64__ && defined __linux__
95 # include "sys/auxv.h"
99 # ifndef PPC_FEATURE2_ARCH_2_07
100 # define PPC_FEATURE2_ARCH_2_07 0x80000000
105 #if defined _WIN32 || defined WINCE
106 #ifndef _WIN32_WINNT // This is needed for the declaration of TryEnterCriticalSection in winbase.h with Visual Studio 2005 (and older?)
107 #define _WIN32_WINNT 0x0400 // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx
110 #if (_WIN32_WINNT >= 0x0602)
111 #include <synchapi.h>
120 #include <wrl/client.h>
121 #ifndef __cplusplus_winrt
122 #include <windows.storage.h>
123 #pragma comment(lib, "runtimeobject.lib")
126 std::wstring GetTempPathWinRT()
128 #ifdef __cplusplus_winrt
129 return std::wstring(Windows::Storage::ApplicationData::Current->TemporaryFolder->Path->Data());
131 Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationDataStatics> appdataFactory;
132 Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationData> appdataRef;
133 Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> storagefolderRef;
134 Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageItem> storageitemRef;
136 HSTRING_HEADER hstrHead;
138 if (FAILED(WindowsCreateStringReference(RuntimeClass_Windows_Storage_ApplicationData,
139 (UINT32)wcslen(RuntimeClass_Windows_Storage_ApplicationData), &hstrHead, &str)))
141 if (FAILED(RoGetActivationFactory(str, IID_PPV_ARGS(appdataFactory.ReleaseAndGetAddressOf()))))
143 if (FAILED(appdataFactory->get_Current(appdataRef.ReleaseAndGetAddressOf())))
145 if (FAILED(appdataRef->get_TemporaryFolder(storagefolderRef.ReleaseAndGetAddressOf())))
147 if (FAILED(storagefolderRef.As(&storageitemRef)))
150 if (FAILED(storageitemRef->get_Path(&str)))
152 wstr = WindowsGetStringRawBuffer(str, NULL);
153 WindowsDeleteString(str);
158 std::wstring GetTempFileNameWinRT(std::wstring prefix)
163 wchar_t* mask = L"%08x_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x";
164 swprintf(&guidStr[0], sizeof(guidStr)/sizeof(wchar_t), mask,
165 g.Data1, g.Data2, g.Data3, UINT(g.Data4[0]), UINT(g.Data4[1]),
166 UINT(g.Data4[2]), UINT(g.Data4[3]), UINT(g.Data4[4]),
167 UINT(g.Data4[5]), UINT(g.Data4[6]), UINT(g.Data4[7]));
169 return prefix.append(std::wstring(guidStr));
175 #include <sys/time.h>
178 #if defined __MACH__ && defined __APPLE__
179 #include <mach/mach.h>
180 #include <mach/mach_time.h>
189 #if defined __linux__ || defined __APPLE__ || defined __EMSCRIPTEN__ || defined __FreeBSD__ || defined __GLIBC__ || defined __HAIKU__
192 #include <sys/types.h>
193 #if defined __ANDROID__
194 #include <sys/sysconf.h>
199 # include <android/log.h>
202 #ifdef DECLARE_CV_CPUID_X86
206 #if defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
207 #if _MSC_VER >= 1400 // MSVS 2005
208 #include <intrin.h> // __cpuidex()
209 #define CV_CPUID_X86 __cpuidex
211 #error "Required MSVS 2005+"
213 #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
214 static void cv_cpuid(int* cpuid_data, int reg_eax, int reg_ecx)
216 int __eax = reg_eax, __ebx = 0, __ecx = reg_ecx, __edx = 0;
217 // tested with available compilers (-fPIC -O2 -m32/-m64): https://godbolt.org/
218 #if !defined(__PIC__) \
219 || defined(__x86_64__) || __GNUC__ >= 5 \
220 || defined(__clang__) || defined(__INTEL_COMPILER)
222 : "+a" (__eax), "=b" (__ebx), "+c" (__ecx), "=d" (__edx)
224 #elif defined(__i386__) // ebx may be reserved as the PIC register
225 __asm__("xchg{l}\t{%%}ebx, %1\n\t"
227 "xchg{l}\t{%%}ebx, %1\n\t"
228 : "+a" (__eax), "=&r" (__ebx), "+c" (__ecx), "=d" (__edx)
231 #error "Configuration error"
233 cpuid_data[0] = __eax; cpuid_data[1] = __ebx; cpuid_data[2] = __ecx; cpuid_data[3] = __edx;
235 #define CV_CPUID_X86 cv_cpuid
243 Exception::Exception() { code = 0; line = 0; }
245 Exception::Exception(int _code, const String& _err, const String& _func, const String& _file, int _line)
246 : code(_code), err(_err), func(_func), file(_file), line(_line)
251 Exception::~Exception() throw() {}
254 \return the error description and the context as a text string.
256 const char* Exception::what() const throw() { return msg.c_str(); }
258 void Exception::formatMessage()
260 size_t pos = err.find('\n');
261 bool multiline = pos != cv::String::npos;
264 std::stringstream ss;
266 while (pos != cv::String::npos)
268 ss << "> " << err.substr(prev_pos, pos - prev_pos) << std::endl;
270 pos = err.find('\n', prev_pos);
272 ss << "> " << err.substr(prev_pos);
273 if (err[err.size() - 1] != '\n')
280 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());
282 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());
286 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");
290 static const char* g_hwFeatureNames[CV_HARDWARE_MAX_FEATURE] = { NULL };
292 static const char* getHWFeatureName(int id)
294 return (id < CV_HARDWARE_MAX_FEATURE) ? g_hwFeatureNames[id] : NULL;
296 static const char* getHWFeatureNameSafe(int id)
298 const char* name = getHWFeatureName(id);
299 return name ? name : "Unknown feature";
304 enum { MAX_FEATURE = CV_HARDWARE_MAX_FEATURE };
306 HWFeatures(bool run_initialize = false)
308 memset( have, 0, sizeof(have[0]) * MAX_FEATURE );
313 static void initializeNames()
315 for (int i = 0; i < CV_HARDWARE_MAX_FEATURE; i++)
317 g_hwFeatureNames[i] = 0;
319 g_hwFeatureNames[CPU_MMX] = "MMX";
320 g_hwFeatureNames[CPU_SSE] = "SSE";
321 g_hwFeatureNames[CPU_SSE2] = "SSE2";
322 g_hwFeatureNames[CPU_SSE3] = "SSE3";
323 g_hwFeatureNames[CPU_SSSE3] = "SSSE3";
324 g_hwFeatureNames[CPU_SSE4_1] = "SSE4.1";
325 g_hwFeatureNames[CPU_SSE4_2] = "SSE4.2";
326 g_hwFeatureNames[CPU_POPCNT] = "POPCNT";
327 g_hwFeatureNames[CPU_FP16] = "FP16";
328 g_hwFeatureNames[CPU_AVX] = "AVX";
329 g_hwFeatureNames[CPU_AVX2] = "AVX2";
330 g_hwFeatureNames[CPU_FMA3] = "FMA3";
332 g_hwFeatureNames[CPU_AVX_512F] = "AVX512F";
333 g_hwFeatureNames[CPU_AVX_512BW] = "AVX512BW";
334 g_hwFeatureNames[CPU_AVX_512CD] = "AVX512CD";
335 g_hwFeatureNames[CPU_AVX_512DQ] = "AVX512DQ";
336 g_hwFeatureNames[CPU_AVX_512ER] = "AVX512ER";
337 g_hwFeatureNames[CPU_AVX_512IFMA] = "AVX512IFMA";
338 g_hwFeatureNames[CPU_AVX_512PF] = "AVX512PF";
339 g_hwFeatureNames[CPU_AVX_512VBMI] = "AVX512VBMI";
340 g_hwFeatureNames[CPU_AVX_512VL] = "AVX512VL";
342 g_hwFeatureNames[CPU_NEON] = "NEON";
344 g_hwFeatureNames[CPU_VSX] = "VSX";
346 g_hwFeatureNames[CPU_AVX512_SKX] = "AVX512-SKX";
349 void initialize(void)
352 if (getenv("OPENCV_DUMP_CONFIG"))
354 fprintf(stderr, "\nOpenCV build configuration is:\n%s\n",
355 cv::getBuildInformation().c_str());
362 int cpuid_data[4] = { 0, 0, 0, 0 };
363 int cpuid_data_ex[4] = { 0, 0, 0, 0 };
365 CV_CPUID_X86(cpuid_data, 1, 0/*unused*/);
367 int x86_family = (cpuid_data[0] >> 8) & 15;
368 if( x86_family >= 6 )
370 have[CV_CPU_MMX] = (cpuid_data[3] & (1<<23)) != 0;
371 have[CV_CPU_SSE] = (cpuid_data[3] & (1<<25)) != 0;
372 have[CV_CPU_SSE2] = (cpuid_data[3] & (1<<26)) != 0;
373 have[CV_CPU_SSE3] = (cpuid_data[2] & (1<<0)) != 0;
374 have[CV_CPU_SSSE3] = (cpuid_data[2] & (1<<9)) != 0;
375 have[CV_CPU_FMA3] = (cpuid_data[2] & (1<<12)) != 0;
376 have[CV_CPU_SSE4_1] = (cpuid_data[2] & (1<<19)) != 0;
377 have[CV_CPU_SSE4_2] = (cpuid_data[2] & (1<<20)) != 0;
378 have[CV_CPU_POPCNT] = (cpuid_data[2] & (1<<23)) != 0;
379 have[CV_CPU_AVX] = (cpuid_data[2] & (1<<28)) != 0;
380 have[CV_CPU_FP16] = (cpuid_data[2] & (1<<29)) != 0;
382 // make the second call to the cpuid command in order to get
383 // information about extended features like AVX2
384 CV_CPUID_X86(cpuid_data_ex, 7, 0);
386 have[CV_CPU_AVX2] = (cpuid_data_ex[1] & (1<<5)) != 0;
388 have[CV_CPU_AVX_512F] = (cpuid_data_ex[1] & (1<<16)) != 0;
389 have[CV_CPU_AVX_512DQ] = (cpuid_data_ex[1] & (1<<17)) != 0;
390 have[CV_CPU_AVX_512IFMA512] = (cpuid_data_ex[1] & (1<<21)) != 0;
391 have[CV_CPU_AVX_512PF] = (cpuid_data_ex[1] & (1<<26)) != 0;
392 have[CV_CPU_AVX_512ER] = (cpuid_data_ex[1] & (1<<27)) != 0;
393 have[CV_CPU_AVX_512CD] = (cpuid_data_ex[1] & (1<<28)) != 0;
394 have[CV_CPU_AVX_512BW] = (cpuid_data_ex[1] & (1<<30)) != 0;
395 have[CV_CPU_AVX_512VL] = (cpuid_data_ex[1] & (1<<31)) != 0;
396 have[CV_CPU_AVX_512VBMI] = (cpuid_data_ex[2] & (1<<1)) != 0;
398 bool have_AVX_OS_support = true;
399 bool have_AVX512_OS_support = true;
400 if (!(cpuid_data[2] & (1<<27)))
401 have_AVX_OS_support = false; // OS uses XSAVE_XRSTORE and CPU support AVX
405 #ifdef _XCR_XFEATURE_ENABLED_MASK // requires immintrin.h
406 xcr0 = (int)_xgetbv(_XCR_XFEATURE_ENABLED_MASK);
407 #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
408 __asm__ ("xgetbv\n\t" : "=a" (xcr0) : "c" (0) : "%edx" );
410 if ((xcr0 & 0x6) != 0x6)
411 have_AVX_OS_support = false; // YMM registers
412 if ((xcr0 & 0xe6) != 0xe6)
413 have_AVX512_OS_support = false; // ZMM registers
416 if (!have_AVX_OS_support)
418 have[CV_CPU_AVX] = false;
419 have[CV_CPU_FP16] = false;
420 have[CV_CPU_AVX2] = false;
421 have[CV_CPU_FMA3] = false;
423 if (!have_AVX_OS_support || !have_AVX512_OS_support)
425 have[CV_CPU_AVX_512F] = false;
426 have[CV_CPU_AVX_512BW] = false;
427 have[CV_CPU_AVX_512CD] = false;
428 have[CV_CPU_AVX_512DQ] = false;
429 have[CV_CPU_AVX_512ER] = false;
430 have[CV_CPU_AVX_512IFMA512] = false;
431 have[CV_CPU_AVX_512PF] = false;
432 have[CV_CPU_AVX_512VBMI] = false;
433 have[CV_CPU_AVX_512VL] = false;
436 if (have[CV_CPU_AVX_512F])
438 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];
441 #endif // CV_CPUID_X86
443 #if defined __ANDROID__ || defined __linux__
445 have[CV_CPU_NEON] = true;
446 have[CV_CPU_FP16] = true;
447 #elif defined __arm__ && defined __ANDROID__
448 #if defined HAVE_CPUFEATURES
449 CV_LOG_INFO(NULL, "calling android_getCpuFeatures() ...");
450 uint64_t features = android_getCpuFeatures();
451 CV_LOG_INFO(NULL, cv::format("calling android_getCpuFeatures() ... Done (%llx)", (long long)features));
452 have[CV_CPU_NEON] = (features & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
453 have[CV_CPU_FP16] = (features & ANDROID_CPU_ARM_FEATURE_VFP_FP16) != 0;
455 CV_LOG_INFO(NULL, "cpufeatures library is not available for CPU detection");
457 CV_LOG_INFO(NULL, "- NEON instructions is enabled via build flags");
458 have[CV_CPU_NEON] = true;
460 CV_LOG_INFO(NULL, "- NEON instructions is NOT enabled via build flags");
463 CV_LOG_INFO(NULL, "- FP16 instructions is enabled via build flags");
464 have[CV_CPU_FP16] = true;
466 CV_LOG_INFO(NULL, "- FP16 instructions is NOT enabled via build flags");
469 #elif defined __arm__
470 int cpufile = open("/proc/self/auxv", O_RDONLY);
475 const size_t size_auxv_t = sizeof(auxv);
477 while ((size_t)read(cpufile, &auxv, size_auxv_t) == size_auxv_t)
479 if (auxv.a_type == AT_HWCAP)
481 have[CV_CPU_NEON] = (auxv.a_un.a_val & 4096) != 0;
482 have[CV_CPU_FP16] = (auxv.a_un.a_val & 2) != 0;
490 #elif (defined __clang__ || defined __APPLE__)
491 #if (defined __ARM_NEON__ || (defined __ARM_NEON && defined __aarch64__))
492 have[CV_CPU_NEON] = true;
494 #if (defined __ARM_FP && (((__ARM_FP & 0x2) != 0) && defined __ARM_NEON__))
495 have[CV_CPU_FP16] = true;
500 have[CV_CPU_VSX] = true;
501 #elif (defined __PPC64__ && defined __linux__)
502 uint64 hwcaps = getauxval(AT_HWCAP);
503 uint64 hwcap2 = getauxval(AT_HWCAP2);
504 have[CV_CPU_VSX] = (hwcaps & PPC_FEATURE_PPC_LE && hwcaps & PPC_FEATURE_HAS_VSX && hwcap2 & PPC_FEATURE2_ARCH_2_07);
506 have[CV_CPU_VSX] = false;
509 int baseline_features[] = { CV_CPU_BASELINE_FEATURES };
510 if (!checkFeatures(baseline_features, sizeof(baseline_features) / sizeof(baseline_features[0])))
513 "******************************************************************\n"
515 "* This OpenCV build doesn't support current CPU/HW configuration *\n"
517 "* Use OPENCV_DUMP_CONFIG=1 environment variable for details *\n"
518 "******************************************************************\n");
519 fprintf(stderr, "\nRequired baseline features:\n");
520 checkFeatures(baseline_features, sizeof(baseline_features) / sizeof(baseline_features[0]), true);
521 CV_ErrorNoReturn(cv::Error::StsAssert, "Missing support for required CPU baseline features. Check OpenCV build configuration and required CPU/HW setup.");
524 readSettings(baseline_features, sizeof(baseline_features) / sizeof(baseline_features[0]));
527 bool checkFeatures(const int* features, int count, bool dump = false)
530 for (int i = 0; i < count; i++)
532 int feature = features[i];
537 if (dump) fprintf(stderr, "%s - OK\n", getHWFeatureNameSafe(feature));
542 if (dump) fprintf(stderr, "%s - NOT AVAILABLE\n", getHWFeatureNameSafe(feature));
549 static inline bool isSymbolSeparator(char c)
551 return c == ',' || c == ';';
554 void readSettings(const int* baseline_features, int baseline_count)
557 const char* disabled_features =
559 getenv("OPENCV_CPU_DISABLE");
563 if (disabled_features && disabled_features[0] != 0)
565 const char* start = disabled_features;
568 while (start[0] != 0 && isSymbolSeparator(start[0]))
574 const char* end = start;
575 while (end[0] != 0 && !isSymbolSeparator(end[0]))
581 cv::String feature(start, end);
584 CV_Assert(feature.size() > 0);
587 for (int i = 0; i < CV_HARDWARE_MAX_FEATURE; i++)
589 if (!g_hwFeatureNames[i]) continue;
590 size_t len = strlen(g_hwFeatureNames[i]);
591 if (len != feature.size()) continue;
592 if (feature.compare(g_hwFeatureNames[i]) == 0)
594 bool isBaseline = false;
595 for (int k = 0; k < baseline_count; k++)
597 if (baseline_features[k] == i)
605 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));
609 if (dump) fprintf(stderr, "OPENCV: Trying to disable unavailable CPU feature on the current platform: '%s'.\n", getHWFeatureNameSafe(i));
619 if (dump) fprintf(stderr, "OPENCV: Trying to disable unknown CPU feature: '%s'.\n", feature.c_str());
625 bool have[MAX_FEATURE+1];
628 static HWFeatures featuresEnabled(true), featuresDisabled = HWFeatures(false);
629 static HWFeatures* currentFeatures = &featuresEnabled;
631 bool checkHardwareSupport(int feature)
633 CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
634 return currentFeatures->have[feature];
637 String getHardwareFeatureName(int feature)
639 const char* name = getHWFeatureName(feature);
640 return name ? String(name) : String();
643 volatile bool useOptimizedFlag = true;
645 void setUseOptimized( bool flag )
647 useOptimizedFlag = flag;
648 currentFeatures = flag ? &featuresEnabled : &featuresDisabled;
650 ipp::setUseIPP(flag);
652 ocl::setUseOpenCL(flag);
654 #ifdef HAVE_TEGRA_OPTIMIZATION
655 ::tegra::setUseTegra(flag);
659 bool useOptimized(void)
661 return useOptimizedFlag;
664 int64 getTickCount(void)
666 #if defined _WIN32 || defined WINCE
667 LARGE_INTEGER counter;
668 QueryPerformanceCounter( &counter );
669 return (int64)counter.QuadPart;
670 #elif defined __linux || defined __linux__
672 clock_gettime(CLOCK_MONOTONIC, &tp);
673 return (int64)tp.tv_sec*1000000000 + tp.tv_nsec;
674 #elif defined __MACH__ && defined __APPLE__
675 return (int64)mach_absolute_time();
679 gettimeofday( &tv, &tz );
680 return (int64)tv.tv_sec*1000000 + tv.tv_usec;
684 double getTickFrequency(void)
686 #if defined _WIN32 || defined WINCE
688 QueryPerformanceFrequency(&freq);
689 return (double)freq.QuadPart;
690 #elif defined __linux || defined __linux__
692 #elif defined __MACH__ && defined __APPLE__
693 static double freq = 0;
696 mach_timebase_info_data_t sTimebaseInfo;
697 mach_timebase_info(&sTimebaseInfo);
698 freq = sTimebaseInfo.denom*1e9/sTimebaseInfo.numer;
706 #if defined __GNUC__ && (defined __i386__ || defined __x86_64__ || defined __ppc__)
707 #if defined(__i386__)
709 int64 getCPUTickCount(void)
712 __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
715 #elif defined(__x86_64__)
717 int64 getCPUTickCount(void)
720 __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
721 return (int64)lo | ((int64)hi << 32);
724 #elif defined(__ppc__)
726 int64 getCPUTickCount(void)
729 unsigned upper, lower, tmp;
737 : "=r"(upper),"=r"(lower),"=r"(tmp)
739 return lower | ((int64)upper << 32);
744 #error "RDTSC not defined"
748 #elif defined _MSC_VER && defined _WIN32 && defined _M_IX86
750 int64 getCPUTickCount(void)
759 //int64 getCPUTickCount(void)
761 // return ippGetCpuClocks();
764 int64 getCPUTickCount(void)
766 return getTickCount();
772 const String& getBuildInformation()
774 static String build_info =
775 #include "version_string.inc"
780 String getVersionString() { return String(CV_VERSION); }
782 int getVersionMajor() { return CV_VERSION_MAJOR; }
784 int getVersionMinor() { return CV_VERSION_MINOR; }
786 int getVersionRevision() { return CV_VERSION_REVISION; }
788 String format( const char* fmt, ... )
790 AutoBuffer<char, 1024> buf;
796 int bsize = static_cast<int>(buf.size());
797 int len = cv_vsnprintf((char *)buf, bsize, fmt, va);
800 CV_Assert(len >= 0 && "Check format string for errors");
807 return String((char *)buf, len);
811 String tempfile( const char* suffix )
815 const char *temp_dir = getenv("OPENCV_TEMP_PATH");
820 RoInitialize(RO_INIT_MULTITHREADED);
821 std::wstring temp_dir = GetTempPathWinRT();
823 std::wstring temp_file = GetTempFileNameWinRT(L"ocv");
824 if (temp_file.empty())
827 temp_file = temp_dir.append(std::wstring(L"\\")).append(temp_file);
828 DeleteFileW(temp_file.c_str());
830 char aname[MAX_PATH];
831 size_t copied = wcstombs(aname, temp_file.c_str(), MAX_PATH);
832 CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
833 fname = String(aname);
836 char temp_dir2[MAX_PATH] = { 0 };
837 char temp_file[MAX_PATH] = { 0 };
839 if (temp_dir == 0 || temp_dir[0] == 0)
841 ::GetTempPathA(sizeof(temp_dir2), temp_dir2);
842 temp_dir = temp_dir2;
844 if(0 == ::GetTempFileNameA(temp_dir, "ocv", 0, temp_file))
847 DeleteFileA(temp_file);
853 //char defaultTemplate[] = "/mnt/sdcard/__opencv_temp.XXXXXX";
854 char defaultTemplate[] = "/data/local/tmp/__opencv_temp.XXXXXX";
856 char defaultTemplate[] = "/tmp/__opencv_temp.XXXXXX";
859 if (temp_dir == 0 || temp_dir[0] == 0)
860 fname = defaultTemplate;
864 char ech = fname[fname.size() - 1];
865 if(ech != '/' && ech != '\\')
867 fname = fname + "__opencv_temp.XXXXXX";
870 const int fd = mkstemp((char*)fname.c_str());
871 if (fd == -1) return String();
874 remove(fname.c_str());
879 if (suffix[0] != '.')
880 return fname + "." + suffix;
882 return fname + suffix;
887 static ErrorCallback customErrorCallback = 0;
888 static void* customErrorCallbackData = 0;
889 static bool breakOnError = false;
891 bool setBreakOnError(bool value)
893 bool prevVal = breakOnError;
894 breakOnError = value;
898 int cv_snprintf(char* buf, int len, const char* fmt, ...)
902 int res = cv_vsnprintf(buf, len, fmt, va);
907 int cv_vsnprintf(char* buf, int len, const char* fmt, va_list args)
910 if (len <= 0) return len == 0 ? 1024 : -1;
911 int res = _vsnprintf_s(buf, len, _TRUNCATE, fmt, args);
912 // ensure null terminating on VS
913 if (res >= 0 && res < len)
920 buf[len - 1] = 0; // truncate happened
921 return res >= len ? res : (len * 2);
924 return vsnprintf(buf, len, fmt, args);
928 void error( const Exception& exc )
930 if (customErrorCallback != 0)
931 customErrorCallback(exc.code, exc.func.c_str(), exc.err.c_str(),
932 exc.file.c_str(), exc.line, customErrorCallbackData);
933 else if (param_dumpErrors)
935 const char* errorStr = cvErrorStr(exc.code);
938 cv_snprintf(buf, sizeof(buf),
939 "OpenCV(%s) Error: %s (%s) in %s, file %s, line %d",
941 errorStr, exc.err.c_str(), exc.func.size() > 0 ?
942 exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line);
944 __android_log_print(ANDROID_LOG_ERROR, "cv::error()", "%s", buf);
946 fflush(stdout); fflush(stderr);
947 fprintf(stderr, "%s\n", buf);
954 static volatile int* p = 0;
961 void error(int _code, const String& _err, const char* _func, const char* _file, int _line)
963 error(cv::Exception(_code, _err, _func, _file, _line));
968 redirectError( ErrorCallback errCallback, void* userdata, void** prevUserdata)
971 *prevUserdata = customErrorCallbackData;
973 ErrorCallback prevCallback = customErrorCallback;
975 customErrorCallback = errCallback;
976 customErrorCallbackData = userdata;
983 CV_IMPL int cvCheckHardwareSupport(int feature)
985 CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
986 return cv::currentFeatures->have[feature];
989 CV_IMPL int cvUseOptimized( int flag )
991 int prevMode = cv::useOptimizedFlag;
992 cv::setUseOptimized( flag != 0 );
996 CV_IMPL int64 cvGetTickCount(void)
998 return cv::getTickCount();
1001 CV_IMPL double cvGetTickFrequency(void)
1003 return cv::getTickFrequency()*1e-6;
1006 CV_IMPL CvErrorCallback
1007 cvRedirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
1009 return cv::redirectError(errCallback, userdata, prevUserdata);
1012 CV_IMPL int cvNulDevReport( int, const char*, const char*,
1013 const char*, int, void* )
1018 CV_IMPL int cvStdErrReport( int, const char*, const char*,
1019 const char*, int, void* )
1024 CV_IMPL int cvGuiBoxReport( int, const char*, const char*,
1025 const char*, int, void* )
1030 CV_IMPL int cvGetErrInfo( const char**, const char**, const char**, int* )
1036 CV_IMPL const char* cvErrorStr( int status )
1038 static char buf[256];
1042 case CV_StsOk : return "No Error";
1043 case CV_StsBackTrace : return "Backtrace";
1044 case CV_StsError : return "Unspecified error";
1045 case CV_StsInternal : return "Internal error";
1046 case CV_StsNoMem : return "Insufficient memory";
1047 case CV_StsBadArg : return "Bad argument";
1048 case CV_StsNoConv : return "Iterations do not converge";
1049 case CV_StsAutoTrace : return "Autotrace call";
1050 case CV_StsBadSize : return "Incorrect size of input array";
1051 case CV_StsNullPtr : return "Null pointer";
1052 case CV_StsDivByZero : return "Division by zero occurred";
1053 case CV_BadStep : return "Image step is wrong";
1054 case CV_StsInplaceNotSupported : return "Inplace operation is not supported";
1055 case CV_StsObjectNotFound : return "Requested object was not found";
1056 case CV_BadDepth : return "Input image depth is not supported by function";
1057 case CV_StsUnmatchedFormats : return "Formats of input arguments do not match";
1058 case CV_StsUnmatchedSizes : return "Sizes of input arguments do not match";
1059 case CV_StsOutOfRange : return "One of arguments\' values is out of range";
1060 case CV_StsUnsupportedFormat : return "Unsupported format or combination of formats";
1061 case CV_BadCOI : return "Input COI is not supported";
1062 case CV_BadNumChannels : return "Bad number of channels";
1063 case CV_StsBadFlag : return "Bad flag (parameter or structure field)";
1064 case CV_StsBadPoint : return "Bad parameter of type CvPoint";
1065 case CV_StsBadMask : return "Bad type of mask argument";
1066 case CV_StsParseError : return "Parsing error";
1067 case CV_StsNotImplemented : return "The function/feature is not implemented";
1068 case CV_StsBadMemBlock : return "Memory block has been corrupted";
1069 case CV_StsAssert : return "Assertion failed";
1070 case CV_GpuNotSupported : return "No CUDA support";
1071 case CV_GpuApiCallError : return "Gpu API call";
1072 case CV_OpenGlNotSupported : return "No OpenGL support";
1073 case CV_OpenGlApiCallError : return "OpenGL API call";
1076 sprintf(buf, "Unknown %s code %d", status >= 0 ? "status":"error", status);
1080 CV_IMPL int cvGetErrMode(void)
1085 CV_IMPL int cvSetErrMode(int)
1090 CV_IMPL int cvGetErrStatus(void)
1095 CV_IMPL void cvSetErrStatus(int)
1100 CV_IMPL void cvError( int code, const char* func_name,
1101 const char* err_msg,
1102 const char* file_name, int line )
1104 cv::error(cv::Exception(code, err_msg, func_name, file_name, line));
1107 /* function, which converts int to int */
1109 cvErrorFromIppStatus( int status )
1113 case CV_BADSIZE_ERR: return CV_StsBadSize;
1114 case CV_BADMEMBLOCK_ERR: return CV_StsBadMemBlock;
1115 case CV_NULLPTR_ERR: return CV_StsNullPtr;
1116 case CV_DIV_BY_ZERO_ERR: return CV_StsDivByZero;
1117 case CV_BADSTEP_ERR: return CV_BadStep;
1118 case CV_OUTOFMEM_ERR: return CV_StsNoMem;
1119 case CV_BADARG_ERR: return CV_StsBadArg;
1120 case CV_NOTDEFINED_ERR: return CV_StsError;
1121 case CV_INPLACE_NOT_SUPPORTED_ERR: return CV_StsInplaceNotSupported;
1122 case CV_NOTFOUND_ERR: return CV_StsObjectNotFound;
1123 case CV_BADCONVERGENCE_ERR: return CV_StsNoConv;
1124 case CV_BADDEPTH_ERR: return CV_BadDepth;
1125 case CV_UNMATCHED_FORMATS_ERR: return CV_StsUnmatchedFormats;
1126 case CV_UNSUPPORTED_COI_ERR: return CV_BadCOI;
1127 case CV_UNSUPPORTED_CHANNELS_ERR: return CV_BadNumChannels;
1128 case CV_BADFLAG_ERR: return CV_StsBadFlag;
1129 case CV_BADRANGE_ERR: return CV_StsBadArg;
1130 case CV_BADCOEF_ERR: return CV_StsBadArg;
1131 case CV_BADFACTOR_ERR: return CV_StsBadArg;
1132 case CV_BADPOINT_ERR: return CV_StsBadPoint;
1140 bool __termination = false;
1146 #if defined _WIN32 || defined WINCE
1152 #if (_WIN32_WINNT >= 0x0600)
1153 ::InitializeCriticalSectionEx(&cs, 1000, 0);
1155 ::InitializeCriticalSection(&cs);
1159 ~Impl() { DeleteCriticalSection(&cs); }
1161 void lock() { EnterCriticalSection(&cs); }
1162 bool trylock() { return TryEnterCriticalSection(&cs) != 0; }
1163 void unlock() { LeaveCriticalSection(&cs); }
1165 CRITICAL_SECTION cs;
1175 pthread_mutexattr_t attr;
1176 pthread_mutexattr_init(&attr);
1177 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
1178 pthread_mutex_init(&mt, &attr);
1179 pthread_mutexattr_destroy(&attr);
1183 ~Impl() { pthread_mutex_destroy(&mt); }
1185 void lock() { pthread_mutex_lock(&mt); }
1186 bool trylock() { return pthread_mutex_trylock(&mt) == 0; }
1187 void unlock() { pthread_mutex_unlock(&mt); }
1197 impl = new Mutex::Impl;
1202 if( CV_XADD(&impl->refcount, -1) == 1 )
1207 Mutex::Mutex(const Mutex& m)
1210 CV_XADD(&impl->refcount, 1);
1213 Mutex& Mutex::operator = (const Mutex& m)
1217 CV_XADD(&m.impl->refcount, 1);
1218 if( CV_XADD(&impl->refcount, -1) == 1 )
1225 void Mutex::lock() { impl->lock(); }
1226 void Mutex::unlock() { impl->unlock(); }
1227 bool Mutex::trylock() { return impl->trylock(); }
1230 //////////////////////////////// thread-local storage ////////////////////////////////
1234 #pragma warning(disable:4505) // unreferenced local function has been removed
1236 #ifndef TLS_OUT_OF_INDEXES
1237 #define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
1241 // TLS platform abstraction layer
1242 class TlsAbstraction
1247 void* GetData() const;
1248 void SetData(void *pData);
1256 pthread_key_t tlsKey;
1262 static __declspec( thread ) void* tlsData = NULL; // using C++11 thread attribute for local thread data
1263 TlsAbstraction::TlsAbstraction() {}
1264 TlsAbstraction::~TlsAbstraction() {}
1265 void* TlsAbstraction::GetData() const
1269 void TlsAbstraction::SetData(void *pData)
1274 TlsAbstraction::TlsAbstraction()
1276 tlsKey = TlsAlloc();
1277 CV_Assert(tlsKey != TLS_OUT_OF_INDEXES);
1279 TlsAbstraction::~TlsAbstraction()
1283 void* TlsAbstraction::GetData() const
1285 return TlsGetValue(tlsKey);
1287 void TlsAbstraction::SetData(void *pData)
1289 CV_Assert(TlsSetValue(tlsKey, pData) == TRUE);
1293 TlsAbstraction::TlsAbstraction()
1295 CV_Assert(pthread_key_create(&tlsKey, NULL) == 0);
1297 TlsAbstraction::~TlsAbstraction()
1299 CV_Assert(pthread_key_delete(tlsKey) == 0);
1301 void* TlsAbstraction::GetData() const
1303 return pthread_getspecific(tlsKey);
1305 void TlsAbstraction::SetData(void *pData)
1307 CV_Assert(pthread_setspecific(tlsKey, pData) == 0);
1311 // Per-thread data structure
1320 std::vector<void*> slots; // Data array for a thread
1321 size_t idx; // Thread index in TLS storage. This is not OS thread ID!
1324 // Main TLS storage class
1331 tlsSlots.reserve(32);
1332 threads.reserve(32);
1336 for(size_t i = 0; i < threads.size(); i++)
1340 /* Current architecture doesn't allow proper global objects release, so this check can cause crashes
1342 // Check if all slots were properly cleared
1343 for(size_t j = 0; j < threads[i]->slots.size(); j++)
1345 CV_Assert(threads[i]->slots[j] == 0);
1354 void releaseThread()
1356 AutoLock guard(mtxGlobalAccess);
1357 ThreadData *pTD = (ThreadData*)tls.GetData();
1358 for(size_t i = 0; i < threads.size(); i++)
1360 if(pTD == threads[i])
1370 // Reserve TLS storage index
1371 size_t reserveSlot()
1373 AutoLock guard(mtxGlobalAccess);
1374 CV_Assert(tlsSlotsSize == tlsSlots.size());
1376 // Find unused slots
1377 for(size_t slot = 0; slot < tlsSlotsSize; slot++)
1387 tlsSlots.push_back(1); tlsSlotsSize++;
1388 return tlsSlotsSize - 1;
1391 // Release TLS storage index and pass associated data to caller
1392 void releaseSlot(size_t slotIdx, std::vector<void*> &dataVec, bool keepSlot = false)
1394 AutoLock guard(mtxGlobalAccess);
1395 CV_Assert(tlsSlotsSize == tlsSlots.size());
1396 CV_Assert(tlsSlotsSize > slotIdx);
1398 for(size_t i = 0; i < threads.size(); i++)
1402 std::vector<void*>& thread_slots = threads[i]->slots;
1403 if (thread_slots.size() > slotIdx && thread_slots[slotIdx])
1405 dataVec.push_back(thread_slots[slotIdx]);
1406 thread_slots[slotIdx] = NULL;
1412 tlsSlots[slotIdx] = 0;
1415 // Get data by TLS storage index
1416 void* getData(size_t slotIdx) const
1418 #ifndef CV_THREAD_SANITIZER
1419 CV_Assert(tlsSlotsSize > slotIdx);
1422 ThreadData* threadData = (ThreadData*)tls.GetData();
1423 if(threadData && threadData->slots.size() > slotIdx)
1424 return threadData->slots[slotIdx];
1429 // Gather data from threads by TLS storage index
1430 void gather(size_t slotIdx, std::vector<void*> &dataVec)
1432 AutoLock guard(mtxGlobalAccess);
1433 CV_Assert(tlsSlotsSize == tlsSlots.size());
1434 CV_Assert(tlsSlotsSize > slotIdx);
1436 for(size_t i = 0; i < threads.size(); i++)
1440 std::vector<void*>& thread_slots = threads[i]->slots;
1441 if (thread_slots.size() > slotIdx && thread_slots[slotIdx])
1442 dataVec.push_back(thread_slots[slotIdx]);
1447 // Set data to storage index
1448 void setData(size_t slotIdx, void* pData)
1450 #ifndef CV_THREAD_SANITIZER
1451 CV_Assert(tlsSlotsSize > slotIdx);
1454 ThreadData* threadData = (ThreadData*)tls.GetData();
1457 threadData = new ThreadData;
1458 tls.SetData((void*)threadData);
1460 AutoLock guard(mtxGlobalAccess);
1461 threadData->idx = threads.size();
1462 threads.push_back(threadData);
1466 if(slotIdx >= threadData->slots.size())
1468 AutoLock guard(mtxGlobalAccess); // keep synchronization with gather() calls
1469 threadData->slots.resize(slotIdx + 1, NULL);
1471 threadData->slots[slotIdx] = pData;
1475 TlsAbstraction tls; // TLS abstraction layer instance
1477 Mutex mtxGlobalAccess; // Shared objects operation guard
1478 size_t tlsSlotsSize; // equal to tlsSlots.size() in synchronized sections
1479 // without synchronization this counter doesn't desrease - it is used for slotIdx sanity checks
1480 std::vector<int> tlsSlots; // TLS keys state
1481 std::vector<ThreadData*> threads; // Array for all allocated data. Thread data pointers are placed here to allow data cleanup
1484 // Create global TLS storage object
1485 static TlsStorage &getTlsStorage()
1487 CV_SINGLETON_LAZY_INIT_REF(TlsStorage, new TlsStorage())
1490 TLSDataContainer::TLSDataContainer()
1492 key_ = (int)getTlsStorage().reserveSlot(); // Reserve key from TLS storage
1495 TLSDataContainer::~TLSDataContainer()
1497 CV_Assert(key_ == -1); // Key must be released in child object
1500 void TLSDataContainer::gatherData(std::vector<void*> &data) const
1502 getTlsStorage().gather(key_, data);
1505 void TLSDataContainer::release()
1507 std::vector<void*> data;
1509 getTlsStorage().releaseSlot(key_, data); // Release key and get stored data for proper destruction
1511 for(size_t i = 0; i < data.size(); i++) // Delete all associated data
1512 deleteDataInstance(data[i]);
1515 void TLSDataContainer::cleanup()
1517 std::vector<void*> data;
1519 getTlsStorage().releaseSlot(key_, data, true); // Extract stored data with removal from TLS tables
1520 for(size_t i = 0; i < data.size(); i++) // Delete all associated data
1521 deleteDataInstance(data[i]);
1524 void* TLSDataContainer::getData() const
1526 CV_Assert(key_ != -1 && "Can't fetch data from terminated TLS container.");
1527 void* pData = getTlsStorage().getData(key_); // Check if data was already allocated
1530 // Create new data instance and save it to TLS storage
1531 pData = createDataInstance();
1532 getTlsStorage().setData(key_, pData);
1537 TLSData<CoreTLSData>& getCoreTlsData()
1539 CV_SINGLETON_LAZY_INIT_REF(TLSData<CoreTLSData>, new TLSData<CoreTLSData>())
1542 #if defined CVAPI_EXPORTS && defined _WIN32 && !defined WINCE
1544 #pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
1548 BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID lpReserved);
1551 BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID lpReserved)
1553 if (fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH)
1555 if (lpReserved != NULL) // called after ExitProcess() call
1557 cv::__termination = true;
1561 // Not allowed to free resources if lpReserved is non-null
1562 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583.aspx
1563 cv::getTlsStorage().releaseThread();
1572 static int g_threadNum = 0;
1577 id(CV_XADD(&g_threadNum, 1))
1579 #ifdef OPENCV_WITH_ITT
1580 __itt_thread_set_name(cv::format("OpenCVThread-%03d", id).c_str());
1585 static TLSData<ThreadID>& getThreadIDTLS()
1587 CV_SINGLETON_LAZY_INIT_REF(TLSData<ThreadID>, new TLSData<ThreadID>());
1591 int utils::getThreadID() { return getThreadIDTLS().get()->id; }
1593 bool utils::getConfigurationParameterBool(const char* name, bool defaultValue)
1596 const char* envValue = NULL;
1598 const char* envValue = getenv(name);
1600 if (envValue == NULL)
1602 return defaultValue;
1604 cv::String value = envValue;
1605 if (value == "1" || value == "True" || value == "true" || value == "TRUE")
1609 if (value == "0" || value == "False" || value == "false" || value == "FALSE")
1613 CV_ErrorNoReturn(cv::Error::StsBadArg, cv::format("Invalid value for %s parameter: %s", name, value.c_str()));
1617 size_t utils::getConfigurationParameterSizeT(const char* name, size_t defaultValue)
1620 const char* envValue = NULL;
1622 const char* envValue = getenv(name);
1624 if (envValue == NULL)
1626 return defaultValue;
1628 cv::String value = envValue;
1630 for (; pos < value.size(); pos++)
1632 if (!isdigit(value[pos]))
1635 cv::String valueStr = value.substr(0, pos);
1636 cv::String suffixStr = value.substr(pos, value.length() - pos);
1637 int v = atoi(valueStr.c_str());
1638 if (suffixStr.length() == 0)
1640 else if (suffixStr == "MB" || suffixStr == "Mb" || suffixStr == "mb")
1641 return v * 1024 * 1024;
1642 else if (suffixStr == "KB" || suffixStr == "Kb" || suffixStr == "kb")
1644 CV_ErrorNoReturn(cv::Error::StsBadArg, cv::format("Invalid value for %s parameter: %s", name, value.c_str()));
1647 cv::String utils::getConfigurationParameterString(const char* name, const char* defaultValue)
1650 const char* envValue = NULL;
1652 const char* envValue = getenv(name);
1654 if (envValue == NULL)
1656 return defaultValue;
1658 cv::String value = envValue;
1663 #ifdef CV_COLLECT_IMPL_DATA
1664 ImplCollector& getImplData()
1666 CV_SINGLETON_LAZY_INIT_REF(ImplCollector, new ImplCollector())
1669 void setImpl(int flags)
1671 cv::AutoLock lock(getImplData().mutex);
1673 getImplData().implFlags = flags;
1674 getImplData().implCode.clear();
1675 getImplData().implFun.clear();
1678 void addImpl(int flag, const char* func)
1680 cv::AutoLock lock(getImplData().mutex);
1682 getImplData().implFlags |= flag;
1683 if(func) // use lazy collection if name was not specified
1685 size_t index = getImplData().implCode.size();
1686 if(!index || (getImplData().implCode[index-1] != flag || getImplData().implFun[index-1].compare(func))) // avoid duplicates
1688 getImplData().implCode.push_back(flag);
1689 getImplData().implFun.push_back(func);
1694 int getImpl(std::vector<int> &impl, std::vector<String> &funName)
1696 cv::AutoLock lock(getImplData().mutex);
1698 impl = getImplData().implCode;
1699 funName = getImplData().implFun;
1700 return getImplData().implFlags; // return actual flags for lazy collection
1703 bool useCollection()
1705 return getImplData().useCollection;
1708 void setUseCollection(bool flag)
1710 cv::AutoLock lock(getImplData().mutex);
1712 getImplData().useCollection = flag;
1718 bool useInstrumentation()
1720 #ifdef ENABLE_INSTRUMENTATION
1721 return getInstrumentStruct().useInstr;
1727 void setUseInstrumentation(bool flag)
1729 #ifdef ENABLE_INSTRUMENTATION
1730 getInstrumentStruct().useInstr = flag;
1736 InstrNode* getTrace()
1738 #ifdef ENABLE_INSTRUMENTATION
1739 return &getInstrumentStruct().rootNode;
1747 #ifdef ENABLE_INSTRUMENTATION
1748 getInstrumentStruct().rootNode.removeChilds();
1749 getInstrumentTLSStruct().pCurrentNode = &getInstrumentStruct().rootNode;
1753 void setFlags(FLAGS modeFlags)
1755 #ifdef ENABLE_INSTRUMENTATION
1756 getInstrumentStruct().flags = modeFlags;
1758 CV_UNUSED(modeFlags);
1763 #ifdef ENABLE_INSTRUMENTATION
1764 return (FLAGS)getInstrumentStruct().flags;
1770 NodeData::NodeData(const char* funName, const char* fileName, int lineNum, void* retAddress, bool alwaysExpand, cv::instr::TYPE instrType, cv::instr::IMPL implType)
1772 m_funName = funName;
1773 m_instrType = instrType;
1774 m_implType = implType;
1775 m_fileName = fileName;
1776 m_lineNum = lineNum;
1777 m_retAddress = retAddress;
1778 m_alwaysExpand = alwaysExpand;
1786 NodeData::NodeData(NodeData &ref)
1790 NodeData& NodeData::operator=(const NodeData &right)
1792 this->m_funName = right.m_funName;
1793 this->m_instrType = right.m_instrType;
1794 this->m_implType = right.m_implType;
1795 this->m_fileName = right.m_fileName;
1796 this->m_lineNum = right.m_lineNum;
1797 this->m_retAddress = right.m_retAddress;
1798 this->m_alwaysExpand = right.m_alwaysExpand;
1800 this->m_threads = right.m_threads;
1801 this->m_counter = right.m_counter;
1802 this->m_ticksTotal = right.m_ticksTotal;
1804 this->m_funError = right.m_funError;
1808 NodeData::~NodeData()
1811 bool operator==(const NodeData& left, const NodeData& right)
1813 if(left.m_lineNum == right.m_lineNum && left.m_funName == right.m_funName && left.m_fileName == right.m_fileName)
1815 if(left.m_retAddress == right.m_retAddress || !(cv::instr::getFlags()&cv::instr::FLAGS_EXPAND_SAME_NAMES || left.m_alwaysExpand))
1821 #ifdef ENABLE_INSTRUMENTATION
1822 InstrStruct& getInstrumentStruct()
1824 static InstrStruct instr;
1828 InstrTLSStruct& getInstrumentTLSStruct()
1830 return *getInstrumentStruct().tlsStruct.get();
1833 InstrNode* getCurrentNode()
1835 return getInstrumentTLSStruct().pCurrentNode;
1838 IntrumentationRegion::IntrumentationRegion(const char* funName, const char* fileName, int lineNum, void *retAddress, bool alwaysExpand, TYPE instrType, IMPL implType)
1843 InstrStruct *pStruct = &getInstrumentStruct();
1844 if(pStruct->useInstr)
1846 InstrTLSStruct *pTLS = &getInstrumentTLSStruct();
1848 // Disable in case of failure
1849 if(!pTLS->pCurrentNode)
1855 int depth = pTLS->pCurrentNode->getDepth();
1856 if(pStruct->maxDepth && pStruct->maxDepth <= depth)
1862 NodeData payload(funName, fileName, lineNum, retAddress, alwaysExpand, instrType, implType);
1863 Node<NodeData>* pChild = NULL;
1865 if(pStruct->flags&FLAGS_MAPPING)
1868 cv::AutoLock guard(pStruct->mutexCreate); // Guard from concurrent child creation
1869 pChild = pTLS->pCurrentNode->findChild(payload);
1872 pChild = new Node<NodeData>(payload);
1873 pTLS->pCurrentNode->addChild(pChild);
1878 pChild = pTLS->pCurrentNode->findChild(payload);
1885 pTLS->pCurrentNode = pChild;
1887 m_regionTicks = getTickCount();
1891 IntrumentationRegion::~IntrumentationRegion()
1893 InstrStruct *pStruct = &getInstrumentStruct();
1894 if(pStruct->useInstr)
1898 InstrTLSStruct *pTLS = &getInstrumentTLSStruct();
1900 if (pTLS->pCurrentNode->m_payload.m_implType == cv::instr::IMPL_OPENCL &&
1901 (pTLS->pCurrentNode->m_payload.m_instrType == cv::instr::TYPE_FUN ||
1902 pTLS->pCurrentNode->m_payload.m_instrType == cv::instr::TYPE_WRAPPER))
1904 cv::ocl::finish(); // TODO Support "async" OpenCL instrumentation
1907 uint64 ticks = (getTickCount() - m_regionTicks);
1909 cv::AutoLock guard(pStruct->mutexCount); // Concurrent ticks accumulation
1910 pTLS->pCurrentNode->m_payload.m_counter++;
1911 pTLS->pCurrentNode->m_payload.m_ticksTotal += ticks;
1912 pTLS->pCurrentNode->m_payload.m_tls.get()->m_ticksTotal += ticks;
1915 pTLS->pCurrentNode = pTLS->pCurrentNode->m_pParent;
1926 struct IPPInitSingleton
1942 ippStatus = ippGetCpuFeatures(&cpuFeatures, NULL);
1945 std::cerr << "ERROR: IPP cannot detect CPU features, IPP was disabled " << std::endl;
1949 ippFeatures = cpuFeatures;
1951 const char* pIppEnv = getenv("OPENCV_IPP");
1952 cv::String env = pIppEnv;
1955 #if IPP_VERSION_X100 >= 201703
1956 const Ipp64u minorFeatures = ippCPUID_MOVBE|ippCPUID_AES|ippCPUID_CLMUL|ippCPUID_ABR|ippCPUID_RDRAND|ippCPUID_F16C|
1957 ippCPUID_ADCOX|ippCPUID_RDSEED|ippCPUID_PREFETCHW|ippCPUID_SHA|ippCPUID_MPX|ippCPUID_AVX512CD|ippCPUID_AVX512ER|
1958 ippCPUID_AVX512PF|ippCPUID_AVX512BW|ippCPUID_AVX512DQ|ippCPUID_AVX512VL|ippCPUID_AVX512VBMI;
1959 #elif IPP_VERSION_X100 >= 201700
1960 const Ipp64u minorFeatures = ippCPUID_MOVBE|ippCPUID_AES|ippCPUID_CLMUL|ippCPUID_ABR|ippCPUID_RDRAND|ippCPUID_F16C|
1961 ippCPUID_ADCOX|ippCPUID_RDSEED|ippCPUID_PREFETCHW|ippCPUID_SHA|ippCPUID_AVX512CD|ippCPUID_AVX512ER|
1962 ippCPUID_AVX512PF|ippCPUID_AVX512BW|ippCPUID_AVX512DQ|ippCPUID_AVX512VL|ippCPUID_AVX512VBMI;
1964 const Ipp64u minorFeatures = 0;
1967 env = env.toLowerCase();
1968 if(env.substr(0, 2) == "ne")
1971 env = env.substr(3, env.size());
1974 if(env == "disabled")
1976 std::cerr << "WARNING: IPP was disabled by OPENCV_IPP environment variable" << std::endl;
1979 else if(env == "sse42")
1980 ippFeatures = minorFeatures|ippCPUID_SSE2|ippCPUID_SSE3|ippCPUID_SSSE3|ippCPUID_SSE41|ippCPUID_SSE42;
1981 else if(env == "avx2")
1982 ippFeatures = minorFeatures|ippCPUID_SSE2|ippCPUID_SSE3|ippCPUID_SSSE3|ippCPUID_SSE41|ippCPUID_SSE42|ippCPUID_AVX|ippCPUID_AVX2;
1983 #if IPP_VERSION_X100 >= 201700
1984 #if defined (_M_AMD64) || defined (__x86_64__)
1985 else if(env == "avx512")
1986 ippFeatures = minorFeatures|ippCPUID_SSE2|ippCPUID_SSE3|ippCPUID_SSSE3|ippCPUID_SSE41|ippCPUID_SSE42|ippCPUID_AVX|ippCPUID_AVX2|ippCPUID_AVX512F;
1990 std::cerr << "ERROR: Improper value of OPENCV_IPP: " << env.c_str() << ". Correct values are: disabled, sse42, avx2, avx512 (Intel64 only)" << std::endl;
1992 // Trim unsupported features
1993 ippFeatures &= cpuFeatures;
1996 // Disable AVX1 since we don't track regressions for it. SSE42 will be used instead
1997 if(cpuFeatures&ippCPUID_AVX && !(cpuFeatures&ippCPUID_AVX2))
1998 ippFeatures &= ~((Ipp64u)ippCPUID_AVX);
2000 // IPP integrations in OpenCV support only SSE4.2, AVX2 and AVX-512 optimizations.
2002 #if IPP_VERSION_X100 >= 201700
2003 cpuFeatures&ippCPUID_AVX512F ||
2005 cpuFeatures&ippCPUID_AVX2 ||
2006 cpuFeatures&ippCPUID_SSE42
2013 if(ippFeatures == cpuFeatures)
2016 IPP_INITIALIZER(ippFeatures)
2017 ippFeatures = ippGetEnabledCpuFeatures();
2019 // Detect top level optimizations to make comparison easier for optimizations dependent conditions
2020 #if IPP_VERSION_X100 >= 201700
2021 if(ippFeatures&ippCPUID_AVX512F)
2023 if((ippFeatures&ippCPUID_AVX512_SKX) == ippCPUID_AVX512_SKX)
2024 ippTopFeatures = ippCPUID_AVX512_SKX;
2025 else if((ippFeatures&ippCPUID_AVX512_KNL) == ippCPUID_AVX512_KNL)
2026 ippTopFeatures = ippCPUID_AVX512_KNL;
2028 ippTopFeatures = ippCPUID_AVX512F; // Unknown AVX512 configuration
2032 if(ippFeatures&ippCPUID_AVX2)
2033 ippTopFeatures = ippCPUID_AVX2;
2034 else if(ippFeatures&ippCPUID_SSE42)
2035 ippTopFeatures = ippCPUID_SSE42;
2037 pIppLibInfo = ippiGetLibVersion();
2044 int ippStatus; // 0 - all is ok, -1 - IPP functions failed
2045 const char *funcname;
2046 const char *filename;
2050 Ipp64u ippTopFeatures;
2051 const IppLibraryVersion *pIppLibInfo;
2054 static IPPInitSingleton& getIPPSingleton()
2056 CV_SINGLETON_LAZY_INIT_REF(IPPInitSingleton, new IPPInitSingleton())
2060 #if OPENCV_ABI_COMPATIBILITY > 300
2061 unsigned long long getIppFeatures()
2063 int getIppFeatures()
2067 #if OPENCV_ABI_COMPATIBILITY > 300
2068 return getIPPSingleton().ippFeatures;
2070 return (int)getIPPSingleton().ippFeatures;
2077 unsigned long long getIppTopFeatures();
2079 unsigned long long getIppTopFeatures()
2082 return getIPPSingleton().ippTopFeatures;
2088 void setIppStatus(int status, const char * const _funcname, const char * const _filename, int _line)
2091 getIPPSingleton().ippStatus = status;
2092 getIPPSingleton().funcname = _funcname;
2093 getIPPSingleton().filename = _filename;
2094 getIPPSingleton().linen = _line;
2096 CV_UNUSED(status); CV_UNUSED(_funcname); CV_UNUSED(_filename); CV_UNUSED(_line);
2103 return getIPPSingleton().ippStatus;
2109 String getIppErrorLocation()
2112 return format("%s:%d %s", getIPPSingleton().filename ? getIPPSingleton().filename : "", getIPPSingleton().linen, getIPPSingleton().funcname ? getIPPSingleton().funcname : "");
2118 String getIppVersion()
2121 const IppLibraryVersion *pInfo = getIPPSingleton().pIppLibInfo;
2123 return format("%s %s %s", pInfo->Name, pInfo->Version, pInfo->BuildDate);
2125 return String("error");
2127 return String("disabled");
2134 CoreTLSData* data = getCoreTlsData().get();
2135 if(data->useIPP < 0)
2137 data->useIPP = getIPPSingleton().useIPP;
2139 return (data->useIPP > 0);
2145 void setUseIPP(bool flag)
2147 CoreTLSData* data = getCoreTlsData().get();
2149 data->useIPP = (getIPPSingleton().useIPP)?flag:false;
2152 data->useIPP = false;
2159 CoreTLSData* data = getCoreTlsData().get();
2160 if(data->useIPP_NE < 0)
2162 data->useIPP_NE = getIPPSingleton().useIPP_NE;
2164 return (data->useIPP_NE > 0);
2170 void setUseIPP_NE(bool flag)
2172 CoreTLSData* data = getCoreTlsData().get();
2174 data->useIPP_NE = (getIPPSingleton().useIPP_NE)?flag:false;
2177 data->useIPP_NE = false;
2185 #ifdef HAVE_TEGRA_OPTIMIZATION
2191 cv::CoreTLSData* data = cv::getCoreTlsData().get();
2193 if (data->useTegra < 0)
2195 const char* pTegraEnv = getenv("OPENCV_TEGRA");
2196 if (pTegraEnv && (cv::String(pTegraEnv) == "disabled"))
2197 data->useTegra = false;
2199 data->useTegra = true;
2202 return (data->useTegra > 0);
2205 void setUseTegra(bool flag)
2207 cv::CoreTLSData* data = cv::getCoreTlsData().get();
2208 data->useTegra = flag;
2211 } // namespace tegra