|
100 | 100 | #define SIMSIMD_DYNAMIC_DISPATCH (0) // true or false
|
101 | 101 | #endif
|
102 | 102 |
|
| 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 | + |
103 | 111 | #include "binary.h" // Hamming, Jaccard
|
104 | 112 | #include "dot.h" // Inner (dot) product, and its conjugate
|
105 | 113 | #include "geospatial.h" // Haversine and Vincenty
|
@@ -292,16 +300,22 @@ SIMSIMD_PUBLIC simsimd_capability_t simsimd_capabilities_implementation(void) {
|
292 | 300 |
|
293 | 301 | #if SIMSIMD_TARGET_ARM
|
294 | 302 |
|
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 |
296 | 305 | #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) | // |
302 | 317 | (simsimd_cap_serial_k));
|
303 |
| -#endif |
304 |
| - |
| 318 | +#else |
305 | 319 | // This is how the `arm-cpusysregs` library does it:
|
306 | 320 | //
|
307 | 321 | // int ID_AA64ISAR1_EL1_BF16() const { return (int)(_aa64isar1 >> 44) & 0x0F; }
|
@@ -373,6 +387,7 @@ SIMSIMD_PUBLIC simsimd_capability_t simsimd_capabilities_implementation(void) {
|
373 | 387 | (simsimd_cap_sve_i8_k * (supports_sve && supports_sve_i8mm)) | //
|
374 | 388 | (simsimd_cap_serial_k));
|
375 | 389 |
|
| 390 | +#endif // not Apple :) |
376 | 391 | #endif // SIMSIMD_TARGET_ARM
|
377 | 392 |
|
378 | 393 | return simsimd_cap_serial_k;
|
|
0 commit comments