blob: b277e56000385ee753b7fbef20e9221b70bb31d3 [file] [log] [blame]
Georgios Pinitascfa2bba2019-06-27 17:00:52 +01001/*
Aleksandr Nikolaeva084b462020-06-25 12:25:52 +01002 * Copyright (c) 2019-2020 Arm Limited.
Georgios Pinitascfa2bba2019-06-27 17:00:52 +01003 *
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 */
Georgios Pinitasf33484f2019-07-29 12:40:59 +010024#ifdef __aarch64__
25
Georgios Pinitascfa2bba2019-06-27 17:00:52 +010026#include "arm_gemm.hpp"
27
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000028#include "kernels/a64_gemm_u16_8x12.hpp"
29#include "kernels/a64_gemm_u8_4x4.hpp"
30#include "kernels/a64_gemm_u8_8x12.hpp"
31#include "kernels/a64_hybrid_u8qa_dot_4x16.hpp"
Georgios Pinitas4ee8b152021-07-16 16:16:43 +010032#include "kernels/a64_hybrid_u8qa_mmla_4x16.hpp"
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000033#include "kernels/a64_hybrid_u8u32_dot_6x16.hpp"
Georgios Pinitas4ee8b152021-07-16 16:16:43 +010034#include "kernels/a64_hybrid_u8u32_mmla_6x16.hpp"
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000035#include "kernels/a64_interleaved_u8u32_mmla_8x12.hpp"
36#include "kernels/a64_smallK_hybrid_u8u32_dot_6x4.hpp"
37#include "kernels/a64_smallK_hybrid_u8u32_dot_8x4.hpp"
Georgios Pinitascfa2bba2019-06-27 17:00:52 +010038
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000039#include "kernels/sve_hybrid_u8qa_dot_4x4VL.hpp"
Georgios Pinitas4ee8b152021-07-16 16:16:43 +010040#include "kernels/sve_hybrid_u8qa_mmla_4x4VL.hpp"
41#include "kernels/sve_hybrid_u8u32_dot_6x4VL.hpp"
42#include "kernels/sve_hybrid_u8u32_mmla_6x4VL.hpp"
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000043#include "kernels/sve_interleaved_u8u32_dot_8x3VL.hpp"
44#include "kernels/sve_interleaved_u8u32_mmla_8x3VL.hpp"
45#include "kernels/sve_smallK_hybrid_u8u32_dot_8x1VL.hpp"
46
47#include "gemm_hybrid_indirect.hpp"
Georgios Pinitascfa2bba2019-06-27 17:00:52 +010048#include "gemm_hybrid_quantized.hpp"
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000049#include "gemm_hybrid_quantized_inline.hpp"
50#include "gemm_interleaved.hpp"
Georgios Pinitascfa2bba2019-06-27 17:00:52 +010051#include "quantize_wrapper.hpp"
52
53namespace arm_gemm {
54
Michalis Spyrou71ac9032019-11-14 14:31:44 +000055static const GemmImplementation<uint8_t, uint8_t, Requantize32> gemm_quint8_methods[] =
Georgios Pinitascfa2bba2019-06-27 17:00:52 +010056{
Michalis Spyrou20fca522021-06-07 14:23:57 +010057#ifdef ARM_COMPUTE_ENABLE_SVE
Georgios Pinitas4ee8b152021-07-16 16:16:43 +010058GemmImplementation<uint8_t, uint8_t, Requantize32>::with_estimate(
59 GemmMethod::GEMM_HYBRID,
60 "sve_hybrid_u8qa_mmla_4x4VL",
61 [](const GemmArgs &args, const Requantize32 &qp) { return quant_hybrid_asymmetric(qp) && args._ci->has_sve2() && args._ci->has_svei8mm(); },
62 [](const GemmArgs &args, const Requantize32 &) { return GemmHybridIndirect<cls_sve_hybrid_u8qa_mmla_4x4VL, uint8_t, uint8_t, Requantize32>::estimate_cycles<uint8_t>(args); },
63 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmHybridIndirect<cls_sve_hybrid_u8qa_mmla_4x4VL, uint8_t, uint8_t, Requantize32>(args, qp); }
64),
65GemmImplementation<uint8_t, uint8_t, Requantize32>::with_estimate(
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000066 GemmMethod::GEMM_INTERLEAVED,
67 "sve_interleaved_u8u32_mmla_8x3VL",
Michalis Spyrou20fca522021-06-07 14:23:57 +010068 [](const GemmArgs &args, const Requantize32 &) { return args._ci->has_svei8mm() && (args._Ksize>8); },
Georgios Pinitas4ee8b152021-07-16 16:16:43 +010069 [](const GemmArgs &args, const Requantize32 &) { return GemmInterleavedQuantized<cls_sve_interleaved_u8u32_mmla_8x3VL, uint8_t, uint8_t>::estimate_cycles<uint8_t>(args); },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000070 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmInterleavedQuantized<cls_sve_interleaved_u8u32_mmla_8x3VL, uint8_t, uint8_t>(args, qp); }
Georgios Pinitas4ee8b152021-07-16 16:16:43 +010071),
72GemmImplementation<uint8_t, uint8_t, Requantize32>::with_estimate(
73 GemmMethod::GEMM_INTERLEAVED,
74 "sve_hybrid_u8u32_mmla_6x4VL",
75 [](const GemmArgs &args, const Requantize32 &) { return args._ci->has_svei8mm(); },
76 [](const GemmArgs &args, const Requantize32 &) { return GemmHybridIndirect<cls_sve_hybrid_u8u32_mmla_6x4VL, uint8_t, uint8_t, Requantize32, true>::estimate_cycles<uint8_t>(args); },
77 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmHybridIndirect<cls_sve_hybrid_u8u32_mmla_6x4VL, uint8_t, uint8_t, Requantize32, true>(args, qp); }
78),
Georgios Pinitascfa2bba2019-06-27 17:00:52 +010079{
80 GemmMethod::GEMM_HYBRID_QUANTIZED,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000081 "sve_smallK_hybrid_u8u32_dot_8x1VL",
Pablo Marquez Telloa50f1932021-03-08 17:27:05 +000082 [](const GemmArgs &args, const Requantize32 &) { return args._ci->has_sve() && args._Ksize<=64 && !args._indirect_input; },
Gunes Bayire42a87f2021-09-13 13:24:38 +010083 [](const GemmArgs &args, const Requantize32 &) { return !(args._ci->has_svei8mm() || args._ci->has_i8mm()); },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000084 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmHybridQuantized<cls_sve_smallK_hybrid_u8u32_dot_8x1VL, uint8_t, uint8_t>(args, qp); }
85},
Georgios Pinitas4ee8b152021-07-16 16:16:43 +010086GemmImplementation<uint8_t, uint8_t, Requantize32>::with_estimate(
SiCongLi410e21e2020-12-11 15:07:53 +000087 GemmMethod::GEMM_HYBRID,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000088 "sve_hybrid_u8qa_dot_4x4VL",
Georgios Pinitas4ee8b152021-07-16 16:16:43 +010089 [](const GemmArgs &args, const Requantize32 &qp) { return args._ci->has_sve2() && quant_hybrid_asymmetric(qp); },
90 [](const GemmArgs &args, const Requantize32 &) { return GemmHybridIndirect<cls_sve_hybrid_u8qa_dot_4x4VL, uint8_t, uint8_t, Requantize32>::estimate_cycles<uint8_t>(args); },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000091 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmHybridIndirect<cls_sve_hybrid_u8qa_dot_4x4VL, uint8_t, uint8_t, Requantize32>(args, qp); }
Georgios Pinitas4ee8b152021-07-16 16:16:43 +010092),
93GemmImplementation<uint8_t, uint8_t, Requantize32>::with_estimate(
SiCongLi410e21e2020-12-11 15:07:53 +000094 GemmMethod::GEMM_HYBRID,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000095 "sve_hybrid_u8u32_dot_6x4VL",
Georgios Pinitas4ee8b152021-07-16 16:16:43 +010096 [](const GemmArgs &args, const Requantize32 &) { return args._ci->has_sve(); },
97 [](const GemmArgs &args, const Requantize32 &) { return GemmHybridIndirect<cls_sve_hybrid_u8u32_dot_6x4VL, uint8_t, uint8_t, Requantize32, true>::estimate_cycles<uint8_t>(args); },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000098 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmHybridIndirect<cls_sve_hybrid_u8u32_dot_6x4VL, uint8_t, uint8_t, Requantize32, true>(args, qp); }
Georgios Pinitas4ee8b152021-07-16 16:16:43 +010099),
100GemmImplementation<uint8_t, uint8_t, Requantize32>::with_estimate(
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000101 GemmMethod::GEMM_INTERLEAVED,
102 "sve_interleaved_u8u32_dot_8x3VL",
Georgios Pinitas4ee8b152021-07-16 16:16:43 +0100103 [](const GemmArgs &args, const Requantize32 &) { return args._ci->has_sve() && (args._Ksize>4); },
104 [](const GemmArgs &args, const Requantize32 &) { return GemmInterleavedQuantized<cls_sve_interleaved_u8u32_dot_8x3VL, uint8_t, uint8_t>::estimate_cycles<uint8_t>(args); },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000105 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmInterleavedQuantized<cls_sve_interleaved_u8u32_dot_8x3VL, uint8_t, uint8_t>(args, qp); }
Georgios Pinitas4ee8b152021-07-16 16:16:43 +0100106),
107#endif // ARM_COMPUTE_ENABLE_SVE
108GemmImplementation<uint8_t, uint8_t, Requantize32>::with_estimate(
109 GemmMethod::GEMM_HYBRID,
110 "a64_hybrid_u8qa_mmla_4x16",
111 [](const GemmArgs &args, const Requantize32 &qp) { return args._ci->has_i8mm() && quant_hybrid_asymmetric(qp); },
112 [](const GemmArgs &args, const Requantize32 &) { return GemmHybridIndirect<cls_a64_hybrid_u8qa_mmla_4x16, uint8_t, uint8_t, Requantize32>::estimate_cycles<uint8_t>(args); },
113 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmHybridIndirect<cls_a64_hybrid_u8qa_mmla_4x16, uint8_t, uint8_t, Requantize32>(args, qp); }
114),
115GemmImplementation<uint8_t, uint8_t, Requantize32>::with_estimate(
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000116 GemmMethod::GEMM_INTERLEAVED,
117 "a64_interleaved_u8u32_mmla_8x12",
Michalis Spyrou20fca522021-06-07 14:23:57 +0100118 [](const GemmArgs &args, const Requantize32 &) { return args._ci->has_i8mm() && (args._Ksize>8); },
Georgios Pinitas4ee8b152021-07-16 16:16:43 +0100119 [](const GemmArgs &args, const Requantize32 &) { return GemmInterleavedQuantized<cls_a64_interleaved_u8u32_mmla_8x12, uint8_t, uint8_t>::estimate_cycles<uint8_t>(args); },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000120 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmInterleavedQuantized<cls_a64_interleaved_u8u32_mmla_8x12, uint8_t, uint8_t>(args, qp); }
Georgios Pinitas4ee8b152021-07-16 16:16:43 +0100121),
122GemmImplementation<uint8_t, uint8_t, Requantize32>::with_estimate(
123 GemmMethod::GEMM_INTERLEAVED,
124 "a64_hybrid_u8u32_mmla_6x16",
125 [](const GemmArgs &args, const Requantize32 &) { return args._ci->has_i8mm(); },
126 [](const GemmArgs &args, const Requantize32 &) { return GemmHybridIndirect<cls_a64_hybrid_u8u32_mmla_6x16, uint8_t, uint8_t, Requantize32, true>::estimate_cycles<uint8_t>(args); },
127 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmHybridIndirect<cls_a64_hybrid_u8u32_mmla_6x16, uint8_t, uint8_t, Requantize32, true>(args, qp); }
128),
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000129{
130 GemmMethod::GEMM_HYBRID_QUANTIZED,
131 "a64_smallK_hybrid_u8u32_dot_8x4",
132 [](const GemmArgs &args, const Requantize32 &) { return args._ci->has_dotprod() && (args._Nsize % 4 == 0) && (args._Ksize<=32) && !args._indirect_input; },
Gunes Bayire42a87f2021-09-13 13:24:38 +0100133 [](const GemmArgs &args, const Requantize32 &) { return !(args._ci->has_svei8mm() || args._ci->has_i8mm()); },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000134 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmHybridQuantized<cls_a64_smallK_hybrid_u8u32_dot_8x4, uint8_t, uint8_t>(args, qp); }
Georgios Pinitascfa2bba2019-06-27 17:00:52 +0100135},
136{
137 GemmMethod::GEMM_HYBRID_QUANTIZED,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000138 "a64_smallK_hybrid_u8u32_dot_6x4",
139 [](const GemmArgs &args, const Requantize32 &) { return args._ci->has_dotprod() && (args._Nsize % 4 == 0) && (args._Ksize>32) && (args._Ksize<=64) && !args._indirect_input; },
Gunes Bayire42a87f2021-09-13 13:24:38 +0100140 [](const GemmArgs &args, const Requantize32 &) { return !(args._ci->has_svei8mm() || args._ci->has_i8mm()); },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000141 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmHybridQuantized<cls_a64_smallK_hybrid_u8u32_dot_6x4, uint8_t, uint8_t>(args, qp); }
Georgios Pinitascfa2bba2019-06-27 17:00:52 +0100142},
143{
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000144 GemmMethod::GEMM_INTERLEAVED,
145 "a64_gemm_u16_8x12",
Aleksandr Nikolaeva084b462020-06-25 12:25:52 +0100146 nullptr,
Georgios Pinitascd22cbf2020-12-02 16:06:01 +0000147 [](const GemmArgs &args, const Requantize32 &) { return args._ci->get_cpu_model() == CPUModel::A53 && args._Msize > 4; },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000148 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmInterleavedQuantized<cls_a64_gemm_u16_8x12, uint8_t, uint8_t>(args, qp); },
149},
Georgios Pinitas33e03072021-01-14 13:43:40 +0000150GemmImplementation<uint8_t, uint8_t, Requantize32>::with_estimate(
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000151 GemmMethod::GEMM_HYBRID,
152 "a64_hybrid_u8qa_dot_4x16",
153 [](const GemmArgs &args, const Requantize32 &qp) { return args._ci->has_dotprod() && quant_hybrid_asymmetric(qp); },
Georgios Pinitas4ee8b152021-07-16 16:16:43 +0100154 [](const GemmArgs &args, const Requantize32 &) { return GemmHybridIndirect<cls_a64_hybrid_u8qa_dot_4x16, uint8_t, uint8_t, Requantize32>::estimate_cycles<uint8_t>(args); },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000155 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmHybridIndirect<cls_a64_hybrid_u8qa_dot_4x16, uint8_t, uint8_t, Requantize32>(args, qp); }
Georgios Pinitas33e03072021-01-14 13:43:40 +0000156),
157GemmImplementation<uint8_t, uint8_t, Requantize32>::with_estimate(
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000158 GemmMethod::GEMM_HYBRID,
159 "a64_hybrid_u8u32_dot_6x16",
160 [](const GemmArgs &args, const Requantize32 &) { return args._ci->has_dotprod(); },
Georgios Pinitas4ee8b152021-07-16 16:16:43 +0100161 [](const GemmArgs &args, const Requantize32 &) { return GemmHybridIndirect<cls_a64_hybrid_u8u32_dot_6x16, uint8_t, uint8_t, Requantize32, true>::estimate_cycles<uint8_t>(args); },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000162 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmHybridIndirect<cls_a64_hybrid_u8u32_dot_6x16, uint8_t, uint8_t, Requantize32, true>(args, qp); }
Georgios Pinitas33e03072021-01-14 13:43:40 +0000163),
164GemmImplementation<uint8_t, uint8_t, Requantize32>::with_estimate(
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000165 GemmMethod::GEMM_INTERLEAVED,
166 "a64_gemm_u8_8x12",
167 [](const GemmArgs &args, const Requantize32 &) { return args._ci->has_dotprod(); },
Georgios Pinitas4ee8b152021-07-16 16:16:43 +0100168 [](const GemmArgs &args, const Requantize32 &) { return GemmInterleavedQuantized<cls_a64_gemm_u8_8x12, uint8_t, uint8_t>::estimate_cycles<uint8_t>(args); },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000169 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmInterleavedQuantized<cls_a64_gemm_u8_8x12, uint8_t, uint8_t>(args, qp); }
Georgios Pinitas33e03072021-01-14 13:43:40 +0000170),
Georgios Pinitas4ee8b152021-07-16 16:16:43 +0100171GemmImplementation<uint8_t, uint8_t, Requantize32>::with_estimate(
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000172 GemmMethod::GEMM_INTERLEAVED,
173 "a64_gemm_u8_4x4",
174 nullptr,
Georgios Pinitas4ee8b152021-07-16 16:16:43 +0100175 [](const GemmArgs &args, const Requantize32 &) { return GemmInterleavedQuantized<cls_a64_gemm_u8_4x4, uint8_t, uint8_t>::estimate_cycles<uint8_t>(args); },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000176 [](const GemmArgs &args, const Requantize32 &qp) { return new GemmInterleavedQuantized<cls_a64_gemm_u8_4x4, uint8_t, uint8_t>(args, qp); }
Georgios Pinitas4ee8b152021-07-16 16:16:43 +0100177),
Georgios Pinitascfa2bba2019-06-27 17:00:52 +0100178{
179 GemmMethod::QUANTIZE_WRAPPER,
180 "quantized_wrapper",
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000181 [](const GemmArgs &args, const Requantize32 &) { return !args._indirect_input; },
Georgios Pinitas4ee8b152021-07-16 16:16:43 +0100182 [](const GemmArgs &, const Requantize32 &) { return false; },
Michalis Spyrou71ac9032019-11-14 14:31:44 +0000183 [](const GemmArgs &args, const Requantize32 &qp) { return new QuantizeWrapper<uint8_t, uint8_t, uint32_t>(args, qp); }
Georgios Pinitascfa2bba2019-06-27 17:00:52 +0100184},
185{
186 GemmMethod::DEFAULT,
187 "",
188 nullptr,
189 nullptr,
190 nullptr
191}
192};
193
194template<>
Michalis Spyrou71ac9032019-11-14 14:31:44 +0000195const GemmImplementation<uint8_t, uint8_t, Requantize32> *gemm_implementation_list<uint8_t, uint8_t, Requantize32>() {
Georgios Pinitascfa2bba2019-06-27 17:00:52 +0100196 return gemm_quint8_methods;
197}
198
Michalis Spyrou71ac9032019-11-14 14:31:44 +0000199template UniqueGemmCommon<uint8_t, uint8_t> gemm<uint8_t, uint8_t, Requantize32>(const GemmArgs &args, const Requantize32 &os);
200template KernelDescription get_gemm_method<uint8_t, uint8_t, Requantize32>(const GemmArgs &args, const Requantize32 &os);
201template std::vector<KernelDescription> get_compatible_kernels<uint8_t, uint8_t, Requantize32>(const GemmArgs &args, const Requantize32 &os);
Georgios Pinitascfa2bba2019-06-27 17:00:52 +0100202
203} // namespace arm_gemm
Georgios Pinitasf33484f2019-07-29 12:40:59 +0100204
205#endif // __aarch64__