aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichalis Spyrou <michalis.spyrou@arm.com>2020-06-18 10:14:57 +0100
committerMichalis Spyrou <michalis.spyrou@arm.com>2020-06-19 14:35:22 +0000
commitce0c67559cf03965acc8f212263a9f53205a0a3f (patch)
treec37105c72538108c46e5964cf49d15acd2d85980
parent3be0b8c8d4e90bd264e9575dc2b6994ce8e14d50 (diff)
downloadComputeLibrary-ce0c67559cf03965acc8f212263a9f53205a0a3f.tar.gz
COMPMID-3377: Async support to NEElementwiseUnaryLayerKernel kernels/functions
Signed-off-by: Michalis Spyrou <michalis.spyrou@arm.com> Change-Id: I208287b44ece051e95f891d43a691cb0ac6e56c5 Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/3419 Tested-by: Arm Jenkins <bsgcomp@arm.com> Reviewed-by: Michele Di Giorgio <michele.digiorgio@arm.com> Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
-rw-r--r--arm_compute/core/CPP/ICPPKernel.h2
-rw-r--r--arm_compute/core/NEON/kernels/NEActivationLayerKernel.h2
-rw-r--r--arm_compute/core/NEON/kernels/NEElementwiseOperationKernel.h47
-rw-r--r--arm_compute/core/NEON/kernels/NEReshapeLayerKernel.h2
-rw-r--r--arm_compute/core/experimental/Types.h26
-rw-r--r--arm_compute/runtime/CPP/CPPScheduler.h4
-rw-r--r--arm_compute/runtime/IOperator.h4
-rw-r--r--arm_compute/runtime/IScheduler.h2
-rw-r--r--arm_compute/runtime/NEON/INEOperator.h4
-rw-r--r--arm_compute/runtime/NEON/functions/NEElementwiseOperations.h383
-rw-r--r--arm_compute/runtime/NEON/functions/NEPReluLayer.h57
-rw-r--r--arm_compute/runtime/OMP/OMPScheduler.h2
-rw-r--r--arm_compute/runtime/SingleThreadScheduler.h2
-rw-r--r--src/core/NEON/kernels/NEActivationLayerKernel.cpp6
-rw-r--r--src/core/NEON/kernels/NEElementwiseOperationKernel.cpp44
-rw-r--r--src/core/NEON/kernels/NEReshapeLayerKernel.cpp6
-rw-r--r--src/runtime/CPP/CPPScheduler.cpp8
-rw-r--r--src/runtime/CPP/SingleThreadScheduler.cpp2
-rw-r--r--src/runtime/NEON/INEOperator.cpp4
-rw-r--r--src/runtime/NEON/functions/NEActivationLayer.cpp6
-rw-r--r--src/runtime/NEON/functions/NEElementwiseOperators.cpp335
-rw-r--r--src/runtime/NEON/functions/NEPReluLayer.cpp47
-rw-r--r--src/runtime/NEON/functions/NEReshapeLayer.cpp7
-rw-r--r--src/runtime/OMP/OMPScheduler.cpp2
-rw-r--r--tests/framework/instruments/SchedulerTimer.cpp2
25 files changed, 883 insertions, 123 deletions
diff --git a/arm_compute/core/CPP/ICPPKernel.h b/arm_compute/core/CPP/ICPPKernel.h
index 3ec54756a0..45c7b52af4 100644
--- a/arm_compute/core/CPP/ICPPKernel.h
+++ b/arm_compute/core/CPP/ICPPKernel.h
@@ -84,7 +84,7 @@ public:
* @param[in] window Region on which to execute the kernel. (Must be a region of the window returned by window())
* @param[in] info Info about executing thread and CPU.
*/
- virtual void run_op(const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs, const Window &window, const ThreadInfo &info)
+ virtual void run_op(const InputTensorMap &inputs, const OutputTensorMap &outputs, const Window &window, const ThreadInfo &info)
{
ARM_COMPUTE_UNUSED(inputs, outputs, window, info);
}
diff --git a/arm_compute/core/NEON/kernels/NEActivationLayerKernel.h b/arm_compute/core/NEON/kernels/NEActivationLayerKernel.h
index 399afa63c6..7064e3dc7c 100644
--- a/arm_compute/core/NEON/kernels/NEActivationLayerKernel.h
+++ b/arm_compute/core/NEON/kernels/NEActivationLayerKernel.h
@@ -76,7 +76,7 @@ public:
static Status validate(const ITensorInfo *input, const ITensorInfo *output, const ActivationLayerInfo &act_info);
// Inherited methods overridden:
- void run_op(const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs,
+ void run_op(const InputTensorMap &inputs, const OutputTensorMap &outputs,
const Window &window, const ThreadInfo &info) override;
private:
diff --git a/arm_compute/core/NEON/kernels/NEElementwiseOperationKernel.h b/arm_compute/core/NEON/kernels/NEElementwiseOperationKernel.h
index 61c25e1a2a..b109ddd0f8 100644
--- a/arm_compute/core/NEON/kernels/NEElementwiseOperationKernel.h
+++ b/arm_compute/core/NEON/kernels/NEElementwiseOperationKernel.h
@@ -57,18 +57,19 @@ public:
/** Default destructor */
~NEElementwiseOperationKernel() = default;
- // Inherited methods overridden:
- void run(const Window &window, const ThreadInfo &info) override;
-
/** Common signature for all the specialised arithmetic functions
*
- * @param[in] input1 First tensor input. Data types supported: QASYMM8/S16/F16/S32/F32.
- * @param[in] input2 Second tensor input. Data types supported: Same as @p input1.
- * @param[in] output Output tensor. Data types supported: Dependent on subclass.
+ * @param[in] input1 First tensor input info. Data types supported: QASYMM8/S16/F16/S32/F32.
+ * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[in] output Output tensor info. Data types supported: Dependent on subclass.
* @param[in] window Region on which to execute the kernel.
*/
using ElementwiseFunction = void(const ITensor *input1, const ITensor *input2, ITensor *output, const Window &window);
+ // Inherited methods overridden:
+ void run_op(const InputTensorMap &inputs, const OutputTensorMap &outputs,
+ const Window &window, const ThreadInfo &info) override;
+
protected:
/** Validate the argument passed to the kernel
*
@@ -81,7 +82,7 @@ protected:
/** Commmon configure function for element-wise operators with no additional options (e.g. Min, Max, SquaredDiff)
*
*/
- void configure_common(const ITensor *input1, const ITensor *input2, ITensor *output);
+ void configure_common(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output);
/** Function to use for the particular tensor types passed to configure() */
std::function<void(const ITensor *input1, const ITensor *input2, ITensor *output, const Window &window)> _function;
@@ -100,11 +101,11 @@ public:
/** Static function to check if given info will lead to a valid configuration of @ref NEArithmeticOperationKernel
*
* @param[in] op Arithmetic operation to be executed.
- * @param[in] input1 First tensor input. Data types supported: QASYMM8/S16/F16/S32/F32.
- * @param[in] input2 Second tensor input. Data types supported: Same as @p input1.
- * @param[in] output Output tensor. Data types supported: Same as @p input1.
+ * @param[in] input1 First tensor input info. Data types supported: QASYMM8/S16/F16/S32/F32.
+ * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[in] output Output tensor info. Data types supported: Same as @p input1.
*/
- void configure(ArithmeticOperation op, const ITensor *input1, const ITensor *input2, ITensor *output);
+ void configure(ArithmeticOperation op, const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output);
/** Static function to check if given info will lead to a valid configuration of @ref NEArithmeticOperationKernel
*
@@ -130,11 +131,11 @@ public:
/** Static function to check if given info will lead to a valid configuration of @ref NEArithmeticOperationKernel
*
- * @param[in] input1 First tensor input. Data types supported: F16/F32.
- * @param[in] input2 Second tensor input. Data types supported: Same as @p input1.
- * @param[in] output Output tensor. Data types supported: Same as @p input1.
+ * @param[in] input1 First tensor input info. Data types supported: F16/F32.
+ * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[in] output Output tensor info. Data types supported: Same as @p input1.
*/
- void configure(const ITensor *input1, const ITensor *input2, ITensor *output);
+ void configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output);
/** Static function to check if given info will lead to a valid configuration of @ref NEArithmeticOperationKernel
*
@@ -159,11 +160,11 @@ public:
/** Static function to check if given info will lead to a valid configuration of @ref NEArithmeticOperationKernel
*
- * @param[in] input1 First tensor input. Data types supported: F16/F32.
- * @param[in] input2 Second tensor input. Data types supported: Same as @p input1.
- * @param[out] output Output tensor. Data types supported: Same as @p input1.
+ * @param[in] input1 First tensor input info. Data types supported: F16/F32.
+ * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[out] output Output tensor info. Data types supported: Same as @p input1.
*/
- void configure(const ITensor *input1, const ITensor *input2, ITensor *output);
+ void configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output);
/** Static function to check if given info will lead to a valid configuration of @ref NEArithmeticOperationKernel
*
@@ -189,11 +190,11 @@ public:
/** Static function to check if given info will lead to a valid configuration of @ref NEComparisonOperationKernel
*
* @param[in] op Comparison operation to be executed.
- * @param[in] input1 First tensor input. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
- * @param[in] input2 Second tensor input. Data types supported: Same as @p input1.
- * @param[in] output Output tensor. Data types supported: U16/U32.
+ * @param[in] input1 First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[in] output Output tensor info. Data types supported: U16/U32.
*/
- void configure(ComparisonOperation op, const ITensor *input1, const ITensor *input2, ITensor *output);
+ void configure(ComparisonOperation op, const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output);
/** Static function to check if given info will lead to a valid configuration of @ref NEComparisonOperationKernel
*
diff --git a/arm_compute/core/NEON/kernels/NEReshapeLayerKernel.h b/arm_compute/core/NEON/kernels/NEReshapeLayerKernel.h
index 7a4dce128d..1ed3554db2 100644
--- a/arm_compute/core/NEON/kernels/NEReshapeLayerKernel.h
+++ b/arm_compute/core/NEON/kernels/NEReshapeLayerKernel.h
@@ -57,7 +57,7 @@ public:
static Status validate(const ITensorInfo *input, const ITensorInfo *output);
// Inherited methods overridden:
- void run_op(const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs,
+ void run_op(const InputTensorMap &inputs, const OutputTensorMap &outputs,
const Window &window, const ThreadInfo &info) override;
};
} // namespace arm_compute
diff --git a/arm_compute/core/experimental/Types.h b/arm_compute/core/experimental/Types.h
index 2b5591872a..62dd6ff305 100644
--- a/arm_compute/core/experimental/Types.h
+++ b/arm_compute/core/experimental/Types.h
@@ -50,29 +50,9 @@ enum class TensorType
ACL_INT_2 = 52
};
-/** Input tensor aggregate */
-struct InputTensor
-{
- InputTensor(TensorType type, const ITensor *tensor)
- : type(type), tensor(tensor)
- {
- }
-
- TensorType type{ TensorType::ACL_UNKNOWN };
- const ITensor *tensor{ nullptr };
-};
-/** Output tensor aggregate */
-struct OutputTensor
-{
- OutputTensor(TensorType type, ITensor *tensor)
- : type(type), tensor(tensor)
- {
- }
-
- TensorType type{ TensorType::ACL_UNKNOWN };
- ITensor *tensor{ nullptr };
-};
-using OperatorTensor = OutputTensor;
+using InputTensorMap = std::map<TensorType, const ITensor *>;
+using OutputTensorMap = std::map<TensorType, ITensor *>;
+using OperatorTensorMap = OutputTensorMap;
namespace experimental
{
diff --git a/arm_compute/runtime/CPP/CPPScheduler.h b/arm_compute/runtime/CPP/CPPScheduler.h
index 2ccb094fdb..2f7951eb59 100644
--- a/arm_compute/runtime/CPP/CPPScheduler.h
+++ b/arm_compute/runtime/CPP/CPPScheduler.h
@@ -77,7 +77,7 @@ public:
* @param[in] inputs Vector that contains the input tensors.
* @param[in] outputs Vector that contains the output tensors.
*/
- void schedule_op(ICPPKernel *kernel, const Hints &hints, const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs) override;
+ void schedule_op(ICPPKernel *kernel, const Hints &hints, const InputTensorMap &inputs, const OutputTensorMap &outputs) override;
protected:
/** Will run the workloads in parallel using num_threads
@@ -87,7 +87,7 @@ protected:
void run_workloads(std::vector<Workload> &workloads) override;
private:
- void schedule_common(ICPPKernel *kernel, const Hints &hints, const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs);
+ void schedule_common(ICPPKernel *kernel, const Hints &hints, const InputTensorMap &inputs, const OutputTensorMap &outputs);
struct Impl;
std::unique_ptr<Impl> _impl;
};
diff --git a/arm_compute/runtime/IOperator.h b/arm_compute/runtime/IOperator.h
index cf3c8b05a1..887bed4de2 100644
--- a/arm_compute/runtime/IOperator.h
+++ b/arm_compute/runtime/IOperator.h
@@ -46,7 +46,7 @@ public:
* @param[in] workspace Vector that contains the workspace tensors.
*
*/
- virtual void run(std::vector<InputTensor> inputs, std::vector<OutputTensor> outputs, std::vector<OperatorTensor> workspace) = 0;
+ virtual void run(InputTensorMap inputs, OutputTensorMap outputs, OperatorTensorMap workspace) = 0;
/** Prepare the function for executing
*
* Any one off pre-processing step required by the function is handled here
@@ -55,7 +55,7 @@ public:
*
* @note Prepare stage might not need all the function's buffers' backing memory to be available in order to execute
*/
- virtual void prepare(std::vector<OperatorTensor> constants) = 0;
+ virtual void prepare(OperatorTensorMap constants) = 0;
/** Return the memory requirements required by the workspace
*/
diff --git a/arm_compute/runtime/IScheduler.h b/arm_compute/runtime/IScheduler.h
index 40da86fd10..29135f42c0 100644
--- a/arm_compute/runtime/IScheduler.h
+++ b/arm_compute/runtime/IScheduler.h
@@ -157,7 +157,7 @@ public:
* @param[in] inputs Vector containing the input tensors.
* @param[in] outputs Vector containing the output tensors.
*/
- virtual void schedule_op(ICPPKernel *kernel, const Hints &hints, const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs) = 0;
+ virtual void schedule_op(ICPPKernel *kernel, const Hints &hints, const InputTensorMap &inputs, const OutputTensorMap &outputs) = 0;
/** Execute all the passed workloads
*
diff --git a/arm_compute/runtime/NEON/INEOperator.h b/arm_compute/runtime/NEON/INEOperator.h
index 2f6e18048d..2e8f8f3d42 100644
--- a/arm_compute/runtime/NEON/INEOperator.h
+++ b/arm_compute/runtime/NEON/INEOperator.h
@@ -54,8 +54,8 @@ public:
INEOperator &operator=(INEOperator &&) = default;
// Inherited methods overridden:
- void run(std::vector<InputTensor> inputs, std::vector<OutputTensor> outputs, std::vector<OperatorTensor> workspace) override final;
- void prepare(std::vector<OperatorTensor> constants) override final;
+ void run(InputTensorMap inputs, OutputTensorMap outputs, OperatorTensorMap workspace) override final;
+ void prepare(OperatorTensorMap constants) override final;
protected:
std::unique_ptr<INEKernel> _kernel;
diff --git a/arm_compute/runtime/NEON/functions/NEElementwiseOperations.h b/arm_compute/runtime/NEON/functions/NEElementwiseOperations.h
index cac105cdb9..08f798ec6e 100644
--- a/arm_compute/runtime/NEON/functions/NEElementwiseOperations.h
+++ b/arm_compute/runtime/NEON/functions/NEElementwiseOperations.h
@@ -25,7 +25,8 @@
#define ARM_COMPUTE_NEELEMENTWISEOPERATIONS_H
#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/NEON/INESimpleFunction.h"
+#include "arm_compute/runtime/IFunction.h"
+#include "arm_compute/runtime/NEON/INEOperator.h"
namespace arm_compute
{
@@ -36,9 +37,21 @@ class ITensor;
* @note The tensor data type for the inputs must be QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
* @note The function performs a max operation between two tensors.
*/
-class NEElementwiseMax : public INESimpleFunction
+class NEElementwiseMax : public IFunction
{
public:
+ /** Default Constructor */
+ NEElementwiseMax();
+ /** Default Destructor */
+ ~NEElementwiseMax();
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwiseMax(const NEElementwiseMax &) = delete;
+ /** Default move constructor */
+ NEElementwiseMax(NEElementwiseMax &&);
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwiseMax &operator=(const NEElementwiseMax &) = delete;
+ /** Default move assignment operator */
+ NEElementwiseMax &operator=(NEElementwiseMax &&);
/** Initialise the kernel's inputs, output and conversion policy.
*
* @param[in, out] input1 First tensor input. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
@@ -57,6 +70,13 @@ public:
* @return a status
*/
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+
+ // Inherited methods overridden:
+ void run() override;
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> _impl;
};
/** Basic function to run @ref NEArithmeticOperationKernel for min
@@ -64,9 +84,21 @@ public:
* @note The tensor data type for the inputs must be QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
* @note The function performs a min operation between two tensors.
*/
-class NEElementwiseMin : public INESimpleFunction
+class NEElementwiseMin : public IFunction
{
public:
+ /** Default Constructor */
+ NEElementwiseMin();
+ /** Default Destructor */
+ ~NEElementwiseMin();
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwiseMin(const NEElementwiseMin &) = delete;
+ /** Default move constructor */
+ NEElementwiseMin(NEElementwiseMin &&);
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwiseMin &operator=(const NEElementwiseMin &) = delete;
+ /** Default move assignment operator */
+ NEElementwiseMin &operator=(NEElementwiseMin &&);
/** Initialise the kernel's inputs, output and conversion policy.
*
* @param[in, out] input1 First tensor input. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
@@ -85,6 +117,13 @@ public:
* @return a status
*/
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+
+ // Inherited methods overridden:
+ void run() override;
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> _impl;
};
/** Basic function to run @ref NEArithmeticOperationKernel for squared difference
@@ -92,9 +131,21 @@ public:
* @note The tensor data type for the inputs must be QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
* @note The function performs a squared different operation between two tensors (i.e., out[i] = (in1[i] - in2[i])^2
*/
-class NEElementwiseSquaredDiff : public INESimpleFunction
+class NEElementwiseSquaredDiff : public IFunction
{
public:
+ /** Default Constructor */
+ NEElementwiseSquaredDiff();
+ /** Default Destructor */
+ ~NEElementwiseSquaredDiff();
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwiseSquaredDiff(const NEElementwiseSquaredDiff &) = delete;
+ /** Default move constructor */
+ NEElementwiseSquaredDiff(NEElementwiseSquaredDiff &&);
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwiseSquaredDiff &operator=(const NEElementwiseSquaredDiff &) = delete;
+ /** Default move assignment operator */
+ NEElementwiseSquaredDiff &operator=(NEElementwiseSquaredDiff &&);
/** Initialise the kernel's inputs, output and conversion policy.
*
* @param[in, out] input1 First tensor input. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
@@ -113,6 +164,13 @@ public:
* @return a status
*/
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+
+ // Inherited methods overridden:
+ void run() override;
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> _impl;
};
/** Basic function to run @ref NEArithmeticOperationKernel for division
@@ -120,9 +178,21 @@ public:
* @note The tensor data type for the inputs must be F16/F32.
* @note The function performs a squared different operation between two tensors (i.e., out[i] = in1[i] / in2[i])
*/
-class NEElementwiseDivision : public INESimpleFunction
+class NEElementwiseDivision : public IFunction
{
public:
+ /** Default Constructor */
+ NEElementwiseDivision();
+ /** Default Destructor */
+ ~NEElementwiseDivision();
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwiseDivision(const NEElementwiseDivision &) = delete;
+ /** Default move constructor */
+ NEElementwiseDivision(NEElementwiseDivision &&);
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwiseDivision &operator=(const NEElementwiseDivision &) = delete;
+ /** Default move assignment operator */
+ NEElementwiseDivision &operator=(NEElementwiseDivision &&);
/** Initialise the kernel's inputs, output and conversion policy.
*
* @param[in, out] input1 First tensor input. Data types supported: F16/F32.
@@ -141,6 +211,13 @@ public:
* @return a status
*/
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+
+ // Inherited methods overridden:
+ void run() override;
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> _impl;
};
/** Basic function to run @ref NEArithmeticOperationKernel for power
@@ -149,9 +226,21 @@ public:
* @note The function performs a elementwise power of in1 to in2 (i.e., out[i] = in1[i] ^ in2[i])
* @note For an exponent that is a float, this function will only work with a positive base.
*/
-class NEElementwisePower : public INESimpleFunction
+class NEElementwisePower : public IFunction
{
public:
+ /** Default Constructor */
+ NEElementwisePower();
+ /** Default Destructor */
+ ~NEElementwisePower();
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwisePower(const NEElementwisePower &) = delete;
+ /** Default move constructor */
+ NEElementwisePower(NEElementwisePower &&);
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwisePower &operator=(const NEElementwisePower &) = delete;
+ /** Default move assignment operator */
+ NEElementwisePower &operator=(NEElementwisePower &&);
/** Initialise the kernel's inputs, output and conversion policy.
*
* @param[in, out] input1 First tensor input. Data types supported: F16/F32.
@@ -170,6 +259,13 @@ public:
* @return a status
*/
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+
+ // Inherited methods overridden:
+ void run() override;
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> _impl;
};
/** Basic function to run @ref NEComparisonOperationKernel.
@@ -177,9 +273,21 @@ public:
* @note The tensor data type for the inputs must be QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
* @note The function performs a comparison operation between two tensors.
*/
-class NEElementwiseComparison : public INESimpleFunction
+class NEElementwiseComparison : public IFunction
{
public:
+ /** Default Constructor */
+ NEElementwiseComparison();
+ /** Default Destructor */
+ ~NEElementwiseComparison();
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwiseComparison(const NEElementwiseComparison &) = delete;
+ /** Default move constructor */
+ NEElementwiseComparison(NEElementwiseComparison &&);
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwiseComparison &operator=(const NEElementwiseComparison &) = delete;
+ /** Default move assignment operator */
+ NEElementwiseComparison &operator=(NEElementwiseComparison &&);
/** Initialise the kernel's inputs, output and conversion policy.
*
* @param[in, out] input1 First tensor input. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
@@ -198,6 +306,13 @@ public:
* @return a status
*/
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, ComparisonOperation op);
+
+ // Inherited methods overridden:
+ void run() override;
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> _impl;
};
/** Basic function to run @ref NEComparisonOperationKernel
@@ -206,9 +321,21 @@ public:
* @note The function performs a comparison operation between two tensors.
*/
template <ComparisonOperation op>
-class NEElementwiseComparisonStatic : public INESimpleFunction
+class NEElementwiseComparisonStatic : public IFunction
{
public:
+ /** Default Constructor */
+ NEElementwiseComparisonStatic();
+ /** Default Destructor */
+ ~NEElementwiseComparisonStatic();
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwiseComparisonStatic(const NEElementwiseComparisonStatic &) = delete;
+ /** Default move constructor */
+ NEElementwiseComparisonStatic(NEElementwiseComparisonStatic &&);
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEElementwiseComparisonStatic &operator=(const NEElementwiseComparisonStatic &) = delete;
+ /** Default move assignment operator */
+ NEElementwiseComparisonStatic &operator=(NEElementwiseComparisonStatic &&);
/** Initialise the kernel's inputs, output and conversion policy.
*
* @param[in, out] input1 First tensor input. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
@@ -225,6 +352,245 @@ public:
* @return a status
*/
static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output);
+
+ // Inherited methods overridden:
+ void run() override;
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> _impl;
+};
+
+/** Basic function to run equal comparison. */
+using NEEqual = NEElementwiseComparisonStatic<ComparisonOperation::Equal>;
+/** Basic function to run not equal comparison. */
+using NENotEqual = NEElementwiseComparisonStatic<ComparisonOperation::NotEqual>;
+/** Basic function to run greater comparison. */
+using NEGreater = NEElementwiseComparisonStatic<ComparisonOperation::Greater>;
+/** Basic function to run greater-equal comparison. */
+using NEGreaterEqual = NEElementwiseComparisonStatic<ComparisonOperation::GreaterEqual>;
+/** Basic function to run less comparison. */
+using NELess = NEElementwiseComparisonStatic<ComparisonOperation::Less>;
+/** Basic function to run less-equal comparison. */
+using NELessEqual = NEElementwiseComparisonStatic<ComparisonOperation::LessEqual>;
+
+namespace experimental
+{
+/** Basic function to run @ref NEArithmeticOperationKernel for max
+ *
+ * @note The tensor data type for the inputs must be QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @note The function performs a max operation between two tensors.
+ */
+class NEElementwiseMax : public INEOperator
+{
+public:
+ /** Initialise the kernel's inputs, output and conversion policy.
+ *
+ * @param[in, out] input1 First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @param[in, out] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[out] output Output tensor info. Data types supported: Same as @p input1.
+ * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
+ */
+ void configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+ /** Static function to check if given info will lead to a valid configuration of @ref NEArithmeticOperationKernel for max
+ *
+ * @param[in] input1 First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[in] output Output tensor info. Data types supported: Same as @p input1.
+ * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
+ *
+ * @return a status
+ */
+ static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+
+ // Inherited methods overridden:
+ MemoryRequirements workspace() const override;
+};
+
+/** Basic function to run @ref NEArithmeticOperationKernel for min
+ *
+ * @note The tensor data type for the inputs must be QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @note The function performs a min operation between two tensors.
+ */
+class NEElementwiseMin : public INEOperator
+{
+public:
+ /** Initialise the kernel's inputs, output and conversion policy.
+ *
+ * @param[in, out] input1 First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @param[in, out] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[out] output Output tensor info. Data types supported: Same as @p input1.
+ * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
+ */
+ void configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+ /** Static function to check if given info will lead to a valid configuration of @ref NEArithmeticOperationKernel for min
+ *
+ * @param[in] input1 First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[in] output Output tensor info. Data types supported: Same as @p input1.
+ * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
+ *
+ * @return a status
+ */
+ static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+
+ // Inherited methods overridden:
+ MemoryRequirements workspace() const override;
+};
+
+/** Basic function to run @ref NEArithmeticOperationKernel for squared difference
+ *
+ * @note The tensor data type for the inputs must be QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @note The function performs a squared different operation between two tensors (i.e., out[i] = (in1[i] - in2[i])^2
+ */
+class NEElementwiseSquaredDiff : public INEOperator
+{
+public:
+ /** Initialise the kernel's inputs, output and conversion policy.
+ *
+ * @param[in, out] input1 First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @param[in, out] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[out] output Output tensor info. Data types supported: Same as @p input1.
+ * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
+ */
+ void configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+ /** Static function to check if given info will lead to a valid configuration of @ref NEArithmeticOperationKernel for squared difference
+ *
+ * @param[in] input1 First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[in] output Output tensor info. Data types supported: Same as @p input1.
+ * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
+ *
+ * @return a status
+ */
+ static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+
+ // Inherited methods overridden:
+ MemoryRequirements workspace() const override;
+};
+
+/** Basic function to run @ref NEArithmeticOperationKernel for division
+ *
+ * @note The tensor data type for the inputs must be F16/F32.
+ * @note The function performs a squared different operation between two tensors (i.e., out[i] = in1[i] / in2[i])
+ */
+class NEElementwiseDivision : public INEOperator
+{
+public:
+ /** Initialise the kernel's inputs, output and conversion policy.
+ *
+ * @param[in, out] input1 First tensor input info. Data types supported: F16/F32.
+ * @param[in, out] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[out] output Output tensor info. Data types supported: Same as @p input1.
+ * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
+ */
+ void configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+ /** Static function to check if given info will lead to a valid configuration of @ref NEArithmeticOperationKernel for division
+ *
+ * @param[in] input1 First tensor input info. Data types supported: F16/F32.
+ * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[in] output Output tensor info. Data types supported: Same as @p input1.
+ * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
+ *
+ * @return a status
+ */
+ static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+
+ // Inherited methods overridden:
+ MemoryRequirements workspace() const override;
+};
+
+/** Basic function to run @ref NEArithmeticOperationKernel for power
+ *
+ * @note The tensor data type for the inputs must be F16/F32.
+ * @note The function performs a elementwise power of in1 to in2 (i.e., out[i] = in1[i] ^ in2[i])
+ * @note For an exponent that is a float, this function will only work with a positive base.
+ */
+class NEElementwisePower : public INEOperator
+{
+public:
+ /** Initialise the kernel's inputs, output and conversion policy.
+ *
+ * @param[in, out] input1 First tensor input info. Data types supported: F16/F32.
+ * @param[in, out] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[out] output Output tensor info. Data types supported: Same as @p input1.
+ * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
+ */
+ void configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+ /** Static function to check if given info will lead to a valid configuration of @ref NEArithmeticOperationKernel for power
+ *
+ * @param[in] input1 First tensor input info. Data types supported: F16/F32.
+ * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[in] output Output tensor info. Data types supported: Same as @p input1.
+ * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Currently not supported.
+ *
+ * @return a status
+ */
+ static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info = ActivationLayerInfo());
+
+ // Inherited methods overridden:
+ MemoryRequirements workspace() const override;
+};
+
+/** Basic function to run @ref NEComparisonOperationKernel.
+ *
+ * @note The tensor data type for the inputs must be QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @note The function performs a comparison operation between two tensors.
+ */
+class NEElementwiseComparison : public INEOperator
+{
+public:
+ /** Initialise the kernel's inputs, output and conversion policy.
+ *
+ * @param[in, out] input1 First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @param[in, out] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[out] output Output tensor info. Data types supported: U16/U32.
+ * @param[in] op Comparison Operation to be performed.
+ */
+ void configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, ComparisonOperation op);
+ /** Static function to check if given info will lead to a valid configuration of @ref NEComparisonOperationKernel
+ *
+ * @param[in] input1 First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[in] output Output tensor info. Data types supported: U16/U32.
+ * @param[in] op Comparison Operation to be performed.
+ *
+ * @return a status
+ */
+ static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, ComparisonOperation op);
+
+ // Inherited methods overridden:
+ MemoryRequirements workspace() const override;
+};
+
+/** Basic function to run @ref NEComparisonOperationKernel
+ *
+ * @note The tensor data type for the inputs must be QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @note The function performs a comparison operation between two tensors.
+ */
+template <ComparisonOperation op>
+class NEElementwiseComparisonStatic : public INEOperator
+{
+public:
+ /** Initialise the kernel's inputs, output and conversion policy.
+ *
+ * @param[in, out] input1 First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @param[in, out] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[out] output Output tensor info. Data types supported: U16/U32.
+ */
+ void configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output);
+ /** Static function to check if given info will lead to a valid configuration of @ref NEComparisonOperationKernel
+ *
+ * @param[in] input1 First tensor input info. Data types supported: QASYMM8/QASYMM8_SIGNED/S16/F16/S32/F32.
+ * @param[in] input2 Second tensor input info. Data types supported: Same as @p input1.
+ * @param[in] output Output tensor info. Data types supported: U16/U32.
+ *
+ * @return a status
+ */
+ static Status validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output);
+
+ // Inherited methods overridden:
+ MemoryRequirements workspace() const override;
};
/** Basic function to run equal comparison. */
@@ -239,5 +605,6 @@ using NEGreaterEqual = NEElementwiseComparisonStatic<ComparisonOperation::Greate
using NELess = NEElementwiseComparisonStatic<ComparisonOperation::Less>;
/** Basic function to run less-equal comparison. */
using NELessEqual = NEElementwiseComparisonStatic<ComparisonOperation::LessEqual>;
+} // namespace experimental
} // namespace arm_compute
#endif /* ARM_COMPUTE_NEELEMENTWISEOPERATIONS_H */
diff --git a/arm_compute/runtime/NEON/functions/NEPReluLayer.h b/arm_compute/runtime/NEON/functions/NEPReluLayer.h
index 102a165383..9229a842e8 100644
--- a/arm_compute/runtime/NEON/functions/NEPReluLayer.h
+++ b/arm_compute/runtime/NEON/functions/NEPReluLayer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 ARM Limited.
+ * Copyright (c) 2019-2020 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -25,21 +25,65 @@
#define ARM_COMPUTE_NEPRELULAYER_H
#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/NEON/INESimpleFunction.h"
+#include "arm_compute/runtime/IFunction.h"
+#include "arm_compute/runtime/NEON/INEOperator.h"
namespace arm_compute
{
class ITensor;
+namespace experimental
+{
/** Basic function to run @ref NEArithmeticOperationKernel for PRELU
*
* @note The function implements an activation layer with the PRELU activation function.
*/
-class NEPReluLayer : public INESimpleFunction
+class NEPReluLayer : public INEOperator
{
public:
/** Set the input and output tensor.
*
+ * @param[in] input Source tensor info. Data types supported: QASYMM8/QASYMM8_SIGNED/F16/F32.
+ * @param[in] alpha Source alpha tensor info. Data types supported: same of @p input.
+ * @param[out] output Destination tensor info. Data type supported: same as @p input
+ */
+ void configure(const ITensorInfo *input, const ITensorInfo *alpha, ITensorInfo *output);
+ /** Static function to check if given info will lead to a valid configuration of @ref NEComparisonOperationKernel
+ *
+ * @param[in] input Source tensor info. Data types supported: QASYMM8/QASYMM8_SIGNED/F16/F32.
+ * @param[in] alpha Source alpha tensor info. Data types supported: same of @p input.
+ * @param[in] output Destination tensor info. Data type supported: same as @p input
+ *
+ * @return a status
+ */
+ static Status validate(const ITensorInfo *input, const ITensorInfo *alpha, const ITensorInfo *output);
+
+ // Inherited methods overridden:
+ MemoryRequirements workspace() const override;
+};
+} // namespace experimental
+
+/** Basic function to run @ref NEArithmeticOperationKernel for PRELU
+ *
+ * @note The function implements an activation layer with the PRELU activation function.
+ */
+class NEPReluLayer : public IFunction
+{
+public:
+ /** Default Constructor */
+ NEPReluLayer();
+ /** Default Destructor */
+ ~NEPReluLayer();
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEPReluLayer(const NEPReluLayer &) = delete;
+ /** Default move constructor */
+ NEPReluLayer(NEPReluLayer &&);
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ NEPReluLayer &operator=(const NEPReluLayer &) = delete;
+ /** Default move assignment operator */
+ NEPReluLayer &operator=(NEPReluLayer &&);
+ /** Set the input and output tensor.
+ *
* @param[in] input Source tensor. Data types supported: QASYMM8/QASYMM8_SIGNED/F16/F32.
* @param[in] alpha Source alpha tensor. Data types supported: same of @p input.
* @param[out] output Destination tensor. Data type supported: same as @p input
@@ -54,6 +98,13 @@ public:
* @return a status
*/
static Status validate(const ITensorInfo *input, const ITensorInfo *alpha, const ITensorInfo *output);
+
+ // Inherited methods overridden:
+ void run() override;
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> _impl;
};
} // namespace arm_compute
#endif /* ARM_COMPUTE_NEPRELULAYER_H */
diff --git a/arm_compute/runtime/OMP/OMPScheduler.h b/arm_compute/runtime/OMP/OMPScheduler.h
index b7c186a838..1742e95263 100644
--- a/arm_compute/runtime/OMP/OMPScheduler.h
+++ b/arm_compute/runtime/OMP/OMPScheduler.h
@@ -66,7 +66,7 @@ public:
* @param[in] inputs Vector containing the input tensors.
* @param[in] outputs Vector containing the output tensors.
*/
- void schedule_op(ICPPKernel *kernel, const Hints &hints, const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs) override;
+ void schedule_op(ICPPKernel *kernel, const Hints &hints, const InputTensorMap &inputs, const OutputTensorMap &outputs) override;
protected:
/** Execute all the passed workloads
diff --git a/arm_compute/runtime/SingleThreadScheduler.h b/arm_compute/runtime/SingleThreadScheduler.h
index 8a69a5be15..0d576b93eb 100644
--- a/arm_compute/runtime/SingleThreadScheduler.h
+++ b/arm_compute/runtime/SingleThreadScheduler.h
@@ -57,7 +57,7 @@ public:
* @param[in] inputs Vector containing the input tensors.
* @param[in] outputs Vector containing the output tensors.
*/
- void schedule_op(ICPPKernel *kernel, const Hints &hints, const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs) override;
+ void schedule_op(ICPPKernel *kernel, const Hints &hints, const InputTensorMap &inputs, const OutputTensorMap &outputs) override;
protected:
/** Will run the workloads sequentially and in order.
diff --git a/src/core/NEON/kernels/NEActivationLayerKernel.cpp b/src/core/NEON/kernels/NEActivationLayerKernel.cpp
index 2c00a76305..43426dc122 100644
--- a/src/core/NEON/kernels/NEActivationLayerKernel.cpp
+++ b/src/core/NEON/kernels/NEActivationLayerKernel.cpp
@@ -855,8 +855,8 @@ Status NEActivationLayerKernel::validate(const ITensorInfo *input, const ITensor
return Status{};
}
-void NEActivationLayerKernel::run_op(const std::vector<InputTensor> &inputs,
- const std::vector<OutputTensor> &outputs,
+void NEActivationLayerKernel::run_op(const InputTensorMap &inputs,
+ const OutputTensorMap &outputs,
const Window &window, const ThreadInfo &info)
{
// Early exit on disabled activation
@@ -872,5 +872,5 @@ void NEActivationLayerKernel::run_op(const std::vector<InputTensor> &inputs,
ARM_COMPUTE_ERROR_ON(inputs.empty() || outputs.empty());
- (this->*_func)(inputs[0].tensor, outputs[0].tensor, window);
+ (this->*_func)(inputs.at(TensorType::ACL_SRC), outputs.at(TensorType::ACL_DST), window);
}
diff --git a/src/core/NEON/kernels/NEElementwiseOperationKernel.cpp b/src/core/NEON/kernels/NEElementwiseOperationKernel.cpp
index 7b2b5e4f19..b4f7a0a902 100644
--- a/src/core/NEON/kernels/NEElementwiseOperationKernel.cpp
+++ b/src/core/NEON/kernels/NEElementwiseOperationKernel.cpp
@@ -1055,13 +1055,13 @@ void elementwise_comp_op_quantized_signed(const ITensor *in1, const ITensor *in2
}
std::function<void(const ITensor *, const ITensor *, ITensor *, const Window &)>
-configure_func(const ITensor *input1, const ITensor *input2, ITensor *output,
+configure_func(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output,
std::map<std::string, NEElementwiseOperationKernel::ElementwiseFunction *> map_function)
{
std::string function_to_call("op_");
- function_to_call += string_from_data_type(input1->info()->data_type()) + "_";
- function_to_call += string_from_data_type(input2->info()->data_type()) + "_";
- function_to_call += string_from_data_type(output->info()->data_type());
+ function_to_call += string_from_data_type(input1->data_type()) + "_";
+ function_to_call += string_from_data_type(input2->data_type()) + "_";
+ function_to_call += string_from_data_type(output->data_type());
auto it = map_function.find(function_to_call);
@@ -1078,7 +1078,7 @@ configure_func(const ITensor *input1, const ITensor *input2, ITensor *output,
template <ArithmeticOperation op>
std::function<void(const ITensor *, const ITensor *, ITensor *, const Window &)>
-configure_arithm_func(const ITensor *input1, const ITensor *input2, ITensor *output)
+configure_arithm_func(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output)
{
static std::map<std::string, NEElementwiseOperationKernel::ElementwiseFunction *> map_function =
{
@@ -1097,7 +1097,7 @@ configure_arithm_func(const ITensor *input1, const ITensor *input2, ITensor *out
template <ComparisonOperation op>
std::function<void(const ITensor *input1, const ITensor *input2, ITensor *output, const Window &window)>
-configure_comp_func(const ITensor *input1, const ITensor *input2, ITensor *output)
+configure_comp_func(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output)
{
static std::map<std::string, NEElementwiseOperationKernel::ElementwiseFunction *> map_function =
{
@@ -1140,41 +1140,36 @@ Status NEElementwiseOperationKernel::validate_arguments_common(const ITensorInfo
return Status{};
}
-void NEElementwiseOperationKernel::configure_common(const ITensor *input1, const ITensor *input2, ITensor *output)
+void NEElementwiseOperationKernel::configure_common(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output)
{
ARM_COMPUTE_ERROR_ON_NULLPTR(input1, input2, output);
// Configure kernel window
- const std::pair<TensorShape, ValidRegion> broadcast_pair = ITensorInfo::broadcast_shape_and_valid_region(*input1->info(), *input2->info());
+ const std::pair<TensorShape, ValidRegion> broadcast_pair = ITensorInfo::broadcast_shape_and_valid_region(*input1, *input2);
const TensorShape &out_shape = broadcast_pair.first;
const ValidRegion &valid_region = broadcast_pair.second;
// Auto initialize output if not initialized
- auto_init_if_empty(*output->info(), out_shape, 1, input1->info()->data_type());
+ auto_init_if_empty(*output, out_shape, 1, input1->data_type());
Window win = calculate_max_window(valid_region);
- _input1 = input1;
- _input2 = input2;
- _output = output;
-
INEKernel::configure(win);
}
-void NEElementwiseOperationKernel::run(const Window &window, const ThreadInfo &info)
+void NEElementwiseOperationKernel::run_op(const InputTensorMap &inputs, const OutputTensorMap &outputs, const Window &window, const ThreadInfo &info)
{
ARM_COMPUTE_UNUSED(info, window);
ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this);
ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(INEKernel::window(), window);
ARM_COMPUTE_ERROR_ON(_function == nullptr);
- _function(_input1, _input2, _output, window);
+ _function(inputs.at(TensorType::ACL_SRC_0), inputs.at(TensorType::ACL_SRC_1), outputs.at(TensorType::ACL_DST), window);
}
/** Arithmetic operators (min, max, squared_diff) */
-
-void NEArithmeticOperationKernel::configure(ArithmeticOperation op, const ITensor *input1, const ITensor *input2, ITensor *output)
+void NEArithmeticOperationKernel::configure(ArithmeticOperation op, const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output)
{
- ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*input1->info(), *input2->info(), *output->info()));
+ ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*input1, *input2, *output));
configure_common(input1, input2, output);
switch(op)
{
@@ -1215,9 +1210,9 @@ Status NEArithmeticOperationKernel::validate(ArithmeticOperation op, const ITens
/** The division operator */
-void NEDivisionOperationKernel::configure(const ITensor *input1, const ITensor *input2, ITensor *output)
+void NEDivisionOperationKernel::configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output)
{
- ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*input1->info(), *input2->info(), *output->info()));
+ ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*input1, *input2, *output));
configure_common(input1, input2, output);
_function = configure_arithm_func<ArithmeticOperation::DIV>(input1, input2, output);
}
@@ -1236,9 +1231,9 @@ Status NEDivisionOperationKernel::validate(const ITensorInfo *input1, const ITen
}
/** The power operator */
-void NEPowerOperationKernel::configure(const ITensor *input1, const ITensor *input2, ITensor *output)
+void NEPowerOperationKernel::configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output)
{
- ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*input1->info(), *input2->info(), *output->info()));
+ ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*input1, *input2, *output));
configure_common(input1, input2, output);
_function = configure_arithm_func<ArithmeticOperation::POWER>(input1, input2, output);
}
@@ -1257,10 +1252,9 @@ Status NEPowerOperationKernel::validate(const ITensorInfo *input1, const ITensor
}
/** Comparison operators (equal, not equal, less than, greater than, less than or equal, greater than or equal) */
-
-void NEComparisonOperationKernel::configure(ComparisonOperation op, const ITensor *input1, const ITensor *input2, ITensor *output)
+void NEComparisonOperationKernel::configure(ComparisonOperation op, const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output)
{
- ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*input1->info(), *input2->info(), *output->info()));
+ ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(*input1, *input2, *output));
configure_common(input1, input2, output);
switch(op)
{
diff --git a/src/core/NEON/kernels/NEReshapeLayerKernel.cpp b/src/core/NEON/kernels/NEReshapeLayerKernel.cpp
index c141eecf75..eb1139d7a3 100644
--- a/src/core/NEON/kernels/NEReshapeLayerKernel.cpp
+++ b/src/core/NEON/kernels/NEReshapeLayerKernel.cpp
@@ -86,14 +86,14 @@ void NEReshapeLayerKernel::configure(const ITensorInfo *input, ITensorInfo *outp
INEKernel::configure(win);
}
-void NEReshapeLayerKernel::run_op(const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs, const Window &window, const ThreadInfo &info)
+void NEReshapeLayerKernel::run_op(const InputTensorMap &inputs, const OutputTensorMap &outputs, const Window &window, const ThreadInfo &info)
{
ARM_COMPUTE_UNUSED(info);
ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this);
ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(INEKernel::window(), window);
- const auto src = inputs[0].tensor;
- auto dst = outputs[0].tensor;
+ const auto src = inputs.at(TensorType::ACL_SRC);
+ auto dst = outputs.at(TensorType::ACL_DST);
switch(src->info()->data_type())
{
diff --git a/src/runtime/CPP/CPPScheduler.cpp b/src/runtime/CPP/CPPScheduler.cpp
index 41e1a2d647..af6d8d77c4 100644
--- a/src/runtime/CPP/CPPScheduler.cpp
+++ b/src/runtime/CPP/CPPScheduler.cpp
@@ -363,7 +363,7 @@ void CPPScheduler::run_workloads(std::vector<IScheduler::Workload> &workloads)
}
#endif /* DOXYGEN_SKIP_THIS */
-void CPPScheduler::schedule_common(ICPPKernel *kernel, const Hints &hints, const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs)
+void CPPScheduler::schedule_common(ICPPKernel *kernel, const Hints &hints, const InputTensorMap &inputs, const OutputTensorMap &outputs)
{
ARM_COMPUTE_ERROR_ON_MSG(!kernel, "The child class didn't set the kernel");
@@ -473,15 +473,15 @@ void CPPScheduler::schedule_common(ICPPKernel *kernel, const Hints &hints, const
}
}
-void CPPScheduler::schedule_op(ICPPKernel *kernel, const Hints &hints, const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs)
+void CPPScheduler::schedule_op(ICPPKernel *kernel, const Hints &hints, const InputTensorMap &inputs, const OutputTensorMap &outputs)
{
schedule_common(kernel, hints, inputs, outputs);
}
void CPPScheduler::schedule(ICPPKernel *kernel, const Hints &hints)
{
- const std::vector<InputTensor> inputs;
- std::vector<OutputTensor> outputs;
+ const InputTensorMap inputs;
+ OutputTensorMap outputs;
schedule_common(kernel, hints, inputs, outputs);
}
} // namespace arm_compute
diff --git a/src/runtime/CPP/SingleThreadScheduler.cpp b/src/runtime/CPP/SingleThreadScheduler.cpp
index 8257628090..63c6c7b298 100644
--- a/src/runtime/CPP/SingleThreadScheduler.cpp
+++ b/src/runtime/CPP/SingleThreadScheduler.cpp
@@ -49,7 +49,7 @@ void SingleThreadScheduler::schedule(ICPPKernel *kernel, const Hints &hints)
kernel->run(kernel->window(), info);
}
-void SingleThreadScheduler::schedule_op(ICPPKernel *kernel, const Hints &hints, const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs)
+void SingleThreadScheduler::schedule_op(ICPPKernel *kernel, const Hints &hints, const InputTensorMap &inputs, const OutputTensorMap &outputs)
{
ARM_COMPUTE_UNUSED(hints);
ThreadInfo info;
diff --git a/src/runtime/NEON/INEOperator.cpp b/src/runtime/NEON/INEOperator.cpp
index 78790856ee..00dab75a95 100644
--- a/src/runtime/NEON/INEOperator.cpp
+++ b/src/runtime/NEON/INEOperator.cpp
@@ -33,7 +33,7 @@ INEOperator::INEOperator(IRuntimeContext *ctx)
{
}
-void INEOperator::run(std::vector<InputTensor> inputs, std::vector<OutputTensor> outputs, std::vector<OperatorTensor> workspace)
+void INEOperator::run(InputTensorMap inputs, OutputTensorMap outputs, OperatorTensorMap workspace)
{
ARM_COMPUTE_UNUSED(workspace);
@@ -45,7 +45,7 @@ void INEOperator::run(std::vector<InputTensor> inputs, std::vector<OutputTensor>
NEScheduler::get().schedule_op(_kernel.get(), Window::DimY, inputs, outputs);
}
-void INEOperator::prepare(std::vector<OperatorTensor> constants)
+void INEOperator::prepare(OperatorTensorMap constants)
{
ARM_COMPUTE_UNUSED(constants);
}
diff --git a/src/runtime/NEON/functions/NEActivationLayer.cpp b/src/runtime/NEON/functions/NEActivationLayer.cpp
index 889ff6b1f4..03222386d9 100644
--- a/src/runtime/NEON/functions/NEActivationLayer.cpp
+++ b/src/runtime/NEON/functions/NEActivationLayer.cpp
@@ -90,9 +90,9 @@ Status NEActivationLayer::validate(const ITensorInfo *input, const ITensorInfo *
void NEActivationLayer::run()
{
- const InputTensor src{ TensorType::ACL_SRC, _impl->src };
- OutputTensor dst{ TensorType::ACL_DST, _impl->dst };
+ const InputTensorMap src{ { TensorType::ACL_SRC, _impl->src } };
+ const OutputTensorMap dst{ { TensorType::ACL_DST, _impl->dst } };
- _impl->op->run({ src }, { dst }, {});
+ _impl->op->run(src, dst, {});
}
} // namespace arm_compute
diff --git a/src/runtime/NEON/functions/NEElementwiseOperators.cpp b/src/runtime/NEON/functions/NEElementwiseOperators.cpp
index 926ae1fa21..63fd5654fd 100644
--- a/src/runtime/NEON/functions/NEElementwiseOperators.cpp
+++ b/src/runtime/NEON/functions/NEElementwiseOperators.cpp
@@ -32,7 +32,9 @@
namespace arm_compute
{
-void NEElementwiseMax::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
+namespace experimental
+{
+void NEElementwiseMax::configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, const ActivationLayerInfo &act_info)
{
ARM_COMPUTE_UNUSED(act_info);
auto k = arm_compute::support::cpp14::make_unique<NEArithmeticOperationKernel>();
@@ -46,7 +48,12 @@ Status NEElementwiseMax::validate(const ITensorInfo *input1, const ITensorInfo *
return NEArithmeticOperationKernel::validate(ArithmeticOperation::MAX, input1, input2, output);
}
-void NEElementwiseMin::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
+MemoryRequirements NEElementwiseMax::workspace() const
+{
+ return MemoryRequirements{};
+}
+
+void NEElementwiseMin::configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, const ActivationLayerInfo &act_info)
{
ARM_COMPUTE_UNUSED(act_info);
auto k = arm_compute::support::cpp14::make_unique<NEArithmeticOperationKernel>();
@@ -60,7 +67,12 @@ Status NEElementwiseMin::validate(const ITensorInfo *input1, const ITensorInfo *
return NEArithmeticOperationKernel::validate(ArithmeticOperation::MIN, input1, input2, output);
}
-void NEElementwiseSquaredDiff::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
+MemoryRequirements NEElementwiseMin::workspace() const
+{
+ return MemoryRequirements{};
+}
+
+void NEElementwiseSquaredDiff::configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, const ActivationLayerInfo &act_info)
{
ARM_COMPUTE_UNUSED(act_info);
auto k = arm_compute::support::cpp14::make_unique<NEArithmeticOperationKernel>();
@@ -74,7 +86,12 @@ Status NEElementwiseSquaredDiff::validate(const ITensorInfo *input1, const ITens
return NEArithmeticOperationKernel::validate(ArithmeticOperation::SQUARED_DIFF, input1, input2, output);
}
-void NEElementwiseDivision::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
+MemoryRequirements NEElementwiseSquaredDiff::workspace() const
+{
+ return MemoryRequirements{};
+}
+
+void NEElementwiseDivision::configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, const ActivationLayerInfo &act_info)
{
ARM_COMPUTE_UNUSED(act_info);
auto k = arm_compute::support::cpp14::make_unique<NEDivisionOperationKernel>();
@@ -88,7 +105,12 @@ Status NEElementwiseDivision::validate(const ITensorInfo *input1, const ITensorI
return NEDivisionOperationKernel::validate(input1, input2, output);
}
-void NEElementwisePower::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
+MemoryRequirements NEElementwiseDivision::workspace() const
+{
+ return MemoryRequirements{};
+}
+
+void NEElementwisePower::configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, const ActivationLayerInfo &act_info)
{
ARM_COMPUTE_UNUSED(act_info);
auto k = arm_compute::support::cpp14::make_unique<NEPowerOperationKernel>();
@@ -102,8 +124,13 @@ Status NEElementwisePower::validate(const ITensorInfo *input1, const ITensorInfo
return NEPowerOperationKernel::validate(input1, input2, output);
}
+MemoryRequirements NEElementwisePower::workspace() const
+{
+ return MemoryRequirements{};
+}
+
template <ComparisonOperation COP>
-void NEElementwiseComparisonStatic<COP>::configure(ITensor *input1, ITensor *input2, ITensor *output)
+void NEElementwiseComparisonStatic<COP>::configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output)
{
auto k = arm_compute::support::cpp14::make_unique<NEComparisonOperationKernel>();
k->configure(COP, input1, input2, output);
@@ -116,7 +143,13 @@ Status NEElementwiseComparisonStatic<COP>::validate(const ITensorInfo *input1, c
return NEComparisonOperationKernel::validate(COP, input1, input2, output);
}
-void NEElementwiseComparison::configure(ITensor *input1, ITensor *input2, ITensor *output, ComparisonOperation op)
+template <ComparisonOperation COP>
+MemoryRequirements NEElementwiseComparisonStatic<COP>::workspace() const
+{
+ return MemoryRequirements{};
+}
+
+void NEElementwiseComparison::configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, ComparisonOperation op)
{
auto k = arm_compute::support::cpp14::make_unique<NEComparisonOperationKernel>();
k->configure(op, input1, input2, output);
@@ -128,6 +161,294 @@ Status NEElementwiseComparison::validate(const ITensorInfo *input1, const ITenso
return NEComparisonOperationKernel::validate(op, input1, input2, output);
}
+MemoryRequirements NEElementwiseComparison::workspace() const
+{
+ return MemoryRequirements{};
+}
+
+// Supported Specializations
+template class NEElementwiseComparisonStatic<ComparisonOperation::Equal>;
+template class NEElementwiseComparisonStatic<ComparisonOperation::NotEqual>;
+template class NEElementwiseComparisonStatic<ComparisonOperation::Greater>;
+template class NEElementwiseComparisonStatic<ComparisonOperation::GreaterEqual>;
+template class NEElementwiseComparisonStatic<ComparisonOperation::Less>;
+template class NEElementwiseComparisonStatic<ComparisonOperation::LessEqual>;
+} // namespace experimental
+
+struct NEElementwiseMax::Impl
+{
+ const ITensor *src_0{ nullptr };
+ const ITensor *src_1{ nullptr };
+ ITensor *dst{ nullptr };
+ std::unique_ptr<experimental::NEElementwiseMax> op{ nullptr };
+};
+
+NEElementwiseMax::NEElementwiseMax()
+ : _impl(support::cpp14::make_unique<Impl>())
+{
+}
+NEElementwiseMax::NEElementwiseMax(NEElementwiseMax &&) = default;
+NEElementwiseMax &NEElementwiseMax::operator=(NEElementwiseMax &&) = default;
+NEElementwiseMax::~NEElementwiseMax() = default;
+
+void NEElementwiseMax::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
+{
+ _impl->src_0 = input1;
+ _impl->src_1 = input2;
+ _impl->dst = output;
+ _impl->op = arm_compute::support::cpp14::make_unique<experimental::NEElementwiseMax>();
+ _impl->op->configure(input1->info(), input2->info(), output->info(), act_info);
+}
+
+Status NEElementwiseMax::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
+{
+ ARM_COMPUTE_RETURN_ERROR_ON(act_info.enabled());
+ return experimental::NEElementwiseMax::validate(input1, input2, output, act_info);
+}
+
+void NEElementwiseMax::run()
+{
+ const InputTensorMap src{ { TensorType::ACL_SRC_0, _impl->src_0 }, { TensorType::ACL_SRC_1, _impl->src_1 } };
+ const OutputTensorMap dst{ { TensorType::ACL_DST, _impl->dst } };
+ _impl->op->run(src, dst, {});
+}
+
+struct NEElementwiseMin::Impl
+{
+ const ITensor *src_0{ nullptr };
+ const ITensor *src_1{ nullptr };
+ ITensor *dst{ nullptr };
+ std::unique_ptr<experimental::NEElementwiseMin> op{ nullptr };
+};
+
+NEElementwiseMin::NEElementwiseMin()
+ : _impl(support::cpp14::make_unique<Impl>())
+{
+}
+NEElementwiseMin::NEElementwiseMin(NEElementwiseMin &&) = default;
+NEElementwiseMin &NEElementwiseMin::operator=(NEElementwiseMin &&) = default;
+NEElementwiseMin::~NEElementwiseMin() = default;
+
+void NEElementwiseMin::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
+{
+ _impl->src_0 = input1;
+ _impl->src_1 = input2;
+ _impl->dst = output;
+ _impl->op = arm_compute::support::cpp14::make_unique<experimental::NEElementwiseMin>();
+ _impl->op->configure(input1->info(), input2->info(), output->info(), act_info);
+}
+
+Status NEElementwiseMin::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
+{
+ ARM_COMPUTE_RETURN_ERROR_ON(act_info.enabled());
+ return experimental::NEElementwiseMin::validate(input1, input2, output, act_info);
+}
+
+void NEElementwiseMin::run()
+{
+ const InputTensorMap src{ { TensorType::ACL_SRC_0, _impl->src_0 }, { TensorType::ACL_SRC_1, _impl->src_1 } };
+ const OutputTensorMap dst{ { TensorType::ACL_DST, _impl->dst } };
+ _impl->op->run(src, dst, {});
+}
+
+struct NEElementwiseSquaredDiff::Impl
+{
+ const ITensor *src_0{ nullptr };
+ const ITensor *src_1{ nullptr };
+ ITensor *dst{ nullptr };
+ std::unique_ptr<experimental::NEElementwiseSquaredDiff> op{ nullptr };
+};
+
+NEElementwiseSquaredDiff::NEElementwiseSquaredDiff()
+ : _impl(support::cpp14::make_unique<Impl>())
+{
+}
+NEElementwiseSquaredDiff::NEElementwiseSquaredDiff(NEElementwiseSquaredDiff &&) = default;
+NEElementwiseSquaredDiff &NEElementwiseSquaredDiff::operator=(NEElementwiseSquaredDiff &&) = default;
+NEElementwiseSquaredDiff::~NEElementwiseSquaredDiff() = default;
+
+void NEElementwiseSquaredDiff::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
+{
+ _impl->src_0 = input1;
+ _impl->src_1 = input2;
+ _impl->dst = output;
+ _impl->op = arm_compute::support::cpp14::make_unique<experimental::NEElementwiseSquaredDiff>();
+ _impl->op->configure(input1->info(), input2->info(), output->info(), act_info);
+}
+
+Status NEElementwiseSquaredDiff::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
+{
+ ARM_COMPUTE_RETURN_ERROR_ON(act_info.enabled());
+ return experimental::NEElementwiseSquaredDiff::validate(input1, input2, output, act_info);
+}
+
+void NEElementwiseSquaredDiff::run()
+{
+ const InputTensorMap src{ { TensorType::ACL_SRC_0, _impl->src_0 }, { TensorType::ACL_SRC_1, _impl->src_1 } };
+ const OutputTensorMap dst{ { TensorType::ACL_DST, _impl->dst } };
+ _impl->op->run(src, dst, {});
+}
+
+struct NEElementwiseDivision::Impl
+{
+ const ITensor *src_0{ nullptr };
+ const ITensor *src_1{ nullptr };
+ ITensor *dst{ nullptr };
+ std::unique_ptr<experimental::NEElementwiseDivision> op{ nullptr };
+};
+
+NEElementwiseDivision::NEElementwiseDivision()
+ : _impl(support::cpp14::make_unique<Impl>())
+{
+}
+NEElementwiseDivision::NEElementwiseDivision(NEElementwiseDivision &&) = default;
+NEElementwiseDivision &NEElementwiseDivision::operator=(NEElementwiseDivision &&) = default;
+NEElementwiseDivision::~NEElementwiseDivision() = default;
+
+void NEElementwiseDivision::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
+{
+ ARM_COMPUTE_UNUSED(act_info);
+ _impl->src_0 = input1;
+ _impl->src_1 = input2;
+ _impl->dst = output;
+ _impl->op = arm_compute::support::cpp14::make_unique<experimental::NEElementwiseDivision>();
+ _impl->op->configure(input1->info(), input2->info(), output->info(), act_info);
+}
+
+Status NEElementwiseDivision::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
+{
+ ARM_COMPUTE_RETURN_ERROR_ON(act_info.enabled());
+ return experimental::NEElementwiseDivision::validate(input1, input2, output, act_info);
+}
+
+void NEElementwiseDivision::run()
+{
+ const InputTensorMap src{ { TensorType::ACL_SRC_0, _impl->src_0 }, { TensorType::ACL_SRC_1, _impl->src_1 } };
+ const OutputTensorMap dst{ { TensorType::ACL_DST, _impl->dst } };
+ _impl->op->run(src, dst, {});
+}
+
+struct NEElementwisePower::Impl
+{
+ const ITensor *src_0{ nullptr };
+ const ITensor *src_1{ nullptr };
+ ITensor *dst{ nullptr };
+ std::unique_ptr<experimental::NEElementwisePower> op{ nullptr };
+};
+
+NEElementwisePower::NEElementwisePower()
+ : _impl(support::cpp14::make_unique<Impl>())
+{
+}
+NEElementwisePower::NEElementwisePower(NEElementwisePower &&) = default;
+NEElementwisePower &NEElementwisePower::operator=(NEElementwisePower &&) = default;
+NEElementwisePower::~NEElementwisePower() = default;
+
+void NEElementwisePower::configure(ITensor *input1, ITensor *input2, ITensor *output, const ActivationLayerInfo &act_info)
+{
+ ARM_COMPUTE_UNUSED(act_info);
+ _impl->src_0 = input1;
+ _impl->src_1 = input2;
+ _impl->dst = output;
+ _impl->op = arm_compute::support::cpp14::make_unique<experimental::NEElementwisePower>();
+ _impl->op->configure(input1->info(), input2->info(), output->info(), act_info);
+}
+
+Status NEElementwisePower::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const ActivationLayerInfo &act_info)
+{
+ ARM_COMPUTE_RETURN_ERROR_ON(act_info.enabled());
+ return experimental::NEElementwisePower::validate(input1, input2, output, act_info);
+}
+
+void NEElementwisePower::run()
+{
+ const InputTensorMap src{ { TensorType::ACL_SRC_0, _impl->src_0 }, { TensorType::ACL_SRC_1, _impl->src_1 } };
+ const OutputTensorMap dst{ { TensorType::ACL_DST, _impl->dst } };
+ _impl->op->run(src, dst, {});
+}
+
+template <ComparisonOperation COP>
+struct NEElementwiseComparisonStatic<COP>::Impl
+{
+ const ITensor *src_0{ nullptr };
+ const ITensor *src_1{ nullptr };
+ ITensor *dst{ nullptr };
+ std::unique_ptr<experimental::NEElementwiseComparisonStatic<COP>> op{ nullptr };
+};
+
+template <ComparisonOperation COP>
+NEElementwiseComparisonStatic<COP>::NEElementwiseComparisonStatic()
+ : _impl(support::cpp14::make_unique<Impl>())
+{
+}
+template <ComparisonOperation COP>
+NEElementwiseComparisonStatic<COP>::NEElementwiseComparisonStatic(NEElementwiseComparisonStatic &&) = default;
+template <ComparisonOperation COP>
+NEElementwiseComparisonStatic<COP> &NEElementwiseComparisonStatic<COP>::operator=(NEElementwiseComparisonStatic &&) = default;
+template <ComparisonOperation COP>
+NEElementwiseComparisonStatic<COP>::~NEElementwiseComparisonStatic() = default;
+
+template <ComparisonOperation COP>
+void NEElementwiseComparisonStatic<COP>::configure(ITensor *input1, ITensor *input2, ITensor *output)
+{
+ _impl->src_0 = input1;
+ _impl->src_1 = input2;
+ _impl->dst = output;
+ _impl->op = arm_compute::support::cpp14::make_unique<experimental::NEElementwiseComparisonStatic<COP>>();
+ _impl->op->configure(input1->info(), input2->info(), output->info());
+}
+
+template <ComparisonOperation COP>
+Status NEElementwiseComparisonStatic<COP>::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output)
+{
+ return experimental::NEElementwiseComparisonStatic<COP>::validate(input1, input2, output);
+}
+
+template <ComparisonOperation COP>
+void NEElementwiseComparisonStatic<COP>::run()
+{
+ const InputTensorMap src{ { TensorType::ACL_SRC_0, _impl->src_0 }, { TensorType::ACL_SRC_1, _impl->src_1 } };
+ const OutputTensorMap dst{ { TensorType::ACL_DST, _impl->dst } };
+ _impl->op->run(src, dst, {});
+}
+
+struct NEElementwiseComparison::Impl
+{
+ const ITensor *src_0{ nullptr };
+ const ITensor *src_1{ nullptr };
+ ITensor *dst{ nullptr };
+ std::unique_ptr<experimental::NEElementwiseComparison> op{ nullptr };
+};
+
+NEElementwiseComparison::NEElementwiseComparison()
+ : _impl(support::cpp14::make_unique<Impl>())
+{
+}
+NEElementwiseComparison::NEElementwiseComparison(NEElementwiseComparison &&) = default;
+NEElementwiseComparison &NEElementwiseComparison::operator=(NEElementwiseComparison &&) = default;
+NEElementwiseComparison::~NEElementwiseComparison() = default;
+
+void NEElementwiseComparison::configure(ITensor *input1, ITensor *input2, ITensor *output, ComparisonOperation op)
+{
+ _impl->src_0 = input1;
+ _impl->src_1 = input2;
+ _impl->dst = output;
+ _impl->op = arm_compute::support::cpp14::make_unique<experimental::NEElementwiseComparison>();
+ _impl->op->configure(input1->info(), input2->info(), output->info(), op);
+}
+
+Status NEElementwiseComparison::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, ComparisonOperation op)
+{
+ return experimental::NEElementwiseComparison::validate(input1, input2, output, op);
+}
+
+void NEElementwiseComparison::run()
+{
+ const InputTensorMap src{ { TensorType::ACL_SRC_0, _impl->src_0 }, { TensorType::ACL_SRC_1, _impl->src_1 } };
+ const OutputTensorMap dst{ { TensorType::ACL_DST, _impl->dst } };
+ _impl->op->run(src, dst, {});
+}
+
// Supported Specializations
template class NEElementwiseComparisonStatic<ComparisonOperation::Equal>;
template class NEElementwiseComparisonStatic<ComparisonOperation::NotEqual>;
diff --git a/src/runtime/NEON/functions/NEPReluLayer.cpp b/src/runtime/NEON/functions/NEPReluLayer.cpp
index 02dfc6f137..1dd01fc162 100644
--- a/src/runtime/NEON/functions/NEPReluLayer.cpp
+++ b/src/runtime/NEON/functions/NEPReluLayer.cpp
@@ -29,7 +29,9 @@
namespace arm_compute
{
-void NEPReluLayer::configure(const ITensor *input, const ITensor *alpha, ITensor *output)
+namespace experimental
+{
+void NEPReluLayer::configure(const ITensorInfo *input, const ITensorInfo *alpha, ITensorInfo *output)
{
auto k = arm_compute::support::cpp14::make_unique<NEArithmeticOperationKernel>();
k->configure(ArithmeticOperation::PRELU, input, alpha, output);
@@ -40,4 +42,47 @@ Status NEPReluLayer::validate(const ITensorInfo *input, const ITensorInfo *alpha
{
return NEArithmeticOperationKernel::validate(ArithmeticOperation::PRELU, input, alpha, output);
}
+
+MemoryRequirements NEPReluLayer::workspace() const
+{
+ return MemoryRequirements{};
+}
+} // nsamespace experimental
+
+struct NEPReluLayer::Impl
+{
+ const ITensor *src_0{ nullptr };
+ const ITensor *src_1{ nullptr };
+ ITensor *dst{ nullptr };
+ std::unique_ptr<experimental::NEPReluLayer> op{ nullptr };
+};
+
+NEPReluLayer::NEPReluLayer()
+ : _impl(support::cpp14::make_unique<Impl>())
+{
+}
+NEPReluLayer::NEPReluLayer(NEPReluLayer &&) = default;
+NEPReluLayer &NEPReluLayer::operator=(NEPReluLayer &&) = default;
+NEPReluLayer::~NEPReluLayer() = default;
+
+void NEPReluLayer::configure(const ITensor *input, const ITensor *alpha, ITensor *output)
+{
+ _impl->src_0 = input;
+ _impl->src_1 = alpha;
+ _impl->dst = output;
+ _impl->op = arm_compute::support::cpp14::make_unique<experimental::NEPReluLayer>();
+ _impl->op->configure(input->info(), alpha->info(), output->info());
+}
+
+void NEPReluLayer::run()
+{
+ const InputTensorMap src{ { TensorType::ACL_SRC_0, _impl->src_0 }, { TensorType::ACL_SRC_1, _impl->src_1 } };
+ const OutputTensorMap dst{ { TensorType::ACL_DST, _impl->dst } };
+ _impl->op->run(src, dst, {});
+}
+
+Status NEPReluLayer::validate(const ITensorInfo *input, const ITensorInfo *alpha, const ITensorInfo *output)
+{
+ return experimental::NEPReluLayer::validate(input, alpha, output);
+}
} // namespace arm_compute
diff --git a/src/runtime/NEON/functions/NEReshapeLayer.cpp b/src/runtime/NEON/functions/NEReshapeLayer.cpp
index daf358e7db..2b866b532c 100644
--- a/src/runtime/NEON/functions/NEReshapeLayer.cpp
+++ b/src/runtime/NEON/functions/NEReshapeLayer.cpp
@@ -89,8 +89,9 @@ Status NEReshapeLayer::validate(const ITensorInfo *input, const ITensorInfo *out
void NEReshapeLayer::run()
{
- const InputTensor src{ TensorType::ACL_SRC, _impl->src };
- OutputTensor dst{ TensorType::ACL_DST, _impl->dst };
- _impl->op->run({ src }, { dst }, {});
+ const InputTensorMap src{ { TensorType::ACL_SRC, _impl->src } };
+ const OutputTensorMap dst{ { TensorType::ACL_DST, _impl->dst } };
+
+ _impl->op->run(src, dst, {});
}
} // namespace arm_compute
diff --git a/src/runtime/OMP/OMPScheduler.cpp b/src/runtime/OMP/OMPScheduler.cpp
index 6d6b285019..5b4b76a9df 100644
--- a/src/runtime/OMP/OMPScheduler.cpp
+++ b/src/runtime/OMP/OMPScheduler.cpp
@@ -83,7 +83,7 @@ void OMPScheduler::schedule(ICPPKernel *kernel, const Hints &hints)
}
}
-void OMPScheduler::schedule_op(ICPPKernel *kernel, const Hints &hints, const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs)
+void OMPScheduler::schedule_op(ICPPKernel *kernel, const Hints &hints, const InputTensorMap &inputs, const OutputTensorMap &outputs)
{
ARM_COMPUTE_ERROR_ON_MSG(!kernel, "The child class didn't set the kernel");
ARM_COMPUTE_ERROR_ON_MSG(hints.strategy() == StrategyHint::DYNAMIC,
diff --git a/tests/framework/instruments/SchedulerTimer.cpp b/tests/framework/instruments/SchedulerTimer.cpp
index 8729179a46..cc505cc6a1 100644
--- a/tests/framework/instruments/SchedulerTimer.cpp
+++ b/tests/framework/instruments/SchedulerTimer.cpp
@@ -86,7 +86,7 @@ public:
_kernels.push_back(std::move(info));
}
- void schedule_op(ICPPKernel *kernel, const Hints &hints, const std::vector<InputTensor> &inputs, const std::vector<OutputTensor> &outputs) override
+ void schedule_op(ICPPKernel *kernel, const Hints &hints, const InputTensorMap &inputs, const OutputTensorMap &outputs) override
{
_timer.start();
_real_scheduler.schedule_op(kernel, hints, inputs, outputs);