blob: 588c45294a4f2e6408633adde38db6dffa2b7833 [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
Sang-Hoon Parkd89e2fa2021-05-17 17:04:50 +010027#include "src/core/common/Macros.h"
Georgios Pinitas7891a732021-08-20 21:39:25 +010028#include "src/cpu/ICpuOperator.h"
Anthony Barbier71d9b572018-07-06 17:05:59 +010029
Anthony Barbier71d9b572018-07-06 17:05:59 +010030namespace arm_compute
31{
Sang-Hoon Park4f7693d2021-05-12 13:59:10 +010032namespace cpu
33{
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000034/* Convolution method supported by the assembly gemm interface */
35enum class AsmConvMethod
36{
37 Im2Col,
38 Indirect,
39 Conv
40};
41
42struct AsmGemmInfo
43{
Ramy Elgammal91780022022-07-20 14:57:37 +010044 AsmConvMethod method{ AsmConvMethod::Im2Col };
45 PadStrideInfo ps_info{};
46 ActivationLayerInfo activation_info{};
47 GEMMLowpOutputStageInfo output_stage{};
48 bool negated_offsets{ true };
49 bool reinterpret_input_as_3d{ false };
50 bool depth_output_gemm3d{ false };
51 int64_t padding_top{ 0 };
52 int64_t padding_left{ 0 };
53 float padding_value{ 0.f };
54 bool fast_mode{ false };
55 bool fixed_format{ false };
56 arm_compute::WeightFormat weight_format{ arm_compute::WeightFormat::UNSPECIFIED };
Mohammed Suhail Munshi4b5f6ef2022-10-21 11:15:54 +010057 bool reshape_b_only_on_first_run{ true };
Georgios Pinitasc0b6f762020-11-02 01:37:17 +000058};
59
Anthony Barbier71d9b572018-07-06 17:05:59 +010060/** Assembly kernel glue */
Sang-Hoon Parkd89e2fa2021-05-17 17:04:50 +010061class CpuGemmAssemblyDispatch : public ICpuOperator
Anthony Barbier71d9b572018-07-06 17:05:59 +010062{
63public:
Michalis Spyrou1a569a32019-09-10 17:20:34 +010064 /** Constructor */
Michele Di Giorgiod7316eb2021-06-16 11:14:41 +010065 CpuGemmAssemblyDispatch();
Sang-Hoon Park4f7693d2021-05-12 13:59:10 +010066 /** Defautl destructor */
67 ~CpuGemmAssemblyDispatch() = default;
Anthony Barbiereaefd002018-07-20 17:49:35 +010068
Sang-Hoon Parkd89e2fa2021-05-17 17:04:50 +010069 ARM_COMPUTE_DISALLOW_COPY_ALLOW_MOVE(CpuGemmAssemblyDispatch);
70
Anthony Barbiereaefd002018-07-20 17:49:35 +010071 class IFallback
72 {
73 public:
Ramy Elgammal91780022022-07-20 14:57:37 +010074 virtual void run(ITensorPack &tensors) = 0;
75 virtual void prepare(ITensorPack &tensors) = 0;
76 virtual experimental::MemoryRequirements workspace() const = 0;
77 virtual bool is_configured() const = 0;
78 virtual bool isVarWeightsKernel() const = 0;
79 virtual ~IFallback() = default;
Anthony Barbiereaefd002018-07-20 17:49:35 +010080 };
Anthony Barbier71d9b572018-07-06 17:05:59 +010081
Anthony Barbier71d9b572018-07-06 17:05:59 +010082public:
Michele Di Giorgio57f30a92020-09-08 14:03:51 +010083 /** If supported create a Compute Library function else fallback to the arm_gemm function.
Anthony Barbierc8e84b52018-07-17 16:48:42 +010084 *
Mohammed Suhail Munshia1b1e412023-03-23 22:21:31 +000085 * @note Configuring "batches"
86 * The shapes of @p a @p b and @p d are arranged as follows:
87 * Lowest dimension <-> Highest dimension
88 * a: [K, M, Batch, Multi]
89 * b: [N, K, Multi]
90 * d: [N, M, Batch, Multi]
91 *
92 * The "Batch" refers to where "Batch" number of MxK slices of tensor a multiplies with a single KxN slice of b
93 * The "Multi" refers to where "Multi" number of individual multiplication of a with b
94 *
95 * E.g. the following are some example input shape configurations
96 *
97 * (1) Normal 2D gemm
98 * a: [K=3, M=4]
99 * b: [N=5, K=3]
100 * d: [N=5, M=4]
101 *
102 * (2) Batches of a sharing b (e.g. gemm-based batched convolution where b is the shared )
103 * a: [K=3, M=4, Batch=9]
104 * b: [N=5, K=3]
105 * d: [N=5, M=4, Batch=9]
106 *
107 * (3) "Batches" of independent gemm (e.g. batched matmul)
108 * a: [K=3, M=4, Batch=1, Multi=7]
109 * b: [N=5, K=3, Multi=7]
110 * d: [N=5, M=4, Batch=1, Multi=7]
111 *
112 * (4) "Batches" of independent gemm where b is also shared
113 * a: [K=3, M=4, Batch=4, Multi=7]
114 * b: [N=5, K=3, Multi=7]
115 * d: [N=5, M=4, Batch=4, Multi=7]
116 *
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000117 * @param[in] a Input tensor (Matrix A)
118 * @param[in] b Input tensor (Matrix B)
119 * @param[in] c Input tensor (Matrix C) used to pass the bias for quantized calculations
120 * @param[out] d Output tensor to store the result of matrix multiplication. Data type supported: same as @p input0.
121 * @param[in] info GEMM meta-data
Anthony Barbierc8e84b52018-07-17 16:48:42 +0100122 */
Sang-Hoon Parkd89e2fa2021-05-17 17:04:50 +0100123 void configure(const ITensorInfo *a, const ITensorInfo *b, const ITensorInfo *c, ITensorInfo *d, const AsmGemmInfo &info);
Anthony Barbiereaefd002018-07-20 17:49:35 +0100124
125 /** Indicates whether or not this function can be used to process the given parameters.
126 *
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000127 * @param[in] a Input tensor info (Matrix A)
128 * @param[in] b Input tensor info (Matrix B)
129 * @param[in] c Input tensor info (Matrix C) used to pass the bias for quantized calculations
130 * @param[in] d Output tensor to store the result of matrix multiplication. Data type supported: same as @p input0.
131 * @param[in] info GEMM meta-data
Anthony Barbiereaefd002018-07-20 17:49:35 +0100132 *
133 * @return a status.
134 */
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000135 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 +0000136
137 /** Indicates whether or not there is an optimal assembly implementation that can be used to process the given parameters.
138 *
Francesco Petrogalli553f6952022-06-30 10:22:01 +0000139 * This method has the same use of @ref
140 * NEGEMMConvolutionLayer::has_opt_impl, with the only caveat that
Ramy Elgammal91780022022-07-20 14:57:37 +0100141 * the value of arm_compute::WeightFormat need to be passed via the
Francesco Petrogalli553f6952022-06-30 10:22:01 +0000142 * parameter info.
Francesco.Petrogalli@arm.come33c5562022-03-31 17:55:35 +0000143 *
144 * @return a status.
145 */
Ramy Elgammal91780022022-07-20 14:57:37 +0100146 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 +0100147 /** Checks if activation is supported by the gemm assembly dispatcher
148 *
149 * @param[in] activation Activation to check
150 *
151 * @return True if activation is supported else false
152 */
153 static bool is_activation_supported(const ActivationLayerInfo &activation);
Anthony Barbierc8e84b52018-07-17 16:48:42 +0100154 /** Was the function successfully configured ?
155 *
156 * @return True if the function is configured and ready to run
157 */
Anthony Barbier71d9b572018-07-06 17:05:59 +0100158 bool is_configured() const;
Francesco Petrogalli553f6952022-06-30 10:22:01 +0000159 /** Indicates if the convolution executes in variable weights mode.
160 *
161 * Similar to @ref CpuGemm::isVarWeightsKernel
162 */
163 bool isVarWeightsKernel() const
164 {
165 return _arm_gemm && _arm_gemm->isVarWeightsKernel();
166 }
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000167
Anthony Barbier71d9b572018-07-06 17:05:59 +0100168 // Inherited methods overridden:
Ramy Elgammal91780022022-07-20 14:57:37 +0100169 void prepare(ITensorPack &tensors) override;
170 void run(ITensorPack &tensors) override;
Michele Di Giorgiod7316eb2021-06-16 11:14:41 +0100171 experimental::MemoryRequirements workspace() const override;
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000172
173private:
Michele Di Giorgiod7316eb2021-06-16 11:14:41 +0100174 std::unique_ptr<IFallback> _arm_gemm; /**< Interface for the arm_gemm fallback */
Anthony Barbier71d9b572018-07-06 17:05:59 +0100175};
Sang-Hoon Park4f7693d2021-05-12 13:59:10 +0100176} // namespace cpu
Anthony Barbierc8e84b52018-07-17 16:48:42 +0100177} // namespace arm_compute
Sang-Hoon Parkd89e2fa2021-05-17 17:04:50 +0100178#endif /* ARM_COMPUTE_CPU_INTERNAL_CPU_GEMM_ASSEMBLY_DISPATCH_H */