1#include "ggml-backend-impl.h"
2
3#if defined(__aarch64__)
4
5#if defined(__linux__)
6#include <sys/auxv.h>
7#elif defined(__APPLE__)
8#include <sys/sysctl.h>
9#endif
10
11#if !defined(HWCAP2_SVE2)
12#define HWCAP2_SVE2 (1 << 1)
13#endif
14
15#if !defined(HWCAP2_I8MM)
16#define HWCAP2_I8MM (1 << 13)
17#endif
18
19#if !defined(HWCAP2_SME)
20#define HWCAP2_SME (1 << 23)
21#endif
22
23struct aarch64_features {
24 // has_neon not needed, aarch64 has NEON guaranteed
25 bool has_dotprod = false;
26 bool has_fp16_va = false;
27 bool has_sve = false;
28 bool has_sve2 = false;
29 bool has_i8mm = false;
30 bool has_sme = false;
31
32 aarch64_features() {
33#if defined(__linux__)
34 uint32_t hwcap = getauxval(AT_HWCAP);
35 uint32_t hwcap2 = getauxval(AT_HWCAP2);
36
37 has_dotprod = !!(hwcap & HWCAP_ASIMDDP);
38 has_fp16_va = !!(hwcap & HWCAP_FPHP);
39 has_sve = !!(hwcap & HWCAP_SVE);
40 has_sve2 = !!(hwcap2 & HWCAP2_SVE2);
41 has_i8mm = !!(hwcap2 & HWCAP2_I8MM);
42 has_sme = !!(hwcap2 & HWCAP2_SME);
43#elif defined(__APPLE__)
44 int oldp = 0;
45 size_t size = sizeof(oldp);
46
47 if (sysctlbyname("hw.optional.arm.FEAT_DotProd", &oldp, &size, NULL, 0) == 0) {
48 has_dotprod = static_cast<bool>(oldp);
49 }
50
51 if (sysctlbyname("hw.optional.arm.FEAT_I8MM", &oldp, &size, NULL, 0) == 0) {
52 has_i8mm = static_cast<bool>(oldp);
53 }
54
55 if (sysctlbyname("hw.optional.arm.FEAT_SME", &oldp, &size, NULL, 0) == 0) {
56 has_sme = static_cast<bool>(oldp);
57 }
58
59 // Apple apparently does not implement SVE yet
60#endif
61 }
62};
63
64static int ggml_backend_cpu_aarch64_score() {
65 int score = 1;
66 aarch64_features af;
67
68#ifdef GGML_USE_DOTPROD
69 if (!af.has_dotprod) { return 0; }
70 score += 1<<1;
71#endif
72#ifdef GGML_USE_FP16_VECTOR_ARITHMETIC
73 if (!af.has_fp16_va) { return 0; }
74 score += 1<<2;
75#endif
76#ifdef GGML_USE_SVE
77 if (!af.has_sve) { return 0; }
78 score += 1<<3;
79#endif
80#ifdef GGML_USE_MATMUL_INT8
81 if (!af.has_i8mm) { return 0; }
82 score += 1<<4;
83#endif
84#ifdef GGML_USE_SVE2
85 if (!af.has_sve2) { return 0; }
86 score += 1<<5;
87#endif
88#ifdef GGML_USE_SME
89 if (!af.has_sme) { return 0; }
90 score += 1<<6;
91#endif
92
93 return score;
94}
95
96GGML_BACKEND_DL_SCORE_IMPL(ggml_backend_cpu_aarch64_score)
97
98# endif // defined(__aarch64__)