Move _GNU_SOURCE to gmxpre.h
[alexxy/gromacs.git] / src / gromacs / gmxlib / gmx_cpuid.c
index 6fd35c42f93176dabc059d540d4238686f417af1..3ea2d42c4032442e9afbc324c83be739edec9689 100644 (file)
  */
 #include "gmxpre.h"
 
+#include "gromacs/legacyheaders/gmx_cpuid.h"
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#ifdef HAVE_SCHED_H
-#  ifndef _GNU_SOURCE
-#    define _GNU_SOURCE 1
-#  endif
-#  include <sched.h>
-#endif
-
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
+
 #ifdef GMX_NATIVE_WINDOWS
 /* MSVC definition for __cpuid() */
     #ifdef _MSC_VER
 /* sysinfo functions */
     #include <windows.h>
 #endif
+#ifdef HAVE_SCHED_H
+    #include <sched.h>
+#endif
 #ifdef HAVE_UNISTD_H
 /* sysconf() definition */
     #include <unistd.h>
 #endif
 
-#include "gromacs/legacyheaders/gmx_cpuid.h"
-
-
 
 /* For convenience, and to enable configure-time invocation, we keep all architectures
  * in a single file, but to avoid repeated ifdefs we set the overall architecture here.
@@ -98,7 +94,7 @@ gmx_cpuid_vendor_string_alternative[GMX_CPUID_NVENDORS] =
     "AuthenticAMD",
     "Fujitsu",
     "ibm", /* Used on BlueGene/Q */
-    "arm"
+    "AArch64"
 };
 
 const char *
@@ -139,7 +135,8 @@ gmx_cpuid_feature_string[GMX_CPUID_NFEATURES] =
     "tdt",
     "x2apic",
     "xop",
-    "arm_neon"
+    "arm_neon",
+    "arm_neon_asimd"
 };
 
 const char *
@@ -155,7 +152,8 @@ gmx_cpuid_simd_string[GMX_CPUID_NSIMD] =
     "AVX2_256",
     "Sparc64 HPC-ACE",
     "IBM_QPX",
-    "ARM_NEON"
+    "ARM_NEON",
+    "ARM_NEON_ASIMD"
 };
 
 /* Max length of brand string */
@@ -246,6 +244,8 @@ static const enum gmx_cpuid_simd compiled_simd = GMX_CPUID_SIMD_X86_SSE4_1;
 static const enum gmx_cpuid_simd compiled_simd = GMX_CPUID_SIMD_X86_SSE2;
 #elif defined GMX_SIMD_ARM_NEON
 static const enum gmx_cpuid_simd compiled_simd = GMX_CPUID_SIMD_ARM_NEON;
+#elif defined GMX_SIMD_ARM_NEON_ASIMD
+static const enum gmx_cpuid_simd compiled_simd = GMX_CPUID_SIMD_ARM_NEON_ASIMD;
 #elif defined GMX_SIMD_SPARC64_HPC_ACE
 static const enum gmx_cpuid_simd compiled_simd = GMX_CPUID_SIMD_SPARC64_HPC_ACE;
 #elif defined GMX_SIMD_IBM_QPX
@@ -803,6 +803,10 @@ cpuid_check_arm(gmx_cpuid_t                cpuid)
             else if (!strcmp(buffer2, "CPU architecture"))
             {
                 cpuid->family = strtol(buffer3, NULL, 10);
+                if (!strcmp(buffer3, "AArch64"))
+                {
+                    cpuid->family = 8;
+                }
             }
             else if (!strcmp(buffer2, "CPU part"))
             {
@@ -816,16 +820,28 @@ cpuid_check_arm(gmx_cpuid_t                cpuid)
             {
                 cpuid->feature[GMX_CPUID_FEATURE_ARM_NEON] = 1;
             }
+            else if (!strcmp(buffer2, "Features") && strstr(buffer3, "asimd"))
+            {
+                cpuid->feature[GMX_CPUID_FEATURE_ARM_NEON_ASIMD] = 1;
+            }
         }
     }
     fclose(fp);
 #else
-    /* Strange non-linux platform. We cannot assume that neon is present. */
+#    ifdef __aarch64__
+    /* Strange 64-bit non-linux platform. However, since NEON ASIMD is present on all
+     * implementations of AArch64 this far, we assume it is present for now.
+     */
+    cpuid->feature[GMX_CPUID_FEATURE_ARM_NEON_ASIMD] = 1;
+#    else
+    /* Strange 32-bit non-linux platform. We cannot assume that neon is present. */
     cpuid->feature[GMX_CPUID_FEATURE_ARM_NEON] = 0;
+#    endif
 #endif
     return 0;
 }
 
+
 /* Try to find the vendor of the current CPU, so we know what specific
  * detection routine to call.
  */
@@ -868,7 +884,7 @@ cpuid_check_vendor(void)
         {
             chomp_substring_before_colon(buffer, before_colon, sizeof(before_colon));
             /* Intel/AMD use "vendor_id", IBM "vendor"(?) or "model". Fujitsu "manufacture".
-             * On ARM there does not seem to be a vendor, but ARM is listed in the Processor string.
+             * On ARM there does not seem to be a vendor, but ARM or AArch64 is listed in the Processor string.
              * Add others if you have them!
              */
             if (!strcmp(before_colon, "vendor_id")
@@ -893,14 +909,12 @@ cpuid_check_vendor(void)
         }
     }
     fclose(fp);
-#elif defined(__arm__) || defined (__arm)
+#elif defined(__arm__) || defined (__arm) || defined(__aarch64__)
     /* If we are using ARM on something that is not linux we have to trust the compiler,
      * and we cannot get the extra info that might be present in /proc/cpuinfo.
-     * This path will not trigger 64-bit arm, which is identified by __aarch64__ instead.
      */
     vendor = GMX_CPUID_VENDOR_ARM;
 #endif
-
     return vendor;
 }
 
@@ -1165,7 +1179,11 @@ gmx_cpuid_simd_suggest  (gmx_cpuid_t                 cpuid)
     }
     else if (gmx_cpuid_vendor(cpuid) == GMX_CPUID_VENDOR_ARM)
     {
-        if (gmx_cpuid_feature(cpuid, GMX_CPUID_FEATURE_ARM_NEON))
+        if (gmx_cpuid_feature(cpuid, GMX_CPUID_FEATURE_ARM_NEON_ASIMD))
+        {
+            tmpsimd = GMX_CPUID_SIMD_ARM_NEON_ASIMD;
+        }
+        else if (gmx_cpuid_feature(cpuid, GMX_CPUID_FEATURE_ARM_NEON))
         {
             tmpsimd = GMX_CPUID_SIMD_ARM_NEON;
         }