Skip to content

Commit 812747d

Browse files
committed
Fix: Use machdep.cpu.brand_string
M1 chips don't support `bf16`, so we need to check the CPU name
1 parent c7952ad commit 812747d

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

include/simsimd/simsimd.h

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@
100100
#define SIMSIMD_DYNAMIC_DISPATCH (0) // true or false
101101
#endif
102102

103+
/* On Apple devices querying CPU feature registers is illegal, so we have import system libraries
104+
* and string-match the name of the CPU name to validate its functionality.
105+
*/
106+
#if __APPLE__
107+
#include <string.h>
108+
#include <sys/sysctl.h>
109+
#endif
110+
103111
#include "binary.h" // Hamming, Jaccard
104112
#include "dot.h" // Inner (dot) product, and its conjugate
105113
#include "geospatial.h" // Haversine and Vincenty
@@ -292,16 +300,22 @@ SIMSIMD_PUBLIC simsimd_capability_t simsimd_capabilities_implementation(void) {
292300

293301
#if SIMSIMD_TARGET_ARM
294302

295-
// Apple bans the use of the MRS instruction, so we hard-code the values
303+
// Apple bans the use of the MRS instruction, so we hard-code the values.
304+
// Only M2 and newer CPUs support `bf16`: https://github.com/corsix/amx/issues/5#issuecomment-1464639729
296305
#if __APPLE__
297-
return (simsimd_capability_t)( //
298-
(simsimd_cap_neon_k) | //
299-
(simsimd_cap_neon_f16_k) | //
300-
(simsimd_cap_neon_bf16_k) | //
301-
(simsimd_cap_neon_i8_k) | //
306+
char model[256];
307+
size_t size = sizeof(model);
308+
unsigned supports_bf16 = 0;
309+
if (sysctlbyname("machdep.cpu.brand_string", &model, &size, NULL, 0) == 0)
310+
supports_bf16 = strstr(model, "M1") == NULL;
311+
312+
return (simsimd_capability_t)( //
313+
(simsimd_cap_neon_k) | //
314+
(simsimd_cap_neon_f16_k) | //
315+
(simsimd_cap_neon_bf16_k * (supports_bf16)) | //
316+
(simsimd_cap_neon_i8_k) | //
302317
(simsimd_cap_serial_k));
303-
#endif
304-
318+
#else
305319
// This is how the `arm-cpusysregs` library does it:
306320
//
307321
// int ID_AA64ISAR1_EL1_BF16() const { return (int)(_aa64isar1 >> 44) & 0x0F; }
@@ -373,6 +387,7 @@ SIMSIMD_PUBLIC simsimd_capability_t simsimd_capabilities_implementation(void) {
373387
(simsimd_cap_sve_i8_k * (supports_sve && supports_sve_i8mm)) | //
374388
(simsimd_cap_serial_k));
375389

390+
#endif // not Apple :)
376391
#endif // SIMSIMD_TARGET_ARM
377392

378393
return simsimd_cap_serial_k;

0 commit comments

Comments
 (0)