ermig1979 / Simd

C++ image processing and machine learning library with using of SIMD: SSE, AVX, AVX-512, AMX for x86/x64, VMX(Altivec) and VSX(Power7) for PowerPC, NEON for ARM.
http://ermig1979.github.io/Simd
MIT License
2.05k stars 409 forks source link

Fix mac os arm64 #232

Closed fspindle closed 2 years ago

fspindle commented 2 years ago

Several fixes for Apple M1 Pro that has the following characteristics

  Platform:
    Host:                        Darwin 21.6.0 arm64
    CMake:                       3.24.2
    CMake generator:             Unix Makefiles
    CMake build tool:            /usr/bin/make
    Configuration:               Release

  System information:
    OS name:                     macOS
    OS release:                  12.6
    OS version:                  21G115
    OS platform:                 arm64
    CPU name:                    Apple M1 Pro
    Is the CPU 64-bit?           yes
    Does the CPU have FPU?       no
    CPU optimization:            NEON
s-trinh commented 2 years ago

Some additional C++11 guard conditions after also comparing with the Simd version embedded into ViSP:

diff --git a/src/Simd/SimdDefs.h b/src/Simd/SimdDefs.h
index 85bc2e4f..b40c4d76 100644
--- a/src/Simd/SimdDefs.h
+++ b/src/Simd/SimdDefs.h
@@ -168,8 +168,16 @@
 #define SIMD_X64_ENABLE
 #endif

-#ifdef __BIG_ENDIAN__
+#if defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) || defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
 #define SIMD_BIG_ENDIAN
+#elif defined(__GLIBC__) || (defined(__GNUC__) && !defined(__llvm__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && defined(__BYTE_ORDER__))
+  #include <endian.h>
+  #if defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)
+    #define SIMD_BIG_ENDIAN
+  #endif
+#elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) ||         \
+    defined(__hpux) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
+  #define SIMD_BIG_ENDIAN
 #endif

 #ifdef __powerpc__
diff --git a/src/Simd/SimdFrame.hpp b/src/Simd/SimdFrame.hpp
index f169c595..bd881cc4 100644
--- a/src/Simd/SimdFrame.hpp
+++ b/src/Simd/SimdFrame.hpp
@@ -89,12 +89,14 @@ namespace Simd
         */
         Frame(const Frame & frame);

+#ifdef SIMD_CPP_2011_ENABLE
         /*!
             Move constructor of Frame structure.

             \param [in] frame - a moved Frame.
         */
         Frame(Frame&& frame) noexcept;
+#endif

         /*!
             Creates a new one plane Frame structure on the base of the image view.
@@ -107,6 +109,7 @@ namespace Simd
         */
         Frame(const View<A> & view, bool flipped_ = false, double timestamp_ = 0);

+#ifdef SIMD_CPP_2011_ENABLE
         /*!
             Creates a new one plane Frame structure on the base of the temporal image view.

@@ -115,6 +118,7 @@ namespace Simd
             \param [in] timestamp_ - a timestamp of created frame. It is equal to 0 by default.
         */
         Frame(View<A>&& view, bool flipped_ = false, double timestamp_ = 0);
+#endif

         /*!
             Creates a new Frame structure with specified width, height and pixel format.
@@ -193,6 +197,7 @@ namespace Simd
         */
         Frame & operator = (const Frame & frame);

+#ifdef SIMD_CPP_2011_ENABLE
         /*!
             Moves Frame structure.

@@ -200,6 +205,7 @@ namespace Simd
             \return a reference to itself.
         */
         Frame& operator = (Frame&& frame);
