blob: 4c05fd1b732fcb903d35b1ab1b581cb6605bb862 [file] [log] [blame]
Pablo Telloeb82fd22018-02-23 13:43:50 +00001/*
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +01002 * Copyright (c) 2017-2020 Arm Limited.
Pablo Telloeb82fd22018-02-23 13:43:50 +00003 *
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 */
24#ifdef __aarch64__
25
26#include "arm_gemm.hpp"
27#include "gemm_common.hpp"
David Manselle39334c2018-07-06 17:53:35 +010028#include "gemm_implementation.hpp"
Pablo Telloeb82fd22018-02-23 13:43:50 +000029#include "gemm_interleaved.hpp"
Georgios Pinitas1d480652019-01-23 11:24:50 +000030#include "gemm_hybrid.hpp"
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000031#include "gemm_hybrid_indirect.hpp"
Pablo Telloeb82fd22018-02-23 13:43:50 +000032
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000033#include "kernels/a64_gemm_u16_8x12.hpp"
David Manselle39334c2018-07-06 17:53:35 +010034#include "kernels/a64_gemm_u8_4x4.hpp"
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000035#include "kernels/a64_gemm_u8_8x12.hpp"
36#include "kernels/a64_hybrid_u8u32_dot_6x16.hpp"
37#include "kernels/a64_interleaved_u8u32_mmla_8x12.hpp"
38#include "kernels/a64_smallK_hybrid_u8u32_dot_6x4.hpp"
39#include "kernels/a64_smallK_hybrid_u8u32_dot_8x4.hpp"
40
41#include "kernels/sve_hybrid_u8u32_dot_6x4VL.hpp"
42#include "kernels/sve_interleaved_u8u32_dot_8x3VL.hpp"
43#include "kernels/sve_interleaved_u8u32_mmla_8x3VL.hpp"
44#include "kernels/sve_smallK_hybrid_u8u32_dot_8x1VL.hpp"
Pablo Telloeb82fd22018-02-23 13:43:50 +000045
Anthony Barbier5f707732018-07-03 16:22:02 +010046namespace arm_gemm {
47
Georgios Pinitas7cd26d42019-01-09 18:35:17 +000048static const GemmImplementation<uint8_t, uint32_t> gemm_u8_methods[] = {
Michalis Spyrou20fca522021-06-07 14:23:57 +010049#ifdef ARM_COMPUTE_ENABLE_SVE
50#ifdef ARM_COMPUTE_ENABLE_I8MM
Georgios Pinitas94672fb2020-01-22 18:36:27 +000051{
52 GemmMethod::GEMM_INTERLEAVED,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000053 "sve_interleaved_u8u32_mmla_8x3VL",
Michalis Spyrou20fca522021-06-07 14:23:57 +010054 [](const GemmArgs &args) { return args._ci->has_svei8mm() && (args._Ksize>8); },
Pablo Marquez Telloa50f1932021-03-08 17:27:05 +000055 [](const GemmArgs &args) { return args._ci->get_cpu_model() != CPUModel::KLEIN; },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000056 [](const GemmArgs &args) { return new GemmInterleaved<cls_sve_interleaved_u8u32_mmla_8x3VL, uint8_t, uint32_t>(args); }
Georgios Pinitas94672fb2020-01-22 18:36:27 +000057},
58#endif
Georgios Pinitas7cd26d42019-01-09 18:35:17 +000059{
Georgios Pinitas14613832019-03-01 19:07:11 +000060 GemmMethod::GEMM_HYBRID,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000061 "smallK_hybrid_u8u32_dot_8x1VL",
Pablo Marquez Telloa50f1932021-03-08 17:27:05 +000062 [](const GemmArgs &args) { return args._ci->has_sve() && args._Ksize<=64 && !args._indirect_input; },
63 [](const GemmArgs &args) { return args._ci->get_cpu_model() != CPUModel::KLEIN; },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000064 [](const GemmArgs &args) { return new GemmHybrid<cls_sve_smallK_hybrid_u8u32_dot_8x1VL, uint8_t, uint32_t>(args); }
Georgios Pinitascfa2bba2019-06-27 17:00:52 +010065},
66{
67 GemmMethod::GEMM_HYBRID,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000068 "sve_hybrid_u8u32_dot_6x4VL",
Pablo Marquez Telloa50f1932021-03-08 17:27:05 +000069 [](const GemmArgs &args) { return args._ci->has_sve(); },
70 [](const GemmArgs &args) { return args._ci->get_cpu_model() != CPUModel::KLEIN && (((args._Ksize <= 128) && (args._Nsize <= 128)) || ((args._nmulti > 1) && ((args._Msize / args._maxthreads) < 8))); },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000071 [](const GemmArgs &args) { return new GemmHybridIndirect<cls_sve_hybrid_u8u32_dot_6x4VL, uint8_t, uint32_t>(args); }
Georgios Pinitas14613832019-03-01 19:07:11 +000072},
73{
Georgios Pinitas7cd26d42019-01-09 18:35:17 +000074 GemmMethod::GEMM_INTERLEAVED,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000075 "sve_interleaved_u8u32_dot_8x3VL",
Pablo Marquez Telloa50f1932021-03-08 17:27:05 +000076 [](const GemmArgs &args) { return args._ci->has_sve() && (args._Ksize>4); },
77 [](const GemmArgs &args) { return args._ci->get_cpu_model() != CPUModel::KLEIN; },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000078 [](const GemmArgs &args) { return new GemmInterleaved<cls_sve_interleaved_u8u32_dot_8x3VL, uint8_t, uint32_t>(args); }
Georgios Pinitas7cd26d42019-01-09 18:35:17 +000079},
Georgios Pinitas421405b2018-10-26 19:05:32 +010080#endif
Michalis Spyrou20fca522021-06-07 14:23:57 +010081#ifdef ARM_COMPUTE_ENABLE_I8MM
Georgios Pinitas94672fb2020-01-22 18:36:27 +000082{
83 GemmMethod::GEMM_INTERLEAVED,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000084 "a64_interleaved_u8u32_mmla_8x12",
Michalis Spyrou20fca522021-06-07 14:23:57 +010085 [](const GemmArgs &args) { return args._ci->has_i8mm() && (args._Ksize>8); },
Georgios Pinitas94672fb2020-01-22 18:36:27 +000086 nullptr,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000087 [](const GemmArgs &args) { return new GemmInterleaved<cls_a64_interleaved_u8u32_mmla_8x12, uint8_t, uint32_t>(args); }
Georgios Pinitas94672fb2020-01-22 18:36:27 +000088},
89#endif
Georgios Pinitas7cd26d42019-01-09 18:35:17 +000090{
Georgios Pinitas1d480652019-01-23 11:24:50 +000091 GemmMethod::GEMM_HYBRID,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000092 "a64_smallK_hybrid_u8u32_dot_8x4",
93 [](const GemmArgs &args) { return args._ci->has_dotprod() && (args._Nsize % 4 == 0) && (args._Ksize<=32) && !args._indirect_input; },
Georgios Pinitascfa2bba2019-06-27 17:00:52 +010094 nullptr,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000095 [](const GemmArgs &args) { return new GemmHybrid<cls_a64_smallK_hybrid_u8u32_dot_8x4, uint8_t, uint32_t>(args); }
Georgios Pinitascfa2bba2019-06-27 17:00:52 +010096},
97{
98 GemmMethod::GEMM_HYBRID,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000099 "a64_smallK_hybrid_u8u32_dot_6x4",
100 [](const GemmArgs &args) { return args._ci->has_dotprod() && (args._Nsize % 4 == 0) && (args._Ksize>32) && (args._Ksize<=64) && !args._indirect_input; },
Georgios Pinitascfa2bba2019-06-27 17:00:52 +0100101 nullptr,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000102 [](const GemmArgs &args) { return new GemmHybrid<cls_a64_smallK_hybrid_u8u32_dot_6x4, uint8_t, uint32_t>(args); }
103},
104{
105 GemmMethod::GEMM_INTERLEAVED,
106 "a64_gemm_u16_8x12",
107 nullptr,
Georgios Pinitascd22cbf2020-12-02 16:06:01 +0000108 [](const GemmArgs &args) { return args._ci->get_cpu_model() == CPUModel::A53 && args._Msize > 4; },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000109 [](const GemmArgs &args) { return new GemmInterleaved<cls_a64_gemm_u16_8x12, uint8_t, uint32_t>(args); },
Georgios Pinitascfa2bba2019-06-27 17:00:52 +0100110},
111{
112 GemmMethod::GEMM_HYBRID,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000113 "a64_hybrid_u8u32_dot_6x16",
114 [](const GemmArgs &args) { return args._ci->has_dotprod(); },
Georgios Pinitas48b3ef82019-10-14 19:03:09 +0100115 [](const GemmArgs &args) { return args._Nsize<=256 && args._Ksize>128; },
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000116 [](const GemmArgs &args) { return new GemmHybridIndirect<cls_a64_hybrid_u8u32_dot_6x16, uint8_t, uint32_t>(args); }
Aleksandr Nikolaeva084b462020-06-25 12:25:52 +0100117},
118{
Georgios Pinitas7cd26d42019-01-09 18:35:17 +0000119 GemmMethod::GEMM_INTERLEAVED,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000120 "a64_gemm_u8_8x12",
Georgios Pinitas48b3ef82019-10-14 19:03:09 +0100121 [](const GemmArgs &args) { return args._ci->has_dotprod(); },
Georgios Pinitas7cd26d42019-01-09 18:35:17 +0000122 nullptr,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000123 [](const GemmArgs &args) { return new GemmInterleaved<cls_a64_gemm_u8_8x12, uint8_t, uint32_t>(args); }
David Mansell9e698d52020-08-25 15:02:02 +0100124},
125{
126 GemmMethod::GEMM_INTERLEAVED,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000127 "a64_gemm_u8_4x4",
Georgios Pinitas7cd26d42019-01-09 18:35:17 +0000128 nullptr,
129 nullptr,
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000130 [](const GemmArgs &args) { return new GemmInterleaved<cls_a64_gemm_u8_4x4, uint8_t, uint32_t>(args); }
Georgios Pinitas7cd26d42019-01-09 18:35:17 +0000131},
132{
133 GemmMethod::DEFAULT,
134 "",
135 nullptr,
136 nullptr,
137 nullptr
138}
David Manselle39334c2018-07-06 17:53:35 +0100139};
140
141template<>
Georgios Pinitas7cd26d42019-01-09 18:35:17 +0000142const GemmImplementation<uint8_t, uint32_t> *gemm_implementation_list<uint8_t, uint32_t>() {
David Manselle39334c2018-07-06 17:53:35 +0100143 return gemm_u8_methods;
Pablo Telloeb82fd22018-02-23 13:43:50 +0000144}
145
David Manselle39334c2018-07-06 17:53:35 +0100146/* Explicitly instantiate the external functions for these types. */
Georgios Pinitas48b3ef82019-10-14 19:03:09 +0100147template UniqueGemmCommon<uint8_t, uint32_t> gemm<uint8_t, uint32_t, Nothing>(const GemmArgs &args, const Nothing &);
148template KernelDescription get_gemm_method<uint8_t, uint32_t, Nothing>(const GemmArgs &args, const Nothing &);
149template std::vector<KernelDescription> get_compatible_kernels<uint8_t, uint32_t, Nothing> (const GemmArgs &args, const Nothing &);
David Manselle39334c2018-07-06 17:53:35 +0100150
Pablo Telloeb82fd22018-02-23 13:43:50 +0000151} // namespace arm_gemm
152
David Manselle39334c2018-07-06 17:53:35 +0100153#endif // __aarch64__