From ce0c67559cf03965acc8f212263a9f53205a0a3f Mon Sep 17 00:00:00 2001 From: Michalis Spyrou Date: Thu, 18 Jun 2020 10:14:57 +0100 Subject: COMPMID-3377: Async support to NEElementwiseUnaryLayerKernel kernels/functions Signed-off-by: Michalis Spyrou Change-Id: I208287b44ece051e95f891d43a691cb0ac6e56c5 Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/3419 Tested-by: Arm Jenkins Reviewed-by: Michele Di Giorgio Comments-Addressed: Arm Jenkins --- arm_compute/core/CPP/ICPPKernel.h | 2 +- .../core/NEON/kernels/NEActivationLayerKernel.h | 2 +- .../NEON/kernels/NEElementwiseOperationKernel.h | 47 +-- .../core/NEON/kernels/NEReshapeLayerKernel.h | 2 +- arm_compute/core/experimental/Types.h | 26 +- arm_compute/runtime/CPP/CPPScheduler.h | 4 +- arm_compute/runtime/IOperator.h | 4 +- arm_compute/runtime/IScheduler.h | 2 +- arm_compute/runtime/NEON/INEOperator.h | 4 +- .../NEON/functions/NEElementwiseOperations.h | 383 ++++++++++++++++++++- arm_compute/runtime/NEON/functions/NEPReluLayer.h | 57 ++- arm_compute/runtime/OMP/OMPScheduler.h | 2 +- arm_compute/runtime/SingleThreadScheduler.h | 2 +- src/core/NEON/kernels/NEActivationLayerKernel.cpp | 6 +- .../NEON/kernels/NEElementwiseOperationKernel.cpp | 44 +-- src/core/NEON/kernels/NEReshapeLayerKernel.cpp | 6 +- src/runtime/CPP/CPPScheduler.cpp | 8 +- src/runtime/CPP/SingleThreadScheduler.cpp | 2 +- src/runtime/NEON/INEOperator.cpp | 4 +- src/runtime/NEON/functions/NEActivationLayer.cpp | 6 +- .../NEON/functions/NEElementwiseOperators.cpp | 335 +++++++++++++++++- src/runtime/NEON/functions/NEPReluLayer.cpp | 47 ++- src/runtime/NEON/functions/NEReshapeLayer.cpp | 7 +- src/runtime/OMP/OMPScheduler.cpp | 2 +- tests/framework/instruments/SchedulerTimer.cpp | 2 +- 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 &inputs, const std::vector &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 &inputs, const std::vector &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 _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 &inputs, const std::vector &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; +using OutputTensorMap = std::map; +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 &inputs, const std::vector &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 &workloads) override; private: - void schedule_common(ICPPKernel *kernel, const Hints &hints, const std::vector &inputs, const std::vector &outputs); + void schedule_common(ICPPKernel *kernel, const Hints &hints, const InputTensorMap &inputs, const OutputTensorMap &outputs); struct Impl; std::unique_ptr _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 inputs, std::vector outputs, std::vector 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 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 &inputs, const std::vector &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 inputs, std::vector outputs, std::vector workspace) override final; - void prepare(std::vector constants) override final; + void run(InputTensorMap inputs, OutputTensorMap outputs, OperatorTensorMap workspace) override final; + void prepare(OperatorTensorMap constants) override final; protected: std::unique_ptr _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; }; /** 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; }; /** 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; }; /** 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; }; /** 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; }; /** 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; }; /** Basic function to run @ref NEComparisonOperationKernel @@ -206,9 +321,21 @@ public: * @note The function performs a comparison operation between two tensors. */ template -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; +}; + +/** Basic function to run equal comparison. */ +using NEEqual = NEElementwiseComparisonStatic; +/** Basic function to run not equal comparison. */ +using NENotEqual = NEElementwiseComparisonStatic; +/** Basic function to run greater comparison. */ +using NEGreater = NEElementwiseComparisonStatic; +/** Basic function to run greater-equal comparison. */ +using NEGreaterEqual = NEElementwiseComparisonStatic; +/** Basic function to run less comparison. */ +using NELess = NEElementwiseComparisonStatic; +/** Basic function to run less-equal comparison. */ +using NELessEqual = NEElementwiseComparisonStatic; + +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 +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; /** Basic function to run less-equal comparison. */ using NELessEqual = NEElementwiseComparisonStatic; +} // 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,19 +25,63 @@ #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. @@ -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; }; } // 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 &inputs, const std::vector &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 &inputs, const std::vector &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 &inputs, - const std::vector &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 &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 -configure_func(const ITensor *input1, const ITensor *input2, ITensor *output, +configure_func(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, std::map 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 std::function -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 map_function = { @@ -1097,7 +1097,7 @@ configure_arithm_func(const ITensor *input1, const ITensor *input2, ITensor *out template std::function -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 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 broadcast_pair = ITensorInfo::broadcast_shape_and_valid_region(*input1->info(), *input2->info()); + const std::pair 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(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(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 &inputs, const std::vector &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 &workloads) } #endif /* DOXYGEN_SKIP_THIS */ -void CPPScheduler::schedule_common(ICPPKernel *kernel, const Hints &hints, const std::vector &inputs, const std::vector &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 &inputs, const std::vector &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 inputs; - std::vector 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 &inputs, const std::vector &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 inputs, std::vector outputs, std::vector workspace) +void INEOperator::run(InputTensorMap inputs, OutputTensorMap outputs, OperatorTensorMap workspace) { ARM_COMPUTE_UNUSED(workspace); @@ -45,7 +45,7 @@ void INEOperator::run(std::vector inputs, std::vector NEScheduler::get().schedule_op(_kernel.get(), Window::DimY, inputs, outputs); } -void INEOperator::prepare(std::vector 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(); @@ -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(); @@ -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(); @@ -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(); @@ -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(); @@ -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 -void NEElementwiseComparisonStatic::configure(ITensor *input1, ITensor *input2, ITensor *output) +void NEElementwiseComparisonStatic::configure(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output) { auto k = arm_compute::support::cpp14::make_unique(); k->configure(COP, input1, input2, output); @@ -116,7 +143,13 @@ Status NEElementwiseComparisonStatic::validate(const ITensorInfo *input1, c return NEComparisonOperationKernel::validate(COP, input1, input2, output); } -void NEElementwiseComparison::configure(ITensor *input1, ITensor *input2, ITensor *output, ComparisonOperation op) +template +MemoryRequirements NEElementwiseComparisonStatic::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(); 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; +template class NEElementwiseComparisonStatic; +template class NEElementwiseComparisonStatic; +template class NEElementwiseComparisonStatic; +template class NEElementwiseComparisonStatic; +template class NEElementwiseComparisonStatic; +} // namespace experimental + +struct NEElementwiseMax::Impl +{ + const ITensor *src_0{ nullptr }; + const ITensor *src_1{ nullptr }; + ITensor *dst{ nullptr }; + std::unique_ptr op{ nullptr }; +}; + +NEElementwiseMax::NEElementwiseMax() + : _impl(support::cpp14::make_unique()) +{ +} +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(); + _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 op{ nullptr }; +}; + +NEElementwiseMin::NEElementwiseMin() + : _impl(support::cpp14::make_unique()) +{ +} +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(); + _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 op{ nullptr }; +}; + +NEElementwiseSquaredDiff::NEElementwiseSquaredDiff() + : _impl(support::cpp14::make_unique()) +{ +} +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(); + _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 op{ nullptr }; +}; + +NEElementwiseDivision::NEElementwiseDivision() + : _impl(support::cpp14::make_unique()) +{ +} +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(); + _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 op{ nullptr }; +}; + +NEElementwisePower::NEElementwisePower() + : _impl(support::cpp14::make_unique()) +{ +} +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(); + _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 +struct NEElementwiseComparisonStatic::Impl +{ + const ITensor *src_0{ nullptr }; + const ITensor *src_1{ nullptr }; + ITensor *dst{ nullptr }; + std::unique_ptr> op{ nullptr }; +}; + +template +NEElementwiseComparisonStatic::NEElementwiseComparisonStatic() + : _impl(support::cpp14::make_unique()) +{ +} +template +NEElementwiseComparisonStatic::NEElementwiseComparisonStatic(NEElementwiseComparisonStatic &&) = default; +template +NEElementwiseComparisonStatic &NEElementwiseComparisonStatic::operator=(NEElementwiseComparisonStatic &&) = default; +template +NEElementwiseComparisonStatic::~NEElementwiseComparisonStatic() = default; + +template +void NEElementwiseComparisonStatic::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>(); + _impl->op->configure(input1->info(), input2->info(), output->info()); +} + +template +Status NEElementwiseComparisonStatic::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output) +{ + return experimental::NEElementwiseComparisonStatic::validate(input1, input2, output); +} + +template +void NEElementwiseComparisonStatic::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 op{ nullptr }; +}; + +NEElementwiseComparison::NEElementwiseComparison() + : _impl(support::cpp14::make_unique()) +{ +} +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(); + _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; template class NEElementwiseComparisonStatic; 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(); 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 op{ nullptr }; +}; + +NEPReluLayer::NEPReluLayer() + : _impl(support::cpp14::make_unique()) +{ +} +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(); + _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 &inputs, const std::vector &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 &inputs, const std::vector &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); -- cgit v1.2.1