+#endif

         /*!
             Creates reference to itself.
@@ -424,6 +430,7 @@ namespace Simd
             planes[i] = frame.planes[i];
     }

+#ifdef SIMD_CPP_2011_ENABLE
     template <template<class> class A> SIMD_INLINE Frame<A>::Frame(Frame && frame) noexcept
         : width(0)
         , height(0)
@@ -433,6 +440,7 @@ namespace Simd
     {
         Swap(frame);
     }
+#endif

     template <template<class> class A> SIMD_INLINE Frame<A>::Frame(const View<A> & view, bool flipped_, double timestamp_)
         : width(view.width)
@@ -454,6 +462,7 @@ namespace Simd
         planes[0] = view;
     }

+#ifdef SIMD_CPP_2011_ENABLE
     template <template<class> class A> SIMD_INLINE Frame<A>::Frame(View<A>&& view, bool flipped_, double timestamp_)
         : width(view.width)
         , height(view.height)
@@ -473,6 +482,7 @@ namespace Simd
         }
         planes[0] = std::move(view);
     }
+#endif

     template <template<class> class A> SIMD_INLINE Frame<A>::Frame(size_t width_, size_t height_, Format format_, bool flipped_, double timestamp_)
         : width(0)
@@ -585,6 +595,7 @@ namespace Simd
         return *this;
     }

+#ifdef SIMD_CPP_2011_ENABLE
     template <template<class> class A> SIMD_INLINE Frame<A>& Frame<A>::operator = (Frame<A>&& frame)
     {
         if (this != &frame)
@@ -594,6 +605,7 @@ namespace Simd
         }
         return *this;
     }
+#endif
     /*! \endcond */

     template <template<class> class A> SIMD_INLINE Frame<A> & Frame<A>::Ref()
