1*4bdc9457SAndroid Build Coastguard Worker // Copyright 2019 Google LLC
2*4bdc9457SAndroid Build Coastguard Worker //
3*4bdc9457SAndroid Build Coastguard Worker // This source code is licensed under the BSD-style license found in the
4*4bdc9457SAndroid Build Coastguard Worker // LICENSE file in the root directory of this source tree.
5*4bdc9457SAndroid Build Coastguard Worker
6*4bdc9457SAndroid Build Coastguard Worker #pragma once
7*4bdc9457SAndroid Build Coastguard Worker
8*4bdc9457SAndroid Build Coastguard Worker #include <cstddef>
9*4bdc9457SAndroid Build Coastguard Worker #include <cstdint>
10*4bdc9457SAndroid Build Coastguard Worker
11*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack.h>
12*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/allocator.h>
13*4bdc9457SAndroid Build Coastguard Worker
14*4bdc9457SAndroid Build Coastguard Worker #include <benchmark/benchmark.h>
15*4bdc9457SAndroid Build Coastguard Worker
16*4bdc9457SAndroid Build Coastguard Worker namespace benchmark {
17*4bdc9457SAndroid Build Coastguard Worker namespace utils {
18*4bdc9457SAndroid Build Coastguard Worker
19*4bdc9457SAndroid Build Coastguard Worker uint32_t WipeCache();
20*4bdc9457SAndroid Build Coastguard Worker uint32_t PrefetchToL1(const void* ptr, size_t size);
21*4bdc9457SAndroid Build Coastguard Worker
22*4bdc9457SAndroid Build Coastguard Worker // Disable support for denormalized numbers in floating-point units.
23*4bdc9457SAndroid Build Coastguard Worker void DisableDenormals();
24*4bdc9457SAndroid Build Coastguard Worker
25*4bdc9457SAndroid Build Coastguard Worker // Return clock rate, in Hz, for the currently used logical processor.
26*4bdc9457SAndroid Build Coastguard Worker uint64_t GetCurrentCpuFrequency();
27*4bdc9457SAndroid Build Coastguard Worker
28*4bdc9457SAndroid Build Coastguard Worker // Return maximum (across all cores/clusters/sockets) last level cache size.
29*4bdc9457SAndroid Build Coastguard Worker // Can overestimate, but not underestimate LLC size.
30*4bdc9457SAndroid Build Coastguard Worker size_t GetMaxCacheSize();
31*4bdc9457SAndroid Build Coastguard Worker
32*4bdc9457SAndroid Build Coastguard Worker // Set number of elements for a unary elementwise microkernel such that:
33*4bdc9457SAndroid Build Coastguard Worker // - It is divisible by 2, 3, 4, 5, 6.
34*4bdc9457SAndroid Build Coastguard Worker // - It is divisible by AVX512 width.
35*4bdc9457SAndroid Build Coastguard Worker // - Total memory footprint does not exceed the characteristic cache size for
36*4bdc9457SAndroid Build Coastguard Worker // the architecture.
37*4bdc9457SAndroid Build Coastguard Worker template<class InType, class OutType>
UnaryElementwiseParameters(benchmark::internal::Benchmark * benchmark)38*4bdc9457SAndroid Build Coastguard Worker void UnaryElementwiseParameters(benchmark::internal::Benchmark* benchmark) {
39*4bdc9457SAndroid Build Coastguard Worker benchmark->ArgName("N");
40*4bdc9457SAndroid Build Coastguard Worker
41*4bdc9457SAndroid Build Coastguard Worker size_t characteristic_l1 = 32 * 1024;
42*4bdc9457SAndroid Build Coastguard Worker size_t characteristic_l2 = 256 * 1024;
43*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_ARM
44*4bdc9457SAndroid Build Coastguard Worker characteristic_l1 = 16 * 1024;
45*4bdc9457SAndroid Build Coastguard Worker characteristic_l2 = 128 * 1024;
46*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_ARM
47*4bdc9457SAndroid Build Coastguard Worker
48*4bdc9457SAndroid Build Coastguard Worker const size_t elementwise_size = sizeof(InType) + sizeof(OutType);
49*4bdc9457SAndroid Build Coastguard Worker benchmark->Arg(characteristic_l1 / elementwise_size / 960 * 960);
50*4bdc9457SAndroid Build Coastguard Worker benchmark->Arg(characteristic_l2 / elementwise_size / 960 * 960);
51*4bdc9457SAndroid Build Coastguard Worker }
52*4bdc9457SAndroid Build Coastguard Worker
53*4bdc9457SAndroid Build Coastguard Worker // Set number of elements for a binary elementwise microkernel such that:
54*4bdc9457SAndroid Build Coastguard Worker // - It is divisible by 2, 3, 4, 5, 6.
55*4bdc9457SAndroid Build Coastguard Worker // - It is divisible by AVX512 width.
56*4bdc9457SAndroid Build Coastguard Worker // - Total memory footprint does not exceed the characteristic cache size for
57*4bdc9457SAndroid Build Coastguard Worker // the architecture.
58*4bdc9457SAndroid Build Coastguard Worker template<class InType, class OutType>
BinaryElementwiseParameters(benchmark::internal::Benchmark * benchmark)59*4bdc9457SAndroid Build Coastguard Worker void BinaryElementwiseParameters(benchmark::internal::Benchmark* benchmark) {
60*4bdc9457SAndroid Build Coastguard Worker benchmark->ArgName("N");
61*4bdc9457SAndroid Build Coastguard Worker
62*4bdc9457SAndroid Build Coastguard Worker size_t characteristic_l1 = 32 * 1024;
63*4bdc9457SAndroid Build Coastguard Worker size_t characteristic_l2 = 256 * 1024;
64*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_ARM
65*4bdc9457SAndroid Build Coastguard Worker characteristic_l1 = 16 * 1024;
66*4bdc9457SAndroid Build Coastguard Worker characteristic_l2 = 128 * 1024;
67*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_ARM
68*4bdc9457SAndroid Build Coastguard Worker
69*4bdc9457SAndroid Build Coastguard Worker const size_t elementwise_size = 2 * sizeof(InType) + sizeof(OutType);
70*4bdc9457SAndroid Build Coastguard Worker benchmark->Arg(characteristic_l1 / elementwise_size / 960 * 960);
71*4bdc9457SAndroid Build Coastguard Worker benchmark->Arg(characteristic_l2 / elementwise_size / 960 * 960);
72*4bdc9457SAndroid Build Coastguard Worker }
73*4bdc9457SAndroid Build Coastguard Worker
74*4bdc9457SAndroid Build Coastguard Worker // Set multi-threading parameters appropriate for the processor.
75*4bdc9457SAndroid Build Coastguard Worker void MultiThreadingParameters(benchmark::internal::Benchmark* benchmark);
76*4bdc9457SAndroid Build Coastguard Worker
77*4bdc9457SAndroid Build Coastguard Worker typedef bool (*IsaCheckFunction)(benchmark::State& state);
78*4bdc9457SAndroid Build Coastguard Worker
79*4bdc9457SAndroid Build Coastguard Worker // Check if either ARM VFPv2 or VFPv3 extension is supported.
80*4bdc9457SAndroid Build Coastguard Worker // If VFP is unsupported, report error in benchmark state, and return false.
81*4bdc9457SAndroid Build Coastguard Worker bool CheckVFP(benchmark::State& state);
82*4bdc9457SAndroid Build Coastguard Worker
83*4bdc9457SAndroid Build Coastguard Worker // Check if ARMv6 extensions are supported.
84*4bdc9457SAndroid Build Coastguard Worker // If ARMv6 extensions are unsupported, report error in benchmark state, and return false.
85*4bdc9457SAndroid Build Coastguard Worker bool CheckARMV6(benchmark::State& state);
86*4bdc9457SAndroid Build Coastguard Worker
87*4bdc9457SAndroid Build Coastguard Worker // Check if ARM NEON extension is supported.
88*4bdc9457SAndroid Build Coastguard Worker // If NEON is unsupported, report error in benchmark state, and return false.
89*4bdc9457SAndroid Build Coastguard Worker bool CheckNEON(benchmark::State& state);
90*4bdc9457SAndroid Build Coastguard Worker
91*4bdc9457SAndroid Build Coastguard Worker // Check if ARM NEON-FP16 extension is supported.
92*4bdc9457SAndroid Build Coastguard Worker // If NEON-FP16 is unsupported, report error in benchmark state, and return false.
93*4bdc9457SAndroid Build Coastguard Worker bool CheckNEONFP16(benchmark::State& state);
94*4bdc9457SAndroid Build Coastguard Worker
95*4bdc9457SAndroid Build Coastguard Worker // Check if ARM NEON-FMA extension is supported.
96*4bdc9457SAndroid Build Coastguard Worker // If NEON-FMA is unsupported, report error in benchmark state, and return false.
97*4bdc9457SAndroid Build Coastguard Worker bool CheckNEONFMA(benchmark::State& state);
98*4bdc9457SAndroid Build Coastguard Worker
99*4bdc9457SAndroid Build Coastguard Worker // Check if ARMv8 NEON instructions are supported.
100*4bdc9457SAndroid Build Coastguard Worker // If ARMv8 NEON is unsupported, report error in benchmark state, and return false.
101*4bdc9457SAndroid Build Coastguard Worker bool CheckNEONV8(benchmark::State& state);
102*4bdc9457SAndroid Build Coastguard Worker
103*4bdc9457SAndroid Build Coastguard Worker // Check if ARM NEON-FP16-ARITH extension is supported.
104*4bdc9457SAndroid Build Coastguard Worker // If NEON-FP16-ARITH is unsupported, report error in benchmark state, and return false.
105*4bdc9457SAndroid Build Coastguard Worker bool CheckNEONFP16ARITH(benchmark::State& state);
106*4bdc9457SAndroid Build Coastguard Worker
107*4bdc9457SAndroid Build Coastguard Worker // Check if ARM NEON-BF16 extension is supported.
108*4bdc9457SAndroid Build Coastguard Worker // If NEON-BF16 is unsupported, report error in benchmark state, and return false.
109*4bdc9457SAndroid Build Coastguard Worker bool CheckNEONBF16(benchmark::State& state);
110*4bdc9457SAndroid Build Coastguard Worker
111*4bdc9457SAndroid Build Coastguard Worker // Check if ARM DOT extension is supported.
112*4bdc9457SAndroid Build Coastguard Worker // If DOT is unsupported, report error in benchmark state, and return false.
113*4bdc9457SAndroid Build Coastguard Worker bool CheckNEONDOT(benchmark::State& state);
114*4bdc9457SAndroid Build Coastguard Worker
115*4bdc9457SAndroid Build Coastguard Worker // Check if x86 SSSE3 extension is supported.
116*4bdc9457SAndroid Build Coastguard Worker // If SSSE3 is unsupported, report error in benchmark state, and return false.
117*4bdc9457SAndroid Build Coastguard Worker bool CheckSSSE3(benchmark::State& state);
118*4bdc9457SAndroid Build Coastguard Worker
119*4bdc9457SAndroid Build Coastguard Worker // Check if x86 SSE4.1 extension is supported.
120*4bdc9457SAndroid Build Coastguard Worker // If SSE4.1 is unsupported, report error in benchmark state, and return false.
121*4bdc9457SAndroid Build Coastguard Worker bool CheckSSE41(benchmark::State& state);
122*4bdc9457SAndroid Build Coastguard Worker
123*4bdc9457SAndroid Build Coastguard Worker // Check if x86 AVX extension is supported.
124*4bdc9457SAndroid Build Coastguard Worker // If AVX is unsupported, report error in benchmark state, and return false.
125*4bdc9457SAndroid Build Coastguard Worker bool CheckAVX(benchmark::State& state);
126*4bdc9457SAndroid Build Coastguard Worker
127*4bdc9457SAndroid Build Coastguard Worker // Check if x86 F16C extension is supported.
128*4bdc9457SAndroid Build Coastguard Worker // If F16C is unsupported, report error in benchmark state, and return false.
129*4bdc9457SAndroid Build Coastguard Worker bool CheckF16C(benchmark::State& state);
130*4bdc9457SAndroid Build Coastguard Worker
131*4bdc9457SAndroid Build Coastguard Worker // Check if x86 XOP extension is supported.
132*4bdc9457SAndroid Build Coastguard Worker // If XOP is unsupported, report error in benchmark state, and return false.
133*4bdc9457SAndroid Build Coastguard Worker bool CheckXOP(benchmark::State& state);
134*4bdc9457SAndroid Build Coastguard Worker
135*4bdc9457SAndroid Build Coastguard Worker // Check if x86 FMA3 extension is supported.
136*4bdc9457SAndroid Build Coastguard Worker // If FMA3 is unsupported, report error in benchmark state, and return false.
137*4bdc9457SAndroid Build Coastguard Worker bool CheckFMA3(benchmark::State& state);
138*4bdc9457SAndroid Build Coastguard Worker
139*4bdc9457SAndroid Build Coastguard Worker // Check if x86 AVX2 extension is supported.
140*4bdc9457SAndroid Build Coastguard Worker // If AVX2 is unsupported, report error in benchmark state, and return false.
141*4bdc9457SAndroid Build Coastguard Worker bool CheckAVX2(benchmark::State& state);
142*4bdc9457SAndroid Build Coastguard Worker
143*4bdc9457SAndroid Build Coastguard Worker // Check if x86 AVX512F extension is supported.
144*4bdc9457SAndroid Build Coastguard Worker // If AVX512F is unsupported, report error in benchmark state, and return false.
145*4bdc9457SAndroid Build Coastguard Worker bool CheckAVX512F(benchmark::State& state);
146*4bdc9457SAndroid Build Coastguard Worker
147*4bdc9457SAndroid Build Coastguard Worker // Check if x86 SKX-level AVX512 extensions (AVX512F, AVX512CD, AVX512BW, AVX512DQ, and AVX512VL) are supported.
148*4bdc9457SAndroid Build Coastguard Worker // If SKX-level AVX512 extensions are unsupported, report error in benchmark state, and return false.
149*4bdc9457SAndroid Build Coastguard Worker bool CheckAVX512SKX(benchmark::State& state);
150*4bdc9457SAndroid Build Coastguard Worker
151*4bdc9457SAndroid Build Coastguard Worker template <class T>
DivideRoundUp(T x,T q)152*4bdc9457SAndroid Build Coastguard Worker inline T DivideRoundUp(T x, T q) {
153*4bdc9457SAndroid Build Coastguard Worker return x / q + T(x % q != 0);
154*4bdc9457SAndroid Build Coastguard Worker }
155*4bdc9457SAndroid Build Coastguard Worker
156*4bdc9457SAndroid Build Coastguard Worker template <class T>
RoundUp(T x,T q)157*4bdc9457SAndroid Build Coastguard Worker inline T RoundUp(T x, T q) {
158*4bdc9457SAndroid Build Coastguard Worker return q * DivideRoundUp(x, q);
159*4bdc9457SAndroid Build Coastguard Worker }
160*4bdc9457SAndroid Build Coastguard Worker
161*4bdc9457SAndroid Build Coastguard Worker template <class T>
Doz(T a,T b)162*4bdc9457SAndroid Build Coastguard Worker inline T Doz(T a, T b) {
163*4bdc9457SAndroid Build Coastguard Worker return a >= b ? a - b : T(0);
164*4bdc9457SAndroid Build Coastguard Worker }
165*4bdc9457SAndroid Build Coastguard Worker
166*4bdc9457SAndroid Build Coastguard Worker // A struct that uses RAII pattern to allocate and release code memory.
167*4bdc9457SAndroid Build Coastguard Worker struct CodeMemoryHelper {
168*4bdc9457SAndroid Build Coastguard Worker CodeMemoryHelper();
169*4bdc9457SAndroid Build Coastguard Worker ~CodeMemoryHelper();
170*4bdc9457SAndroid Build Coastguard Worker
171*4bdc9457SAndroid Build Coastguard Worker xnn_code_buffer buffer;
172*4bdc9457SAndroid Build Coastguard Worker xnn_status status;
173*4bdc9457SAndroid Build Coastguard Worker };
174*4bdc9457SAndroid Build Coastguard Worker
175*4bdc9457SAndroid Build Coastguard Worker } // namespace utils
176*4bdc9457SAndroid Build Coastguard Worker } // namespace benchmark
177