hardware: detect ARM SVE architecture at runtime
authorGilles Gouaillardet <gilles@rist.or.jp>
Wed, 16 Sep 2020 05:32:23 +0000 (14:32 +0900)
committerArtem Zhmurov <zhmurov@gmail.com>
Thu, 1 Oct 2020 21:16:41 +0000 (21:16 +0000)
 - issue a warning if the application was built with NEON simd support
 - check the vector length at runtime is the same than at cmake time,
   and aborts otherwise

src/gromacs/hardware/cpuinfo.cpp
src/gromacs/hardware/cpuinfo.h
src/gromacs/simd/support.cpp
src/gromacs/simd/support.h

index 51d8cc7d961c8f443900c33b54b4a95d0242dde6..f81a6f027998424c6aef3bcfb62f916552ad9eb8 100644 (file)
@@ -947,6 +947,10 @@ void detectProcCpuInfoArm(const std::map<std::string, std::string>& cpuInfo,
                 features->insert(CpuInfo::Feature::Arm_NeonAsimd);
             }
         }
+        if (s.find("sve") != std::string::npos)
+        {
+            features->insert(CpuInfo::Feature::Arm_Sve);
+        }
     }
 }
 
@@ -1043,6 +1047,9 @@ CpuInfo CpuInfo::detect()
         result.features_.insert(Feature::Arm_Neon);      // ARMv8 always has Neon
         result.features_.insert(Feature::Arm_NeonAsimd); // ARMv8 always has Neon-asimd
 #endif
+#if defined __arch64__ && defined __ARM_FEATURE_SVE
+        result.features_.insert(Feature::Arm_Sve);
+#endif
 
 #if defined sun
         result.vendor_ = CpuInfo::Vendor::Oracle;
@@ -1148,6 +1155,7 @@ const std::string& CpuInfo::featureString(Feature f)
         { Feature::X86_Xop, "xop" },
         { Feature::Arm_Neon, "neon" },
         { Feature::Arm_NeonAsimd, "neon_asimd" },
+        { Feature::Arm_Sve, "sve" },
         { Feature::Ibm_Qpx, "qpx" },
         { Feature::Ibm_Vmx, "vmx" },
         { Feature::Ibm_Vsx, "vsx" },
index bd2ac5bc0dc8e5b4f397a3598a7d7336e907734e..fe09e27807a74b899ee1d321f3ff5a9aa7a2305c 100644 (file)
@@ -146,6 +146,7 @@ public:
         X86_Xop,         //!< AMD extended instructions, only AMD for now
         Arm_Neon,        //!< 32-bit ARM NEON
         Arm_NeonAsimd,   //!< 64-bit ARM AArch64 Advanced SIMD
+        Arm_Sve,         //!< ARM Scalable Vector Extensions
         Ibm_Qpx,         //!< IBM QPX SIMD (BlueGene/Q)
         Ibm_Vmx,         //!< IBM VMX SIMD (Altivec on Power6 and later)
         Ibm_Vsx,         //!< IBM VSX SIMD (Power7 and later)
index 7512e0e909353fc3bef38b89a19cae41d77c1989..f88b801944a7e081060655b2200fe0a6e253c287 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
 
 #include "config.h"
 
+#if GMX_SIMD_ARM_SVE
+#    include <arm_sve.h>
+#endif
+
 #include <cstdio>
 #include <cstdlib>
 
@@ -56,6 +60,7 @@
 
 #include "gromacs/hardware/cpuinfo.h"
 #include "gromacs/hardware/identifyavx512fmaunits.h"
+#include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/stringutil.h"
 
 namespace gmx
@@ -80,6 +85,7 @@ const std::string& simdString(SimdType s)
         { SimdType::X86_Mic, "X86_MIC" },
         { SimdType::Arm_Neon, "ARM_NEON" },
         { SimdType::Arm_NeonAsimd, "ARM_NEON_ASIMD" },
