Compute Library
 22.08
CpuIsaInfo.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
25 
26 #include "arm_compute/core/Error.h"
28 
29 /* Arm Feature flags */
30 #define ARM_COMPUTE_CPU_FEATURE_HWCAP_HALF (1 << 1)
31 #define ARM_COMPUTE_CPU_FEATURE_HWCAP_NEON (1 << 12)
32 
33 /* Arm64 Feature flags */
34 #define ARM_COMPUTE_CPU_FEATURE_HWCAP_ASIMD (1 << 1)
35 #define ARM_COMPUTE_CPU_FEATURE_HWCAP_FPHP (1 << 9)
36 #define ARM_COMPUTE_CPU_FEATURE_HWCAP_ASIMDHP (1 << 10)
37 #define ARM_COMPUTE_CPU_FEATURE_HWCAP_ASIMDDP (1 << 20)
38 #define ARM_COMPUTE_CPU_FEATURE_HWCAP_SVE (1 << 22)
39 #define ARM_COMPUTE_CPU_FEATURE_HWCAP2_SVE2 (1 << 1)
40 #define ARM_COMPUTE_CPU_FEATURE_HWCAP2_SVEI8MM (1 << 9)
41 #define ARM_COMPUTE_CPU_FEATURE_HWCAP2_SVEF32MM (1 << 10)
42 #define ARM_COMPUTE_CPU_FEATURE_HWCAP2_SVEBF16 (1 << 12)
43 #define ARM_COMPUTE_CPU_FEATURE_HWCAP2_I8MM (1 << 13)
44 #define ARM_COMPUTE_CPU_FEATURE_HWCAP2_BF16 (1 << 14)
45 
46 namespace arm_compute
47 {
48 namespace cpuinfo
49 {
50 namespace
51 {
52 inline bool is_feature_supported(uint64_t features, uint64_t feature_mask)
53 {
54  return (features & feature_mask);
55 }
56 
57 #if defined(__arm__)
58 void decode_hwcaps(CpuIsaInfo &isa, const uint32_t hwcaps, const uint32_t hwcaps2)
59 {
60  ARM_COMPUTE_UNUSED(hwcaps2);
61  isa.fp16 = is_feature_supported(hwcaps, ARM_COMPUTE_CPU_FEATURE_HWCAP_HALF);
62  isa.neon = is_feature_supported(hwcaps, ARM_COMPUTE_CPU_FEATURE_HWCAP_NEON);
63 }
64 #elif defined(__aarch64__)
65 void decode_hwcaps(CpuIsaInfo &isa, const uint32_t hwcaps, const uint32_t hwcaps2)
66 {
67  // High-level SIMD support
68  isa.neon = is_feature_supported(hwcaps, ARM_COMPUTE_CPU_FEATURE_HWCAP_ASIMD);
69  isa.sve = is_feature_supported(hwcaps, ARM_COMPUTE_CPU_FEATURE_HWCAP_SVE);
70  isa.sve2 = is_feature_supported(hwcaps2, ARM_COMPUTE_CPU_FEATURE_HWCAP2_SVE2);
71 
72  // Data-type support
73  isa.fp16 = is_feature_supported(hwcaps, ARM_COMPUTE_CPU_FEATURE_HWCAP_FPHP | ARM_COMPUTE_CPU_FEATURE_HWCAP_ASIMDHP);
74  isa.bf16 = is_feature_supported(hwcaps2, ARM_COMPUTE_CPU_FEATURE_HWCAP2_BF16);
75  isa.svebf16 = is_feature_supported(hwcaps2, ARM_COMPUTE_CPU_FEATURE_HWCAP2_SVEBF16);
76 
77  // Instruction extensions
78  isa.dot = is_feature_supported(hwcaps, ARM_COMPUTE_CPU_FEATURE_HWCAP_ASIMDDP);
79  isa.i8mm = is_feature_supported(hwcaps2, ARM_COMPUTE_CPU_FEATURE_HWCAP2_I8MM);
80  isa.svei8mm = is_feature_supported(hwcaps2, ARM_COMPUTE_CPU_FEATURE_HWCAP2_SVEI8MM);
81  isa.svef32mm = is_feature_supported(hwcaps2, ARM_COMPUTE_CPU_FEATURE_HWCAP2_SVEF32MM);
82 }
83 #else /* defined(__aarch64__) */
84 void decode_hwcaps(CpuIsaInfo &isa, const uint32_t hwcaps, const uint32_t hwcaps2)
85 {
86  ARM_COMPUTE_UNUSED(isa, hwcaps, hwcaps2);
87 }
88 #endif /* defined(__aarch64__) */
89 
90 void decode_regs(CpuIsaInfo &isa, const uint64_t isar0, const uint64_t isar1, const uint64_t pfr0, const uint64_t svefr0)
91 {
92  auto is_supported = [](uint64_t feature_reg, uint8_t feature_pos) -> bool
93  {
94  return ((feature_reg >> feature_pos) & 0xf);
95  };
96 
97  // High-level SIMD support
98  isa.sve = is_supported(pfr0, 32);
99  isa.sve2 = is_supported(svefr0, 0);
100 
101  // Data-type support
102  isa.fp16 = is_supported(pfr0, 16);
103  isa.bf16 = is_supported(isar1, 44);
104  isa.svebf16 = is_supported(svefr0, 20);
105 
106  // Instruction extensions
107  isa.dot = is_supported(isar0, 44);
108  isa.i8mm = is_supported(isar1, 48);
109  isa.svei8mm = is_supported(svefr0, 44);
110  isa.svef32mm = is_supported(svefr0, 52);
111 }
112 
113 /** Handle features from allow-listed models in case of problematic kernels
114  *
115  * @param[in, out] isa ISA to update
116  * @param[in] model CPU model type
117  */
118 void allowlisted_model_features(CpuIsaInfo &isa, CpuModel model)
119 {
120  if(isa.dot == false)
121  {
122  isa.dot = model_supports_dot(model);
123  }
124  if(isa.fp16 == false)
125  {
126  isa.fp16 = model_supports_fp16(model);
127  }
128 }
129 } // namespace
130 
131 CpuIsaInfo init_cpu_isa_from_hwcaps(uint32_t hwcaps, uint32_t hwcaps2, uint32_t midr)
132 {
133  CpuIsaInfo isa;
134 
135  decode_hwcaps(isa, hwcaps, hwcaps2);
136 
137  const CpuModel model = midr_to_model(midr);
138  allowlisted_model_features(isa, model);
139 
140  return isa;
141 }
142 
143 CpuIsaInfo init_cpu_isa_from_regs(uint64_t isar0, uint64_t isar1, uint64_t pfr0, uint64_t svefr0, uint64_t midr)
144 {
145  CpuIsaInfo isa;
146 
147  decode_regs(isa, isar0, isar1, pfr0, svefr0);
148 
149  const CpuModel model = midr_to_model(midr);
150  allowlisted_model_features(isa, model);
151 
152  return isa;
153 }
154 } // namespace cpuinfo
155 } // namespace arm_compute
#define ARM_COMPUTE_CPU_FEATURE_HWCAP2_I8MM
Definition: CpuIsaInfo.cpp:43
#define ARM_COMPUTE_CPU_FEATURE_HWCAP_HALF
Definition: CpuIsaInfo.cpp:30
#define ARM_COMPUTE_CPU_FEATURE_HWCAP2_SVEI8MM
Definition: CpuIsaInfo.cpp:40
#define ARM_COMPUTE_CPU_FEATURE_HWCAP2_SVE2
Definition: CpuIsaInfo.cpp:39
arm_compute::CPUModel CpuModel
Definition: CpuModel.h:36
bool is_supported(const PoolingArgs &args, const Nothing &)
CPUModel
CPU models types.
Definition: CPPTypes.h:58
#define ARM_COMPUTE_CPU_FEATURE_HWCAP2_SVEBF16
Definition: CpuIsaInfo.cpp:42
#define ARM_COMPUTE_CPU_FEATURE_HWCAP_ASIMDHP
Definition: CpuIsaInfo.cpp:36
cpuinfo::CpuIsaInfo isa
Copyright (c) 2017-2022 Arm Limited.
bool model_supports_fp16(CpuModel model)
Check if a model supports half-precision floating point arithmetic.
Definition: CpuModel.cpp:46
CPU ISA (Instruction Set Architecture) information.
Definition: CpuIsaInfo.h:37
bool model_supports_dot(CpuModel model)
Check if a model supports dot product.
Definition: CpuModel.cpp:63
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:152
#define ARM_COMPUTE_CPU_FEATURE_HWCAP_SVE
Definition: CpuIsaInfo.cpp:38
CpuIsaInfo init_cpu_isa_from_hwcaps(uint32_t hwcaps, uint32_t hwcaps2, uint32_t midr)
Identify ISA related information through system information.
Definition: CpuIsaInfo.cpp:131
#define ARM_COMPUTE_CPU_FEATURE_HWCAP_ASIMDDP
Definition: CpuIsaInfo.cpp:37
#define ARM_COMPUTE_CPU_FEATURE_HWCAP_NEON
Definition: CpuIsaInfo.cpp:31
#define ARM_COMPUTE_CPU_FEATURE_HWCAP2_SVEF32MM
Definition: CpuIsaInfo.cpp:41
#define ARM_COMPUTE_CPU_FEATURE_HWCAP_ASIMD
Definition: CpuIsaInfo.cpp:34
#define ARM_COMPUTE_CPU_FEATURE_HWCAP_FPHP
Definition: CpuIsaInfo.cpp:35
#define ARM_COMPUTE_CPU_FEATURE_HWCAP2_BF16
Definition: CpuIsaInfo.cpp:44
CpuIsaInfo init_cpu_isa_from_regs(uint64_t isar0, uint64_t isar1, uint64_t pfr0, uint64_t svefr0, uint64_t midr)
Identify ISA related information through register information.
Definition: CpuIsaInfo.cpp:143
CpuModel midr_to_model(uint32_t midr)
Extract the model type from the MIDR value.
Definition: CpuModel.cpp:78