blob: 66c3223a4e4bd2bfb9252ea8fb33e8f103c7d1bc [file] [log] [blame]
Anthony Barbier71d9b572018-07-06 17:05:59 +01001/*
Mohammed Suhail Munshia1b1e412023-03-23 22:21:31 +00002 * Copyright (c) 2018-2023 Arm Limited.
Anthony Barbier71d9b572018-07-06 17:05:59 +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 */
Sang-Hoon Parkd89e2fa2021-05-17 17:04:50 +010024#ifndef ARM_COMPUTE_CPU_INTERNAL_CPU_GEMM_ASSEMBLY_DISPATCH_H
25#define ARM_COMPUTE_CPU_INTERNAL_CPU_GEMM_ASSEMBLY_DISPATCH_H
Anthony Barbier71d9b572018-07-06 17:05:59 +010026
Matthew Benthamf1aeab92023-05-30 13:35:34 +000027#include "arm_compute/core/ActivationLayerInfo.h"
Sang-Hoon Parkd89e2fa2021-05-17 17:04:50 +010028#include "src/core/common/Macros.h"
Georgios Pinitas7891a732021-08-20 21:39:25 +010029#include "src/cpu/ICpuOperator.h"
Anthony Barbier71d9b572018-07-06 17:05:59 +010030
Anthony Barbier71d9b572018-07-06 17:05:59 +010031namespace arm_compute
32{
Sang-Hoon Park4f7693d2021-05-12 13:59:10 +010033namespace cpu
34{
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000035/* Convolution method supported by the assembly gemm interface */
36enum class AsmConvMethod
37{
38 Im2Col,
39 Indirect,
40 Conv
41};
42
43struct AsmGemmInfo
44{
Ramy Elgammal91780022022-07-20 14:57:37 +010045 AsmConvMethod method{ AsmConvMethod::Im2Col };
46 PadStrideInfo ps_info{};
47 ActivationLayerInfo activation_info{};
48 GEMMLowpOutputStageInfo output_stage{};
49 bool negated_offsets{ true };
50 bool reinterpret_input_as_3d{ false };
51 bool depth_output_gemm3d{ false };
52 int64_t padding_top{ 0 };
53 int64_t padding_left{ 0 };
54 float padding_value{ 0.f };
55 bool fast_mode{ false };
56 bool fixed_format{ false };
57 arm_compute::WeightFormat weight_format{ arm_compute::WeightFormat::UNSPECIFIED };
Mohammed Suhail Munshi4b5f6ef2022-10-21 11:15:54 +010058 bool reshape_b_only_on_first_run{ true };
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000059};
60
Anthony Barbier71d9b572018-07-06 17:05:59 +010061/** Assembly kernel glue */
Sang-Hoon Parkd89e2fa2021-05-17 17:04:50 +010062class CpuGemmAssemblyDispatch : public ICpuOperator
Anthony Barbier71d9b572018-07-06 17:05:59 +010063{
64public:
Michalis Spyrou1a569a32019-09-10 17:20:34 +010065 /** Constructor */
Michele Di Giorgiod7316eb2021-06-16 11:14:41 +010066 CpuGemmAssemblyDispatch();
Sang-Hoon Park4f7693d2021-05-12 13:59:10 +010067 /** Defautl destructor */
68 ~CpuGemmAssemblyDispatch() = default;
Anthony Barbiereaefd002018-07-20 17:49:35 +010069
Sang-Hoon Parkd89e2fa2021-05-17 17:04:50 +010070 ARM_COMPUTE_DISALLOW_COPY_ALLOW_MOVE(CpuGemmAssemblyDispatch);
71
Anthony Barbiereaefd002018-07-20 17:49:35 +010072 class IFallback
73 {
74 public:
Ramy Elgammal91780022022-07-20 14:57:37 +010075 virtual void run(ITensorPack &tensors) = 0;
76 virtual void prepare(ITensorPack &tensors) = 0;
77 virtual experimental::MemoryRequirements workspace() const = 0;
78 virtual bool is_configured() const = 0;
79 virtual bool isVarWeightsKernel() const = 0;
80 virtual ~IFallback() = default;
Anthony Barbiereaefd002018-07-20 17:49:35 +010081 };
Anthony Barbier71d9b572018-07-06 17:05:59 +010082
Anthony Barbier71d9b572018-07-06 17:05:59 +010083public:
Michele Di Giorgio57f30a92020-09-08 14:03:51 +010084 /** If supported create a Compute Library function else fallback to the arm_gemm function.
Anthony Barbierc8e84b52018-07-17 16:48:42 +010085 *
Mohammed Suhail Munshia1b1e412023-03-23 22:21:31 +000086 * @note Configuring "batches"
87 * The shapes of @p a @p b and @p d are arranged as follows:
88 * Lowest dimension <-> Highest dimension
89 * a: [K, M, Batch, Multi]
90 * b: [N, K, Multi]
91 * d: [N, M, Batch, Multi]
92 *
93 * The "Batch" refers to where "Batch" number of MxK slices of tensor a multiplies with a single KxN slice of b
94 * The "Multi" refers to where "Multi" number of individual multiplication of a with b
95 *
96 * E.g. the following are some example input shape configurations
97 *
98 * (1) Normal 2D gemm
99 * a: [K=3, M=4]
100 * b: [N=5, K=3]
101 * d: [N=5, M=4]
102 *
103 * (2) Batches of a sharing b (e.g. gemm-based batched convolution where b is the shared )
104 * a: [K=3, M=4, Batch=9]
105 * b: [N=5, K=3]
106 * d: [N=5, M=4, Batch=9]
107 *
108 * (3) "Batches" of independent gemm (e.g. batched matmul)
109 * a: [K=3, M=4, Batch=1, Multi=7]
110 * b: [N=5, K=3, Multi=7]
111 * d: [N=5, M=4, Batch=1, Multi=7]
112 *
113 * (4) "Batches" of independent gemm where b is also shared
114 * a: [K=3, M=4, Batch=4, Multi=7]
115 * b: [N=5, K=3, Multi=7]
116 * d: [N=5, M=4, Batch=4, Multi=7]
117 *
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000118 * @param[in] a Input tensor (Matrix A)
119 * @param[in] b Input tensor (Matrix B)
120 * @param[in] c Input tensor (Matrix C) used to pass the bias for quantized calculations
121 * @param[out] d Output tensor to store the result of matrix multiplication. Data type supported: same as @p input0.
122 * @param[in] info GEMM meta-data
Anthony Barbierc8e84b52018-07-17 16:48:42 +0100123 */
Sang-Hoon Parkd89e2fa2021-05-17 17:04:50 +0100124 void configure(const ITensorInfo *a, const ITensorInfo *b, const ITensorInfo *c, ITensorInfo *d, const AsmGemmInfo &info);
Anthony Barbiereaefd002018-07-20 17:49:35 +0100125
126 /** Indicates whether or not this function can be used to process the given parameters.
127 *
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000128 * @param[in] a Input tensor info (Matrix A)
129 * @param[in] b Input tensor info (Matrix B)
130 * @param[in] c Input tensor info (Matrix C) used to pass the bias for quantized calculations
131 * @param[in] d Output tensor to store the result of matrix multiplication. Data type supported: same as @p input0.
132 * @param[in] info GEMM meta-data
Anthony Barbiereaefd002018-07-20 17:49:35 +0100133 *
134 * @return a status.
135 */
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000136 static Status validate(const ITensorInfo *a, const ITensorInfo *b, const ITensorInfo *c, const ITensorInfo *d, const AsmGemmInfo &info);
Francesco.Petrogalli@arm.come33c5562022-03-31 17:55:35 +0000137
138 /** Indicates whether or not there is an optimal assembly implementation that can be used to process the given parameters.
139 *
Francesco Petrogalli553f6952022-06-30 10:22:01 +0000140 * This method has the same use of @ref
141 * NEGEMMConvolutionLayer::has_opt_impl, with the only caveat that
Ramy Elgammal91780022022-07-20 14:57:37 +0100142 * the value of arm_compute::WeightFormat need to be passed via the
Francesco Petrogalli553f6952022-06-30 10:22:01 +0000143 * parameter info.
Francesco.Petrogalli@arm.come33c5562022-03-31 17:55:35 +0000144 *
145 * @return a status.
146 */
Ramy Elgammal91780022022-07-20 14:57:37 +0100147 static Status has_opt_impl(arm_compute::WeightFormat &weight_format, const ITensorInfo *a, const ITensorInfo *b, const ITensorInfo *c, const ITensorInfo *d, const AsmGemmInfo &info);
Georgios Pinitas48b3ef82019-10-14 19:03:09 +0100148 /** Checks if activation is supported by the gemm assembly dispatcher
149 *
150 * @param[in] activation Activation to check
151 *
152 * @return True if activation is supported else false
153 */
154 static bool is_activation_supported(const ActivationLayerInfo &activation);
Anthony Barbierc8e84b52018-07-17 16:48:42 +0100155 /** Was the function successfully configured ?
156 *
157 * @return True if the function is configured and ready to run
158 */
Anthony Barbier71d9b572018-07-06 17:05:59 +0100159 bool is_configured() const;
Francesco Petrogalli553f6952022-06-30 10:22:01 +0000160 /** Indicates if the convolution executes in variable weights mode.
161 *
162 * Similar to @ref CpuGemm::isVarWeightsKernel
163 */
164 bool isVarWeightsKernel() const
165 {
166 return _arm_gemm && _arm_gemm->isVarWeightsKernel();
167 }
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000168
Anthony Barbier71d9b572018-07-06 17:05:59 +0100169 // Inherited methods overridden:
Ramy Elgammal91780022022-07-20 14:57:37 +0100170 void prepare(ITensorPack &tensors) override;
171 void run(ITensorPack &tensors) override;
Michele Di Giorgiod7316eb2021-06-16 11:14:41 +0100172 experimental::MemoryRequirements workspace() const override;
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000173
174private:
Michele Di Giorgiod7316eb2021-06-16 11:14:41 +0100175 std::unique_ptr<IFallback> _arm_gemm; /**< Interface for the arm_gemm fallback */
Anthony Barbier71d9b572018-07-06 17:05:59 +0100176};
Sang-Hoon Park4f7693d2021-05-12 13:59:10 +0100177} // namespace cpu
Anthony Barbierc8e84b52018-07-17 16:48:42 +0100178} // namespace arm_compute
Sang-Hoon Parkd89e2fa2021-05-17 17:04:50 +0100179#endif /* ARM_COMPUTE_CPU_INTERNAL_CPU_GEMM_ASSEMBLY_DISPATCH_H */