+        { SimdType::Arm_Sve, "ARM_SVE" },
         { SimdType::Ibm_Vmx, "IBM_VMX" },
         { SimdType::Ibm_Vsx, "IBM_VSX" },
         { SimdType::Fujitsu_HpcAce, "Fujitsu HPC-ACE" }
@@ -179,7 +185,11 @@ SimdType simdSuggested(const CpuInfo& c)
 
                 break;
             case CpuInfo::Vendor::Arm:
-                if (c.feature(CpuInfo::Feature::Arm_NeonAsimd))
+                if (c.feature(CpuInfo::Feature::Arm_Sve))
+                {
+                    suggested = SimdType::Arm_Sve;
+                }
+                else if (c.feature(CpuInfo::Feature::Arm_NeonAsimd))
                 {
                     suggested = SimdType::Arm_NeonAsimd;
                 }
@@ -234,6 +244,8 @@ SimdType simdCompiled()
     return SimdType::Arm_Neon;
 #elif GMX_SIMD_ARM_NEON_ASIMD
     return SimdType::Arm_NeonAsimd;
+#elif GMX_SIMD_ARM_SVE
+    return SimdType::Arm_Sve;
 #elif GMX_SIMD_IBM_VMX
     return SimdType::Ibm_Vmx;
 #elif GMX_SIMD_IBM_VSX
@@ -319,6 +331,21 @@ bool simdCheck(gmx::SimdType wanted, FILE* log, bool warnToStdErr)
         warnMsg = wrapper.wrapToString(formatString(
                 "Compiled SIMD: %s, but for this host/run %s might be better (see log).",
                 simdString(compiled).c_str(), simdString(wanted).c_str()));
+#if GMX_SIMD_ARM_SVE
+    }
+    else if ((compiled == SimdType::Arm_Sve) && (svcntb() != GMX_SIMD_ARM_SVE_LENGTH / 8))
+    {
+        logMsg  = wrapper.wrapToString(formatString(
+                "Longest SVE length requested by all nodes in run: %d\n"
+                "SVE length selected at compile time:               %ld\n"
+                "This program was compiled for different hardware than you are running on, "
+                "which will lead to incorrect behavior.\n"
+                "Aborting",
+                GMX_SIMD_ARM_SVE_LENGTH, svcntb() * 8));
+        warnMsg = wrapper.wrapToString(formatString(
+                "Compiled SVE Length: %d, but for this process requires %ld (see log).",
+                GMX_SIMD_ARM_SVE_LENGTH, svcntb() * 8));
+#endif
     }
 
     if (!logMsg.empty() && log != nullptr)
@@ -329,6 +356,12 @@ bool simdCheck(gmx::SimdType wanted, FILE* log, bool warnToStdErr)
     {
         fprintf(stderr, "%s\n", warnMsg.c_str());
     }
+#if GMX_SIMD_ARM_SVE
+    if ((compiled == SimdType::Arm_Sve) && (svcntb() != GMX_SIMD_ARM_SVE_LENGTH / 8))
+    {
+        gmx_exit_on_fatal_error(ExitType_Abort, 1);
+    }
+#endif
 
     return (wanted == compiled);
 }
index 1fd891658dfbb1909a2a859081dd59b12de491ce..2e108126749e06f8c8efc3f78a7cef4f7980f748 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -70,6 +70,7 @@ enum class SimdType
     X86_Mic,       //!< Knight's corner
     Arm_Neon,      //!< 32-bit ARM NEON
     Arm_NeonAsimd, //!< 64-bit ARM AArch64 Advanced SIMD
+    Arm_Sve,       //!< ARM Scalable Vector Extensions
     Ibm_Vmx,       //!< IBM VMX SIMD (Altivec on Power6 and later)
     Ibm_Vsx,       //!< IBM VSX SIMD (Power7 and later)
     Fujitsu_HpcAce //!< Fujitsu K-computer