Compute Library
 19.08
NEGEMM Class Reference

Basic function to execute GEMM on NEON. More...

#include <NEGEMM.h>

Collaboration diagram for NEGEMM:
[legend]

Public Member Functions

 NEGEMM (std::shared_ptr< IMemoryManager > memory_manager=nullptr)
 Constructor. More...
 
 NEGEMM (const NEGEMM &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
 NEGEMM (NEGEMM &&)=default
 Default move constructor. More...
 
NEGEMMoperator= (const NEGEMM &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
NEGEMMoperator= (NEGEMM &&)=default
 Default move assignment operator. More...
 
void configure (const ITensor *a, const ITensor *b, const ITensor *c, ITensor *d, float alpha, float beta, const GEMMInfo &gemm_info=GEMMInfo())
 Initialise the kernel's inputs, output. More...
 
void run () override
 Run the kernels contained in the function. More...
 
void prepare () override
 Prepare the function for executing. More...
 
- Public Member Functions inherited from IFunction
virtual ~IFunction ()=default
 Destructor. More...
 

Static Public Member Functions

static Status validate (const ITensorInfo *a, const ITensorInfo *b, const ITensorInfo *c, const ITensorInfo *output, float alpha, float beta, const GEMMInfo &gemm_info=GEMMInfo())
 Static function to check if given info will lead to a valid configuration of NEGEMM. More...
 

Detailed Description

Basic function to execute GEMM on NEON.

This function calls the following NEON kernels:

  1. NEGEMMInterleave4x4Kernel (if the output tensor is a matrix)
  2. NEGEMMTranspose1xWKernel (if the output tensor is a matrix)
  3. NEGEMMMatrixMultiplyKernel
  4. NEGEMMMatrixAdditionKernel (if c != nullptr and beta != 0.0)

Definition at line 50 of file NEGEMM.h.

Constructor & Destructor Documentation

◆ NEGEMM() [1/3]

NEGEMM ( std::shared_ptr< IMemoryManager memory_manager = nullptr)

Constructor.

Definition at line 45 of file NEGEMM.cpp.

46  : _memory_group(memory_manager), _interleave_kernel(), _transpose_kernel(), _mm_kernel(), _asm_glue(memory_manager), _ma_kernel(), _tmp_a(), _tmp_b(), _original_b(nullptr),
47  _run_vector_matrix_multiplication(false), _run_addition(false), _reshape_b_only_on_first_run(false), _is_prepared(false)
48 {
49 }

◆ NEGEMM() [2/3]

NEGEMM ( const NEGEMM )
delete

Prevent instances of this class from being copied (As this class contains pointers)

◆ NEGEMM() [3/3]

NEGEMM ( NEGEMM &&  )
default

Default move constructor.

Member Function Documentation

◆ configure()

void configure ( const ITensor a,
const ITensor b,
const ITensor c,
ITensor d,
float  alpha,
float  beta,
const GEMMInfo gemm_info = GEMMInfo() 
)

Initialise the kernel's inputs, output.

Note
GEMM: General Matrix Multiply - [alpha * A * B + beta * C].
GEMM: The tensors a, b, c, d must have the same data type. You should not mix data types when calling this function.
Parameters
[in]aFirst input tensor (Matrix A or Vector A). Data type supported: F16/F32
[in]bSecond input tensor (Matrix B). Data type supported: same as a
[in]cThird input tensor (Matrix C). It can be a nullptr if just the multiplication between a and b is needed. Data type supported: same as a
[out]dOutput tensor. Data type supported: same as a
[in]alphaWeight of the matrix product
[in]betaWeight of matrix C
[in]gemm_info(Optional) Specifies if the matrix A and/or matrix B have been reshaped and if the reshape of matrix B should happen only for the first run

Definition at line 51 of file NEGEMM.cpp.

52 {
53  ARM_COMPUTE_ERROR_THROW_ON(NEGEMM::validate(a->info(), b->info(), (c != nullptr) ? c->info() : nullptr, d->info(), alpha, beta, gemm_info));
54 
55  // Check if we need to reshape the matrix B only on the first run
56  _is_prepared = false;
57  _reshape_b_only_on_first_run = gemm_info.reshape_b_only_on_first_run();
58  _run_vector_matrix_multiplication = a->info()->dimension(1) < 2;
59  _original_b = b;
60 
61  bool run_optimised = c == nullptr && bool(NEGEMMAssemblyDispatch::validate(a->info(), b->info(), c != nullptr ? c->info() : nullptr, d->info(), alpha, beta, gemm_info));
62 
63  if(run_optimised)
64  {
66  {
67  GEMMInfo gemm_info_ntb = gemm_info;
68  gemm_info_ntb.set_pretranpose_B(false);
69  _asm_glue.configure(a, b, c, d, alpha, beta, gemm_info_ntb);
70  }
71  else
72  {
73  _asm_glue.configure(a, b, c, d, alpha, beta, gemm_info);
74  }
75  ARM_COMPUTE_ERROR_ON(!_asm_glue.is_configured());
76  }
77  else
78  {
79  if(_run_vector_matrix_multiplication)
80  {
81  // Configure the matrix multiply kernel
82  _mm_kernel.configure(a, b, d, alpha, false);
83  }
84  else
85  {
86  TensorShape shape_tmp_a = a->info()->tensor_shape();
87  TensorShape shape_tmp_b = b->info()->tensor_shape();
88 
89  shape_tmp_a.set(0, a->info()->dimension(0) * 4);
90  shape_tmp_a.set(1, std::ceil(a->info()->dimension(1) / 4.0f));
91 
92  const unsigned int transpose_w = 16 / data_size_from_type(b->info()->data_type());
93  shape_tmp_b.set(0, b->info()->dimension(1) * transpose_w);
94  shape_tmp_b.set(1, std::ceil(b->info()->dimension(0) / static_cast<float>(transpose_w)));
95 
96  TensorInfo info_a = a->info()->clone()->set_tensor_shape(shape_tmp_a).set_is_resizable(true);
97  TensorInfo info_b = b->info()->clone()->set_tensor_shape(shape_tmp_b).set_is_resizable(true);
98 
99  _tmp_a.allocator()->init(info_a);
100  _tmp_b.allocator()->init(info_b);
101 
102  // Manage intermediate buffers
103  _memory_group.manage(&_tmp_a);
104  if(!_reshape_b_only_on_first_run)
105  {
106  _memory_group.manage(&_tmp_b);
107  }
108 
109  int m = a->info()->dimension(1);
110  int n = b->info()->dimension(0);
111  int k = a->info()->dimension(0);
112 
113  // Configure interleave kernel
114  _interleave_kernel.configure(a, &_tmp_a);
115 
116  // Configure transpose kernel
117  _transpose_kernel.configure(b, &_tmp_b);
118 
119  // Configure matrix multiplication kernel
120  _mm_kernel.configure(&_tmp_a, &_tmp_b, d, alpha, true, GEMMReshapeInfo(m, n, k));
121 
122  // Allocate once the all configure methods have been called
123  _tmp_a.allocator()->allocate();
124  if(!_reshape_b_only_on_first_run)
125  {
126  _tmp_b.allocator()->allocate();
127  }
128  }
129 
130  // Configure matrix addition kernel
131  if(beta != 0 && c != nullptr)
132  {
133  _ma_kernel.configure(c, d, beta);
134  _run_addition = true;
135  }
136  }
137 }
void init(const TensorAllocator &allocator, const Coordinates &coords, TensorInfo &sub_info)
Shares the same backing memory with another tensor allocator, while the tensor info might be differen...
SimpleTensor< float > b
Definition: DFT.cpp:157
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:337
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Definition: Error.h:327
TensorAllocator * allocator()
Return a pointer to the tensor's allocator.
Definition: Tensor.cpp:48
void configure(const ITensor *a, const ITensor *b, const ITensor *c, ITensor *d, float alpha, float beta, const GEMMInfo &gemm_info)
If supported create an ACL function else fallback to the arm_gemm function.
static Status validate(const ITensorInfo *a, const ITensorInfo *b, const ITensorInfo *c, const ITensorInfo *output, float alpha, float beta, const GEMMInfo &gemm_info=GEMMInfo())
Static function to check if given info will lead to a valid configuration of NEGEMM.
Definition: NEGEMM.cpp:139
void manage(TensorType *obj)
Sets a object to be managed by the given memory group.
bool is_configured() const
Was the function successfully configured ?
void allocate() override
Allocate size specified by TensorInfo of CPU memory.
void configure(const ITensor *input, ITensor *output)
Initialise the kernel's input and output.
size_t data_size_from_type(DataType data_type)
The size in bytes of the data type.
Definition: Utils.h:109
static MemoryPolicy get_policy()
Definition: MEMUtils.cpp:86
void configure(const ITensor *input, ITensor *output)
Initialise the kernel's input and output.
void configure(const ITensor *input0, const ITensor *input1, ITensor *output, float alpha, bool is_interleaved, const GEMMReshapeInfo &reshape_info=GEMMReshapeInfo())
Initialise the kernel's input and output.
void configure(const ITensor *input, ITensor *output, float beta)
Initialise the kernel's input and output.
static Status validate(const ITensorInfo *a, const ITensorInfo *b, const ITensorInfo *c, const ITensorInfo *d, float alpha, float beta, const GEMMInfo &gemm_info)
Indicates whether or not this function can be used to process the given parameters.

References TensorAllocator::allocate(), Tensor::allocator(), arm_compute::test::validation::alpha, ARM_COMPUTE_ERROR_ON, ARM_COMPUTE_ERROR_THROW_ON, arm_compute::test::validation::b, ICloneable< T >::clone(), NEGEMMInterleave4x4Kernel::configure(), NEGEMMMatrixAdditionKernel::configure(), NEGEMMMatrixMultiplyKernel::configure(), NEGEMMTranspose1xWKernel::configure(), NEGEMMAssemblyDispatch::configure(), arm_compute::data_size_from_type(), ITensorInfo::dimension(), MEMInfo::get_policy(), ITensor::info(), TensorAllocator::init(), NEGEMMAssemblyDispatch::is_configured(), MemoryGroupBase< TensorType >::manage(), arm_compute::MINIMIZE, GEMMInfo::reshape_b_only_on_first_run(), TensorShape::set(), GEMMInfo::set_pretranpose_B(), ITensorInfo::tensor_shape(), NEGEMM::validate(), and NEGEMMAssemblyDispatch::validate().

Referenced by NERNNLayer::configure(), NEWinogradConvolutionLayer::configure(), and NELSTMLayer::configure().

◆ operator=() [1/2]

NEGEMM& operator= ( const NEGEMM )
delete

Prevent instances of this class from being copied (As this class contains pointers)

◆ operator=() [2/2]

NEGEMM& operator= ( NEGEMM &&  )
default

Default move assignment operator.

◆ prepare()

void prepare ( )
overridevirtual

Prepare the function for executing.

Any one off pre-processing step required by the function is handled here

Note
Prepare stage might not need all the function's buffers' backing memory to be available in order to execute

Reimplemented from IFunction.

Definition at line 273 of file NEGEMM.cpp.

274 {
275  if(!_is_prepared)
276  {
277  if(_asm_glue.is_configured())
278  {
279  ARM_COMPUTE_ERROR_ON(!_original_b->is_used());
280 
281  _asm_glue.prepare();
282  }
283  else if(_reshape_b_only_on_first_run && !_run_vector_matrix_multiplication && !_asm_glue.is_configured())
284  {
285  ARM_COMPUTE_ERROR_ON(!_original_b->is_used());
286 
287  _tmp_b.allocator()->allocate();
288  NEScheduler::get().schedule(&_transpose_kernel, Window::DimY);
289  _original_b->mark_as_unused();
290  }
291 
292  _is_prepared = true;
293  }
294 }
bool is_used() const
Flags if the tensor is used or not.
Definition: ITensor.cpp:162
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:337
TensorAllocator * allocator()
Return a pointer to the tensor's allocator.
Definition: Tensor.cpp:48
void mark_as_unused() const
Marks a tensor as unused.
Definition: ITensor.cpp:167
void prepare() override
Runs a preparation step, usually for pre-transposing matrix b.
bool is_configured() const
Was the function successfully configured ?
void allocate() override
Allocate size specified by TensorInfo of CPU memory.
static constexpr size_t DimY
Alias for dimension 1 also known as Y dimension.
Definition: Window.h:45
virtual void schedule(ICPPKernel *kernel, const Hints &hints)=0
Runs the kernel in the same thread as the caller synchronously.
static IScheduler & get()
Access the scheduler singleton.
Definition: Scheduler.cpp:96

References TensorAllocator::allocate(), Tensor::allocator(), ARM_COMPUTE_ERROR_ON, Window::DimY, Scheduler::get(), NEGEMMAssemblyDispatch::is_configured(), ITensor::is_used(), ITensor::mark_as_unused(), NEGEMMAssemblyDispatch::prepare(), and IScheduler::schedule().

Referenced by NERNNLayer::prepare(), NEFullyConnectedLayer::prepare(), NEGEMMConvolutionLayer::prepare(), and NEGEMM::run().

◆ run()

void run ( )
overridevirtual

Run the kernels contained in the function.

For NEON kernels:

  • Multi-threading is used for the kernels which are parallelisable.
  • By default std::thread::hardware_concurrency() threads are used.
Note
CPPScheduler::set_num_threads() can be used to manually set the number of threads

For OpenCL kernels:

  • All the kernels are enqueued on the queue associated with CLScheduler.
  • The queue is then flushed.
Note
The function will not block until the kernels are executed. It is the user's responsibility to wait.
Will call prepare() on first run if hasn't been done

Implements IFunction.

Definition at line 239 of file NEGEMM.cpp.

240 {
241  prepare();
242 
243  MemoryGroupResourceScope scope_mg(_memory_group);
244 
245  if(_asm_glue.is_configured())
246  {
247  _asm_glue.run();
248  }
249  else
250  {
251  if(!_run_vector_matrix_multiplication)
252  {
253  // Run interleave kernel
254  NEScheduler::get().schedule(&_interleave_kernel, Window::DimY);
255 
256  if(!_reshape_b_only_on_first_run)
257  {
258  // Run transpose kernel
259  NEScheduler::get().schedule(&_transpose_kernel, Window::DimY);
260  }
261  }
262 
263  NEScheduler::get().schedule(&_mm_kernel, _run_vector_matrix_multiplication ? Window::DimX : Window::DimY);
264 
265  // Run matrix addition kernel
266  if(_run_addition)
267  {
268  NEScheduler::get().schedule(&_ma_kernel, Window::DimY);
269  }
270  }
271 }
void run() override
Run the kernels contained in the function.
static constexpr size_t DimX
Alias for dimension 0 also known as X dimension.
Definition: Window.h:43
bool is_configured() const
Was the function successfully configured ?
static constexpr size_t DimY
Alias for dimension 1 also known as Y dimension.
Definition: Window.h:45
virtual void schedule(ICPPKernel *kernel, const Hints &hints)=0
Runs the kernel in the same thread as the caller synchronously.
void prepare() override
Prepare the function for executing.
Definition: NEGEMM.cpp:273
static IScheduler & get()
Access the scheduler singleton.
Definition: Scheduler.cpp:96

References Window::DimX, Window::DimY, Scheduler::get(), NEGEMMAssemblyDispatch::is_configured(), NEGEMM::prepare(), NEGEMMAssemblyDispatch::run(), and IScheduler::schedule().

Referenced by NEWinogradConvolutionLayer::run(), NERNNLayer::run(), NEFullyConnectedLayer::run(), NELSTMLayer::run(), and NEGEMMConvolutionLayer::run().

◆ validate()

Status validate ( const ITensorInfo a,
const ITensorInfo b,
const ITensorInfo c,
const ITensorInfo output,
float  alpha,
float  beta,
const GEMMInfo gemm_info = GEMMInfo() 
)
static

Static function to check if given info will lead to a valid configuration of NEGEMM.

Parameters
[in]aFirst input tensor info (Matrix or Vector A). Data types supported: F16/F32
[in]bSecond input tensor info (Matrix B). Data type supported: same as a.
[in]cThird input tensor info (Matrix C). It can be a nullptr if just the multiplication between a and b is needed. Data type supported: same as a.
[out]outputOutput tensor info. Data type supported: same as a
[in]alphaWeight of the matrix product
[in]betaWeight of matrix C
[in]gemm_info(Optional) Specifies if the matrix A and/or matrix B have been reshaped and if the reshape of matrix B should happen only for the first run
Returns
a status

Definition at line 139 of file NEGEMM.cpp.

140 {
142 
146  ARM_COMPUTE_RETURN_ERROR_ON_MSG(a->dimension(0) != b->dimension(1), "The product AB is defined only if the number of columns in A is equal to the number of rows in B");
147  ARM_COMPUTE_RETURN_ERROR_ON_MSG(gemm_info.is_a_reshaped(), "Matrix A already reshaped is not supported");
148  ARM_COMPUTE_RETURN_ERROR_ON_MSG(gemm_info.is_b_reshaped(), "Matrix B already reshaped is not supported");
149 
150  if(c != nullptr)
151  {
152  ARM_COMPUTE_RETURN_ERROR_ON(gemm_info.depth_output_gemm3d() != 0);
153  ARM_COMPUTE_RETURN_ERROR_ON(gemm_info.reinterpret_input_as_3d());
155  ARM_COMPUTE_RETURN_ERROR_ON_MSG(a->dimension(1) != c->dimension(1), "The C matrix must have the same number of rows as the matrix A");
156  ARM_COMPUTE_RETURN_ERROR_ON_MSG(b->dimension(0) != c->dimension(0), "The C matrix must have the same number of columns as the matrix B");
157  }
158 
159  if(output->total_size() != 0)
160  {
161  ARM_COMPUTE_RETURN_ERROR_ON(b->dimension(0) != output->dimension(0));
162  if(gemm_info.depth_output_gemm3d() != 0)
163  {
164  if(gemm_info.reinterpret_input_as_3d())
165  {
166  ARM_COMPUTE_RETURN_ERROR_ON(a->dimension(1) != output->dimension(1));
167  ARM_COMPUTE_RETURN_ERROR_ON(a->dimension(2) != output->dimension(2));
168  }
169  else
170  {
171  ARM_COMPUTE_RETURN_ERROR_ON(a->dimension(1) != output->dimension(1) * output->dimension(2));
172  }
173  }
174  else
175  {
176  ARM_COMPUTE_RETURN_ERROR_ON(a->dimension(1) != output->dimension(1));
177  }
178  }
179 
180  // Check if we need to run the optimized assembly kernel
181  const bool run_optimised = c == nullptr && bool(NEGEMMAssemblyDispatch::validate(a, b, c, output, alpha, beta, gemm_info));
182 
183  if(!run_optimised)
184  {
185  ARM_COMPUTE_RETURN_ERROR_ON_MSG(gemm_info.reinterpret_input_as_3d(), "NEGEMM cannot reinterpret the input tensor as 3D");
186  ARM_COMPUTE_RETURN_ERROR_ON_MSG(gemm_info.depth_output_gemm3d() != 0, "NEGEMM cannot reinterpret the output tensor as 3D");
187 
188  // Check if the first input tensor is a vector.
189  const bool run_vector_matrix_multiplication = a->dimension(1) < 2;
190  // Check if we need to reshape the matrix A and matrix B
191  const bool run_interleave_transpose = !run_vector_matrix_multiplication && !(gemm_info.reshape_b_only_on_first_run());
192 
193  // Arguments used by GEMMReshapeInfo
194  // If we pass the matrix A and matrix B reshaped to NEGEMMMatrixMultiplyKernel, we need to pass m, n, k, mult_transpose1xW_width and mult_interleave4x4_height to NEGEMMReshapeInfo
195  // in order to know how the matrices have been reshaped
196  const int m = a->dimension(1);
197  const int n = b->dimension(0);
198  const int k = a->dimension(0);
199  int mult_transpose1xW_width = 1;
200  int mult_interleave4x4_height = 1;
201 
202  const GEMMReshapeInfo reshape_info = GEMMReshapeInfo(m, n, k, mult_transpose1xW_width, mult_interleave4x4_height, gemm_info.depth_output_gemm3d());
203 
204  const ITensorInfo *matrix_a_info = a;
205  const ITensorInfo *matrix_b_info = b;
206 
207  TensorInfo tmp_a_info{};
208  TensorInfo tmp_b_info{};
209  TensorInfo tmp_output_info = *output->clone();
210 
211  if(run_interleave_transpose)
212  {
213  matrix_a_info = &tmp_a_info;
214  matrix_b_info = &tmp_b_info;
215 
216  // Validate interleave kernel
217  auto_init_if_empty(tmp_a_info, a->clone()->set_tensor_shape(compute_interleaved_shape(*a, mult_interleave4x4_height, gemm_info.reinterpret_input_as_3d())));
219 
220  // Validate transpose kernel
221  auto_init_if_empty(tmp_b_info, b->clone()->set_tensor_shape(compute_transpose1xW_with_element_size_shape(*b, mult_transpose1xW_width)));
223  }
224 
225  // Validate matrix multiply
226  auto_init_if_empty(tmp_output_info, matrix_a_info->clone()->set_tensor_shape(compute_mm_shape(*matrix_a_info, *matrix_b_info, run_interleave_transpose, reshape_info)));
227  ARM_COMPUTE_RETURN_ON_ERROR(NEGEMMMatrixMultiplyKernel::validate(matrix_a_info, matrix_b_info, &tmp_output_info, alpha, run_interleave_transpose, reshape_info));
228  }
229 
230  // Validate matrix addition kernel
231  if(beta != 0 && c != nullptr)
232  {
234  }
235 
236  return Status{};
237 }
TensorShape compute_transpose1xW_with_element_size_shape(const ITensorInfo &b, int mult_transpose1xW_width=1)
Calculate the transposed 1xW width element shape.
SimpleTensor< float > b
Definition: DFT.cpp:157
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...)
Definition: Validate.h:545
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Definition: Error.h:193
TensorShape compute_mm_shape(const ITensorInfo &input0, const ITensorInfo &input1, bool is_interleaved_transposed, const GEMMReshapeInfo &reshape_info)
Calculate the matrix multiplication output shape of two tensors.
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
Definition: Validate.h:791
1 channel, 1 F32 per channel
#define ARM_COMPUTE_RETURN_ERROR_ON(cond)
If the condition is true, an error is returned.
Definition: Error.h:244
static Status validate(const ITensorInfo *input, const ITensorInfo *output, float beta)
Static function to check if given info will lead to a valid configuration of NEGEMMMatrixAdditionKern...
TensorShape compute_interleaved_shape(const ITensorInfo &a, int mult_interleave4x4_height=1, bool reinterpret_input_as_3d=false)
Calculate the interleaved shape of an input tensor.
static Status validate(const ITensorInfo *input, const ITensorInfo *output)
Static function to check if given info will lead to a valid configuration of NEGEMMTranspose1xWKernel...
bool auto_init_if_empty(ITensorInfo &info, const TensorShape &shape, int num_channels, DataType data_type, QuantizationInfo quantization_info=QuantizationInfo())
Auto initialize the tensor info (shape, number of channels and data type) if the current assignment i...
Definition: Helpers.inl:201
#define ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(tensor)
Definition: Validate.h:71
1 channel, 1 F16 per channel
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:160
static Status validate(const ITensorInfo *input, const ITensorInfo *output)
Static function to check if given info will lead to a valid configuration of NEGEMMInterleave4x4Kerne...
#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond,...)
If the condition is true, an error is returned.
Definition: Error.h:214
static Status validate(const ITensorInfo *input0, const ITensorInfo *input1, const ITensorInfo *output, float alpha, bool is_interleaved, const GEMMReshapeInfo &reshape_info)
Static function to check if given info will lead to a valid configuration of NEGEMMMatrixMultiplyKern...
static Status validate(const ITensorInfo *a, const ITensorInfo *b, const ITensorInfo *c, const ITensorInfo *d, float alpha, float beta, const GEMMInfo &gemm_info)
Indicates whether or not this function can be used to process the given parameters.

References arm_compute::test::validation::alpha, ARM_COMPUTE_RETURN_ERROR_ON, ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED, ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN, ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES, ARM_COMPUTE_RETURN_ERROR_ON_MSG, ARM_COMPUTE_RETURN_ON_ERROR, ARM_COMPUTE_UNUSED, arm_compute::auto_init_if_empty(), arm_compute::test::validation::b, ICloneable< T >::clone(), TensorInfo::clone(), arm_compute::misc::shape_calculator::compute_interleaved_shape(), arm_compute::misc::shape_calculator::compute_mm_shape(), arm_compute::misc::shape_calculator::compute_transpose1xW_with_element_size_shape(), GEMMInfo::depth_output_gemm3d(), ITensorInfo::dimension(), arm_compute::F16, arm_compute::F32, GEMMInfo::is_a_reshaped(), GEMMInfo::is_b_reshaped(), GEMMInfo::reinterpret_input_as_3d(), GEMMInfo::reshape_b_only_on_first_run(), ITensorInfo::total_size(), NEGEMMInterleave4x4Kernel::validate(), NEGEMMMatrixAdditionKernel::validate(), NEGEMMMatrixMultiplyKernel::validate(), NEGEMMTranspose1xWKernel::validate(), and NEGEMMAssemblyDispatch::validate().

Referenced by NEGEMM::configure(), and NELSTMLayer::validate().


The documentation for this class was generated from the following files: