|
129 | 129 | #define _SIMSIMD_HAS_POSIX_EXTENSIONS 0 |
130 | 130 | #endif |
131 | 131 |
|
| 132 | +// On Windows ARM, we use IsProcessorFeaturePresent API for capability detection |
| 133 | +#if defined(_SIMSIMD_DEFINED_WINDOWS) && _SIMSIMD_TARGET_ARM |
| 134 | +#include <processthreadsapi.h> // `IsProcessorFeaturePresent` |
| 135 | +#endif |
| 136 | + |
132 | 137 | #ifdef __cplusplus |
133 | 138 | extern "C" { |
134 | 139 | #endif |
@@ -613,8 +618,25 @@ SIMSIMD_PUBLIC simsimd_capability_t _simsimd_capabilities_arm(void) { |
613 | 618 | (simsimd_cap_sve2_k * (supports_sve2)) | // |
614 | 619 | (simsimd_cap_sve2p1_k * (supports_sve2p1)) | // |
615 | 620 | (simsimd_cap_serial_k)); |
616 | | -#else // if !_SIMSIMD_DEFINED_LINUX |
617 | | - return simsimd_cap_serial_k; |
| 621 | + |
| 622 | +#elif defined(_SIMSIMD_DEFINED_WINDOWS) |
| 623 | + |
| 624 | + // On Windows ARM, use the `IsProcessorFeaturePresent` API for capability detection. |
| 625 | + // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent |
| 626 | + unsigned supports_neon = IsProcessorFeaturePresent(PF_ARM_V8_INSTRUCTIONS_AVAILABLE); |
| 627 | + unsigned supports_dp = IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE); |
| 628 | + |
| 629 | + // Windows API doesn't provide reliable detection for FP16, BF16. |
| 630 | + return (simsimd_capability_t)( // |
| 631 | + (simsimd_cap_neon_k * (supports_neon)) | // |
| 632 | + (simsimd_cap_neon_i8_k * (supports_neon && supports_dp)) | // |
| 633 | + (simsimd_cap_serial_k)); |
| 634 | + |
| 635 | +#else // Unknown platform |
| 636 | + |
| 637 | + // Conservative fallback for unknown platforms: NEON is mandatory in ARMv8-A (ARM64) |
| 638 | + return (simsimd_capability_t)(simsimd_cap_neon_k | simsimd_cap_serial_k); |
| 639 | + |
618 | 640 | #endif |
619 | 641 | } |
620 | 642 |
|
|
0 commit comments