diff --git a/src/Simd/SimdLib.hpp b/src/Simd/SimdLib.hpp
index a06344bf..3752fccd 100644
--- a/src/Simd/SimdLib.hpp
+++ b/src/Simd/SimdLib.hpp
@@ -303,7 +303,7 @@ namespace Simd
     {
         assert(Compatible(src0, src1, dst) && Compatible(alpha0, alpha1) && EqualSize(dst, alpha0) && alpha0.format == View<A>::Gray8 && dst.ChannelSize() == 1);

-        SimdAlphaBlending2x(src0.data, src0.stride, alpha0.data, alpha0.stride, 
+        SimdAlphaBlending2x(src0.data, src0.stride, alpha0.data, alpha0.stride,
             src1.data, src1.stride, alpha1.data, alpha1.stride,
             dst.width, dst.height, dst.ChannelCount(), dst.data, dst.stride);
     }
@@ -2731,7 +2731,7 @@ namespace Simd

         \fn void LitterCpuCache(size_t k = 2)

-        \short It creates a large buffer and fills it. 
+        \short It creates a large buffer and fills it.

         This function litters CPU cache. It is useful for test purposes.

@@ -3205,7 +3205,7 @@ namespace Simd
             Point<ptrdiff_t> size = src.Size() << level;
             if (level)
             {
-                std::vector<View<A>> pyramid(level);
+                std::vector<View<A> > pyramid(level);
                 pyramid[0].Resize(size, src.format);
                 Simd::ResizeBilinear(src, pyramid[0]);
                 for (size_t i = 1; i < level; ++i)
@@ -4117,7 +4117,7 @@ namespace Simd

         SimdSquareSum(src.data, src.stride, src.width, src.height, &sum);
     }
-    
+
     /*! @ingroup other_statistic

         \fn void ValueSquareSum(const View<A>& src, uint64_t & valueSum, uint64_t & squareSum)
diff --git a/src/Simd/SimdNeonCpu.cpp b/src/Simd/SimdNeonCpu.cpp
index c0772047..6accb475 100644
--- a/src/Simd/SimdNeonCpu.cpp
+++ b/src/Simd/SimdNeonCpu.cpp
@@ -44,7 +44,7 @@ namespace Simd
 #if defined(_MSC_VER)
             return true;
 #elif defined(__GNUC__)
-#if defined(SIMD_ARM64_ENABLE)
+#if defined(SIMD_ARM64_ENABLE) || (TARGET_OS_IOS != 0) // Modification for iOS
             return true;
 #else
             return Base::CheckBit(AT_HWCAP, HWCAP_NEON);
diff --git a/src/Simd/SimdSse41ImageLoad.cpp b/src/Simd/SimdSse41ImageLoad.cpp
index 77a6d5d0..2b6a605d 100644
--- a/src/Simd/SimdSse41ImageLoad.cpp
+++ b/src/Simd/SimdSse41ImageLoad.cpp
@@ -144,7 +144,7 @@ namespace Simd
             ImageLoaderParam param(data, size, *format);
             if (param.Validate())
             {
-                std::unique_ptr<ImageLoader> loader(CreateImageLoader(param));
+                Holder<ImageLoader> loader(CreateImageLoader(param)); // Modified for c++ 98
                 if (loader)
                 {
                     if (loader->FromStream())
diff --git a/src/Simd/SimdSse41ImageSave.cpp b/src/Simd/SimdSse41ImageSave.cpp
index 29daaa8c..2d03fedb 100644
--- a/src/Simd/SimdSse41ImageSave.cpp
+++ b/src/Simd/SimdSse41ImageSave.cpp
@@ -124,7 +124,7 @@ namespace Simd
             ImageSaverParam param(width, height, format, file, quality);
             if (param.Validate())
             {
-                std::unique_ptr<ImageSaver> saver(CreateImageSaver(param));
+                Holder<ImageSaver> saver(CreateImageSaver(param)); // Modified for c++ 98
                 if (saver)
                 {
                     if (saver->ToStream(src, stride))
diff --git a/src/Simd/SimdUpdate.h b/src/Simd/SimdUpdate.h
index 53ac61af..1d255a52 100644
--- a/src/Simd/SimdUpdate.h
+++ b/src/Simd/SimdUpdate.h
@@ -31,7 +31,7 @@ namespace Simd
     enum UpdateType
     {
         UpdateSet = 0,
-        UpdateAdd = 1,
+        UpdateAdd = 1
     };

     namespace Base
diff --git a/src/Simd/SimdView.hpp b/src/Simd/SimdView.hpp
index f7a9748b..e20fb2b3 100644
--- a/src/Simd/SimdView.hpp
+++ b/src/Simd/SimdView.hpp
@@ -155,12 +155,14 @@ namespace Simd
         */
         View(const View & view);

+#ifdef SIMD_CPP_2011_ENABLE
         /*!
             Move constructor of View structure.

             \param [in] view - a moved View.
         */
         View(View&& view) noexcept;
+#endif

 #ifdef SIMD_OPENCV_ENABLE
         /*!
@@ -270,6 +272,7 @@ namespace Simd
         */
         View & operator = (const View & view);

+#ifdef SIMD_CPP_2011_ENABLE
         /*!
             Moves View structure.

@@ -277,6 +280,7 @@ namespace Simd
             \return a reference to itself.
         */
         View& operator = (View&& view);
+#endif

 #ifdef SIMD_OPENCV_ENABLE
         /*!
@@ -291,7 +295,7 @@ namespace Simd
 #endif

         /*!
-            Creates reference to itself. 
+            Creates reference to itself.
             It may be useful if we need to create reference to the temporary object:
             \verbatim
             #include "Simd/SimdLib.hpp"
@@ -527,13 +531,13 @@ namespace Simd

         /*!
             Loads image from file.
-            
+
             Supported formats are described by ::SimdImageFileType enumeration.

             \note PGM and PPM files with comments are not supported.

             \param [in] path - a path to image file.
-            \param [in] format - a desired format of loaded image. 
+            \param [in] format - a desired format of loaded image.
                 Supported values are View::Gray8, View::Bgr24, View::Bgra32, View::Rgb24, View::Rgba32 and View::None.
                 Default value is View::None (loads image in native pixel format of image file).
             \return - a result of loading.
@@ -558,7 +562,7 @@ namespace Simd

         /*!
             Saves image to file.
- 
+
             \param [in] path - a path to file.
             \param [in] type - a image file format. By default is equal to ::SimdImageFileUndefined (format auto choice).
             \param [in] quality - a parameter of compression quality (if file format supports it).
@@ -740,6 +744,7 @@ namespace Simd
     {
     }

+#ifdef SIMD_CPP_2011_ENABLE
     template <template<class> class A> SIMD_INLINE View<A>::View(View<A> && view) noexcept
         : width(0)
         , height(0)
@@ -750,6 +755,7 @@ namespace Simd
     {
         Swap(view);
     }
+#endif
     /*! \endcond */

 #ifdef SIMD_OPENCV_ENABLE
@@ -948,6 +954,7 @@ namespace Simd
         return *this;
     }

+#ifdef SIMD_CPP_2011_ENABLE
     template <template<class> class A> SIMD_INLINE View<A>& View<A>::operator = (View<A>&& view)
     {
         if (this != &view)
@@ -957,6 +964,7 @@ namespace Simd
         }
         return *this;
     }
+#endif
     /*! \endcond */

 #ifdef SIMD_OPENCV_ENABLE

For the additional guard for endianness, it comes from:

https://github.com/lagadic/visp/blame/0df2cb1d81c45e75c56cfb5d051fe0f06e478822/3rdparty/simdlib/Simd/SimdDefs.h#L136