"GenuineIntel",
"AuthenticAMD",
"Fujitsu",
- "IBM",
+ "IBM", /* Used on Power and BlueGene/Q */
"ARM"
};
"GenuineIntel",
"AuthenticAMD",
"Fujitsu",
- "ibm", /* Used on BlueGene/Q */
+ "ibm", /* Used on Power and BlueGene/Q */
"AArch64"
};
"x2apic",
"xop",
"arm_neon",
- "arm_neon_asimd"
+ "arm_neon_asimd",
+ "QPX",
+ "VMX"
};
const char *
"AVX2_256",
"Sparc64 HPC-ACE",
"IBM_QPX",
+ "IBM_VMX",
"ARM_NEON",
"ARM_NEON_ASIMD"
};
static const enum gmx_cpuid_simd compiled_simd = GMX_CPUID_SIMD_SPARC64_HPC_ACE;
#elif defined GMX_SIMD_IBM_QPX
static const enum gmx_cpuid_simd compiled_simd = GMX_CPUID_SIMD_IBM_QPX;
+#elif defined GMX_SIMD_IBM_VMX
+static const enum gmx_cpuid_simd compiled_simd = GMX_CPUID_SIMD_IBM_VMX;
#elif defined GMX_SIMD_REFERENCE
static const enum gmx_cpuid_simd compiled_simd = GMX_CPUID_SIMD_REFERENCE;
#else
}
+static int
+cpuid_check_ibm(gmx_cpuid_t cpuid)
+{
+#if defined(__linux__) || defined(__linux)
+ FILE *fp;
+ char buffer[GMX_CPUID_STRLEN], before_colon[GMX_CPUID_STRLEN], after_colon[GMX_CPUID_STRLEN];
+
+ if ( (fp = fopen("/proc/cpuinfo", "r")) != NULL)
+ {
+ while ( (fgets(buffer, sizeof(buffer), fp) != NULL))
+ {
+ chomp_substring_before_colon(buffer, before_colon, GMX_CPUID_STRLEN);
+ chomp_substring_after_colon(buffer, after_colon, GMX_CPUID_STRLEN);
+
+ if (!strcmp(before_colon, "model name") ||
+ !strcmp(before_colon, "model") ||
+ !strcmp(before_colon, "Processor") ||
+ !strcmp(before_colon, "cpu"))
+ {
+ strncpy(cpuid->brand, after_colon, GMX_CPUID_STRLEN);
+
+ if (strstr(after_colon, "altivec"))
+ {
+ cpuid->feature[GMX_CPUID_FEATURE_IBM_VMX] = 1;
+ }
+ }
+ }
+ }
+ fclose(fp);
+
+ if (strstr(cpuid->brand, "A2"))
+ {
+ /* BlueGene/Q */
+ cpuid->feature[GMX_CPUID_FEATURE_IBM_QPX] = 1;
+ }
+#else
+ strncpy(cpuid->brand, "Unknown CPU brand", GMX_CPUID_STRLEN);
+ cpuid->feature[GMX_CPUID_FEATURE_IBM_QPX] = 0;
+ cpuid->feature[GMX_CPUID_FEATURE_IBM_VMX] = 0;
+#endif
+ return 0;
+}
+
+
/* Try to find the vendor of the current CPU, so we know what specific
* detection routine to call.
*/
while ( (vendor == GMX_CPUID_VENDOR_UNKNOWN) && (fgets(buffer, sizeof(buffer), fp) != NULL))
{
chomp_substring_before_colon(buffer, before_colon, sizeof(before_colon));
- /* Intel/AMD use "vendor_id", IBM "vendor"(?) or "model". Fujitsu "manufacture".
+ /* Intel/AMD use "vendor_id", IBM "vendor", "model", or "cpu". Fujitsu "manufacture".
* 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!
*/
|| !strcmp(before_colon, "vendor")
|| !strcmp(before_colon, "manufacture")
|| !strcmp(before_colon, "model")
- || !strcmp(before_colon, "Processor"))
+ || !strcmp(before_colon, "Processor")
+ || !strcmp(before_colon, "cpu"))
{
chomp_substring_after_colon(buffer, after_colon, sizeof(after_colon));
for (i = GMX_CPUID_VENDOR_UNKNOWN; i < GMX_CPUID_NVENDORS; i++)
vendor = i;
}
}
+ /* If we did not find vendor yet, check if it is IBM:
+ * On some Power/PowerPC systems it only says power, not IBM.
+ */
+ if (vendor == GMX_CPUID_VENDOR_UNKNOWN &&
+ ((strstr(after_colon, "POWER") || strstr(after_colon, "Power") ||
+ strstr(after_colon, "power"))))
+ {
+ vendor = GMX_CPUID_VENDOR_IBM;
+ }
}
}
}
case GMX_CPUID_VENDOR_ARM:
cpuid_check_arm(cpuid);
break;
+ case GMX_CPUID_VENDOR_IBM:
+ cpuid_check_ibm(cpuid);
+ break;
default:
/* Default value */
strncpy(cpuid->brand, "Unknown CPU brand", GMX_CPUID_STRLEN);
}
else if (gmx_cpuid_vendor(cpuid) == GMX_CPUID_VENDOR_IBM)
{
- if (strstr(gmx_cpuid_brand(cpuid), "A2"))
+ if (gmx_cpuid_feature(cpuid, GMX_CPUID_FEATURE_IBM_QPX))
{
tmpsimd = GMX_CPUID_SIMD_IBM_QPX;
}
+ else if (gmx_cpuid_feature(cpuid, GMX_CPUID_FEATURE_IBM_VMX))
+ {
+ tmpsimd = GMX_CPUID_SIMD_IBM_VMX;
+ }
}
else if (gmx_cpuid_vendor(cpuid) == GMX_CPUID_VENDOR_ARM)
{