NEON detection in runtime
authorIlya Lavrenov <ilya.lavrenov@itseez.com>
Tue, 30 Dec 2014 13:53:19 +0000 (16:53 +0300)
committerIlya Lavrenov <ilya.lavrenov@itseez.com>
Mon, 12 Jan 2015 22:35:53 +0000 (01:35 +0300)
modules/core/src/system.cpp
modules/imgproc/src/filter.cpp
modules/ts/src/ts_func.cpp

index d9a2087..b4484f9 100644 (file)
 # endif
 #endif
 
+#if defined ANDROID || defined __linux__
+#  include <unistd.h>
+#  include <fcntl.h>
+#  include <elf.h>
+#  include <linux/auxvec.h>
+#endif
+
 #if defined WIN32 || defined _WIN32 || defined WINCE
 #ifndef _WIN32_WINNT           // This is needed for the declaration of TryEnterCriticalSection in winbase.h with Visual Studio 2005 (and older?)
   #define _WIN32_WINNT 0x0400  // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx
@@ -253,6 +260,29 @@ struct HWFeatures
             f.have[CV_CPU_AVX]    = (((cpuid_data[2] & (1<<28)) != 0)&&((cpuid_data[2] & (1<<27)) != 0));//OS uses XSAVE_XRSTORE and CPU support AVX
         }
 
+    #if defined ANDROID || defined __linux__
+        int cpufile = open("/proc/self/auxv", O_RDONLY);
+
+        if (cpufile >= 0)
+        {
+            Elf32_auxv_t auxv;
+            const size_t size_auxv_t = sizeof(Elf32_auxv_t);
+
+            while (read(cpufile, &auxv, sizeof(Elf32_auxv_t)) == size_auxv_t)
+            {
+                if (auxv.a_type == AT_HWCAP)
+                {
+                    f.have[CV_CPU_NEON] = (auxv.a_un.a_val & 4096) != 0;
+                    break;
+                }
+            }
+
+            close(cpufile);
+        }
+    #elif (defined __clang__ || defined __APPLE__) && defined __ARM_NEON__
+        f.have[CV_CPU_NEON] = true;
+    #endif
+
         return f;
     }
 
index f376507..63a1005 100644 (file)
@@ -2231,9 +2231,8 @@ struct SymmRowSmallVec_8u32s
 
     int operator()(const uchar* src, uchar* _dst, int width, int cn) const
     {
-        //Uncomment the two following lines when runtime support for neon is implemented.
-        // if( !checkHardwareSupport(CV_CPU_NEON) )
-        //     return 0;
+         if( !checkHardwareSupport(CV_CPU_NEON) )
+             return 0;
 
         int i = 0, _ksize = kernel.rows + kernel.cols - 1;
         int* dst = (int*)_dst;
@@ -2459,9 +2458,8 @@ struct SymmColumnVec_32s8u
 
     int operator()(const uchar** _src, uchar* dst, int width) const
     {
-        //Uncomment the two following lines when runtime support for neon is implemented.
-        // if( !checkHardwareSupport(CV_CPU_NEON) )
-        //     return 0;
+         if( !checkHardwareSupport(CV_CPU_NEON) )
+             return 0;
 
         int _ksize = kernel.rows + kernel.cols - 1;
         int ksize2 = _ksize / 2;
@@ -2612,9 +2610,8 @@ struct SymmColumnSmallVec_32s16s
 
     int operator()(const uchar** _src, uchar* _dst, int width) const
     {
-        //Uncomment the two following lines when runtime support for neon is implemented.
-        // if( !checkHardwareSupport(CV_CPU_NEON) )
-        //     return 0;
+         if( !checkHardwareSupport(CV_CPU_NEON) )
+             return 0;
 
         int ksize2 = (kernel.rows + kernel.cols - 1)/2;
         const float* ky = kernel.ptr<float>() + ksize2;
@@ -2788,15 +2785,13 @@ struct SymmColumnVec_32f16s
         kernel = _kernel;
         delta = (float)_delta;
         CV_Assert( (symmetryType & (KERNEL_SYMMETRICAL | KERNEL_ASYMMETRICAL)) != 0 );
-        //Uncomment the following line when runtime support for neon is implemented.
-        // neon_supported = checkHardwareSupport(CV_CPU_NEON);
+         neon_supported = checkHardwareSupport(CV_CPU_NEON);
     }
 
     int operator()(const uchar** _src, uchar* _dst, int width) const
     {
-        //Uncomment the two following lines when runtime support for neon is implemented.
-        // if( !neon_supported )
-        //     return 0;
+         if( !neon_supported )
+             return 0;
 
         int _ksize = kernel.rows + kernel.cols - 1;
         int ksize2 = _ksize / 2;
@@ -2943,9 +2938,8 @@ struct SymmRowSmallVec_32f
 
     int operator()(const uchar* _src, uchar* _dst, int width, int cn) const
     {
-        //Uncomment the two following lines when runtime support for neon is implemented.
-        // if( !checkHardwareSupport(CV_CPU_NEON) )
-        //     return 0;
+         if( !checkHardwareSupport(CV_CPU_NEON) )
+             return 0;
 
         int i = 0, _ksize = kernel.rows + kernel.cols - 1;
         float* dst = (float*)_dst;
index 7745c86..03877c0 100644 (file)
@@ -3020,7 +3020,7 @@ void printVersionInfo(bool useStdOut)
     if (checkHardwareSupport(CV_CPU_AVX)) cpu_features += " avx";
 #endif
 #if CV_NEON
-    cpu_features += " neon"; // NEON is currently not checked at runtime
+    if (checkHardwareSupport(CV_CPU_NEON)) cpu_features += " neon";
 #endif
 
     cpu_features.erase(0, 1); // erase initial space