summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/simd/simd_check.h
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/simd/simd_check.h')
-rw-r--r--ml/dlib/dlib/simd/simd_check.h177
1 files changed, 177 insertions, 0 deletions
diff --git a/ml/dlib/dlib/simd/simd_check.h b/ml/dlib/dlib/simd/simd_check.h
new file mode 100644
index 000000000..c4ca0c3b8
--- /dev/null
+++ b/ml/dlib/dlib/simd/simd_check.h
@@ -0,0 +1,177 @@
+// Copyright (C) 2013 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#ifndef DLIB_SIMd_CHECK_Hh_
+#define DLIB_SIMd_CHECK_Hh_
+
+#include <array>
+#include <iostream>
+
+//#define DLIB_DO_NOT_USE_SIMD
+
+// figure out which SIMD instructions we can use.
+#ifndef DLIB_DO_NOT_USE_SIMD
+ #if defined(_MSC_VER)
+ #ifdef __AVX__
+ #ifndef DLIB_HAVE_SSE2
+ #define DLIB_HAVE_SSE2
+ #endif
+ #ifndef DLIB_HAVE_SSE3
+ #define DLIB_HAVE_SSE3
+ #endif
+ #ifndef DLIB_HAVE_SSE41
+ #define DLIB_HAVE_SSE41
+ #endif
+ #ifndef DLIB_HAVE_AVX
+ #define DLIB_HAVE_AVX
+ #endif
+ #endif
+ #if (defined( _M_X64) || defined(_M_IX86_FP) && _M_IX86_FP >= 2) && !defined(DLIB_HAVE_SSE2)
+ #define DLIB_HAVE_SSE2
+ #endif
+ #else
+ #ifdef __SSE2__
+ #ifndef DLIB_HAVE_SSE2
+ #define DLIB_HAVE_SSE2
+ #endif
+ #endif
+ #ifdef __SSSE3__
+ #ifndef DLIB_HAVE_SSE3
+ #define DLIB_HAVE_SSE3
+ #endif
+ #endif
+ #ifdef __SSE4_1__
+ #ifndef DLIB_HAVE_SSE41
+ #define DLIB_HAVE_SSE41
+ #endif
+ #endif
+ #ifdef __AVX__
+ #ifndef DLIB_HAVE_AVX
+ #define DLIB_HAVE_AVX
+ #endif
+ #endif
+ #ifdef __AVX2__
+ #ifndef DLIB_HAVE_AVX2
+ #define DLIB_HAVE_AVX2
+ #endif
+ #endif
+ #ifdef __ALTIVEC__
+ #ifndef DLIB_HAVE_ALTIVEC
+ #define DLIB_HAVE_ALTIVEC
+ #endif
+ #endif
+ #ifdef __VSX__
+ #ifndef DLIB_HAVE_VSX
+ #define DLIB_HAVE_VSX
+ #endif
+ #endif
+ #ifdef __VEC__ // __VEC__ = 10206
+ #ifndef DLIB_HAVE_POWER_VEC // vector and vec_ intrinsics
+ #define DLIB_HAVE_POWER_VEC
+ #endif
+ #endif
+ #ifdef __ARM_NEON
+ #ifndef DLIB_HAVE_NEON
+ #define DLIB_HAVE_NEON
+ #endif
+ #endif
+ #endif
+#endif
+
+
+// ----------------------------------------------------------------------------------------
+
+
+#ifdef DLIB_HAVE_ALTIVEC
+#include <altivec.h>
+#endif
+
+#ifdef DLIB_HAVE_SSE2
+ #include <xmmintrin.h>
+ #include <emmintrin.h>
+ #include <mmintrin.h>
+#endif
+#ifdef DLIB_HAVE_SSE3
+ #include <pmmintrin.h> // SSE3
+ #include <tmmintrin.h>
+#endif
+#ifdef DLIB_HAVE_SSE41
+ #include <smmintrin.h> // SSE4
+#endif
+#ifdef DLIB_HAVE_AVX
+ #include <immintrin.h> // AVX
+#endif
+#ifdef DLIB_HAVE_AVX2
+ #include <immintrin.h> // AVX
+// #include <avx2intrin.h>
+#endif
+#ifdef DLIB_HAVE_NEON
+ #include <arm_neon.h> // ARM NEON
+#endif
+
+// ----------------------------------------------------------------------------------------
+// Define functions to check, at runtime, what instructions are available
+
+#if defined(_MSC_VER) && (defined(_M_I86) || defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) )
+ #include <intrin.h>
+
+ inline std::array<unsigned int,4> cpuid(int function_id)
+ {
+ std::array<unsigned int,4> info;
+ // Load EAX, EBX, ECX, EDX into info
+ __cpuid((int*)info.data(), function_id);
+ return info;
+ }
+
+#elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__i686__) || defined(__amd64__) || defined(__x86_64__))
+ #include <cpuid.h>
+
+ inline std::array<unsigned int,4> cpuid(int function_id)
+ {
+ std::array<unsigned int,4> info;
+ // Load EAX, EBX, ECX, EDX into info
+ __cpuid(function_id, info[0], info[1], info[2], info[3]);
+ return info;
+ }
+
+#else
+
+ inline std::array<unsigned int,4> cpuid(int)
+ {
+ return std::array<unsigned int,4>{};
+ }
+
+#endif
+
+ inline bool cpu_has_sse2_instructions() { return 0!=(cpuid(1)[3]&(1<<26)); }
+ inline bool cpu_has_sse3_instructions() { return 0!=(cpuid(1)[2]&(1<<0)); }
+ inline bool cpu_has_sse41_instructions() { return 0!=(cpuid(1)[2]&(1<<19)); }
+ inline bool cpu_has_sse42_instructions() { return 0!=(cpuid(1)[2]&(1<<20)); }
+ inline bool cpu_has_avx_instructions() { return 0!=(cpuid(1)[2]&(1<<28)); }
+ inline bool cpu_has_avx2_instructions() { return 0!=(cpuid(7)[1]&(1<<5)); }
+ inline bool cpu_has_avx512_instructions() { return 0!=(cpuid(7)[1]&(1<<16)); }
+
+ inline void warn_about_unavailable_but_used_cpu_instructions()
+ {
+#if defined(DLIB_HAVE_AVX2)
+ if (!cpu_has_avx2_instructions())
+ std::cerr << "Dlib was compiled to use AVX2 instructions, but these aren't available on your machine." << std::endl;
+#elif defined(DLIB_HAVE_AVX)
+ if (!cpu_has_avx_instructions())
+ std::cerr << "Dlib was compiled to use AVX instructions, but these aren't available on your machine." << std::endl;
+#elif defined(DLIB_HAVE_SSE41)
+ if (!cpu_has_sse41_instructions())
+ std::cerr << "Dlib was compiled to use SSE41 instructions, but these aren't available on your machine." << std::endl;
+#elif defined(DLIB_HAVE_SSE3)
+ if (!cpu_has_sse3_instructions())
+ std::cerr << "Dlib was compiled to use SSE3 instructions, but these aren't available on your machine." << std::endl;
+#elif defined(DLIB_HAVE_SSE2)
+ if (!cpu_has_sse2_instructions())
+ std::cerr << "Dlib was compiled to use SSE2 instructions, but these aren't available on your machine." << std::endl;
+#endif
+ }
+
+// ----------------------------------------------------------------------------------------
+
+#endif // DLIB_SIMd_CHECK_Hh_
+
+