diff options
Diffstat (limited to 'arm_compute/graph')
108 files changed, 2220 insertions, 1575 deletions
diff --git a/arm_compute/graph/backends/GLES/GCFunctionFactory.h b/arm_compute/graph/DataLayerVisitor.h index 289a3cb0f8..11d9f1ddc9 100644 --- a/arm_compute/graph/backends/GLES/GCFunctionFactory.h +++ b/arm_compute/graph/DataLayerVisitor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2021, 2023 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -21,37 +21,41 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_GCFUNCTIONFACTORY_H -#define ARM_COMPUTE_GRAPH_GCFUNCTIONFACTORY_H +#ifndef ACL_ARM_COMPUTE_GRAPH_DATALAYERVISITOR_H +#define ACL_ARM_COMPUTE_GRAPH_DATALAYERVISITOR_H -#include "arm_compute/runtime/IFunction.h" - -#include <memory> +#include "arm_compute/graph/IGraphPrinter.h" +#include "arm_compute/graph/INodeVisitor.h" +#include "arm_compute/graph/Types.h" namespace arm_compute { namespace graph { -// Forward declarations -class INode; -class GraphContext; - -namespace backends -{ -/** Factory for generating GLES compute backend functions **/ -class GCFunctionFactory final +/** Graph printer visitor. */ +class DataLayerVisitor final : public DefaultNodeVisitor { public: - /** Create a backend execution function depending on the node type - * - * @param[in] node Node to create the backend function for - * @param[in] ctx Context to use - * - * @return Backend function - */ - static std::unique_ptr<arm_compute::IFunction> create(INode *node, GraphContext &ctx); + using LayerData = std::map<std::string, std::string>; + /** Default Constructor **/ + DataLayerVisitor() = default; + + const LayerData &layer_data() const; + + // Reveal Parent method + using DefaultNodeVisitor::visit; + // Inherited methods overridden + void visit(ConvolutionLayerNode &n) override; + void visit(DepthwiseConvolutionLayerNode &n) override; + void visit(FusedConvolutionBatchNormalizationNode &n) override; + void visit(FusedDepthwiseConvolutionBatchNormalizationNode &n) override; + void visit(OutputNode &n) override; + + void default_visit(INode &n) override; + +private: + LayerData _layer_data{}; }; -} // namespace backends } // namespace graph } // namespace arm_compute -#endif //ARM_COMPUTE_GRAPH_GCFUNCTIONFACTORY_H +#endif // ACL_ARM_COMPUTE_GRAPH_DATALAYERVISITOR_H diff --git a/arm_compute/graph/Edge.h b/arm_compute/graph/Edge.h index e40914efd0..7f5075d885 100644 --- a/arm_compute/graph/Edge.h +++ b/arm_compute/graph/Edge.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -48,8 +48,18 @@ public: * @param[in] consumer_idx Consumer node input index * @param[in] tensor Tensor associated with the edge */ - Edge(EdgeID id, INode *producer, unsigned int producer_idx, INode *consumer, unsigned int consumer_idx, Tensor *tensor) - : _id(id), _producer(producer), _consumer(consumer), _producer_idx(producer_idx), _consumer_idx(consumer_idx), _tensor(tensor) + Edge(EdgeID id, + INode *producer, + unsigned int producer_idx, + INode *consumer, + unsigned int consumer_idx, + Tensor *tensor) + : _id(id), + _producer(producer), + _consumer(consumer), + _producer_idx(producer_idx), + _consumer_idx(consumer_idx), + _tensor(tensor) { } diff --git a/arm_compute/graph/Graph.h b/arm_compute/graph/Graph.h index dce92c67f1..e6e173f5fa 100644 --- a/arm_compute/graph/Graph.h +++ b/arm_compute/graph/Graph.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2020,2023 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -30,7 +30,6 @@ #include "arm_compute/graph/Types.h" #include "support/Mutex.h" -#include "support/ToolchainSupport.h" #include <map> #include <memory> @@ -80,7 +79,7 @@ public: * @return ID of the node */ template <typename NT, typename... Ts> - NodeID add_node(Ts &&... args); + NodeID add_node(Ts &&...args); /** Remove the node with the given ID * * @param[in] nid ID of the node to remove @@ -222,23 +221,23 @@ private: TensorID create_tensor(const TensorDescriptor &desc = TensorDescriptor()); private: - GraphID _id = GraphID(0); /**< Graph id */ - std::string _name = {}; /**< Graph name */ - std::vector<std::unique_ptr<INode>> _nodes = {}; /**< Graph nodes */ - std::vector<std::unique_ptr<Edge>> _edges = {}; /**< Graph edges */ - std::vector<std::unique_ptr<Tensor>> _tensors = {}; /**< Graph tensors */ + GraphID _id = GraphID(0); /**< Graph id */ + std::string _name = {}; /**< Graph name */ + std::vector<std::unique_ptr<INode>> _nodes = {}; /**< Graph nodes */ + std::vector<std::unique_ptr<Edge>> _edges = {}; /**< Graph edges */ + std::vector<std::unique_ptr<Tensor>> _tensors = {}; /**< Graph tensors */ std::map<NodeType, std::vector<NodeID>> _tagged_nodes = {}; /**< Graph nodes map with the node type as key */ - arm_compute::Mutex _mtx = {}; /**< Mutex used for graph construction */ + arm_compute::Mutex _mtx = {}; /**< Mutex used for graph construction */ }; template <typename NT, typename... Ts> -inline NodeID Graph::add_node(Ts &&... args) +inline NodeID Graph::add_node(Ts &&...args) { arm_compute::lock_guard<arm_compute::Mutex> lock(_mtx); // Create node NodeID nid = _nodes.size(); - auto node = support::cpp14::make_unique<NT>(std::forward<Ts>(args)...); + auto node = std::make_unique<NT>(std::forward<Ts>(args)...); node->set_graph(this); node->set_id(nid); @@ -246,7 +245,7 @@ inline NodeID Graph::add_node(Ts &&... args) _tagged_nodes[node->type()].push_back(nid); // Associate a new tensor with each output - for(auto &output : node->_outputs) + for (auto &output : node->_outputs) { output = create_tensor(); } diff --git a/arm_compute/graph/GraphBuilder.h b/arm_compute/graph/GraphBuilder.h index 612703cae5..118d06bdda 100644 --- a/arm_compute/graph/GraphBuilder.h +++ b/arm_compute/graph/GraphBuilder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -51,7 +51,8 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_const_node(Graph &g, NodeParams params, const TensorDescriptor &desc, ITensorAccessorUPtr accessor = nullptr); + static NodeID + add_const_node(Graph &g, NodeParams params, const TensorDescriptor &desc, ITensorAccessorUPtr accessor = nullptr); /** Adds an input layer node to the graph * * @param[in] g Graph to add the node to @@ -61,7 +62,8 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_input_node(Graph &g, NodeParams params, const TensorDescriptor &desc, ITensorAccessorUPtr accessor = nullptr); + static NodeID + add_input_node(Graph &g, NodeParams params, const TensorDescriptor &desc, ITensorAccessorUPtr accessor = nullptr); /** Adds an output layer node to the graph * * @param[in] g Graph to add the node to @@ -71,7 +73,8 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_output_node(Graph &g, NodeParams params, NodeIdxPair input, ITensorAccessorUPtr accessor = nullptr); + static NodeID + add_output_node(Graph &g, NodeParams params, NodeIdxPair input, ITensorAccessorUPtr accessor = nullptr); /** Adds an activation layer node to the graph * * @param[in] g Graph to add the node to @@ -82,8 +85,30 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_activation_node(Graph &g, NodeParams params, NodeIdxPair input, ActivationLayerInfo act_info, + static NodeID add_activation_node(Graph &g, + NodeParams params, + NodeIdxPair input, + ActivationLayerInfo act_info, const QuantizationInfo &out_quant_info = QuantizationInfo()); + /** Adds an activation layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the activation layer node as a NodeID-Index pair + * @param[in] op Reduction Operation: min or max + * @param[in] axis Axis to perform reduction operation across + * @param[in] out_data_type (Optional) Output data type + * @param[in] out_quant_info (Optional) Output quantization info + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_arg_min_max_node(Graph &g, + NodeParams params, + NodeIdxPair input, + ReductionOperation op, + unsigned int axis, + DataType out_data_type = DataType::UNKNOWN, + const QuantizationInfo &out_quant_info = QuantizationInfo()); /** Adds a batch normalization layer node to the graph * * @param[in] g Graph to add the node to @@ -97,9 +122,14 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_batch_normalization_node(Graph &g, NodeParams params, NodeIdxPair input, float epsilon, - ITensorAccessorUPtr mean_accessor = nullptr, ITensorAccessorUPtr var_accessor = nullptr, - ITensorAccessorUPtr beta_accessor = nullptr, ITensorAccessorUPtr gamma_accessor = nullptr); + static NodeID add_batch_normalization_node(Graph &g, + NodeParams params, + NodeIdxPair input, + float epsilon, + ITensorAccessorUPtr mean_accessor = nullptr, + ITensorAccessorUPtr var_accessor = nullptr, + ITensorAccessorUPtr beta_accessor = nullptr, + ITensorAccessorUPtr gamma_accessor = nullptr); /** Adds a bounding box transform layer node to the graph * * @param[in] g Graph to add the node to @@ -110,7 +140,8 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_bounding_box_transform_node(Graph &g, NodeParams params, NodeIdxPair input, NodeIdxPair deltas, BoundingBoxTransformInfo info); + static NodeID add_bounding_box_transform_node( + Graph &g, NodeParams params, NodeIdxPair input, NodeIdxPair deltas, BoundingBoxTransformInfo info); /** Adds an channel shuffle layer node to the graph * * @param[in] g Graph to add the node to @@ -123,8 +154,6 @@ public: static NodeID add_channel_shuffle_node(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_groups); /** Adds a convolution layer node to the graph * - * TODO (COMPMID-1113): Add a graph descriptor for convolution layer node - * * @param[in] g Graph to add the node to * @param[in] params Common node parameters * @param[in] input Input to the convolution layer node as a NodeID-Index pair @@ -141,10 +170,17 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_convolution_node(Graph &g, NodeParams params, NodeIdxPair input, - Size2D kernel_spatial_extend, unsigned int depth, PadStrideInfo conv_info, unsigned int num_groups = 1, - ConvolutionMethod method = ConvolutionMethod::Default, FastMathHint fast_math_hint = FastMathHint::Disabled, - ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr, + static NodeID add_convolution_node(Graph &g, + NodeParams params, + NodeIdxPair input, + Size2D kernel_spatial_extend, + unsigned int depth, + PadStrideInfo conv_info, + unsigned int num_groups = 1, + ConvolutionMethod method = ConvolutionMethod::Default, + FastMathHint fast_math_hint = FastMathHint::Disabled, + ITensorAccessorUPtr weights_accessor = nullptr, + ITensorAccessorUPtr bias_accessor = nullptr, const QuantizationInfo &weights_quant_info = QuantizationInfo(), const QuantizationInfo &out_quant_info = QuantizationInfo()); /** Adds a deconvolution layer node to the graph @@ -160,9 +196,14 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_deconvolution_node(Graph &g, NodeParams params, NodeIdxPair input, - Size2D kernel_spatial_extend, unsigned int depth, PadStrideInfo deconv_info, - ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr); + static NodeID add_deconvolution_node(Graph &g, + NodeParams params, + NodeIdxPair input, + Size2D kernel_spatial_extend, + unsigned int depth, + PadStrideInfo deconv_info, + ITensorAccessorUPtr weights_accessor = nullptr, + ITensorAccessorUPtr bias_accessor = nullptr); /** Adds a depth concatenate node to the graph * * @param[in] g Graph to add the node to @@ -172,7 +213,20 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_concatenate_node(Graph &g, NodeParams params, const std::vector<NodeIdxPair> &inputs, const descriptors::ConcatLayerDescriptor &concat_descriptor); + static NodeID add_concatenate_node(Graph &g, + NodeParams params, + const std::vector<NodeIdxPair> &inputs, + const descriptors::ConcatLayerDescriptor &concat_descriptor); + /** Adds an depth to space layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the depth to space layer node as a NodeID-Index pair + * @param[in] block_shape Block shape to reshape tensor with + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_depth_to_space_node(Graph &g, NodeParams params, NodeIdxPair input, int32_t block_shape); /** Adds a depth-wise convolution layer node to the graph * * @param[in] g Graph to add the node to @@ -189,11 +243,18 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_depthwise_convolution_node(Graph &g, NodeParams params, NodeIdxPair input, - Size2D kernel_spatial_extend, PadStrideInfo conv_info, int depth_multiplier = 1, - DepthwiseConvolutionMethod method = DepthwiseConvolutionMethod::Default, - ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr, const QuantizationInfo &quant_info = QuantizationInfo(), - const QuantizationInfo &out_quant_info = QuantizationInfo()); + static NodeID + add_depthwise_convolution_node(Graph &g, + NodeParams params, + NodeIdxPair input, + Size2D kernel_spatial_extend, + PadStrideInfo conv_info, + int depth_multiplier = 1, + DepthwiseConvolutionMethod method = DepthwiseConvolutionMethod::Default, + ITensorAccessorUPtr weights_accessor = nullptr, + ITensorAccessorUPtr bias_accessor = nullptr, + const QuantizationInfo &quant_info = QuantizationInfo(), + const QuantizationInfo &out_quant_info = QuantizationInfo()); /** Adds an element-wise layer node to the graph * * @param[in] g Graph to add the node to @@ -204,7 +265,8 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_elementwise_node(Graph &g, NodeParams params, NodeIdxPair input0, NodeIdxPair input1, EltwiseOperation operation); + static NodeID add_elementwise_node( + Graph &g, NodeParams params, NodeIdxPair input0, NodeIdxPair input1, EltwiseOperation operation); /** Adds a dequantization node to the graph * * @param[in] g Graph to add the node to @@ -225,7 +287,12 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_detection_output_node(Graph &g, NodeParams params, NodeIdxPair input_loc, NodeIdxPair input_conf, NodeIdxPair input_priorbox, const DetectionOutputLayerInfo &detect_info); + static NodeID add_detection_output_node(Graph &g, + NodeParams params, + NodeIdxPair input_loc, + NodeIdxPair input_conf, + NodeIdxPair input_priorbox, + const DetectionOutputLayerInfo &detect_info); /** Adds a detection post process layer node to the graph * * @param[in] g Graph to add the node to @@ -238,8 +305,12 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_detection_post_process_node(Graph &g, NodeParams params, NodeIdxPair input_box_encoding, NodeIdxPair input_class_prediction, - const DetectionPostProcessLayerInfo &detect_info, ITensorAccessorUPtr anchors_accessor = nullptr, + static NodeID add_detection_post_process_node(Graph &g, + NodeParams params, + NodeIdxPair input_box_encoding, + NodeIdxPair input_class_prediction, + const DetectionPostProcessLayerInfo &detect_info, + ITensorAccessorUPtr anchors_accessor = nullptr, const QuantizationInfo &anchor_quant_info = QuantizationInfo()); /** Adds a Dummy node to the graph * @@ -272,13 +343,19 @@ public: * @param[in] bias_nid (Optional) Node ID of the bias node data. Defaults to EmptyNodeID * @param[in] fc_info (Optional) Fully connected layer metadata * @param[in] out_quant_info (Optional) Output quantization info + * @param[in] fast_math_hint (Optional) Fast math hint * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_fully_connected_layer(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_outputs, - NodeID weights_nid, NodeID bias_nid = EmptyNodeID, + static NodeID add_fully_connected_layer(Graph &g, + NodeParams params, + NodeIdxPair input, + unsigned int num_outputs, + NodeID weights_nid, + NodeID bias_nid = EmptyNodeID, const FullyConnectedLayerInfo fc_info = FullyConnectedLayerInfo(), - const QuantizationInfo &out_quant_info = QuantizationInfo()); + const QuantizationInfo &out_quant_info = QuantizationInfo(), + FastMathHint fast_math_hint = FastMathHint::Disabled); /** Adds a fully connected layer node to the graph * * @param[in] g Graph to add the layer to @@ -290,14 +367,20 @@ public: * @param[in] fc_info (Optional) Fully connected layer metadata * @param[in] weights_quant_info (Optional) Weights quantization info * @param[in] out_quant_info (Optional) Output quantization info + * @param[in] fast_math_hint (Optional) Fast math hint * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_fully_connected_layer(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_outputs, - ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr, - const FullyConnectedLayerInfo fc_info = FullyConnectedLayerInfo(), + static NodeID add_fully_connected_layer(Graph &g, + NodeParams params, + NodeIdxPair input, + unsigned int num_outputs, + ITensorAccessorUPtr weights_accessor = nullptr, + ITensorAccessorUPtr bias_accessor = nullptr, + const FullyConnectedLayerInfo fc_info = FullyConnectedLayerInfo(), const QuantizationInfo &weights_quant_info = QuantizationInfo(), - const QuantizationInfo &out_quant_info = QuantizationInfo()); + const QuantizationInfo &out_quant_info = QuantizationInfo(), + FastMathHint fast_math_hint = FastMathHint::Disabled); /** Adds a generate proposals layer node to the graph * * @param[in] g Graph to add the layer to @@ -309,8 +392,23 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_generate_proposals_node(Graph &g, NodeParams params, NodeIdxPair scores, NodeIdxPair deltas, - NodeIdxPair anchors, GenerateProposalsInfo info); + static NodeID add_generate_proposals_node(Graph &g, + NodeParams params, + NodeIdxPair scores, + NodeIdxPair deltas, + NodeIdxPair anchors, + GenerateProposalsInfo info); + /** Adds a L2 Normalize layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the normalization layer node as a NodeID-Index pair + * @param[in] axis Axis to perform normalization on + * @param[in] epsilon Lower bound value for the normalization + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_l2_normalize_node(Graph &g, NodeParams params, NodeIdxPair input, int axis, float epsilon); /** Adds a normalization layer node to the graph * * @param[in] g Graph to add the node to @@ -320,7 +418,8 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_normalization_node(Graph &g, NodeParams params, NodeIdxPair input, NormalizationLayerInfo norm_info); + static NodeID + add_normalization_node(Graph &g, NodeParams params, NodeIdxPair input, NormalizationLayerInfo norm_info); /** Adds a normalize planar YUV layer node to the graph * * @param[in] g Graph to add the node to @@ -331,8 +430,11 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_normalize_planar_yuv_node(Graph &g, NodeParams params, NodeIdxPair input, - ITensorAccessorUPtr mean_accessor = nullptr, ITensorAccessorUPtr std_accessor = nullptr); + static NodeID add_normalize_planar_yuv_node(Graph &g, + NodeParams params, + NodeIdxPair input, + ITensorAccessorUPtr mean_accessor = nullptr, + ITensorAccessorUPtr std_accessor = nullptr); /** Adds a pad layer node to the graph * * @param[in] g Graph to add the node to @@ -344,7 +446,11 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_pad_node(Graph &g, NodeParams params, NodeIdxPair input, const PaddingList &paddings, PixelValue pad_value = PixelValue()); + static NodeID add_pad_node(Graph &g, + NodeParams params, + NodeIdxPair input, + const PaddingList &paddings, + PixelValue pad_value = PixelValue()); /** Adds a permute layer node to the graph * * @param[in] g Graph to add the node to @@ -356,7 +462,11 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_permute_node(Graph &g, NodeParams params, NodeIdxPair input, PermutationVector perm, DataLayout layout = DataLayout::UNKNOWN); + static NodeID add_permute_node(Graph &g, + NodeParams params, + NodeIdxPair input, + PermutationVector perm, + DataLayout layout = DataLayout::UNKNOWN); /** Adds a pooling layer node to the graph * * @param[in] g Graph to add the node to @@ -388,8 +498,12 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_print_node(Graph &g, NodeParams params, NodeIdxPair input, std::ostream &stream, const IOFormatInfo &format_info = IOFormatInfo(), - const std::function<ITensor *(ITensor *)> transform = nullptr); + static NodeID add_print_node(Graph &g, + NodeParams params, + NodeIdxPair input, + std::ostream &stream, + const IOFormatInfo &format_info = IOFormatInfo(), + const std::function<ITensor *(ITensor *)> transform = nullptr); /** Adds a priorbox layer node to the graph * * @param[in] g Graph to add the node to @@ -400,7 +514,8 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_priorbox_node(Graph &g, NodeParams params, NodeIdxPair input0, NodeIdxPair input1, const PriorBoxLayerInfo &prior_info); + static NodeID add_priorbox_node( + Graph &g, NodeParams params, NodeIdxPair input0, NodeIdxPair input1, const PriorBoxLayerInfo &prior_info); /** Adds a quantization layer node to the graph * * @param[in] g Graph to add the node to @@ -410,7 +525,21 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_quantization_node(Graph &g, NodeParams params, NodeIdxPair input, const QuantizationInfo &out_quant_info); + static NodeID + add_quantization_node(Graph &g, NodeParams params, NodeIdxPair input, const QuantizationInfo &out_quant_info); + /** Adds a reduction sum layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the reorg layer node as a NodeID-Index pair + * @param[in] op Reduction operation + * @param[in] axis Reduction axis + * @param[in] keep_dims (Optional) Whether to keep the reduced dimension after the operation. Defaults to true. + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_reduction_operation_node( + Graph &g, NodeParams params, NodeIdxPair input, ReductionOperation op, int axis, bool keep_dims = true); /** Adds a reorg layer node to the graph * * @param[in] g Graph to add the node to @@ -442,7 +571,12 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_resize_node(Graph &g, NodeParams params, NodeIdxPair input, InterpolationPolicy policy, float width_scale, float height_scale); + static NodeID add_resize_node(Graph &g, + NodeParams params, + NodeIdxPair input, + InterpolationPolicy policy, + float width_scale, + float height_scale); /** Adds a ROI align layer node to the graph * * @param[in] g Graph to add the node to @@ -453,7 +587,8 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_roi_align_node(Graph &g, NodeParams params, NodeIdxPair input, NodeIdxPair rois, ROIPoolingLayerInfo pool_info); + static NodeID + add_roi_align_node(Graph &g, NodeParams params, NodeIdxPair input, NodeIdxPair rois, ROIPoolingLayerInfo pool_info); /** Adds a scale layer node to the graph * This layer computes a product of the input with a scale (read from mul_accessor) and it applies an offset (read from add_accessor). * output = input * mul_w + add_w @@ -466,8 +601,11 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_scale_layer(Graph &g, const NodeParams ¶ms, NodeIdxPair input, - ITensorAccessorUPtr mul_accessor = nullptr, ITensorAccessorUPtr add_accessor = nullptr); + static NodeID add_scale_layer(Graph &g, + const NodeParams ¶ms, + NodeIdxPair input, + ITensorAccessorUPtr mul_accessor = nullptr, + ITensorAccessorUPtr add_accessor = nullptr); /** Adds a softmax node to the graph * * @param[in] g Graph to add the node to @@ -488,7 +626,8 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_slice_node(Graph &g, NodeParams params, NodeIdxPair input, Coordinates &starts, Coordinates &ends); + static NodeID + add_slice_node(Graph &g, NodeParams params, NodeIdxPair input, Coordinates &starts, Coordinates &ends); /** Adds a split node to the graph * * @param[in] g Graph to add the node to @@ -499,7 +638,8 @@ public: * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_split_node(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_splits, unsigned int axis = 0); + static NodeID + add_split_node(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_splits, unsigned int axis = 0); /** Adds a stack layer node to the graph * * @param[in] g Graph to add the node to @@ -510,28 +650,35 @@ public: * @return Node ID of the created node, EmptyNodeID in case of error */ static NodeID add_stack_node(Graph &g, NodeParams params, const std::vector<NodeIdxPair> &inputs, int axis); - /** Adds an upsample layer to the graph + /** Adds a strided slice node to the graph * - * @param[in] g Graph to add the node to - * @param[in] params Common node parameters - * @param[in] input Input to the yolo layer node as a NodeID-Index pair - * @param[in] info Upsample layer stride info - * @param[in] upsampling_policy Upsampling policy used + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the strided slice layer node as a NodeID-Index pair + * @param[in] starts The starts of the dimensions of the input tensor to be sliced. The length must be of rank(input). + * @param[in] ends The ends of the dimensions of the input tensor to be sliced. The length must be of rank(input). + * @param[in] strides The strides of the dimensions of the input tensor to be sliced. The length must be of rank(input). + * @param[in] info Contains masks for the starts, ends and strides * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_upsample_node(Graph &g, NodeParams params, NodeIdxPair input, Size2D info, InterpolationPolicy upsampling_policy); + static NodeID add_strided_slice_node(Graph &g, + NodeParams params, + NodeIdxPair input, + Coordinates &starts, + Coordinates &ends, + BiStrides &strides, + StridedSliceLayerInfo info); /** Adds a yolo layer to the graph * - * @param[in] g Graph to add the node to - * @param[in] params Common node parameters - * @param[in] input Input to the yolo layer node as a NodeID-Index pair - * @param[in] act_info Activation layer parameters - * @param[in] num_classes Number of classes to activate + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the yolo layer node as a NodeID-Index pair + * @param[in] act_info Activation layer parameters * * @return Node ID of the created node, EmptyNodeID in case of error */ - static NodeID add_yolo_node(Graph &g, NodeParams params, NodeIdxPair input, ActivationLayerInfo act_info, int32_t num_classes); + static NodeID add_yolo_node(Graph &g, NodeParams params, NodeIdxPair input, ActivationLayerInfo act_info); }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/GraphContext.h b/arm_compute/graph/GraphContext.h index 973264afba..68fbaf5478 100644 --- a/arm_compute/graph/GraphContext.h +++ b/arm_compute/graph/GraphContext.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -25,7 +25,6 @@ #define ARM_COMPUTE_GRAPH_GRAPH_CONTEXT_H #include "arm_compute/graph/Types.h" - #include "arm_compute/runtime/IMemoryManager.h" #include "arm_compute/runtime/IWeightsManager.h" @@ -39,18 +38,18 @@ namespace graph /** Contains structs required for memory management */ struct MemoryManagerContext { - Target target = { Target::UNSPECIFIED }; /**< Target */ - std::shared_ptr<arm_compute::IMemoryManager> intra_mm = { nullptr }; /**< Intra-function memory manager */ - std::shared_ptr<arm_compute::IMemoryManager> cross_mm = { nullptr }; /**< Cross-function memory manager */ - std::shared_ptr<arm_compute::IMemoryGroup> cross_group = { nullptr }; /**< Cross-function memory group */ - IAllocator *allocator = { nullptr }; /**< Backend allocator to use */ + Target target = {Target::UNSPECIFIED}; /**< Target */ + std::shared_ptr<arm_compute::IMemoryManager> intra_mm = {nullptr}; /**< Intra-function memory manager */ + std::shared_ptr<arm_compute::IMemoryManager> cross_mm = {nullptr}; /**< Cross-function memory manager */ + std::shared_ptr<arm_compute::IMemoryGroup> cross_group = {nullptr}; /**< Cross-function memory group */ + IAllocator *allocator = {nullptr}; /**< Backend allocator to use */ }; /** Contains structs required for weights management */ struct WeightsManagerContext { - Target target = { Target::UNSPECIFIED }; /**< Target */ - std::shared_ptr<arm_compute::IWeightsManager> wm = { nullptr }; /**< Weights manager */ + Target target = {Target::UNSPECIFIED}; /**< Target */ + std::shared_ptr<arm_compute::IWeightsManager> wm = {nullptr}; /**< Weights manager */ }; /** Graph context **/ @@ -125,7 +124,7 @@ public: void finalize(); private: - GraphConfig _config; /**< Graph configuration */ + GraphConfig _config; /**< Graph configuration */ std::map<Target, MemoryManagerContext> _memory_managers; /**< Memory managers for each target */ std::map<Target, WeightsManagerContext> _weights_managers; /**< Weights managers for each target */ }; diff --git a/arm_compute/graph/GraphManager.h b/arm_compute/graph/GraphManager.h index 23fa73254b..ae48e818ec 100644 --- a/arm_compute/graph/GraphManager.h +++ b/arm_compute/graph/GraphManager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/IDeviceBackend.h b/arm_compute/graph/IDeviceBackend.h index d40d752952..8ae92e3177 100644 --- a/arm_compute/graph/IDeviceBackend.h +++ b/arm_compute/graph/IDeviceBackend.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019,2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -88,7 +88,8 @@ public: * * @return Backend sub-tensor handle */ - virtual std::unique_ptr<ITensorHandle> create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) = 0; + virtual std::unique_ptr<ITensorHandle> + create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) = 0; /** Configure a backend Node * * @note This creates an appropriate configured backend function for the given node @@ -118,6 +119,8 @@ public: * @return Weights manager */ virtual std::shared_ptr<arm_compute::IWeightsManager> create_weights_manager() = 0; + /** Synchronize kernels execution on the backend. On GPU, this results in a blocking call waiting for all kernels to be completed. */ + virtual void sync() = 0; }; } // namespace backends } // namespace graph diff --git a/arm_compute/graph/IGraphMutator.h b/arm_compute/graph/IGraphMutator.h index 94a28f63b1..1c68b17c01 100644 --- a/arm_compute/graph/IGraphMutator.h +++ b/arm_compute/graph/IGraphMutator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/IGraphPrinter.h b/arm_compute/graph/IGraphPrinter.h index 73f3fa8ba3..9ee11d514f 100644 --- a/arm_compute/graph/IGraphPrinter.h +++ b/arm_compute/graph/IGraphPrinter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/INode.h b/arm_compute/graph/INode.h index 5536bb97ab..5646ea81d2 100644 --- a/arm_compute/graph/INode.h +++ b/arm_compute/graph/INode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019,2021,2023 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -21,14 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_INODE_H -#define ARM_COMPUTE_GRAPH_INODE_H +#ifndef ACL_ARM_COMPUTE_GRAPH_INODE_H +#define ACL_ARM_COMPUTE_GRAPH_INODE_H #include "arm_compute/core/Error.h" #include "arm_compute/graph/LayerDescriptors.h" #include "arm_compute/graph/TensorDescriptor.h" #include "arm_compute/graph/Types.h" +#include <list> #include <set> namespace arm_compute @@ -255,4 +256,4 @@ protected: }; } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_INODE_H */ +#endif // ACL_ARM_COMPUTE_GRAPH_INODE_H diff --git a/arm_compute/graph/INodeVisitor.h b/arm_compute/graph/INodeVisitor.h index deaa8f1a51..efe191adfc 100644 --- a/arm_compute/graph/INodeVisitor.h +++ b/arm_compute/graph/INodeVisitor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2021, 2023 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -21,8 +21,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_INODEVISITOR_H -#define ARM_COMPUTE_GRAPH_INODEVISITOR_H +#ifndef ACL_ARM_COMPUTE_GRAPH_INODEVISITOR_H +#define ACL_ARM_COMPUTE_GRAPH_INODEVISITOR_H #include "arm_compute/graph/nodes/NodesFwd.h" @@ -191,125 +191,41 @@ public: #ifndef DOXYGEN_SKIP_THIS // Inherited methods overridden - virtual void visit(INode &) override - { - default_visit(); - } - virtual void visit(ActivationLayerNode &) override - { - default_visit(); - } - virtual void visit(BatchNormalizationLayerNode &) override - { - default_visit(); - } - virtual void visit(ConcatenateLayerNode &) override - { - default_visit(); - } - virtual void visit(ConstNode &) override - { - default_visit(); - } - virtual void visit(ConvolutionLayerNode &) override - { - default_visit(); - } - virtual void visit(DequantizationLayerNode &) override - { - default_visit(); - } - virtual void visit(DetectionOutputLayerNode &) override - { - default_visit(); - } - virtual void visit(DetectionPostProcessLayerNode &) override - { - default_visit(); - } - virtual void visit(DepthwiseConvolutionLayerNode &) override - { - default_visit(); - } - virtual void visit(EltwiseLayerNode &) override - { - default_visit(); - } - virtual void visit(FlattenLayerNode &) override - { - default_visit(); - } - virtual void visit(FullyConnectedLayerNode &) override - { - default_visit(); - } - virtual void visit(FusedConvolutionBatchNormalizationNode &) override - { - default_visit(); - } - virtual void visit(FusedDepthwiseConvolutionBatchNormalizationNode &) override - { - default_visit(); - } - virtual void visit(InputNode &) override - { - default_visit(); - } - virtual void visit(NormalizationLayerNode &) override - { - default_visit(); - } - virtual void visit(OutputNode &) override - { - default_visit(); - } - virtual void visit(PermuteLayerNode &) override - { - default_visit(); - } - virtual void visit(PoolingLayerNode &) override - { - default_visit(); - } - virtual void visit(PReluLayerNode &) override - { - default_visit(); - } - virtual void visit(PrintLayerNode &) override - { - default_visit(); - } - virtual void visit(PriorBoxLayerNode &) override - { - default_visit(); - } - virtual void visit(QuantizationLayerNode &) override - { - default_visit(); - } - virtual void visit(ReshapeLayerNode &) override - { - default_visit(); - } - virtual void visit(SoftmaxLayerNode &) override - { - default_visit(); - } - virtual void visit(SplitLayerNode &) override - { - default_visit(); - } - virtual void visit(StackLayerNode &) override - { - default_visit(); - } + virtual void visit(INode &n) override; + virtual void visit(ActivationLayerNode &n) override; + virtual void visit(BatchNormalizationLayerNode &n) override; + virtual void visit(ConcatenateLayerNode &n) override; + virtual void visit(ConstNode &n) override; + virtual void visit(ConvolutionLayerNode &n) override; + virtual void visit(DequantizationLayerNode &n) override; + virtual void visit(DetectionOutputLayerNode &n) override; + virtual void visit(DetectionPostProcessLayerNode &n) override; + virtual void visit(DepthwiseConvolutionLayerNode &n) override; + virtual void visit(EltwiseLayerNode &n) override; + virtual void visit(FlattenLayerNode &n) override; + virtual void visit(FullyConnectedLayerNode &n) override; + virtual void visit(FusedConvolutionBatchNormalizationNode &n) override; + virtual void visit(FusedDepthwiseConvolutionBatchNormalizationNode &n) override; + virtual void visit(InputNode &n) override; + virtual void visit(NormalizationLayerNode &n) override; + virtual void visit(OutputNode &n) override; + virtual void visit(PermuteLayerNode &n) override; + virtual void visit(PoolingLayerNode &n) override; + virtual void visit(PReluLayerNode &n) override; + virtual void visit(PrintLayerNode &n) override; + virtual void visit(PriorBoxLayerNode &n) override; + virtual void visit(QuantizationLayerNode &n) override; + virtual void visit(ReshapeLayerNode &n) override; + virtual void visit(SoftmaxLayerNode &n) override; + virtual void visit(SplitLayerNode &n) override; + virtual void visit(StackLayerNode &n) override; #endif /* DOXYGEN_SKIP_THIS */ /** Function to be overloaded by the client and implement default behavior for the * non-overloaded visitors */ - virtual void default_visit() = 0; + virtual void default_visit(INode &n) = 0; }; } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_INODEVISITOR_H */ +#endif // ACL_ARM_COMPUTE_GRAPH_INODEVISITOR_H diff --git a/arm_compute/graph/ITensorAccessor.h b/arm_compute/graph/ITensorAccessor.h index f7add3742a..a8818be2e5 100644 --- a/arm_compute/graph/ITensorAccessor.h +++ b/arm_compute/graph/ITensorAccessor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019,2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -45,6 +45,14 @@ public: * @return True if access is successful else false */ virtual bool access_tensor(ITensor &tensor) = 0; + /** Returns true if the tensor data is being accessed + * + * @return True if the tensor data is being accessed by the accessor. False otherwise + */ + virtual bool access_tensor_data() + { + return true; + } }; using ITensorAccessorUPtr = std::unique_ptr<ITensorAccessor>; diff --git a/arm_compute/graph/ITensorHandle.h b/arm_compute/graph/ITensorHandle.h index 1d78e78df5..0908d64818 100644 --- a/arm_compute/graph/ITensorHandle.h +++ b/arm_compute/graph/ITensorHandle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/LayerDescriptors.h b/arm_compute/graph/LayerDescriptors.h index d8e6a6a87b..d632ed9e78 100644 --- a/arm_compute/graph/LayerDescriptors.h +++ b/arm_compute/graph/LayerDescriptors.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020 ARM Limited. + * Copyright (c) 2019-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -37,8 +37,7 @@ namespace descriptors struct ConcatLayerDescriptor { /** Default constructor */ - ConcatLayerDescriptor() - : axis(DataLayoutDimension::CHANNEL), output_qinfo() + ConcatLayerDescriptor() : axis(DataLayoutDimension::CHANNEL), output_qinfo() { } @@ -46,8 +45,7 @@ struct ConcatLayerDescriptor * * @param[in] axis Axis. */ - ConcatLayerDescriptor(DataLayoutDimension axis) - : axis(axis), output_qinfo() + ConcatLayerDescriptor(DataLayoutDimension axis) : axis(axis), output_qinfo() { } @@ -76,9 +74,16 @@ struct EltwiseLayerDescriptor * @param[in] r_policy (Optional) Rounding policy used for the operation. Defaults to @ref RoundingPolicy::TO_ZERO * @param[in] fused_activation (Optional) Fused activation information. Defaults to empty (identity) @ref ActivationLayerInfo */ - EltwiseLayerDescriptor(EltwiseOperation op, QuantizationInfo out_quant_info = QuantizationInfo(), ConvertPolicy c_policy = ConvertPolicy::SATURATE, RoundingPolicy r_policy = RoundingPolicy::TO_ZERO, + EltwiseLayerDescriptor(EltwiseOperation op, + QuantizationInfo out_quant_info = QuantizationInfo(), + ConvertPolicy c_policy = ConvertPolicy::SATURATE, + RoundingPolicy r_policy = RoundingPolicy::TO_ZERO, ActivationLayerInfo fused_activation = ActivationLayerInfo()) - : op(op), out_quant_info(out_quant_info), c_policy(c_policy), r_policy(r_policy), fused_activation(fused_activation) + : op(op), + out_quant_info(out_quant_info), + c_policy(c_policy), + r_policy(r_policy), + fused_activation(fused_activation) { } @@ -89,6 +94,37 @@ struct EltwiseLayerDescriptor ActivationLayerInfo fused_activation; /**< Fused activation info */ }; +/** Unary Elementwise layer descriptor */ +struct UnaryEltwiseLayerDescriptor +{ + /** Constructor + * + * @param[in] op Unary element-wise operation to perform + * @param[in] out_quant_info (Optional) Output quantization information. Defaults to empty @ref QuantizationInfo + * @param[in] c_policy (Optional) Convert policy used for the operation. Defaults to @ref ConvertPolicy::SATURATE + * @param[in] r_policy (Optional) Rounding policy used for the operation. Defaults to @ref RoundingPolicy::TO_ZERO + * @param[in] fused_activation (Optional) Fused activation information. Defaults to empty (identity) @ref ActivationLayerInfo + */ + UnaryEltwiseLayerDescriptor(UnaryEltwiseOperation op, + QuantizationInfo out_quant_info = QuantizationInfo(), + ConvertPolicy c_policy = ConvertPolicy::SATURATE, + RoundingPolicy r_policy = RoundingPolicy::TO_ZERO, + ActivationLayerInfo fused_activation = ActivationLayerInfo()) + : op(op), + out_quant_info(out_quant_info), + c_policy(c_policy), + r_policy(r_policy), + fused_activation(fused_activation) + { + } + + UnaryEltwiseOperation op; /**< Unary element-wise operation to perform */ + QuantizationInfo out_quant_info; /**< Output quantization information */ + ConvertPolicy c_policy; /**< Convert policy */ + RoundingPolicy r_policy; /**< Rounding policy */ + ActivationLayerInfo fused_activation; /**< Fused activation info */ +}; + /** Deconvolution layer descriptor */ struct DeconvolutionLayerDescriptor { @@ -105,7 +141,7 @@ struct DeconvolutionLayerDescriptor PadStrideInfo info; /**< Padding and stride information */ QuantizationInfo out_quant_info; /**< Output quantization information */ }; -} // namespace descriptor +} // namespace descriptors } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_LAYER_DESCRIPTORS_H */
\ No newline at end of file +#endif /* ARM_COMPUTE_LAYER_DESCRIPTORS_H */ diff --git a/arm_compute/graph/Logger.h b/arm_compute/graph/Logger.h index 8aa87f0927..e83d5f4ddc 100644 --- a/arm_compute/graph/Logger.h +++ b/arm_compute/graph/Logger.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -31,14 +31,14 @@ * * @note It will eventually create all default loggers in don't exist */ -#define ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER() \ - do \ - { \ - if(arm_compute::logging::LoggerRegistry::get().logger("GRAPH") == nullptr) \ - { \ - arm_compute::logging::LoggerRegistry::get().create_reserved_loggers(); \ - } \ - } while(false) +#define ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER() \ + do \ + { \ + if (arm_compute::logging::LoggerRegistry::get().logger("GRAPH") == nullptr) \ + { \ + arm_compute::logging::LoggerRegistry::get().create_reserved_loggers(); \ + } \ + } while (false) #else /* ARM_COMPUTE_LOGGING_ENABLED */ #define ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER() #endif /* ARM_COMPUTE_LOGGING_ENABLED */ diff --git a/arm_compute/graph/PassManager.h b/arm_compute/graph/PassManager.h index c8920ba296..efdf6ab98f 100644 --- a/arm_compute/graph/PassManager.h +++ b/arm_compute/graph/PassManager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/Tensor.h b/arm_compute/graph/Tensor.h index 42d5d10735..0ffae28ecc 100644 --- a/arm_compute/graph/Tensor.h +++ b/arm_compute/graph/Tensor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -24,11 +24,10 @@ #ifndef ARM_COMPUTE_GRAPH_TENSOR_H #define ARM_COMPUTE_GRAPH_TENSOR_H -#include "arm_compute/graph/Types.h" - #include "arm_compute/graph/ITensorAccessor.h" #include "arm_compute/graph/ITensorHandle.h" #include "arm_compute/graph/TensorDescriptor.h" +#include "arm_compute/graph/Types.h" #include <memory> #include <set> diff --git a/arm_compute/graph/TensorDescriptor.h b/arm_compute/graph/TensorDescriptor.h index 0cd892b935..46a6ab2c27 100644 --- a/arm_compute/graph/TensorDescriptor.h +++ b/arm_compute/graph/TensorDescriptor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -26,8 +26,7 @@ #include "arm_compute/graph/Types.h" -#include "arm_compute/core/utils/misc/ICloneable.h" -#include "support/MemorySupport.h" +#include "support/ICloneable.h" #include <memory> @@ -53,7 +52,11 @@ struct TensorDescriptor final : public misc::ICloneable<TensorDescriptor> QuantizationInfo tensor_quant_info = QuantizationInfo(), DataLayout tensor_data_layout = DataLayout::NCHW, Target tensor_target = Target::UNSPECIFIED) - : shape(tensor_shape), data_type(tensor_data_type), layout(tensor_data_layout), quant_info(tensor_quant_info), target(tensor_target) + : shape(tensor_shape), + data_type(tensor_data_type), + layout(tensor_data_layout), + quant_info(tensor_quant_info), + target(tensor_target) { } /** Sets tensor descriptor shape @@ -104,14 +107,14 @@ struct TensorDescriptor final : public misc::ICloneable<TensorDescriptor> // Inherited methods overridden: std::unique_ptr<TensorDescriptor> clone() const override { - return support::cpp14::make_unique<TensorDescriptor>(*this); + return std::make_unique<TensorDescriptor>(*this); } - TensorShape shape{}; /**< Tensor shape */ - DataType data_type{ DataType::UNKNOWN }; /**< Data type */ - DataLayout layout{ DataLayout::NCHW }; /**< Data layout */ - QuantizationInfo quant_info{}; /**< Quantization info */ - Target target{ Target::UNSPECIFIED }; /**< Target */ + TensorShape shape{}; /**< Tensor shape */ + DataType data_type{DataType::UNKNOWN}; /**< Data type */ + DataLayout layout{DataLayout::NCHW}; /**< Data layout */ + QuantizationInfo quant_info{}; /**< Quantization info */ + Target target{Target::UNSPECIFIED}; /**< Target */ }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/TypeLoader.h b/arm_compute/graph/TypeLoader.h index e1b920c24d..286bfebeb5 100644 --- a/arm_compute/graph/TypeLoader.h +++ b/arm_compute/graph/TypeLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -30,29 +30,6 @@ namespace arm_compute { -/** Converts a string to a strong types enumeration @ref DataType - * - * @param[in] name String to convert - * - * @return Converted DataType enumeration - */ -arm_compute::DataType data_type_from_name(const std::string &name); - -/** Input Stream operator for @ref DataType - * - * @param[in] stream Stream to parse - * @param[out] data_type Output data type - * - * @return Updated stream - */ -inline ::std::istream &operator>>(::std::istream &stream, arm_compute::DataType &data_type) -{ - std::string value; - stream >> value; - data_type = data_type_from_name(value); - return stream; -} - /** Converts a string to a strong types enumeration @ref DataLayout * * @param[in] name String to convert diff --git a/arm_compute/graph/TypePrinter.h b/arm_compute/graph/TypePrinter.h index d56407b52b..5e83820ab3 100644 --- a/arm_compute/graph/TypePrinter.h +++ b/arm_compute/graph/TypePrinter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2021, 2023 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -21,8 +21,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_TYPE_PRINTER_H -#define ARM_COMPUTE_GRAPH_TYPE_PRINTER_H +#ifndef ACL_ARM_COMPUTE_GRAPH_TYPEPRINTER_H +#define ACL_ARM_COMPUTE_GRAPH_TYPEPRINTER_H #include "arm_compute/core/Error.h" #include "arm_compute/core/Types.h" @@ -37,19 +37,19 @@ namespace graph /** Formatted output of the Target. */ inline ::std::ostream &operator<<(::std::ostream &os, const Target &target) { - switch(target) + switch (target) { case Target::UNSPECIFIED: os << "UNSPECIFIED"; break; case Target::NEON: - os << "NEON"; + os << "Neon"; break; case Target::CL: os << "CL"; break; - case Target::GC: - os << "GC"; + case Target::CLVK: + os << "CLVK"; break; default: ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); @@ -60,11 +60,14 @@ inline ::std::ostream &operator<<(::std::ostream &os, const Target &target) inline ::std::ostream &operator<<(::std::ostream &os, const NodeType &node_type) { - switch(node_type) + switch (node_type) { case NodeType::ActivationLayer: os << "ActivationLayer"; break; + case NodeType::ArgMinMaxLayer: + os << "ArgMinMaxLayer"; + break; case NodeType::BatchNormalizationLayer: os << "BatchNormalizationLayer"; break; @@ -83,6 +86,9 @@ inline ::std::ostream &operator<<(::std::ostream &os, const NodeType &node_type) case NodeType::DeconvolutionLayer: os << "DeconvolutionLayer"; break; + case NodeType::DepthToSpaceLayer: + os << "DepthToSpaceLayer"; + break; case NodeType::DequantizationLayer: os << "DequantizationLayer"; break; @@ -98,6 +104,9 @@ inline ::std::ostream &operator<<(::std::ostream &os, const NodeType &node_type) case NodeType::EltwiseLayer: os << "EltwiseLayer"; break; + case NodeType::UnaryEltwiseLayer: + os << "UnaryEltwiseLayer"; + break; case NodeType::FlattenLayer: os << "FlattenLayer"; break; @@ -113,6 +122,9 @@ inline ::std::ostream &operator<<(::std::ostream &os, const NodeType &node_type) case NodeType::GenerateProposalsLayer: os << "GenerateProposalsLayer"; break; + case NodeType::L2NormalizeLayer: + os << "L2NormalizeLayer"; + break; case NodeType::NormalizationLayer: os << "NormalizationLayer"; break; @@ -140,6 +152,9 @@ inline ::std::ostream &operator<<(::std::ostream &os, const NodeType &node_type) case NodeType::QuantizationLayer: os << "QuantizationLayer"; break; + case NodeType::ReductionOperationLayer: + os << "ReductionOperationLayer"; + break; case NodeType::ReorgLayer: os << "ReorgLayer"; break; @@ -164,12 +179,12 @@ inline ::std::ostream &operator<<(::std::ostream &os, const NodeType &node_type) case NodeType::StackLayer: os << "StackLayer"; break; + case NodeType::StridedSliceLayer: + os << "StridedSliceLayer"; + break; case NodeType::UpsampleLayer: os << "UpsampleLayer"; break; - case NodeType::YOLOLayer: - os << "YOLOLayer"; - break; case NodeType::Input: os << "Input"; break; @@ -192,7 +207,7 @@ inline ::std::ostream &operator<<(::std::ostream &os, const NodeType &node_type) /** Formatted output of the EltwiseOperation type. */ inline ::std::ostream &operator<<(::std::ostream &os, const EltwiseOperation &eltwise_op) { - switch(eltwise_op) + switch (eltwise_op) { case EltwiseOperation::Add: os << "Add"; @@ -203,6 +218,9 @@ inline ::std::ostream &operator<<(::std::ostream &os, const EltwiseOperation &el case EltwiseOperation::Sub: os << "Sub"; break; + case EltwiseOperation::Div: + os << "Div"; + break; default: ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); } @@ -213,7 +231,7 @@ inline ::std::ostream &operator<<(::std::ostream &os, const EltwiseOperation &el /** Formatted output of the ConvolutionMethod type. */ inline ::std::ostream &operator<<(::std::ostream &os, const ConvolutionMethod &method) { - switch(method) + switch (method) { case ConvolutionMethod::Default: os << "Default"; @@ -237,7 +255,7 @@ inline ::std::ostream &operator<<(::std::ostream &os, const ConvolutionMethod &m /** Formatted output of the FastMathHint type. */ inline ::std::ostream &operator<<(::std::ostream &os, const FastMathHint &hint) { - switch(hint) + switch (hint) { case FastMathHint::Enabled: os << "Enabled"; @@ -255,7 +273,7 @@ inline ::std::ostream &operator<<(::std::ostream &os, const FastMathHint &hint) /** Formatted output of the DepthwiseConvolutionMethod type. */ inline ::std::ostream &operator<<(::std::ostream &os, const DepthwiseConvolutionMethod &method) { - switch(method) + switch (method) { case DepthwiseConvolutionMethod::Default: os << "DEFAULT"; @@ -271,4 +289,4 @@ inline ::std::ostream &operator<<(::std::ostream &os, const DepthwiseConvolution } } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_TYPE_PRINTER_H */ +#endif // ACL_ARM_COMPUTE_GRAPH_TYPEPRINTER_H diff --git a/arm_compute/graph/Types.h b/arm_compute/graph/Types.h index 296f757c9b..5541e3cbcc 100644 --- a/arm_compute/graph/Types.h +++ b/arm_compute/graph/Types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2021, 2023 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -21,13 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_TYPES_H -#define ARM_COMPUTE_GRAPH_TYPES_H +#ifndef ACL_ARM_COMPUTE_GRAPH_TYPES_H +#define ACL_ARM_COMPUTE_GRAPH_TYPES_H #include "arm_compute/core/Error.h" #include "arm_compute/core/PixelValue.h" #include "arm_compute/core/Types.h" +#include "arm_compute/function_info/ActivationLayerInfo.h" +#include "arm_compute/function_info/ConvolutionInfo.h" +#include "arm_compute/function_info/FullyConnectedLayerInfo.h" +#include "arm_compute/function_info/GEMMInfo.h" #include "arm_compute/runtime/CL/CLTunerTypes.h" +#include "arm_compute/runtime/CL/CLTypes.h" #include <limits> #include <string> @@ -36,30 +41,31 @@ namespace arm_compute { namespace graph { +using arm_compute::CLBackendType; using arm_compute::CLTunerMode; using arm_compute::Status; using arm_compute::Coordinates; -using arm_compute::DataType; using arm_compute::DataLayout; using arm_compute::DataLayoutDimension; -using arm_compute::TensorShape; -using arm_compute::Size2D; +using arm_compute::DataType; using arm_compute::PermutationVector; using arm_compute::PixelValue; +using arm_compute::Size2D; +using arm_compute::TensorShape; using arm_compute::ActivationLayerInfo; using arm_compute::DetectionOutputLayerInfo; using arm_compute::DetectionPostProcessLayerInfo; -using arm_compute::NormType; -using arm_compute::NormalizationLayerInfo; +using arm_compute::DimensionRoundingType; using arm_compute::FullyConnectedLayerInfo; +using arm_compute::InterpolationPolicy; +using arm_compute::NormalizationLayerInfo; +using arm_compute::NormType; using arm_compute::PadStrideInfo; using arm_compute::PoolingLayerInfo; using arm_compute::PoolingType; using arm_compute::PriorBoxLayerInfo; -using arm_compute::DimensionRoundingType; -using arm_compute::InterpolationPolicy; using GraphID = unsigned int; using TensorID = unsigned int; @@ -76,26 +82,31 @@ constexpr EdgeID EmptyEdgeID = std::numeric_limits<EdgeID>::max(); // Forward declarations struct TensorDescriptor; + /** Graph configuration structure */ struct GraphConfig { - bool use_function_memory_manager{ true }; /**< Use a memory manager to manage per-funcion auxilary memory */ - bool use_function_weights_manager{ true }; /**< Use a weights manager to manage transformed weights */ - bool use_transition_memory_manager{ true }; /**< Use a memory manager to manager transition buffer memory */ - bool use_tuner{ false }; /**< Use a tuner in tunable backends */ - bool convert_to_uint8{ false }; /**< Convert graph to a synthetic uint8 graph */ - CLTunerMode tuner_mode{ CLTunerMode::EXHAUSTIVE }; /**< Tuner mode to be used by the CL tuner */ - int num_threads{ -1 }; /**< Number of threads to use (thread capable backends), if 0 the backend will auto-initialize, if -1 the backend will stay as it is. */ - std::string tuner_file{ "acl_tuner.csv" }; /**< File to load/store tuning values from */ + bool use_function_memory_manager{true}; /**< Use a memory manager to manage per-function auxilary memory */ + bool use_function_weights_manager{true}; /**< Use a weights manager to manage transformed weights */ + bool use_transition_memory_manager{true}; /**< Use a memory manager to manager transition buffer memory */ + bool use_tuner{false}; /**< Use a tuner in tunable backends */ + bool use_synthetic_type{false}; /**< Convert graph to a synthetic graph for a data type */ + DataType synthetic_type{DataType::QASYMM8}; /**< The data type of the synthetic graph */ + CLTunerMode tuner_mode{CLTunerMode::EXHAUSTIVE}; /**< Tuner mode to be used by the CL tuner */ + int num_threads{ + -1}; /**< Number of threads to use (thread capable backends), if 0 the backend will auto-initialize, if -1 the backend will stay as it is. */ + std::string tuner_file{"acl_tuner.csv"}; /**< File to load/store tuning values from */ + std::string mlgo_file{"heuristics.mlgo"}; /**< Filename to load MLGO heuristics from */ + CLBackendType backend_type{CLBackendType::Native}; /**< CL backend type to use */ }; /**< Device target types */ enum class Target { UNSPECIFIED, /**< Unspecified Target */ - NEON, /**< NEON capable target device */ + NEON, /**< Arm® Neon™ capable target device */ CL, /**< OpenCL capable target device */ - GC, /**< GLES compute capable target device */ + CLVK, /**< CLVK capable target device */ }; /** Supported Element-wise operations */ @@ -103,7 +114,16 @@ enum class EltwiseOperation { Add, /**< Arithmetic addition */ Sub, /**< Arithmetic subtraction */ - Mul /**< Arithmetic multiplication */ + Mul, /**< Arithmetic multiplication */ + Max, /**< Arithmetic maximum */ + Div, /**< Arithmetic division */ + Min, /**< Arithmetic minimum */ +}; + +/** Supported Unary Element-wise operations */ +enum class UnaryEltwiseOperation +{ + Exp /**< Exp */ }; /** Supported Convolution layer methods */ @@ -134,12 +154,14 @@ enum class FastMathHint enum class NodeType { ActivationLayer, + ArgMinMaxLayer, BatchNormalizationLayer, BoundingBoxTransformLayer, ChannelShuffleLayer, ConcatenateLayer, ConvolutionLayer, DeconvolutionLayer, + DepthToSpaceLayer, DepthwiseConvolutionLayer, DequantizationLayer, DetectionOutputLayer, @@ -150,6 +172,7 @@ enum class NodeType FusedConvolutionBatchNormalizationLayer, FusedDepthwiseConvolutionBatchNormalizationLayer, GenerateProposalsLayer, + L2NormalizeLayer, NormalizationLayer, NormalizePlanarYUVLayer, PadLayer, @@ -159,6 +182,7 @@ enum class NodeType PrintLayer, PriorBoxLayer, QuantizationLayer, + ReductionOperationLayer, ReorgLayer, ReshapeLayer, ResizeLayer, @@ -167,8 +191,9 @@ enum class NodeType SliceLayer, SplitLayer, StackLayer, + StridedSliceLayer, UpsampleLayer, - YOLOLayer, + UnaryEltwiseLayer, Input, Output, @@ -202,4 +227,4 @@ struct NodeParams }; } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_TYPES_H */ +#endif // ACL_ARM_COMPUTE_GRAPH_TYPES_H diff --git a/arm_compute/graph/Utils.h b/arm_compute/graph/Utils.h index cb421fc55a..9813ff05c7 100644 --- a/arm_compute/graph/Utils.h +++ b/arm_compute/graph/Utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -36,7 +36,7 @@ class GraphContext; inline bool is_utility_node(INode *node) { - std::set<NodeType> utility_node_types = { NodeType::PrintLayer }; + std::set<NodeType> utility_node_types = {NodeType::PrintLayer}; return utility_node_types.find(node->type()) != utility_node_types.end(); } @@ -76,7 +76,7 @@ bool is_target_supported(Target target); /** Returns default target for execution * * @note If an OpenCL backend exists then OpenCL is returned, - * else if the NEON backend exists returns NEON as target. + * else if the CPU backend exists returns @ref Target::NEON as target. * If no backends are registered an error is raised. * * @return Default target @@ -107,6 +107,8 @@ void setup_requested_backend_context(GraphContext &ctx, Target target); * @param[in,out] ctx Graph Context */ void release_default_graph_context(GraphContext &ctx); +/** Synchronize kernels execution on the backends. On GPU, this results in a blocking call waiting for all kernels to be completed. */ +void sync_backends(); /** Get size of a tensor's given dimension depending on its layout * * @param[in] descriptor Descriptor @@ -130,6 +132,13 @@ size_t get_dimension_idx(DataLayout data_layout, const DataLayoutDimension data_ * @return A list with the driving node of a given node */ std::vector<NodeIdxPair> get_driving_nodes(const INode &node); +/** Get the list of driver nodes of a given node + * + * @param[in] node Node to find the driver node of + * + * @return A list with the driver node of a given node + */ +std::vector<NodeIdxPair> get_driver_nodes(const INode &node); /** Configures tensor * * @param[in, out] tensor Tensor to configure diff --git a/arm_compute/graph/Workload.h b/arm_compute/graph/Workload.h index a36c28a181..8ff0a548ae 100644 --- a/arm_compute/graph/Workload.h +++ b/arm_compute/graph/Workload.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -69,8 +69,7 @@ public: */ struct ExecutionTask { - ExecutionTask(std::unique_ptr<arm_compute::IFunction> &&f, INode *n) - : task(std::move(f)), node(n) + ExecutionTask(std::unique_ptr<arm_compute::IFunction> &&f, INode *n) : task(std::move(f)), node(n) { } /** Prevent instances of this class from being copied (As this class contains pointers) */ @@ -97,11 +96,11 @@ struct ExecutionTask /** Execution workload */ struct ExecutionWorkload { - std::vector<Tensor *> inputs = {}; /**< Input handles */ - std::vector<Tensor *> outputs = {}; /**< Output handles */ - std::vector<ExecutionTask> tasks = {}; /**< Execution workload */ - Graph *graph = { nullptr }; /**< Graph bound to the workload */ - GraphContext *ctx = { nullptr }; /**< Graph execution context */ + std::vector<Tensor *> inputs = {}; /**< Input handles */ + std::vector<Tensor *> outputs = {}; /**< Output handles */ + std::vector<ExecutionTask> tasks = {}; /**< Execution workload */ + Graph *graph = {nullptr}; /**< Graph bound to the workload */ + GraphContext *ctx = {nullptr}; /**< Graph execution context */ }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/algorithms/Algorithms.h b/arm_compute/graph/algorithms/Algorithms.h index 89441c854f..2088d38fd7 100644 --- a/arm_compute/graph/algorithms/Algorithms.h +++ b/arm_compute/graph/algorithms/Algorithms.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/algorithms/TopologicalSort.h b/arm_compute/graph/algorithms/TopologicalSort.h index 486c0b5aca..25476e28f3 100644 --- a/arm_compute/graph/algorithms/TopologicalSort.h +++ b/arm_compute/graph/algorithms/TopologicalSort.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/backends/BackendRegistrar.h b/arm_compute/graph/backends/BackendRegistrar.h index 5d1582dc9d..2879361fef 100644 --- a/arm_compute/graph/backends/BackendRegistrar.h +++ b/arm_compute/graph/backends/BackendRegistrar.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -24,8 +24,8 @@ #ifndef ARM_COMPUTE_GRAPH_BACKEND_REGISTRAR_H #define ARM_COMPUTE_GRAPH_BACKEND_REGISTRAR_H -#include "arm_compute/graph/Types.h" #include "arm_compute/graph/backends/BackendRegistry.h" +#include "arm_compute/graph/Types.h" #include <utility> @@ -58,4 +58,4 @@ inline BackendRegistrar<T>::BackendRegistrar(Target target) } // namespace backends } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_BACKEND_REGISTRAR_H */
\ No newline at end of file +#endif /* ARM_COMPUTE_GRAPH_BACKEND_REGISTRAR_H */ diff --git a/arm_compute/graph/backends/BackendRegistry.h b/arm_compute/graph/backends/BackendRegistry.h index c9e84bdcca..7c11d35faf 100644 --- a/arm_compute/graph/backends/BackendRegistry.h +++ b/arm_compute/graph/backends/BackendRegistry.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -26,7 +26,6 @@ #include "arm_compute/graph/IDeviceBackend.h" #include "arm_compute/graph/Types.h" -#include "support/MemorySupport.h" #include <map> #include <memory> @@ -93,7 +92,7 @@ private: template <typename T> inline void BackendRegistry::add_backend(Target target) { - _registered_backends[target] = support::cpp14::make_unique<T>(); + _registered_backends[target] = std::make_unique<T>(); } } // namespace backends } // namespace graph diff --git a/arm_compute/graph/backends/CL/CLDeviceBackend.h b/arm_compute/graph/backends/CL/CLDeviceBackend.h index 492dca0682..09e19d7688 100644 --- a/arm_compute/graph/backends/CL/CLDeviceBackend.h +++ b/arm_compute/graph/backends/CL/CLDeviceBackend.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -25,9 +25,10 @@ #define ARM_COMPUTE_GRAPH_CLDEVICEBACKEND_H #include "arm_compute/graph/IDeviceBackend.h" - #include "arm_compute/runtime/CL/CLBufferAllocator.h" +#include "arm_compute/runtime/CL/CLGEMMHeuristicsHandle.h" #include "arm_compute/runtime/CL/CLTuner.h" +#include "arm_compute/runtime/CL/CLTypes.h" namespace arm_compute { @@ -57,23 +58,27 @@ public: void set_kernel_tuning_mode(CLTunerMode tuning_mode); // Inherited overridden methods - void initialize_backend() override; - void setup_backend_context(GraphContext &ctx) override; - void release_backend_context(GraphContext &ctx) override; + void initialize_backend() override; + void setup_backend_context(GraphContext &ctx) override; + void release_backend_context(GraphContext &ctx) override; bool is_backend_supported() override; IAllocator *backend_allocator() override; std::unique_ptr<ITensorHandle> create_tensor(const Tensor &tensor) override; - std::unique_ptr<ITensorHandle> create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; - std::unique_ptr<arm_compute::IFunction> configure_node(INode &node, GraphContext &ctx) override; - Status validate_node(INode &node) override; - std::shared_ptr<arm_compute::IMemoryManager> create_memory_manager(MemoryManagerAffinity affinity) override; + std::unique_ptr<ITensorHandle> + create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; + std::unique_ptr<arm_compute::IFunction> configure_node(INode &node, GraphContext &ctx) override; + Status validate_node(INode &node) override; + std::shared_ptr<arm_compute::IMemoryManager> create_memory_manager(MemoryManagerAffinity affinity) override; std::shared_ptr<arm_compute::IWeightsManager> create_weights_manager() override; + void sync() override; private: int _context_count; /**< Counts how many contexts are currently using the backend */ CLTuner _tuner; /**< CL kernel tuner */ - std::unique_ptr<CLBufferAllocator> _allocator; /**< CL buffer affinity allocator */ - std::string _tuner_file; /**< Filename to load/store the tuner's values from */ + CLGEMMHeuristicsHandle _gemm_heuristics; /**< GEMM heuristics */ + std::unique_ptr<CLBufferAllocator> _allocator; /**< CL buffer affinity allocator */ + std::string _tuner_file; /**< Filename to load/store the tuner's values from */ + CLBackendType _backend_type; /**< OpenCL backend type to use */ }; } // namespace backends } // namespace graph diff --git a/arm_compute/graph/backends/CL/CLFunctionFactory.h b/arm_compute/graph/backends/CL/CLFunctionFactory.h index 264612c8b7..e832f4547f 100644 --- a/arm_compute/graph/backends/CL/CLFunctionFactory.h +++ b/arm_compute/graph/backends/CL/CLFunctionFactory.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/backends/CL/CLNodeValidator.h b/arm_compute/graph/backends/CL/CLNodeValidator.h index 2f43cd4696..6e102a3b21 100644 --- a/arm_compute/graph/backends/CL/CLNodeValidator.h +++ b/arm_compute/graph/backends/CL/CLNodeValidator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/backends/CL/CLSubTensorHandle.h b/arm_compute/graph/backends/CL/CLSubTensorHandle.h index 3379febd9c..85eebec639 100644 --- a/arm_compute/graph/backends/CL/CLSubTensorHandle.h +++ b/arm_compute/graph/backends/CL/CLSubTensorHandle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -25,7 +25,6 @@ #define ARM_COMPUTE_GRAPH_CLSUBTENSORHANDLE_H #include "arm_compute/graph/ITensorHandle.h" - #include "arm_compute/runtime/CL/CLSubTensor.h" namespace arm_compute @@ -45,7 +44,10 @@ public: * @param[in] coords Starting coordinates * @param[in] extend_parent Extends parent shape if true */ - CLSubTensorHandle(ITensorHandle *parent_handle, const TensorShape &shape, const Coordinates &coords, bool extend_parent = false); + CLSubTensorHandle(ITensorHandle *parent_handle, + const TensorShape &shape, + const Coordinates &coords, + bool extend_parent = false); /** Destructor: free the tensor's memory */ ~CLSubTensorHandle() = default; /** Allow instances of this class to be move constructed */ @@ -58,10 +60,10 @@ public: CLSubTensorHandle &operator=(const CLSubTensorHandle &) = delete; // Inherited overridden methods - void allocate() override; - void free() override; - void manage(IMemoryGroup *mg) override; - void map(bool blocking) override; + void allocate() override; + void free() override; + void manage(IMemoryGroup *mg) override; + void map(bool blocking) override; void unmap() override; void release_if_unused() override; arm_compute::ITensor &tensor() override; diff --git a/arm_compute/graph/backends/CL/CLTensorHandle.h b/arm_compute/graph/backends/CL/CLTensorHandle.h index 1452ef822c..57e9794ec3 100644 --- a/arm_compute/graph/backends/CL/CLTensorHandle.h +++ b/arm_compute/graph/backends/CL/CLTensorHandle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -25,7 +25,6 @@ #define ARM_COMPUTE_GRAPH_CLTENSORHANDLE_H #include "arm_compute/graph/ITensorHandle.h" - #include "arm_compute/runtime/CL/CLTensor.h" namespace arm_compute @@ -51,10 +50,10 @@ public: CLTensorHandle &operator=(CLTensorHandle &&) = default; // Inherited overridden methods - void allocate() override; - void free() override; - void manage(IMemoryGroup *mg) override; - void map(bool blocking) override; + void allocate() override; + void free() override; + void manage(IMemoryGroup *mg) override; + void map(bool blocking) override; void unmap() override; void release_if_unused() override; arm_compute::ITensor &tensor() override; diff --git a/arm_compute/graph/backends/FunctionHelpers.h b/arm_compute/graph/backends/FunctionHelpers.h index 382b18a888..fd8b6b5a69 100644 --- a/arm_compute/graph/backends/FunctionHelpers.h +++ b/arm_compute/graph/backends/FunctionHelpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2021, 2023 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -21,23 +21,23 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_BACKENDS_DETAIL_FUNCTION_HELPERS_H -#define ARM_COMPUTE_GRAPH_BACKENDS_DETAIL_FUNCTION_HELPERS_H +#ifndef ACL_ARM_COMPUTE_GRAPH_BACKENDS_FUNCTIONHELPERS_H +#define ACL_ARM_COMPUTE_GRAPH_BACKENDS_FUNCTIONHELPERS_H +#include "arm_compute/core/Error.h" +#include "arm_compute/core/Helpers.h" +#include "arm_compute/core/ITensorInfo.h" +#include "arm_compute/graph/backends/FusedConvolutionBatchNormalizationFunction.h" +#include "arm_compute/graph/backends/FusedDepthwiseConvolutionBatchNormalizationFunction.h" +#include "arm_compute/graph/backends/Utils.h" #include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/nodes/Nodes.h" #include "arm_compute/graph/Tensor.h" #include "arm_compute/graph/TypePrinter.h" #include "arm_compute/graph/Types.h" #include "arm_compute/graph/Utils.h" -#include "arm_compute/graph/backends/FusedConvolutionBatchNormalizationFunction.h" -#include "arm_compute/graph/backends/FusedDepthwiseConvolutionBatchNormalizationFunction.h" -#include "arm_compute/graph/backends/Utils.h" -#include "arm_compute/graph/nodes/Nodes.h" -#include "arm_compute/core/Error.h" -#include "arm_compute/core/Helpers.h" -#include "arm_compute/core/ITensorInfo.h" -#include "arm_compute/core/utils/misc/Cast.h" +#include "support/Cast.h" namespace arm_compute { @@ -47,13 +47,6 @@ namespace backends { namespace detail { -// Address rule DR-9R5 (1579. Return by converting move constructor) -#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5)) -#define RETURN_UNIQUE_PTR(x) (x) -#else /* defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5)) */ -#define RETURN_UNIQUE_PTR(x) (std::move(x)) -#endif /* defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5)) */ - /** Returns backing tensor of a given tensor * * @tparam TargetInfo Target information @@ -66,13 +59,16 @@ template <typename TargetInfo> typename TargetInfo::TensorType *get_backing_tensor(arm_compute::graph::Tensor *tensor) { typename TargetInfo::TensorType *backing_tensor = nullptr; - if(tensor != nullptr) + if (tensor != nullptr) { ARM_COMPUTE_ERROR_ON(tensor->desc().target != TargetInfo::TargetType); // Get backing tensor handle ITensorHandle *tensor_handle = tensor->handle(); // Get backing tensor - backing_tensor = (tensor_handle != nullptr) ? arm_compute::utils::cast::polymorphic_cast<typename TargetInfo::TensorType *>(&tensor_handle->tensor()) : nullptr; + backing_tensor = (tensor_handle != nullptr) + ? arm_compute::utils::cast::polymorphic_cast<typename TargetInfo::TensorType *>( + &tensor_handle->tensor()) + : nullptr; } return backing_tensor; @@ -81,11 +77,8 @@ typename TargetInfo::TensorType *get_backing_tensor(arm_compute::graph::Tensor * template <typename TargetInfo> void validate_node(const INode &node, size_t num_expected_inputs, size_t num_expected_outputs) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating " << node.type() - << " Target: " << TargetInfo::TargetType - << " ID: " << node.id() - << node.name() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating " << node.type() << " Target: " << TargetInfo::TargetType + << " ID: " << node.id() << node.name() << std::endl); ARM_COMPUTE_ERROR_ON(TargetInfo::TargetType != node.assigned_target()); ARM_COMPUTE_ERROR_ON(node.num_inputs() != num_expected_inputs); @@ -113,22 +106,48 @@ std::unique_ptr<IFunction> create_activation_layer(ActivationLayerNode &node) const ActivationLayerInfo act_info = node.activation_info(); // Create function - auto func = support::cpp14::make_unique<ActivationLayerFunction>(); + auto func = std::make_unique<ActivationLayerFunction>(); func->configure(input, output, act_info); - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Shape: " << input->info()->tensor_shape() - << " Activation function: " << act_info.activation() - << " a: " << act_info.a() - << " b: " << act_info.b() - << " InPlace : " << is_in_place_operation(input, output) - << std::endl); - - return RETURN_UNIQUE_PTR(func); + ARM_COMPUTE_LOG_GRAPH_INFO( + "Instantiated " << node.name() << " Type: " << node.type() << " Target: " << TargetInfo::TargetType + << " Data Type: " << input->info()->data_type() << " Shape: " << input->info()->tensor_shape() + << " Activation function: " << act_info.activation() << " a: " << act_info.a() << " b: " + << act_info.b() << " InPlace : " << is_in_place_operation(input, output) << std::endl); + + return func; +} + +/** Creates a backend argminmax layer function + * + * @tparam ArgMinMaxLayerFunction Backend activation function + * @tparam TargetInfo Target-specific information + * + * @param[in] node Node to create the backend function for + * + * @return Backend argminmax layer function + */ +template <typename ArgMinMaxLayerFunction, typename TargetInfo> +std::unique_ptr<IFunction> create_arg_min_max_layer(ArgMinMaxLayerNode &node) +{ + validate_node<TargetInfo>(node, 1 /* expected inputs */, 1 /* expected outputs */); + + // Extract IO and info + typename TargetInfo::TensorType *input = get_backing_tensor<TargetInfo>(node.input(0)); + typename TargetInfo::TensorType *output = get_backing_tensor<TargetInfo>(node.output(0)); + const ReductionOperation op = node.reduction_operation(); + unsigned int axis = node.axis(); + + // Create function + auto func = std::make_unique<ArgMinMaxLayerFunction>(); + func->configure(input, axis, output, op); + + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Shape: " << input->info()->tensor_shape() + << " Reduction Operation: " << op << " axis: " << axis << std::endl); + + return func; } /** Create a backend batch normalization layer function @@ -157,22 +176,17 @@ std::unique_ptr<IFunction> create_batch_normalization_layer(BatchNormalizationLa const ActivationLayerInfo fused_act = node.fused_activation(); // Create and configure function - auto func = support::cpp14::make_unique<BatchNormalizationLayerFunction>(); + auto func = std::make_unique<BatchNormalizationLayerFunction>(); func->configure(input, output, mean, var, beta, gamma, epsilon, fused_act); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Shape: " << input->info()->tensor_shape() - << " Epsilon: " << epsilon << " " - << (fused_act.enabled() ? to_string(fused_act.activation()) : "") - << " InPlace: " << is_in_place_operation(input, output) - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Shape: " << input->info()->tensor_shape() << " Epsilon: " << epsilon + << " " << (fused_act.enabled() ? to_string(fused_act.activation()) : "") + << " InPlace: " << is_in_place_operation(input, output) << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend batch normalization layer function @@ -186,7 +200,8 @@ std::unique_ptr<IFunction> create_batch_normalization_layer(BatchNormalizationLa * @return Backend batch normalization layer function */ template <typename FusedLayerTypes, typename TargetInfo> -std::unique_ptr<IFunction> create_fused_convolution_batch_normalization_layer(FusedConvolutionBatchNormalizationNode &node, GraphContext &ctx) +std::unique_ptr<IFunction> +create_fused_convolution_batch_normalization_layer(FusedConvolutionBatchNormalizationNode &node, GraphContext &ctx) { validate_node<TargetInfo>(node, 7 /* expected inputs */, 1 /* expected outputs */); @@ -216,20 +231,17 @@ std::unique_ptr<IFunction> create_fused_convolution_batch_normalization_layer(Fu // Create and configure function std::tie(func, func_name) = create_named_memory_managed_function<FType>( - std::string("FusedConvolutionBatchNormalizationLayer"), mm, input, weights, biases, output, mean, var, beta, gamma, epsilon, conv_info, num_groups, fast_math, fused_act); + std::string("FusedConvolutionBatchNormalizationLayer"), mm, input, weights, biases, output, mean, var, beta, + gamma, epsilon, conv_info, num_groups, fast_math, fused_act); // Log info ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() + << node.name() << " Type: " << node.type() << " Target: " << TargetInfo::TargetType + << " Data Type: " << input->info()->data_type() << " Input shape: " + << input->info()->tensor_shape() << " Weights shape: " << weights->info()->tensor_shape() << " Output shape: " << output->info()->tensor_shape() - << (fused_act.enabled() ? " " + to_string(fused_act.activation()) : "") - << std::endl); - return RETURN_UNIQUE_PTR(func); + << (fused_act.enabled() ? " " + to_string(fused_act.activation()) : "") << std::endl); + return func; } /** Create a backend fused depthwise convolution batch normalization layer function @@ -243,7 +255,9 @@ std::unique_ptr<IFunction> create_fused_convolution_batch_normalization_layer(Fu * @return Backend fused depthwise convolution batch normalization layer function */ template <typename FusedLayerTypes, typename TargetInfo> -std::unique_ptr<IFunction> create_fused_depthwise_convolution_batch_normalization_layer(FusedDepthwiseConvolutionBatchNormalizationNode &node, GraphContext &ctx) +std::unique_ptr<IFunction> +create_fused_depthwise_convolution_batch_normalization_layer(FusedDepthwiseConvolutionBatchNormalizationNode &node, + GraphContext &ctx) { validate_node<TargetInfo>(node, 7 /* expected inputs */, 1 /* expected outputs */); @@ -272,20 +286,17 @@ std::unique_ptr<IFunction> create_fused_depthwise_convolution_batch_normalizatio // Create and configure function std::tie(func, func_name) = create_named_memory_managed_function<FType>( - std::string("FusedDepthwiseConvolutionBatchNormalizationLayer"), mm, input, weights, biases, output, mean, var, beta, gamma, epsilon, conv_info, depth_multiplier, fused_act); + std::string("FusedDepthwiseConvolutionBatchNormalizationLayer"), mm, input, weights, biases, output, mean, var, + beta, gamma, epsilon, conv_info, depth_multiplier, fused_act); // Log info ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() + << node.name() << " Type: " << node.type() << " Target: " << TargetInfo::TargetType + << " Data Type: " << input->info()->data_type() << " Input shape: " + << input->info()->tensor_shape() << " Weights shape: " << weights->info()->tensor_shape() << " Output shape: " << output->info()->tensor_shape() - << (fused_act.enabled() ? " " + to_string(fused_act.activation()) : "") - << std::endl); - return RETURN_UNIQUE_PTR(func); + << (fused_act.enabled() ? " " + to_string(fused_act.activation()) : "") << std::endl); + return func; } /** Create a backend bounding box transform layer function @@ -309,21 +320,17 @@ std::unique_ptr<IFunction> create_bounding_box_transform_layer(BoundingBoxTransf const BoundingBoxTransformInfo bbox_info = node.info(); // Create and configure function - auto func = support::cpp14::make_unique<BoundingBoxTransformLayerFunction>(); + auto func = std::make_unique<BoundingBoxTransformLayerFunction>(); func->configure(input, output, deltas, bbox_info); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Shape: " << input->info()->tensor_shape() - << " BoundingBox Info img W: " << bbox_info.img_width() << " " - << " BoundingBox Info img H: " << bbox_info.img_height() << " " - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO( + "Instantiated " << node.name() << " Type: " << node.type() << " Target: " << TargetInfo::TargetType + << " Data Type: " << input->info()->data_type() << " Shape: " << input->info()->tensor_shape() + << " BoundingBox Info img W: " << bbox_info.img_width() << " " + << " BoundingBox Info img H: " << bbox_info.img_height() << " " << std::endl); - return RETURN_UNIQUE_PTR(func); + return std::move(func); } /** Create a backend channel shuffle layer function @@ -346,19 +353,15 @@ std::unique_ptr<IFunction> create_channel_shuffle_layer(ChannelShuffleLayerNode const unsigned int num_groups = node.num_groups(); // Create function - auto func = support::cpp14::make_unique<ChannelShuffleLayerFunction>(); + auto func = std::make_unique<ChannelShuffleLayerFunction>(); func->configure(input, output, num_groups); - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Shape: " << input->info()->tensor_shape() - << " Num groups: " << num_groups - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Shape: " << input->info()->tensor_shape() + << " Num groups: " << num_groups << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend layer concatenate function @@ -373,54 +376,49 @@ std::unique_ptr<IFunction> create_channel_shuffle_layer(ChannelShuffleLayerNode template <typename ConcatenateLayerFunction, typename TargetInfo> std::unique_ptr<arm_compute::IFunction> create_concatenate_layer(ConcatenateLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating Concatenate node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating Concatenate node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); // Return nullptr if depth concatenate is switched off - if(!node.is_enabled()) + if (!node.is_enabled()) { return nullptr; } // Extract IO and info - std::vector<typename TargetInfo::TensorType *> inputs; - for(unsigned int i = 0; i < node.num_inputs(); ++i) + std::vector<typename TargetInfo::SrcTensorType *> inputs; + for (unsigned int i = 0; i < node.num_inputs(); ++i) { inputs.push_back(get_backing_tensor<TargetInfo>(node.input(i))); } - typename TargetInfo::TensorType *output = get_backing_tensor<TargetInfo>(node.output(0)); - const DataLayout data_layout = node.output(0) != nullptr ? node.output(0)->desc().layout : DataLayout::UNKNOWN; - const size_t concat_axis = get_dimension_idx(data_layout, node.concatenation_axis()); + typename TargetInfo::TensorType *output = get_backing_tensor<TargetInfo>(node.output(0)); + const DataLayout data_layout = node.output(0) != nullptr ? node.output(0)->desc().layout : DataLayout::UNKNOWN; + const size_t concat_axis = get_dimension_idx(data_layout, node.concatenation_axis()); // Create and configure function - auto func = support::cpp14::make_unique<ConcatenateLayerFunction>(); + auto func = std::make_unique<ConcatenateLayerFunction>(); func->configure(inputs, output, concat_axis); // Log info const bool is_quantized = is_data_type_quantized_asymmetric(output->info()->data_type()); std::ostringstream qss; - if(is_quantized) + if (is_quantized) { qss << " Output QuantInfo: " << output->info()->quantization_info(); } - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << output->info()->data_type() - << " Shape: " << output->info()->tensor_shape() - << " Num Inputs: " << inputs.size() - << " Axis: " << concat_axis - << qss.str() - << std::endl); - - return RETURN_UNIQUE_PTR(func); + ARM_COMPUTE_LOG_GRAPH_INFO( + "Instantiated " << node.name() << " Type: " << node.type() << " Target: " << TargetInfo::TargetType + << " Data Type: " << output->info()->data_type() << " Shape: " << output->info()->tensor_shape() + << " Num Inputs: " << inputs.size() << " Axis: " << concat_axis << qss.str() << std::endl); + + return func; } /** Create a backend convolution layer function * * @tparam ConvolutionLayerFunctions Backend convolution functions - * @tparam TargetInfo Target-specific information + * @tparam TargetInfo Target-specific information * * @param[in] node Node to create the backend function for * @param[in] ctx Graph context @@ -440,7 +438,7 @@ std::unique_ptr<IFunction> create_convolution_layer(ConvolutionLayerNode &node, const bool is_quantized = is_data_type_quantized_asymmetric(input->info()->data_type()); - if(is_quantized) + if (is_quantized) { biases->info()->set_data_type(DataType::S32); } @@ -456,56 +454,51 @@ std::unique_ptr<IFunction> create_convolution_layer(ConvolutionLayerNode &node, std::unique_ptr<IFunction> func; std::string func_name; - if(conv_algorithm == ConvolutionMethod::Winograd) + if (conv_algorithm == ConvolutionMethod::Winograd) { ARM_COMPUTE_ERROR_ON_MSG(num_groups != 1, "WinogradConvolutionLayer does not support grouping!"); - std::tie(func, func_name) = create_named_memory_managed_function<typename ConvolutionLayerFunctions::WinogradConvolutionLayer>( - std::string("WinogradConvolutionLayer"), mm, - input, weights, biases, output, conv_info, fused_act, fast_math); + std::tie(func, func_name) = + create_named_memory_managed_function<typename ConvolutionLayerFunctions::WinogradConvolutionLayer>( + std::string("WinogradConvolutionLayer"), mm, input, weights, biases, output, conv_info, fused_act, + fast_math); } - else if(conv_algorithm == ConvolutionMethod::Direct) + else if (conv_algorithm == ConvolutionMethod::Direct) { ARM_COMPUTE_ERROR_ON_MSG(num_groups != 1, "DirectConvolutionLayer does not support grouping!"); std::tie(func, func_name) = create_named_function<typename ConvolutionLayerFunctions::DirectConvolutionLayer>( - std::string("DirectConvolutionLayer"), - input, weights, biases, output, conv_info, fused_act); + std::string("DirectConvolutionLayer"), input, weights, biases, output, conv_info, fused_act); } - else if(conv_algorithm == ConvolutionMethod::GEMM) + else if (conv_algorithm == ConvolutionMethod::GEMM) { - std::tie(func, func_name) = create_named_memory_managed_function<typename ConvolutionLayerFunctions::GEMMConvolutionLayer>( - std::string("GEMMConvolutionLayer"), mm, - input, weights, biases, output, conv_info, - WeightsInfo(), Size2D(1U, 1U), fused_act, num_groups); + std::tie(func, func_name) = + create_named_memory_managed_function<typename ConvolutionLayerFunctions::GEMMConvolutionLayer>( + std::string("GEMMConvolutionLayer"), mm, input, weights, biases, output, conv_info, WeightsInfo(), + Size2D(1U, 1U), fused_act, num_groups); } else { - std::tie(func, func_name) = create_named_memory_managed_function<typename ConvolutionLayerFunctions::GenericConvolutionLayer>( - std::string("GenericConvolutionLayer"), mm, - input, weights, biases, output, conv_info, - WeightsInfo(), Size2D(1U, 1U), fused_act, fast_math, num_groups); + std::tie(func, func_name) = + create_named_memory_managed_function<typename ConvolutionLayerFunctions::GenericConvolutionLayer>( + std::string("GenericConvolutionLayer"), mm, input, weights, biases, output, conv_info, WeightsInfo(), + Size2D(1U, 1U), fused_act, fast_math, num_groups); } // Log info std::ostringstream qss; - if(is_quantized) + if (is_quantized) { qss << " Input QuantInfo: " << input->info()->quantization_info() << " Weights QuantInfo: " << weights->info()->quantization_info() << " Output QuantInfo: " << output->info()->quantization_info(); } ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << func_name - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Groups: " << num_groups + << node.name() << " Type: " << func_name << " Target: " << TargetInfo::TargetType + << " Data Type: " << input->info()->data_type() << " Groups: " << num_groups << " Input shape: " << input->info()->tensor_shape() << " Weights shape: " << weights->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << qss.str() - << (fused_act.enabled() ? " " + to_string(fused_act.activation()) : "") - << std::endl); - return RETURN_UNIQUE_PTR(func); + << " Output shape: " << output->info()->tensor_shape() << qss.str() + << (fused_act.enabled() ? " " + to_string(fused_act.activation()) : "") << std::endl); + return func; } /** Create a backend deconvolution layer function @@ -536,19 +529,14 @@ std::unique_ptr<IFunction> create_deconvolution_layer(DeconvolutionLayerNode &no std::unique_ptr<IFunction> func; std::tie(func, std::ignore) = create_named_memory_managed_function<DeconvolutionLayerFunction>( - std::string(), mm, - input, weights, biases, output, deconv_info); + std::string(), mm, input, weights, biases, output, deconv_info); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Weights shape: " << weights->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() << std::endl); return func; } @@ -574,7 +562,7 @@ std::unique_ptr<IFunction> create_depthwise_convolution_layer(DepthwiseConvoluti const bool is_quantized = is_data_type_quantized_asymmetric(input->info()->data_type()); - if(is_quantized) + if (is_quantized) { biases->info()->set_data_type(DataType::S32); } @@ -587,31 +575,61 @@ std::unique_ptr<IFunction> create_depthwise_convolution_layer(DepthwiseConvoluti std::unique_ptr<IFunction> func; std::string func_name; - std::tie(func, func_name) = create_named_function<DepthwiseConvolutionLayer>( - std::string("DepthwiseConvolutionLayer"), - input, weights, biases, output, conv_info, depth_multiplier, fused_act); + std::tie(func, func_name) = + create_named_function<DepthwiseConvolutionLayer>(std::string("DepthwiseConvolutionLayer"), input, weights, + biases, output, conv_info, depth_multiplier, fused_act); // Log info std::ostringstream qss; - if(is_quantized) + if (is_quantized) { qss << " Input QuantInfo: " << input->info()->quantization_info() << " Weights QuantInfo: " << weights->info()->quantization_info() << " Output QuantInfo: " << output->info()->quantization_info(); } ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << func_name - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() + << node.name() << " Type: " << func_name << " Target: " << TargetInfo::TargetType + << " Data Type: " << input->info()->data_type() << " Input shape: " + << input->info()->tensor_shape() << " Weights shape: " << weights->info()->tensor_shape() << " Output shape: " << output->info()->tensor_shape() - << " Depth multiplier: " << depth_multiplier - << qss.str() - << (fused_act.enabled() ? " " + to_string(fused_act.activation()) : "") - << std::endl); - return RETURN_UNIQUE_PTR(func); + << " Depth multiplier: " << depth_multiplier << qss.str() + << (fused_act.enabled() ? " " + to_string(fused_act.activation()) : "") << std::endl); + return func; +} + +/** Create a backend depth to space layer function + * + * @tparam DepthToSpaceLayerNode Function Backend depth to space function + * @tparam TargetInfo Target-specific information + * + * @param[in] node Node to create the backend function for + * + * @return Backend depth to space layer function + */ +template <typename DepthToSpaceLayerFunction, typename TargetInfo> +std::unique_ptr<IFunction> create_depth_to_space_layer(DepthToSpaceLayerNode &node) +{ + validate_node<TargetInfo>(node, 1 /* expected inputs */, 1 /* expected outputs */); + + // Extract IO and info + typename TargetInfo::TensorType *input = get_backing_tensor<TargetInfo>(node.input(0)); + typename TargetInfo::TensorType *output = get_backing_tensor<TargetInfo>(node.output(0)); + + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto func = std::make_unique<DepthToSpaceLayerFunction>(); + func->configure(input, output, node.block_shape()); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Block Size: " << node.block_shape() + << " Output shape: " << output->info()->tensor_shape() << std::endl); + + return func; } /** Create a backend dequantize layer function @@ -636,21 +654,17 @@ std::unique_ptr<IFunction> create_dequantization_layer(DequantizationLayerNode & ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<DequantizationLayerFunction>(); + auto func = std::make_unique<DequantizationLayerFunction>(); func->configure(input, output); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Input quantization info: " << output->info()->quantization_info() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Input quantization info: " << output->info()->quantization_info() + << " Output shape: " << output->info()->tensor_shape() << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend detection output layer function * @@ -679,23 +693,19 @@ std::unique_ptr<IFunction> create_detection_output_layer(DetectionOutputLayerNod ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<DetectionOutputLayerFunction>(); + auto func = std::make_unique<DetectionOutputLayerFunction>(); func->configure(input0, input1, input2, output, detect_info); // Log info ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input0->info()->data_type() - << " Input0 shape: " << input0->info()->tensor_shape() - << " Input1 shape: " << input1->info()->tensor_shape() + << node.name() << " Type: " << node.type() << " Target: " << TargetInfo::TargetType + << " Data Type: " << input0->info()->data_type() << " Input0 shape: " + << input0->info()->tensor_shape() << " Input1 shape: " << input1->info()->tensor_shape() << " Input2 shape: " << input2->info()->tensor_shape() << " Output shape: " << output->info()->tensor_shape() - << " DetectionOutputLayer info: " << detect_info - << std::endl); + << " DetectionOutputLayer info: " << detect_info << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend detection post process layer function @@ -731,26 +741,22 @@ std::unique_ptr<IFunction> create_detection_post_process_layer(DetectionPostProc ARM_COMPUTE_ERROR_ON(output3 == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<DetectionPostProcessLayerFunction>(); + auto func = std::make_unique<DetectionPostProcessLayerFunction>(); func->configure(input0, input1, input2, output0, output1, output2, output3, detect_info); // Log info ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input0->info()->data_type() - << " Input0 shape: " << input0->info()->tensor_shape() - << " Input1 shape: " << input1->info()->tensor_shape() + << node.name() << " Type: " << node.type() << " Target: " << TargetInfo::TargetType + << " Data Type: " << input0->info()->data_type() << " Input0 shape: " + << input0->info()->tensor_shape() << " Input1 shape: " << input1->info()->tensor_shape() << " Input2 shape: " << input2->info()->tensor_shape() << " Output0 shape: " << output0->info()->tensor_shape() << " Output1 shape: " << output1->info()->tensor_shape() << " Output2 shape: " << output2->info()->tensor_shape() << " Output3 shape: " << output3->info()->tensor_shape() - << " DetectionPostProcessLayer info: " << detect_info - << std::endl); + << " DetectionPostProcessLayer info: " << detect_info << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend element-wise operation layer function @@ -780,23 +786,31 @@ std::unique_ptr<IFunction> create_eltwise_layer(EltwiseLayerNode &node) std::unique_ptr<IFunction> func = nullptr; std::string func_name; - if(eltwise_op == EltwiseOperation::Add) + if (eltwise_op == EltwiseOperation::Add) { std::tie(func, func_name) = create_named_function<typename EltwiseFunctions::Addition>( - std::string("ArithmeticAddition"), - input1, input2, output, convert_policy, act_info); + std::string("ArithmeticAddition"), input1, input2, output, convert_policy, act_info); } - else if(eltwise_op == EltwiseOperation::Sub) + else if (eltwise_op == EltwiseOperation::Sub) { std::tie(func, func_name) = create_named_function<typename EltwiseFunctions::Subtraction>( - std::string("ArithmeticSubtraction"), - input1, input2, output, convert_policy, act_info); + std::string("ArithmeticSubtraction"), input1, input2, output, convert_policy, act_info); } - else if(eltwise_op == EltwiseOperation::Mul) + else if (eltwise_op == EltwiseOperation::Mul) { std::tie(func, func_name) = create_named_function<typename EltwiseFunctions::Multiplication>( - std::string("PixelWiseMultiplication"), - input1, input2, output, 1.f, convert_policy, node.rounding_policy(), act_info); + std::string("PixelWiseMultiplication"), input1, input2, output, 1.f, convert_policy, node.rounding_policy(), + act_info); + } + else if (eltwise_op == EltwiseOperation::Max) + { + std::tie(func, func_name) = create_named_function<typename EltwiseFunctions::Maximum>( + std::string("ElementwiseMaximum"), input1, input2, output, act_info); + } + else if (eltwise_op == EltwiseOperation::Div) + { + std::tie(func, func_name) = create_named_function<typename EltwiseFunctions::Division>( + std::string("ArithmeticDivision"), input1, input2, output, act_info); } else { @@ -804,16 +818,55 @@ std::unique_ptr<IFunction> create_eltwise_layer(EltwiseLayerNode &node) } // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Operation: " << func_name - << " Data Type: " << input1->info()->data_type() - << " Shape: " << input1->info()->tensor_shape() - << std::endl); - - return RETURN_UNIQUE_PTR(func); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() + << " Target: " << TargetInfo::TargetType << " Operation: " << func_name + << " Data Type: " << input1->info()->data_type() + << " Shape: " << input1->info()->tensor_shape() << std::endl); + + return func; +} + +/** Create a backend unary element-wise operation layer function + * + * @tparam UnaryEltwiseFunctions Backend unary element-wise function + * @tparam TargetInfo Target-specific information + * + * @param[in] node Node to create the backend function for + * + * @return Backend unary element-wise operation layer function + */ +template <typename UnaryEltwiseFunctions, typename TargetInfo> +std::unique_ptr<IFunction> create_unary_eltwise_layer(UnaryEltwiseLayerNode &node) +{ + validate_node<TargetInfo>(node, 1 /* expected inputs */, 1 /* expected outputs */); + + // Extract IO and info + typename TargetInfo::TensorType *input = get_backing_tensor<TargetInfo>(node.input(0)); + typename TargetInfo::TensorType *output = get_backing_tensor<TargetInfo>(node.output(0)); + const UnaryEltwiseOperation eltwise_op = node.eltwise_descriptor().op; + + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + std::unique_ptr<IFunction> func = nullptr; + std::string func_name; + if (eltwise_op == UnaryEltwiseOperation::Exp) + { + std::tie(func, func_name) = + create_named_function<typename UnaryEltwiseFunctions::Exp>(std::string("Exp"), input, output); + } + else + { + ARM_COMPUTE_ERROR("Unsupported unary element-wise operation!"); + } + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() + << " Target: " << TargetInfo::TargetType << " Operation: " << func_name + << " Data Type: " << input->info()->data_type() + << " Shape: " << input->info()->tensor_shape() << std::endl); + + return func; } /** Create a backend flatten layer function @@ -838,20 +891,16 @@ std::unique_ptr<IFunction> create_flatten_layer(FlattenLayerNode &node) ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<FlattenLayerFunction>(); + auto func = std::make_unique<FlattenLayerFunction>(); func->configure(input, output); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend fully connected layer function @@ -874,7 +923,8 @@ std::unique_ptr<IFunction> create_fully_connected_layer(FullyConnectedLayerNode typename TargetInfo::TensorType *weights = get_backing_tensor<TargetInfo>(node.input(1)); typename TargetInfo::TensorType *biases = get_backing_tensor<TargetInfo>(node.input(2)); typename TargetInfo::TensorType *output = get_backing_tensor<TargetInfo>(node.output(0)); - const FullyConnectedLayerInfo fc_info = node.info(); + FullyConnectedLayerInfo fc_info = node.info(); + fc_info.enable_fast_math = (node.fast_math_hint() == FastMathHint::Enabled); ARM_COMPUTE_ERROR_ON(input == nullptr); ARM_COMPUTE_ERROR_ON(weights == nullptr); @@ -883,31 +933,26 @@ std::unique_ptr<IFunction> create_fully_connected_layer(FullyConnectedLayerNode // Create and configure function auto wm = get_weights_manager(ctx, TargetInfo::TargetType); auto mm = get_memory_manager(ctx, TargetInfo::TargetType); - auto func = support::cpp14::make_unique<FullyConnectedLayerFunction>(mm, wm.get()); + auto func = std::make_unique<FullyConnectedLayerFunction>(mm, wm.get()); func->configure(input, weights, biases, output, fc_info); const bool is_quantized = is_data_type_quantized_asymmetric(input->info()->data_type()); // Log info std::ostringstream qss; - if(is_quantized) + if (is_quantized) { qss << " Input QuantInfo: " << input->info()->quantization_info() << " Weights QuantInfo: " << weights->info()->quantization_info() << " Output QuantInfo: " << output->info()->quantization_info(); } - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << qss.str() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << qss.str() << " Input shape: " << input->info()->tensor_shape() + << " Weights shape: " << weights->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend generate proposals layer function @@ -941,22 +986,59 @@ std::unique_ptr<IFunction> create_generate_proposals_layer(GenerateProposalsLaye ARM_COMPUTE_ERROR_ON(scores_out == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<GenerateProposalsLayerFunction>(get_memory_manager(ctx, TargetInfo::TargetType)); + auto func = std::make_unique<GenerateProposalsLayerFunction>(get_memory_manager(ctx, TargetInfo::TargetType)); func->configure(scores, deltas, anchors, proposals, scores_out, num_valid_proposals, info); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.type() - << " Target " << TargetInfo::TargetType - << " Data Type: " << scores->info()->data_type() - << " Scores shape: " << scores->info()->tensor_shape() + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " + << node.type() << " Target " << TargetInfo::TargetType << " Data Type: " + << scores->info()->data_type() << " Scores shape: " << scores->info()->tensor_shape() << " Deltas shape: " << deltas->info()->tensor_shape() << " Anchors shape: " << anchors->info()->tensor_shape() << " Proposals shape: " << proposals->info()->tensor_shape() << " Num valid proposals shape: " << num_valid_proposals->info()->tensor_shape() - << " Scores Out shape: " << scores_out->info()->tensor_shape() - << std::endl); + << " Scores Out shape: " << scores_out->info()->tensor_shape() << std::endl); - return RETURN_UNIQUE_PTR(func); + return std::move(func); +} + +/** Create a backend l2 normalization layer function + * + * @tparam NormalizationLayerFunction Backend normalization function + * @tparam TargetInfo Target-specific information + * + * @param[in] node Node to create the backend function for + * @param[in] ctx Graph context + * + * @return Backend normalization layer function + */ +template <typename L2NormalizeLayerFunction, typename TargetInfo> +std::unique_ptr<IFunction> create_l2_normalize_layer(L2NormalizeLayerNode &node, GraphContext &ctx) +{ + validate_node<TargetInfo>(node, 1 /* expected inputs */, 1 /* expected outputs */); + + // Extract IO and info + typename TargetInfo::TensorType *input = get_backing_tensor<TargetInfo>(node.input(0)); + typename TargetInfo::TensorType *output = get_backing_tensor<TargetInfo>(node.output(0)); + int axis = node.axis(); + float epsilon = node.epsilon(); + + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto mm = get_memory_manager(ctx, TargetInfo::TargetType); + auto func = std::make_unique<L2NormalizeLayerFunction>(mm); + func->configure(input, output, axis, epsilon); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << " Axis: " << axis << " Epsilon: " << epsilon << std::endl); + + return func; } /** Create a backend normalization layer function @@ -984,21 +1066,17 @@ std::unique_ptr<IFunction> create_normalization_layer(NormalizationLayerNode &no ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<NormalizationLayerFunction>(); + auto func = std::make_unique<NormalizationLayerFunction>(); func->configure(input, output, norm_info); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " Normalization info: " << norm_info.type() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << " Normalization info: " << norm_info.type() << std::endl); - return RETURN_UNIQUE_PTR(func); + return std::move(func); } /** Create a backend normalize planar YUV layer function @@ -1026,19 +1104,15 @@ std::unique_ptr<IFunction> create_normalize_planar_yuv_layer(NormalizePlanarYUVL ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<NormalizePlanarYUVLayerFunction>(); + auto func = std::make_unique<NormalizePlanarYUVLayerFunction>(); func->configure(input, output, mean, std); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Shape: " << input->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Shape: " << input->info()->tensor_shape() << std::endl); - return RETURN_UNIQUE_PTR(func); + return std::move(func); } /** Create a backend pad layer function @@ -1064,20 +1138,16 @@ std::unique_ptr<IFunction> create_pad_layer(PadLayerNode &node) ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<PadLayerFunction>(); + auto func = std::make_unique<PadLayerFunction>(); func->configure(input, output, padding, pad_value); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend permute layer function @@ -1102,21 +1172,17 @@ std::unique_ptr<IFunction> create_permute_layer(PermuteLayerNode &node) ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<PermuteLayerFunction>(); + auto func = std::make_unique<PermuteLayerFunction>(); func->configure(input, output, perm); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " Permutation vector: " << perm - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << " Permutation vector: " << perm << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend pooling layer function @@ -1141,21 +1207,17 @@ std::unique_ptr<IFunction> create_pooling_layer(PoolingLayerNode &node) ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<PoolingLayerFunction>(); + auto func = std::make_unique<PoolingLayerFunction>(); func->configure(input, output, pool_info); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " Pooling info: " << pool_info.pool_type - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << " Pooling info: " << pool_info.pool_type << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend PRelu layer function @@ -1180,20 +1242,16 @@ std::unique_ptr<IFunction> create_prelu_layer(PReluLayerNode &node) ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<PReluFunction>(); + auto func = std::make_unique<PReluFunction>(); func->configure(input, alpha, output); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend print layer function @@ -1214,13 +1272,9 @@ std::unique_ptr<IFunction> create_print_layer(PrintLayerNode &node) ARM_COMPUTE_UNUSED(input); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() << std::endl); return nullptr; } @@ -1249,22 +1303,18 @@ std::unique_ptr<IFunction> create_priorbox_layer(PriorBoxLayerNode &node) ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<PriorBoxLayerFunction>(); + auto func = std::make_unique<PriorBoxLayerFunction>(); func->configure(input0, input1, output, prior_info); // Log info ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input0->info()->data_type() - << " Input0 shape: " << input0->info()->tensor_shape() - << " Input1 shape: " << input1->info()->tensor_shape() + << node.name() << " Type: " << node.type() << " Target: " << TargetInfo::TargetType + << " Data Type: " << input0->info()->data_type() << " Input0 shape: " + << input0->info()->tensor_shape() << " Input1 shape: " << input1->info()->tensor_shape() << " Output shape: " << output->info()->tensor_shape() - << " PriorBoxLayer info: " << prior_info - << std::endl); + << " PriorBoxLayer info: " << prior_info << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend quantization layer function @@ -1288,20 +1338,55 @@ std::unique_ptr<IFunction> create_quantization_layer(QuantizationLayerNode &node ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<QuantizationLayerFunction>(); + auto func = std::make_unique<QuantizationLayerFunction>(); func->configure(input, output); // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() << std::endl); + + return func; +} + +/** Create a backend reduction operation layer function + * + * @tparam ReductionOperationFunction Backend reduction operation function + * @tparam TargetInfo Target-specific information + * + * @param[in] node Node to create the backend function for + * @param[in] ctx Graph context + * + * @return Backend reduction sum layer function + */ +template <typename ReductionOperationFunction, typename TargetInfo> +std::unique_ptr<IFunction> create_reduction_operation_layer(ReductionLayerNode &node, GraphContext &ctx) +{ + validate_node<TargetInfo>(node, 1 /* expected inputs */, 1 /* expected outputs */); + + // Extract IO and info + typename TargetInfo::TensorType *input = get_backing_tensor<TargetInfo>(node.input(0)); + typename TargetInfo::TensorType *output = get_backing_tensor<TargetInfo>(node.output(0)); + ReductionOperation op = node.op(); + int axis = node.axis(); + bool keep_dims = node.keep_dims(); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto func = std::make_unique<ReductionOperationFunction>(get_memory_manager(ctx, TargetInfo::TargetType)); + func->configure(input, output, axis, op, keep_dims); + + // Log info ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType + << node.name() << " Type: " << node.type() << " Target: " << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); + << " Output shape: " << output->info()->tensor_shape() << " Operation: " << op + << " Axis: " << axis << " Keep dimensions:" << keep_dims << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend reorg layer function @@ -1325,20 +1410,16 @@ std::unique_ptr<IFunction> create_reorg_layer(ReorgLayerNode &node) ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<ReorgLayerFunction>(); + auto func = std::make_unique<ReorgLayerFunction>(); func->configure(input, output, node.stride()); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend reshape layer function @@ -1362,20 +1443,16 @@ std::unique_ptr<IFunction> create_reshape_layer(ReshapeLayerNode &node) ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<ReshapeLayerFunction>(); + auto func = std::make_unique<ReshapeLayerFunction>(); func->configure(input, output); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend resize layer function @@ -1400,21 +1477,18 @@ std::unique_ptr<IFunction> create_resize_layer(ResizeLayerNode &node) const InterpolationPolicy policy = node.policy(); // Create and configure function - auto func = support::cpp14::make_unique<ResizeLayerFunction>(); - func->configure(input, output, policy, BorderMode::CONSTANT); + auto func = std::make_unique<ResizeLayerFunction>(); + func->configure(input, output, + ScaleKernelInfo{policy, BorderMode::CONSTANT, PixelValue(), SamplingPolicy::CENTER, false, false}); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " Interpolation: " << policy - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << " Interpolation: " << policy << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend ROI align layer function @@ -1442,24 +1516,20 @@ std::unique_ptr<IFunction> create_roi_align_layer(ROIAlignLayerNode &node) const ROIPoolingLayerInfo pool_info = node.pooling_info(); // Create and configure function - auto func = support::cpp14::make_unique<ROIAlignLayerFunction>(); + auto func = std::make_unique<ROIAlignLayerFunction>(); func->configure(input, rois, output, pool_info); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " ROIs shape: " << rois->info()->tensor_shape() - << " ROIPooling width: " << pool_info.pooled_width() - << " ROIPooling height: " << pool_info.pooled_height() - << std::endl); - - return RETURN_UNIQUE_PTR(func); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << " ROIs shape: " << rois->info()->tensor_shape() + << " ROIPooling width: " << pool_info.pooled_width() + << " ROIPooling height: " << pool_info.pooled_height() << std::endl); + + return std::move(func); } /** Create a backend slice layer function @@ -1483,20 +1553,16 @@ std::unique_ptr<IFunction> create_slice_layer(SliceLayerNode &node) ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<SliceLayerFunction>(); + auto func = std::make_unique<SliceLayerFunction>(); func->configure(input, output, node.starts(), node.ends()); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend softmax layer function @@ -1522,20 +1588,16 @@ std::unique_ptr<IFunction> create_softmax_layer(SoftmaxLayerNode &node, GraphCon ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<SoftmaxLayerFunction>(get_memory_manager(ctx, TargetInfo::TargetType)); + auto func = std::make_unique<SoftmaxLayerFunction>(get_memory_manager(ctx, TargetInfo::TargetType)); func->configure(input, output, beta); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } /** Create a backend layer stack function @@ -1550,12 +1612,13 @@ std::unique_ptr<IFunction> create_softmax_layer(SoftmaxLayerNode &node, GraphCon template <typename StackLayerFunction, typename TargetInfo> std::unique_ptr<arm_compute::IFunction> create_stack_layer(StackLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating Stack node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating Stack node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); // Extract IO and info std::vector<typename TargetInfo::TensorType *> inputs; - for(unsigned int i = 0; i < node.num_inputs(); ++i) + for (unsigned int i = 0; i < node.num_inputs(); ++i) { inputs.push_back(get_backing_tensor<TargetInfo>(node.input(i))); } @@ -1563,113 +1626,60 @@ std::unique_ptr<arm_compute::IFunction> create_stack_layer(StackLayerNode &node) const int axis = node.axis(); // Create and configure function - auto func = support::cpp14::make_unique<StackLayerFunction>(); + auto func = std::make_unique<StackLayerFunction>(); func->configure(inputs, axis, output); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << output->info()->data_type() - << " Inputs shape: " << inputs[0]->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " Num Inputs: " << inputs.size() - << " Axis: " << axis - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() + << " Target: " << TargetInfo::TargetType + << " Data Type: " << output->info()->data_type() + << " Inputs shape: " << inputs[0]->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << " Num Inputs: " << inputs.size() << " Axis: " << axis << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } -/** Create a backend Upsample layer function - * - * @tparam UpsampleLayerFunction Backend Upsample function - * @tparam TargetInfo Target-specific information - * - * @param[in] node Node to create the backend function for - * @param[in] ctx Graph context - * - * @return Backend Upsample layer function - */ -template <typename UpsampleLayerFunction, typename TargetInfo> -std::unique_ptr<IFunction> create_upsample_layer(UpsampleLayerNode &node, GraphContext &ctx) -{ - ARM_COMPUTE_UNUSED(ctx); - validate_node<TargetInfo>(node, 1 /* expected inputs */, 1 /* expected outputs */); - - // Extract IO and info - typename TargetInfo::TensorType *input = get_backing_tensor<TargetInfo>(node.input(0)); - typename TargetInfo::TensorType *output = get_backing_tensor<TargetInfo>(node.output(0)); - const Size2D info = node.info(); - const InterpolationPolicy upsampling_policy = node.upsampling_policy(); - ARM_COMPUTE_ERROR_ON(upsampling_policy != InterpolationPolicy::NEAREST_NEIGHBOR); - ARM_COMPUTE_ERROR_ON(info.x() != 2 || info.y() != 2); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - // Create and configure function - auto func = support::cpp14::make_unique<UpsampleLayerFunction>(); - func->configure(input, output, info, upsampling_policy); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " Strides: " << info - << " Upsampling policy: " << upsampling_policy - << std::endl); - - return RETURN_UNIQUE_PTR(func); -} -/** Create a backend YOLO layer function +/** Create a backend slice layer function * - * @tparam YoloLayerFunction Backend YOLO function - * @tparam TargetInfo Target-specific information + * @tparam StridedSliceLayerFunction Backend strided slice function + * @tparam TargetInfo Target-specific information * * @param[in] node Node to create the backend function for - * @param[in] ctx Graph context * - * @return Backend YOLO layer function + * @return Backend strided slice layer function */ -template <typename YOLOlayerFunction, typename TargetInfo> -std::unique_ptr<IFunction> create_yolo_layer(YOLOLayerNode &node, GraphContext &ctx) +template <typename StridedSliceLayerFunction, typename TargetInfo> +std::unique_ptr<IFunction> create_strided_slice_layer(StridedSliceLayerNode &node) { - ARM_COMPUTE_UNUSED(ctx); validate_node<TargetInfo>(node, 1 /* expected inputs */, 1 /* expected outputs */); // Extract IO and info - typename TargetInfo::TensorType *input = get_backing_tensor<TargetInfo>(node.input(0)); - typename TargetInfo::TensorType *output = get_backing_tensor<TargetInfo>(node.output(0)); - const ActivationLayerInfo act_info = node.activation_info(); - const int32_t num_classes = node.num_classes(); - ARM_COMPUTE_ERROR_ON(num_classes <= 0); + typename TargetInfo::TensorType *input = get_backing_tensor<TargetInfo>(node.input(0)); + typename TargetInfo::TensorType *output = get_backing_tensor<TargetInfo>(node.output(0)); + Coordinates starts = node.starts(); + Coordinates ends = node.ends(); + BiStrides strides = node.strides(); + StridedSliceLayerInfo info = node.strided_slice_info(); + ARM_COMPUTE_ERROR_ON(input == nullptr); ARM_COMPUTE_ERROR_ON(output == nullptr); // Create and configure function - auto func = support::cpp14::make_unique<YOLOlayerFunction>(); - func->configure(input, output, act_info, num_classes); + auto func = std::make_unique<StridedSliceLayerFunction>(); + func->configure(input, output, starts, ends, strides, info.begin_mask(), info.end_mask(), info.shrink_axis_mask()); // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " - << node.name() - << " Type: " << node.type() - << " Target: " << TargetInfo::TargetType - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " Activation function: " << act_info.activation() - << " Num classes: " << num_classes - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << node.name() << " Type: " << node.type() << " Target: " + << TargetInfo::TargetType << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() << std::endl); - return RETURN_UNIQUE_PTR(func); + return func; } } // namespace detail } // namespace backends } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_BACKENDS_DETAIL_FUNCTION_HELPERS_H */ +#endif // ACL_ARM_COMPUTE_GRAPH_BACKENDS_FUNCTIONHELPERS_H diff --git a/arm_compute/graph/backends/FusedConvolutionBatchNormalizationFunction.h b/arm_compute/graph/backends/FusedConvolutionBatchNormalizationFunction.h index 895906da13..27e21cbc7e 100644 --- a/arm_compute/graph/backends/FusedConvolutionBatchNormalizationFunction.h +++ b/arm_compute/graph/backends/FusedConvolutionBatchNormalizationFunction.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited. + * Copyright (c) 2019, 2023 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -22,11 +22,12 @@ * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_BACKENDS_FUSED_CONVOLUTION_BATCH_NORMAZLIZATION_FUNCTION_H -#define ARM_COMPUTE_GRAPH_BACKENDS_FUSED_CONVOLUTION_BATCH_NORMAZLIZATION_FUNCTION_H +#ifndef ACL_ARM_COMPUTE_GRAPH_BACKENDS_FUSEDCONVOLUTIONBATCHNORMALIZATIONFUNCTION_H +#define ACL_ARM_COMPUTE_GRAPH_BACKENDS_FUSEDCONVOLUTIONBATCHNORMALIZATIONFUNCTION_H #include "arm_compute/core/Types.h" #include "arm_compute/runtime/IFunction.h" +#include "arm_compute/runtime/IMemoryManager.h" namespace arm_compute { @@ -69,15 +70,19 @@ public: * @param[in] fused_act Activation layer information in case of a fused activation. * */ - void configure(TensorType *input, - TensorType *weights, - TensorType *bias, - TensorType *output, - const TensorType *mean, - const TensorType *var, - const TensorType *beta, - const TensorType *gamma, - float epsilon, const PadStrideInfo &conv_info, unsigned int num_groups, bool fast_math, ActivationLayerInfo const &fused_act) + void configure(TensorType *input, + TensorType *weights, + TensorType *bias, + TensorType *output, + const TensorType *mean, + const TensorType *var, + const TensorType *beta, + const TensorType *gamma, + float epsilon, + const PadStrideInfo &conv_info, + unsigned int num_groups, + bool fast_math, + ActivationLayerInfo const &fused_act) { // We don't run any validate, as we assume that the layers have been already validated const bool has_bias = (bias != nullptr); @@ -85,7 +90,7 @@ public: // We check if the layer has a bias. If yes, use it in-place. If not, we need to create one // as batch normalization might end up with a bias != 0 - if(has_bias) + if (has_bias) { _fused_batch_norm_layer.configure(weights, mean, var, nullptr, nullptr, bias, beta, gamma, epsilon); bias_to_use = bias; @@ -96,9 +101,10 @@ public: bias_to_use = &_fused_bias; } - _conv_layer.configure(input, weights, bias_to_use, output, conv_info, WeightsInfo(), Size2D(1U, 1U), fused_act, fast_math, num_groups); + _conv_layer.configure(input, weights, bias_to_use, output, conv_info, WeightsInfo(), Size2D(1U, 1U), fused_act, + fast_math, num_groups); - if(!has_bias) + if (!has_bias) { _fused_bias.allocator()->allocate(); } @@ -113,7 +119,7 @@ public: void prepare() { - if(!_is_prepared) + if (!_is_prepared) { _fused_batch_norm_layer.run(); _is_prepared = true; @@ -130,4 +136,4 @@ private: } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_BACKENDS_FUSED_CONVOLUTION_BATCH_NORMAZLIZATION_FUNCTION_H */ +#endif // ACL_ARM_COMPUTE_GRAPH_BACKENDS_FUSEDCONVOLUTIONBATCHNORMALIZATIONFUNCTION_H diff --git a/arm_compute/graph/backends/FusedDepthwiseConvolutionBatchNormalizationFunction.h b/arm_compute/graph/backends/FusedDepthwiseConvolutionBatchNormalizationFunction.h index 37f3eab2e3..07a2cdd8b8 100644 --- a/arm_compute/graph/backends/FusedDepthwiseConvolutionBatchNormalizationFunction.h +++ b/arm_compute/graph/backends/FusedDepthwiseConvolutionBatchNormalizationFunction.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited. + * Copyright (c) 2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -67,15 +67,18 @@ public: * @param[in] fused_act Activation layer information in case of a fused activation. * */ - void configure(TensorType *input, - TensorType *weights, - TensorType *bias, - TensorType *output, - const TensorType *mean, - const TensorType *var, - const TensorType *beta, - const TensorType *gamma, - float epsilon, const PadStrideInfo &conv_info, unsigned int depth_multiplier, ActivationLayerInfo const &fused_act) + void configure(TensorType *input, + TensorType *weights, + TensorType *bias, + TensorType *output, + const TensorType *mean, + const TensorType *var, + const TensorType *beta, + const TensorType *gamma, + float epsilon, + const PadStrideInfo &conv_info, + unsigned int depth_multiplier, + ActivationLayerInfo const &fused_act) { // We don't run any validate, as we assume that the layers have been already validated const bool has_bias = (bias != nullptr); @@ -83,20 +86,23 @@ public: // We check if the layer has a bias. If yes, use it in-place. If not, we need to create one // as batch normalization might end up with a bias != 0 - if(has_bias) + if (has_bias) { - _fused_batch_norm_layer.configure(weights, mean, var, nullptr, nullptr, bias, beta, gamma, epsilon, FuseBatchNormalizationType::DEPTHWISECONVOLUTION); + _fused_batch_norm_layer.configure(weights, mean, var, nullptr, nullptr, bias, beta, gamma, epsilon, + FuseBatchNormalizationType::DEPTHWISECONVOLUTION); bias_to_use = bias; } else { - _fused_batch_norm_layer.configure(weights, mean, var, nullptr, &_fused_bias, nullptr, beta, gamma, epsilon, FuseBatchNormalizationType::DEPTHWISECONVOLUTION); + _fused_batch_norm_layer.configure(weights, mean, var, nullptr, &_fused_bias, nullptr, beta, gamma, epsilon, + FuseBatchNormalizationType::DEPTHWISECONVOLUTION); bias_to_use = &_fused_bias; } - _depth_conv_layer.configure(input, weights, bias_to_use, output, conv_info, depth_multiplier, fused_act.enabled() ? fused_act : ActivationLayerInfo()); + _depth_conv_layer.configure(input, weights, bias_to_use, output, conv_info, depth_multiplier, + fused_act.enabled() ? fused_act : ActivationLayerInfo()); - if(!has_bias) + if (!has_bias) { _fused_bias.allocator()->allocate(); } @@ -111,7 +117,7 @@ public: void prepare() { - if(!_is_prepared) + if (!_is_prepared) { _fused_batch_norm_layer.run(); _is_prepared = true; diff --git a/arm_compute/graph/backends/GLES/GCDeviceBackend.h b/arm_compute/graph/backends/GLES/GCDeviceBackend.h deleted file mode 100644 index a6c0bfe7ed..0000000000 --- a/arm_compute/graph/backends/GLES/GCDeviceBackend.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2018-2019 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef ARM_COMPUTE_GRAPH_GCDEVICEBACKEND_H -#define ARM_COMPUTE_GRAPH_GCDEVICEBACKEND_H - -#include "arm_compute/graph/IDeviceBackend.h" - -#include "arm_compute/runtime/GLES_COMPUTE/GCBufferAllocator.h" - -namespace arm_compute -{ -namespace graph -{ -namespace backends -{ -/** GLES Compute device backend */ -class GCDeviceBackend final : public IDeviceBackend -{ -public: - /** Default Constructor */ - GCDeviceBackend(); - - // Inherited overridden methods - void initialize_backend() override; - void setup_backend_context(GraphContext &ctx) override; - void release_backend_context(GraphContext &ctx) override; - bool is_backend_supported() override; - IAllocator *backend_allocator() override; - std::unique_ptr<ITensorHandle> create_tensor(const Tensor &tensor) override; - std::unique_ptr<ITensorHandle> create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; - std::unique_ptr<arm_compute::IFunction> configure_node(INode &node, GraphContext &ctx) override; - Status validate_node(INode &node) override; - std::shared_ptr<arm_compute::IMemoryManager> create_memory_manager(MemoryManagerAffinity affinity) override; - std::shared_ptr<arm_compute::IWeightsManager> create_weights_manager() override; - -private: - bool _initialized; /**< Flag that specifies if the backend has been default initialized */ - GCBufferAllocator _allocator; /**< GLES buffer affinity allocator */ -}; -} // namespace backends -} // namespace graph -} // namespace arm_compute -#endif //ARM_COMPUTE_GRAPH_GCDEVICEBACKEND_H diff --git a/arm_compute/graph/backends/GLES/GCTensorHandle.h b/arm_compute/graph/backends/GLES/GCTensorHandle.h deleted file mode 100644 index 119731df58..0000000000 --- a/arm_compute/graph/backends/GLES/GCTensorHandle.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2018-2019 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef ARM_COMPUTE_GRAPH_GCTENSORHANDLE_H -#define ARM_COMPUTE_GRAPH_GCTENSORHANDLE_H - -#include "arm_compute/graph/ITensorHandle.h" - -#include "arm_compute/runtime/GLES_COMPUTE/GCTensor.h" - -namespace arm_compute -{ -namespace graph -{ -namespace backends -{ -/** GLES compute tensor handle interface object **/ -class GCTensorHandle final : public ITensorHandle -{ -public: - /** Default Constructor - * - * @param[in] info Tensor metadata - */ - GCTensorHandle(const ITensorInfo &info); - /** Destructor: free the tensor's memory */ - ~GCTensorHandle() = default; - /** Allow instances of this class to be move constructed */ - GCTensorHandle(GCTensorHandle &&) = default; - /** Allow instances of this class to be moved */ - GCTensorHandle &operator=(GCTensorHandle &&) = default; - - // Inherited overridden methods - void allocate() override; - void free() override; - void manage(IMemoryGroup *mg) override; - void map(bool blocking) override; - void unmap() override; - void release_if_unused() override; - arm_compute::ITensor &tensor() override; - const arm_compute::ITensor &tensor() const override; - ITensorHandle *parent_handle() override; - bool is_subtensor() const override; - Target target() const override; - -private: - arm_compute::GCTensor _tensor; /**< Backend Tensor */ -}; -} // namespace backends -} // namespace graph -} // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_GCTENSORHANDLE_H */ diff --git a/arm_compute/graph/backends/NEON/NEDeviceBackend.h b/arm_compute/graph/backends/NEON/NEDeviceBackend.h index 87acc5551e..cd817a20d8 100644 --- a/arm_compute/graph/backends/NEON/NEDeviceBackend.h +++ b/arm_compute/graph/backends/NEON/NEDeviceBackend.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -25,7 +25,6 @@ #define ARM_COMPUTE_GRAPH_NEDEVICEBACKEND_H #include "arm_compute/graph/IDeviceBackend.h" - #include "arm_compute/runtime/Allocator.h" namespace arm_compute @@ -34,27 +33,29 @@ namespace graph { namespace backends { -/** NEON device backend */ +/** CPU device backend */ class NEDeviceBackend final : public IDeviceBackend { public: NEDeviceBackend(); // Inherited overridden methods - void initialize_backend() override; - void setup_backend_context(GraphContext &ctx) override; - void release_backend_context(GraphContext &ctx) override; + void initialize_backend() override; + void setup_backend_context(GraphContext &ctx) override; + void release_backend_context(GraphContext &ctx) override; bool is_backend_supported() override; IAllocator *backend_allocator() override; std::unique_ptr<ITensorHandle> create_tensor(const Tensor &tensor) override; - std::unique_ptr<ITensorHandle> create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; - std::unique_ptr<arm_compute::IFunction> configure_node(INode &node, GraphContext &ctx) override; - Status validate_node(INode &node) override; - std::shared_ptr<arm_compute::IMemoryManager> create_memory_manager(MemoryManagerAffinity affinity) override; + std::unique_ptr<ITensorHandle> + create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; + std::unique_ptr<arm_compute::IFunction> configure_node(INode &node, GraphContext &ctx) override; + Status validate_node(INode &node) override; + std::shared_ptr<arm_compute::IMemoryManager> create_memory_manager(MemoryManagerAffinity affinity) override; std::shared_ptr<arm_compute::IWeightsManager> create_weights_manager() override; + void sync() override; private: - Allocator _allocator; /**< NEON backend allocator */ + Allocator _allocator; /**< Backend allocator */ }; } // namespace backends } // namespace graph diff --git a/arm_compute/graph/backends/NEON/NEFunctionFactory.h b/arm_compute/graph/backends/NEON/NEFunctionFactory.h index b05b9f0c8b..6365b71f32 100644 --- a/arm_compute/graph/backends/NEON/NEFunctionFactory.h +++ b/arm_compute/graph/backends/NEON/NEFunctionFactory.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -38,7 +38,7 @@ class GraphContext; namespace backends { -/** Factory for generating NEON backend functions **/ +/** Factory for generating CPU backend functions **/ class NEFunctionFactory final { public: diff --git a/arm_compute/graph/backends/NEON/NENodeValidator.h b/arm_compute/graph/backends/NEON/NENodeValidator.h index 578f405575..5d23b8bb06 100644 --- a/arm_compute/graph/backends/NEON/NENodeValidator.h +++ b/arm_compute/graph/backends/NEON/NENodeValidator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/backends/NEON/NESubTensorHandle.h b/arm_compute/graph/backends/NEON/NESubTensorHandle.h index 1dbc0530e5..3619f4ed1b 100644 --- a/arm_compute/graph/backends/NEON/NESubTensorHandle.h +++ b/arm_compute/graph/backends/NEON/NESubTensorHandle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -25,7 +25,6 @@ #define ARM_COMPUTE_GRAPH_NESUBTENSORHANDLE_H #include "arm_compute/graph/ITensorHandle.h" - #include "arm_compute/runtime/SubTensor.h" namespace arm_compute @@ -34,7 +33,7 @@ namespace graph { namespace backends { -/** NEON Sub-Tensor handle interface object **/ +/** CPU Sub-Tensor handle interface object **/ class NESubTensorHandle final : public ITensorHandle { public: @@ -45,7 +44,10 @@ public: * @param[in] coords Starting coordinates * @param[in] extend_parent Extends parent shape if true */ - NESubTensorHandle(ITensorHandle *parent_handle, const TensorShape &shape, const Coordinates &coords, bool extend_parent = false); + NESubTensorHandle(ITensorHandle *parent_handle, + const TensorShape &shape, + const Coordinates &coords, + bool extend_parent = false); /** Destructor: free the tensor's memory */ ~NESubTensorHandle() = default; /** Allow instances of this class to be move constructed */ @@ -58,10 +60,10 @@ public: NESubTensorHandle &operator=(const NESubTensorHandle &) = delete; // Inherited overridden methods - void allocate() override; - void free() override; - void manage(IMemoryGroup *mg) override; - void map(bool blocking) override; + void allocate() override; + void free() override; + void manage(IMemoryGroup *mg) override; + void map(bool blocking) override; void unmap() override; void release_if_unused() override; arm_compute::ITensor &tensor() override; diff --git a/arm_compute/graph/backends/NEON/NETensorHandle.h b/arm_compute/graph/backends/NEON/NETensorHandle.h index 0f1b748cba..1df90822ba 100644 --- a/arm_compute/graph/backends/NEON/NETensorHandle.h +++ b/arm_compute/graph/backends/NEON/NETensorHandle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -25,7 +25,6 @@ #define ARM_COMPUTE_GRAPH_NETENSORHANDLE_H #include "arm_compute/graph/ITensorHandle.h" - #include "arm_compute/runtime/Tensor.h" namespace arm_compute @@ -34,7 +33,7 @@ namespace graph { namespace backends { -/** NEON Tensor handle interface object **/ +/** CPU Tensor handle interface object **/ class NETensorHandle final : public ITensorHandle { public: @@ -51,10 +50,10 @@ public: NETensorHandle &operator=(NETensorHandle &&) = default; // Inherited overridden methods - void allocate() override; - void free() override; - void manage(IMemoryGroup *mg) override; - void map(bool blocking) override; + void allocate() override; + void free() override; + void manage(IMemoryGroup *mg) override; + void map(bool blocking) override; void unmap() override; void release_if_unused() override; arm_compute::ITensor &tensor() override; diff --git a/arm_compute/graph/backends/Utils.h b/arm_compute/graph/backends/Utils.h index 4893340b4c..5f4e66c207 100644 --- a/arm_compute/graph/backends/Utils.h +++ b/arm_compute/graph/backends/Utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -42,9 +42,10 @@ namespace backends * @return A configured backend function */ template <typename FunctionType, typename FunctionNameType, typename... ParameterType> -std::pair<std::unique_ptr<arm_compute::IFunction>, FunctionNameType> create_named_function(FunctionNameType name, ParameterType... args) +std::tuple<std::unique_ptr<arm_compute::IFunction>, FunctionNameType> create_named_function(FunctionNameType name, + ParameterType... args) { - auto f = arm_compute::support::cpp14::make_unique<FunctionType>(); + auto f = std::make_unique<FunctionType>(); f->configure(std::forward<ParameterType>(args)...); return std::make_pair(std::move(f), name); } @@ -58,11 +59,10 @@ std::pair<std::unique_ptr<arm_compute::IFunction>, FunctionNameType> create_name * @return A configured backend function */ template <typename FunctionType, typename FunctionNameType, typename MemoryManagerType, typename... ParameterType> -std::pair<std::unique_ptr<arm_compute::IFunction>, FunctionNameType> create_named_memory_managed_function(FunctionNameType name, - MemoryManagerType mm, - ParameterType... args) +std::tuple<std::unique_ptr<arm_compute::IFunction>, FunctionNameType> +create_named_memory_managed_function(FunctionNameType name, MemoryManagerType mm, ParameterType... args) { - auto f = arm_compute::support::cpp14::make_unique<FunctionType>(mm); + auto f = std::make_unique<FunctionType>(mm); f->configure(std::forward<ParameterType>(args)...); return std::make_pair(std::move(f), name); } diff --git a/arm_compute/graph/backends/ValidateHelpers.h b/arm_compute/graph/backends/ValidateHelpers.h index 673caf9eac..0e102942a7 100644 --- a/arm_compute/graph/backends/ValidateHelpers.h +++ b/arm_compute/graph/backends/ValidateHelpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2021, 2023 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -21,17 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_BACKENDS_DETAIL_VALIDATE_HELPERS_H -#define ARM_COMPUTE_GRAPH_BACKENDS_DETAIL_VALIDATE_HELPERS_H - -#include "arm_compute/graph/Logger.h" -#include "arm_compute/graph/Tensor.h" -#include "arm_compute/graph/Types.h" -#include "arm_compute/graph/nodes/Nodes.h" +#ifndef ACL_ARM_COMPUTE_GRAPH_BACKENDS_VALIDATEHELPERS_H +#define ACL_ARM_COMPUTE_GRAPH_BACKENDS_VALIDATEHELPERS_H #include "arm_compute/core/Error.h" #include "arm_compute/core/Helpers.h" #include "arm_compute/core/ITensorInfo.h" +#include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/nodes/Nodes.h" +#include "arm_compute/graph/Tensor.h" +#include "arm_compute/graph/Types.h" namespace arm_compute { @@ -52,6 +51,30 @@ inline arm_compute::ITensorInfo *get_backing_tensor_info(arm_compute::graph::Ten return ((tensor == nullptr) || (tensor->handle() == nullptr)) ? nullptr : tensor->handle()->tensor().info(); } +/** Validates a ArgMinMax layer node + * + * @tparam ArgMinMax layer function type + * + * @param[in] node Node to validate + * + * @return Status + */ +template <typename ArgMinMaxLayer> +Status validate_arg_min_max_layer(ArgMinMaxLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Validating ArgMinMaxLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + arm_compute::ITensorInfo *input = detail::get_backing_tensor_info(node.input(0)); + arm_compute::ITensorInfo *output = get_backing_tensor_info(node.output(0)); + + // Validate function + return ArgMinMaxLayer::validate(input, node.axis(), output, node.reduction_operation()); +} + /** Validates a Bounding Box Transform layer node * * @tparam BoundingBoxTransformLayer Bounding Box Transform layer function type @@ -63,7 +86,8 @@ inline arm_compute::ITensorInfo *get_backing_tensor_info(arm_compute::graph::Ten template <typename BoundingBoxTransformLayer> Status validate_bounding_box_transform_layer(BoundingBoxTransformLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating BoundingBoxTransformLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating BoundingBoxTransformLayer node with ID : " << node.id() << " and Name: " + << node.name() << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 2); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -87,7 +111,8 @@ Status validate_bounding_box_transform_layer(BoundingBoxTransformLayerNode &node template <typename ChannelShuffleLayer> Status validate_channel_shuffle_layer(ChannelShuffleLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating ChannelShuffle node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Validating ChannelShuffle node with ID : " << node.id() << " and Name: " << node.name() << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -110,10 +135,14 @@ Status validate_channel_shuffle_layer(ChannelShuffleLayerNode &node) * * @return Status */ -template <typename ConvolutionLayer, typename DirectConvolutionLayer, typename GEMMConvolutionLayer, typename WinogradConvolutionLayer> +template <typename ConvolutionLayer, + typename DirectConvolutionLayer, + typename GEMMConvolutionLayer, + typename WinogradConvolutionLayer> Status validate_convolution_layer(ConvolutionLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating ConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Validating ConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 3); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -123,7 +152,7 @@ Status validate_convolution_layer(ConvolutionLayerNode &node) arm_compute::ITensorInfo *biases = get_backing_tensor_info(node.input(2)); arm_compute::ITensorInfo *output = get_backing_tensor_info(node.output(0)); - if(is_data_type_quantized_asymmetric(input->data_type())) + if (is_data_type_quantized_asymmetric(input->data_type())) { biases->set_data_type(DataType::S32); } @@ -135,23 +164,24 @@ Status validate_convolution_layer(ConvolutionLayerNode &node) // Validate function Status status{}; - switch(conv_algorithm) + switch (conv_algorithm) { case ConvolutionMethod::Direct: ARM_COMPUTE_RETURN_ERROR_ON_MSG(num_groups != 1, "DirectConvolutionLayer does not support grouping!"); status = DirectConvolutionLayer::validate(input, weights, biases, output, conv_info); break; case ConvolutionMethod::GEMM: - status = GEMMConvolutionLayer::validate(input, weights, biases, output, conv_info, - WeightsInfo(), Size2D(1, 1), ActivationLayerInfo(), num_groups); + status = GEMMConvolutionLayer::validate(input, weights, biases, output, conv_info, WeightsInfo(), + Size2D(1, 1), ActivationLayerInfo(), num_groups); break; case ConvolutionMethod::Winograd: ARM_COMPUTE_RETURN_ERROR_ON_MSG(num_groups != 1, "WinogradConvolutionLayer does not support grouping!"); - status = WinogradConvolutionLayer::validate(input, weights, biases, output, conv_info, ActivationLayerInfo(), fast_math); + status = WinogradConvolutionLayer::validate(input, weights, biases, output, conv_info, + ActivationLayerInfo(), fast_math); break; case ConvolutionMethod::Default: - status = ConvolutionLayer::validate(input, weights, biases, output, conv_info, - WeightsInfo(), Size2D(1, 1), ActivationLayerInfo(), fast_math, num_groups); + status = ConvolutionLayer::validate(input, weights, biases, output, conv_info, WeightsInfo(), Size2D(1, 1), + ActivationLayerInfo(), fast_math, num_groups); break; default: ARM_COMPUTE_RETURN_ERROR_MSG("Unsupported convolution method"); @@ -171,7 +201,8 @@ Status validate_convolution_layer(ConvolutionLayerNode &node) template <typename DepthwiseConvolutionLayer> Status validate_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating DepthwiseConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating DepthwiseConvolutionLayer node with ID : " << node.id() << " and Name: " + << node.name() << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 3); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -187,7 +218,7 @@ Status validate_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node) // Validate function Status status{}; - switch(dwc_algorithm) + switch (dwc_algorithm) { case DepthwiseConvolutionMethod::Default: case DepthwiseConvolutionMethod::Optimized3x3: @@ -199,6 +230,28 @@ Status validate_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node) return status; } +/** Validates a depth to space layer node + * + * @tparam DequantizationLayer Dequantize layer type + * + * @param[in] node Node to validate + * + * @return Status + */ +template <typename DepthToSpaceLayer> +Status validate_depth_to_space_layer(DepthToSpaceLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Validating DetectionOutputLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + arm_compute::ITensorInfo *input = get_backing_tensor_info(node.input(0)); + arm_compute::ITensorInfo *output = get_backing_tensor_info(node.output(0)); + + return DepthToSpaceLayer::validate(input, output, node.block_shape()); +} /** Validates a dequantize layer node * * @tparam DequantizationLayer Dequantize layer type @@ -210,7 +263,8 @@ Status validate_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node) template <typename DequantizationLayer> Status validate_dequantization_layer(DequantizationLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating DetectionOutputLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Validating DetectionOutputLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -231,7 +285,8 @@ Status validate_dequantization_layer(DequantizationLayerNode &node) template <typename DetectionOutputLayer> Status validate_detection_output_layer(DetectionOutputLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating DetectionOutputLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Validating DetectionOutputLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 3); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -255,7 +310,8 @@ Status validate_detection_output_layer(DetectionOutputLayerNode &node) template <typename DetectionPostProcessLayer> Status validate_detection_post_process_layer(DetectionPostProcessLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating DetectionPostProcessLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating DetectionPostProcessLayer node with ID : " << node.id() << " and Name: " + << node.name() << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 3); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 4); @@ -283,7 +339,8 @@ Status validate_detection_post_process_layer(DetectionPostProcessLayerNode &node template <typename GenerateProposalsLayer> Status validate_generate_proposals_layer(GenerateProposalsLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating GenerateProposalsLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Validating GenerateProposalsLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 3); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 3); @@ -299,6 +356,32 @@ Status validate_generate_proposals_layer(GenerateProposalsLayerNode &node) return GenerateProposalsLayer::validate(scores, deltas, anchors, proposals, scores_out, num_valid_proposals, info); } +/** Validates a L2Normalization layer node + * + * @tparam L2Normalization layer type + * + * @param[in] node Node to validate + * + * @return Status + */ +template <typename L2NormalizeLayer> +Status validate_l2_normalize_layer(L2NormalizeLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Validating L2NormalizeLayerNode node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + arm_compute::ITensorInfo *input = detail::get_backing_tensor_info(node.input(0)); + arm_compute::ITensorInfo *output = get_backing_tensor_info(node.output(0)); + int axis = node.axis(); + float epsilon = node.epsilon(); + + // Validate function + return L2NormalizeLayer::validate(input, output, axis, epsilon); +} + /** Validates a NormalizePlanarYUV layer node * * @tparam NormalizePlanarYUVLayer layer type @@ -310,7 +393,8 @@ Status validate_generate_proposals_layer(GenerateProposalsLayerNode &node) template <typename NormalizePlanarYUVLayer> Status validate_normalize_planar_yuv_layer(NormalizePlanarYUVLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating NormalizePlanarYUVLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Validating NormalizePlanarYUVLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 3); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -335,7 +419,8 @@ Status validate_normalize_planar_yuv_layer(NormalizePlanarYUVLayerNode &node) template <typename PadLayer> Status validate_pad_layer(PadLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating PadLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating PadLayer node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -358,14 +443,15 @@ Status validate_pad_layer(PadLayerNode &node) template <typename PermuteLayer> Status validate_permute_layer(PermuteLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating PermuteLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating PermuteLayer node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); // Extract IO and info arm_compute::ITensorInfo *input = get_backing_tensor_info(node.input(0)); arm_compute::ITensorInfo *output = get_backing_tensor_info(node.output(0)); - const PermutationVector &perm = node.permutation_vector(); + const PermutationVector &perm = node.permutation_vector(); return PermuteLayer::validate(input, output, perm); } @@ -381,7 +467,8 @@ Status validate_permute_layer(PermuteLayerNode &node) template <typename PReluLayer> Status validate_prelu_layer(PReluLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating PRelu node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating PRelu node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 2); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -404,7 +491,8 @@ Status validate_prelu_layer(PReluLayerNode &node) template <typename PriorBoxLayer> Status validate_priorbox_layer(PriorBoxLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating PriorBoxLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Validating PriorBoxLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 2); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -428,7 +516,8 @@ Status validate_priorbox_layer(PriorBoxLayerNode &node) template <typename QuantizationLayer> Status validate_quantization_layer(QuantizationLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating QuantizationLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Validating QuantizationLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -440,6 +529,31 @@ Status validate_quantization_layer(QuantizationLayerNode &node) return QuantizationLayer::validate(input, output); } +/** Validates a Reduction operation layer node + * + * @tparam ReductionLayer Reduction layer type + * + * @param[in] node Node to validate + * + * @return Status + */ +template <typename ReductionLayer> +Status validate_reduction_operation_layer(ReductionLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Validating ReductionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + + ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); + + // Extract input and output + arm_compute::ITensorInfo *input = detail::get_backing_tensor_info(node.input(0)); + arm_compute::ITensorInfo *output = get_backing_tensor_info(node.output(0)); + + // Validate function + return ReductionLayer::validate(input, output, node.axis(), node.op(), node.keep_dims()); +} + /** Validates a Reorg layer node * * @tparam ReorgLayer Reorg layer type @@ -451,7 +565,8 @@ Status validate_quantization_layer(QuantizationLayerNode &node) template <typename ReorgLayer> Status validate_reorg_layer(ReorgLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating ReorgLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating ReorgLayer node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -474,7 +589,8 @@ Status validate_reorg_layer(ReorgLayerNode &node) template <typename ReshapeLayer> Status validate_reshape_layer(ReshapeLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating ReshapeLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating ReshapeLayer node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -497,14 +613,15 @@ Status validate_reshape_layer(ReshapeLayerNode &node) template <typename ROIAlignLayer> Status validate_roi_align_layer(ROIAlignLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating ROIAlignLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Validating ROIAlignLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 2); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); // Extract input and output - arm_compute::ITensorInfo *input = detail::get_backing_tensor_info(node.input(0)); - arm_compute::ITensorInfo *rois = detail::get_backing_tensor_info(node.input(1)); - arm_compute::ITensorInfo *output = detail::get_backing_tensor_info(node.output(0)); + arm_compute::ITensorInfo *input = detail::get_backing_tensor_info(node.input(0)); + arm_compute::ITensorInfo *rois = detail::get_backing_tensor_info(node.input(1)); + arm_compute::ITensorInfo *output = detail::get_backing_tensor_info(node.output(0)); const ROIPoolingLayerInfo &pool_info = node.pooling_info(); // Validate function @@ -522,7 +639,8 @@ Status validate_roi_align_layer(ROIAlignLayerNode &node) template <typename SliceLayer> Status validate_slice_layer(SliceLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating Slice node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating Slice node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); @@ -535,53 +653,120 @@ Status validate_slice_layer(SliceLayerNode &node) return SliceLayer::validate(input, output, starts, ends); } -/** Validates a Upsample layer node +/** Validates a Strided Slice layer node * - * @tparam UpsampleLayer Upsample layer type + * @tparam StridedSliceLayer Strided Slice layer function type * * @param[in] node Node to validate * * @return Status */ -template <typename UpsampleLayer> -Status validate_upsample_layer(UpsampleLayerNode &node) +template <typename StridedSliceLayer> +Status validate_strided_slice_layer(StridedSliceLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating UpsampleLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating StridedSlice node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); + // Extract IO and info + arm_compute::ITensorInfo *input = get_backing_tensor_info(node.input(0)); + arm_compute::ITensorInfo *output = get_backing_tensor_info(node.output(0)); + const Coordinates starts = node.starts(); + const Coordinates ends = node.ends(); + const BiStrides strides = node.strides(); + const StridedSliceLayerInfo info = node.strided_slice_info(); + + return StridedSliceLayer::validate(input, output, starts, ends, strides, info.begin_mask(), info.end_mask(), + info.shrink_axis_mask()); +} + +/** Validates a element-wise layer node + * + * @param[in] node Node to validate + * + * @return Status + */ +template <typename EltwiseLayerFunctions> +Status validate_eltwise_Layer(EltwiseLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating EltwiseLayer node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); + ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 2); + ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); + // Extract input and output - arm_compute::ITensorInfo *input = detail::get_backing_tensor_info(node.input(0)); - arm_compute::ITensorInfo *output = get_backing_tensor_info(node.output(0)); + const arm_compute::ITensorInfo *input1 = detail::get_backing_tensor_info(node.input(0)); + const arm_compute::ITensorInfo *input2 = detail::get_backing_tensor_info(node.input(1)); + const arm_compute::ITensorInfo *output = get_backing_tensor_info(node.output(0)); + const EltwiseOperation eltwise_op = node.eltwise_operation(); + const ConvertPolicy convert_policy = node.convert_policy(); + const RoundingPolicy round_policy = node.rounding_policy(); + const ActivationLayerInfo act_info = node.fused_activation(); + const QuantizationInfo quant_info = node.output_quant_info(); // Validate function - return UpsampleLayer::validate(input, output, node.info(), node.upsampling_policy()); + if (eltwise_op == EltwiseOperation::Add) + { + return EltwiseLayerFunctions::ArithmeticAddition::validate(input1, input2, output, convert_policy, act_info); + } + else if (eltwise_op == EltwiseOperation::Sub) + { + return EltwiseLayerFunctions::ArithmeticSubtraction::validate(input1, input2, output, convert_policy, act_info); + } + else if (eltwise_op == EltwiseOperation::Mul) + { + return EltwiseLayerFunctions::PixelWiseMultiplication::validate(input1, input2, output, 1.0f, convert_policy, + round_policy, act_info); + } + else if (eltwise_op == EltwiseOperation::Max) + { + return EltwiseLayerFunctions::ElementwiseMax::validate(input1, input2, output, act_info); + } + else if (eltwise_op == EltwiseOperation::Div) + { + return EltwiseLayerFunctions::ArithmeticDivision::validate(input1, input2, output, act_info); + } + else + { + ARM_COMPUTE_ERROR("Unsupported element-wise operation!"); + } + return Status{}; } -/** Validates a YOLO layer node - * - * @tparam YOLOLayer YOLO layer type +/** Validates a unary element-wise layer node * * @param[in] node Node to validate * * @return Status */ -template <typename YOLOLayer> -Status validate_yolo_layer(YOLOLayerNode &node) +template <typename UnaryEltwiseLayerFunctions> +Status validate_unary_eltwise_layer(UnaryEltwiseLayerNode &node) { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating YOLOLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating EltwiseLayer node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 1); ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); // Extract input and output - arm_compute::ITensorInfo *input = detail::get_backing_tensor_info(node.input(0)); - arm_compute::ITensorInfo *output = get_backing_tensor_info(node.output(0)); + arm_compute::ITensorInfo *input = detail::get_backing_tensor_info(node.input(0)); + arm_compute::ITensorInfo *output = get_backing_tensor_info(node.output(0)); + const UnaryEltwiseOperation eltwise_op = node.eltwise_descriptor().op; // Validate function - return YOLOLayer::validate(input, output, node.activation_info(), node.num_classes()); + if (eltwise_op == UnaryEltwiseOperation::Exp) + { + return UnaryEltwiseLayerFunctions::ExpLayer::validate(input, output); + } + else + { + ARM_COMPUTE_ERROR("Unsupported unary element-wise operation!"); + } + + return Status{}; } } // namespace detail } // namespace backends } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_BACKENDS_DETAIL_VALIDATE_HELPERS_H */ +#endif // ACL_ARM_COMPUTE_GRAPH_BACKENDS_VALIDATEHELPERS_H diff --git a/arm_compute/graph/detail/CrossLayerMemoryManagerHelpers.h b/arm_compute/graph/detail/CrossLayerMemoryManagerHelpers.h index 30c084edf5..1f43ac4197 100644 --- a/arm_compute/graph/detail/CrossLayerMemoryManagerHelpers.h +++ b/arm_compute/graph/detail/CrossLayerMemoryManagerHelpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/detail/ExecutionHelpers.h b/arm_compute/graph/detail/ExecutionHelpers.h index aa1af27052..b1662bb82f 100644 --- a/arm_compute/graph/detail/ExecutionHelpers.h +++ b/arm_compute/graph/detail/ExecutionHelpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/frontend/ILayer.h b/arm_compute/graph/frontend/ILayer.h index 30652a7406..7eb405b739 100644 --- a/arm_compute/graph/frontend/ILayer.h +++ b/arm_compute/graph/frontend/ILayer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/frontend/IStream.h b/arm_compute/graph/frontend/IStream.h index e155bbc725..1831ac0be3 100644 --- a/arm_compute/graph/frontend/IStream.h +++ b/arm_compute/graph/frontend/IStream.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -84,8 +84,8 @@ public: } protected: - StreamHints _hints = {}; /**< Execution and algorithmic hints */ - NodeID _tail_node = { EmptyNodeID }; /**< NodeID pointing to the last(tail) node of the graph */ + StreamHints _hints = {}; /**< Execution and algorithmic hints */ + NodeID _tail_node = {EmptyNodeID}; /**< NodeID pointing to the last(tail) node of the graph */ }; } // namespace frontend } // namespace graph diff --git a/arm_compute/graph/frontend/IStreamOperators.h b/arm_compute/graph/frontend/IStreamOperators.h index 8e2ca41c4e..deaf66daef 100644 --- a/arm_compute/graph/frontend/IStreamOperators.h +++ b/arm_compute/graph/frontend/IStreamOperators.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/frontend/Layers.h b/arm_compute/graph/frontend/Layers.h index 61a6fd47ee..bd321e6f1a 100644 --- a/arm_compute/graph/frontend/Layers.h +++ b/arm_compute/graph/frontend/Layers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -24,13 +24,12 @@ #ifndef ARM_COMPUTE_GRAPH_LAYERS_H #define ARM_COMPUTE_GRAPH_LAYERS_H -#include "arm_compute/graph/GraphBuilder.h" -#include "arm_compute/graph/Types.h" +#include "arm_compute/core/utils/misc/Utility.h" #include "arm_compute/graph/frontend/ILayer.h" #include "arm_compute/graph/frontend/IStream.h" #include "arm_compute/graph/frontend/SubStream.h" - -#include "arm_compute/core/utils/misc/Utility.h" +#include "arm_compute/graph/GraphBuilder.h" +#include "arm_compute/graph/Types.h" #include <memory> #include <string> @@ -50,14 +49,13 @@ public: * @param[in] desc Description of input tensor. * @param[in] accessor Accessor to get input tensor data from. */ - InputLayer(TensorDescriptor desc, ITensorAccessorUPtr accessor) - : _desc(desc), _accessor(std::move(accessor)) + InputLayer(TensorDescriptor desc, ITensorAccessorUPtr accessor) : _desc(desc), _accessor(std::move(accessor)) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; + NodeParams common_params = {name(), s.hints().target_hint}; return GraphBuilder::add_input_node(s.graph(), common_params, _desc, std::move(_accessor)); } @@ -75,14 +73,13 @@ public: * @param[in] desc Description of input tensor. * @param[in] accessor Accessor to get input tensor data from. */ - ConstantLayer(TensorDescriptor desc, ITensorAccessorUPtr accessor) - : _desc(desc), _accessor(std::move(accessor)) + ConstantLayer(TensorDescriptor desc, ITensorAccessorUPtr accessor) : _desc(desc), _accessor(std::move(accessor)) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; + NodeParams common_params = {name(), s.hints().target_hint}; return GraphBuilder::add_const_node(s.graph(), common_params, _desc, std::move(_accessor)); } @@ -107,8 +104,8 @@ public: NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), _connection_idx }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), _connection_idx}; return GraphBuilder::add_output_node(s.graph(), common_params, input, std::move(_accessor)); } @@ -126,18 +123,17 @@ public: * @param[in] act_info Activation information * @param[in] out_quant_info (Optional) Output quantization info */ - ActivationLayer(ActivationLayerInfo act_info, - const QuantizationInfo out_quant_info = QuantizationInfo()) - : _act_info(act_info), - _out_quant_info(std::move(out_quant_info)) + ActivationLayer(ActivationLayerInfo act_info, const QuantizationInfo out_quant_info = QuantizationInfo()) + : _act_info(act_info), _out_quant_info(std::move(out_quant_info)) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; - return GraphBuilder::add_activation_node(s.graph(), common_params, input, _act_info, std::move(_out_quant_info)); + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; + return GraphBuilder::add_activation_node(s.graph(), common_params, input, _act_info, + std::move(_out_quant_info)); } private: @@ -145,6 +141,46 @@ private: const QuantizationInfo _out_quant_info; }; +/** ArgMinMax Layer */ +class ArgMinMaxLayer final : public ILayer +{ +public: + /** Construct an activation layer. + * + * @param[in] op Reduction Operation: min or max + * @param[in] axis Axis to perform reduction along + * @param[in] out_data_type (Optional) Output tensor data type + * @param[in] out_quant_info (Optional) Output quantization info + */ + ArgMinMaxLayer(ReductionOperation op, + unsigned int axis, + DataType out_data_type = DataType::UNKNOWN, + const QuantizationInfo out_quant_info = QuantizationInfo()) + : _op(op), _axis(axis), _out_data_type(out_data_type), _out_quant_info(std::move(out_quant_info)) + { + } + + /** Create layer and add to the given stream. + * + * @param[in] s Stream to add layer to. + * + * @return ID of the created node. + */ + NodeID create_layer(IStream &s) override + { + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; + return GraphBuilder::add_arg_min_max_node(s.graph(), common_params, input, _op, _axis, _out_data_type, + std::move(_out_quant_info)); + } + +private: + ReductionOperation _op; + unsigned int _axis; + DataType _out_data_type; + QuantizationInfo _out_quant_info; +}; + /** Batchnormalization Layer */ class BatchNormalizationLayer final : public ILayer { @@ -162,7 +198,11 @@ public: ITensorAccessorUPtr gamma = nullptr, ITensorAccessorUPtr beta = nullptr, float epsilon = 0.001f) - : _mean(std::move(mean)), _var(std::move(var)), _gamma(std::move(gamma)), _beta(std::move(beta)), _epsilon(epsilon) + : _mean(std::move(mean)), + _var(std::move(var)), + _gamma(std::move(gamma)), + _beta(std::move(beta)), + _epsilon(epsilon) { } @@ -171,10 +211,10 @@ public: ARM_COMPUTE_ERROR_ON(_mean == nullptr); ARM_COMPUTE_ERROR_ON(_var == nullptr); - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; - return GraphBuilder::add_batch_normalization_node(s.graph(), common_params, input, _epsilon, - std::move(_mean), std::move(_var), std::move(_beta), std::move(_gamma)); + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; + return GraphBuilder::add_batch_normalization_node(s.graph(), common_params, input, _epsilon, std::move(_mean), + std::move(_var), std::move(_beta), std::move(_gamma)); } private: @@ -195,7 +235,9 @@ public: * @param[in] sub_stream_deltas Graph sub-stream for the deltas * @param[in] info Contains BoundingBox operation information described in @ref BoundingBoxTransformInfo. */ - BoundingBoxTransformLayer(SubStream &&sub_stream_input, SubStream &&sub_stream_deltas, BoundingBoxTransformInfo info) + BoundingBoxTransformLayer(SubStream &&sub_stream_input, + SubStream &&sub_stream_deltas, + BoundingBoxTransformInfo info) : _ss_input(sub_stream_input), _ss_deltas(sub_stream_deltas), _bbox_info(info) { } @@ -208,9 +250,9 @@ public: */ NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { _ss_input.tail_node(), 0 }; - NodeIdxPair deltas = { _ss_deltas.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {_ss_input.tail_node(), 0}; + NodeIdxPair deltas = {_ss_deltas.tail_node(), 0}; return GraphBuilder::add_bounding_box_transform_node(s.graph(), common_params, input, deltas, _bbox_info); } @@ -228,15 +270,14 @@ public: * * @param[in] num_groups Number of groups */ - ChannelShuffleLayer(unsigned int num_groups) - : _num_groups(num_groups) + ChannelShuffleLayer(unsigned int num_groups) : _num_groups(num_groups) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_channel_shuffle_node(s.graph(), common_params, input, _num_groups); } @@ -255,17 +296,15 @@ public: * @param[in] rest_sub_streams Rest sub-graph branches */ template <typename... Ts> - ConcatLayer(SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&... rest_sub_streams) + ConcatLayer(SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&...rest_sub_streams) : _sub_streams(), _concat_descriptor(DataLayoutDimension::CHANNEL) { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream1))); - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream2))); + _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream1))); + _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream2))); - utility::for_each([&](SubStream && sub_stream) - { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream))); - }, - std::move(rest_sub_streams)...); + utility::for_each([&](SubStream &&sub_stream) + { _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream))); }, + std::move(rest_sub_streams)...); } /** Construct a concatenation layer * @@ -275,33 +314,33 @@ public: * @param[in] rest_sub_streams Rest sub-graph branches */ template <typename... Ts> - ConcatLayer(descriptors::ConcatLayerDescriptor concat_descriptor, SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&... rest_sub_streams) + ConcatLayer(descriptors::ConcatLayerDescriptor concat_descriptor, + SubStream &&sub_stream1, + SubStream &&sub_stream2, + Ts &&...rest_sub_streams) : _sub_streams(), _concat_descriptor(concat_descriptor) { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream1))); - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream2))); + _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream1))); + _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream2))); - utility::for_each([&](SubStream && sub_stream) - { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream))); - }, - std::move(rest_sub_streams)...); + utility::for_each([&](SubStream &&sub_stream) + { _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream))); }, + std::move(rest_sub_streams)...); } /** Construct a concat layer * * @param[in] sub_stream Sub-stream */ template <typename... Ts> - ConcatLayer(SubStream &&sub_stream) - : _sub_streams(), _concat_descriptor(DataLayoutDimension::CHANNEL) + ConcatLayer(SubStream &&sub_stream) : _sub_streams(), _concat_descriptor(DataLayoutDimension::CHANNEL) { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream))); + _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream))); } NodeID create_layer(IStream &s) override { NodeID nid = EmptyNodeID; - NodeParams common_params = { name(), s.hints().target_hint }; - if(_sub_streams.size() == 1 && _sub_streams.at(0) != nullptr) + NodeParams common_params = {name(), s.hints().target_hint}; + if (_sub_streams.size() == 1 && _sub_streams.at(0) != nullptr) { nid = _sub_streams[0]->tail_node(); } @@ -309,14 +348,14 @@ public: { // Collect tail nodes and concatenate std::vector<NodeIdxPair> nodes; - for(auto &ss : _sub_streams) + for (auto &ss : _sub_streams) { - if(ss && (ss->tail_node() != EmptyNodeID)) + if (ss && (ss->tail_node() != EmptyNodeID)) { const auto tail_node = s.graph().node(ss->tail_node()); - if(tail_node != nullptr && tail_node->type() != NodeType::Output) + if (tail_node != nullptr && tail_node->type() != NodeType::Output) { - nodes.push_back({ ss->tail_node(), 0 }); + nodes.push_back({ss->tail_node(), 0}); } } } @@ -369,12 +408,12 @@ public: NodeID create_layer(IStream &s) override { - NodeIdxPair input = { s.tail_node(), 0 }; - NodeParams common_params = { name(), s.hints().target_hint }; - return GraphBuilder::add_convolution_node(s.graph(), common_params, input, - Size2D(_conv_width, _conv_height), _ofm, _conv_info, _num_groups, - s.hints().convolution_method_hint, s.hints().fast_math_hint, - std::move(_weights), std::move(_bias), std::move(_weights_quant_info), std::move(_out_quant_info)); + NodeIdxPair input = {s.tail_node(), 0}; + NodeParams common_params = {name(), s.hints().target_hint}; + return GraphBuilder::add_convolution_node(s.graph(), common_params, input, Size2D(_conv_width, _conv_height), + _ofm, _conv_info, _num_groups, s.hints().convolution_method_hint, + s.hints().fast_math_hint, std::move(_weights), std::move(_bias), + std::move(_weights_quant_info), std::move(_out_quant_info)); } private: @@ -419,11 +458,10 @@ public: NodeID create_layer(IStream &s) override { - NodeIdxPair input = { s.tail_node(), 0 }; - NodeParams common_params = { name(), s.hints().target_hint }; - return GraphBuilder::add_deconvolution_node(s.graph(), common_params, input, - Size2D(_conv_width, _conv_height), _ofm, _deconv_info, - std::move(_weights), std::move(_bias)); + NodeIdxPair input = {s.tail_node(), 0}; + NodeParams common_params = {name(), s.hints().target_hint}; + return GraphBuilder::add_deconvolution_node(s.graph(), common_params, input, Size2D(_conv_width, _conv_height), + _ofm, _deconv_info, std::move(_weights), std::move(_bias)); } private: @@ -471,12 +509,12 @@ public: NodeID create_layer(IStream &s) override { - NodeIdxPair input = { s.tail_node(), 0 }; - NodeParams common_params = { name(), s.hints().target_hint }; - return GraphBuilder::add_depthwise_convolution_node(s.graph(), common_params, - input, Size2D(_conv_width, _conv_height), _conv_info, _depth_multiplier, - s.hints().depthwise_convolution_method_hint, - std::move(_weights), std::move(_bias), std::move(_weights_quant_info), std::move(_out_quant_info)); + NodeIdxPair input = {s.tail_node(), 0}; + NodeParams common_params = {name(), s.hints().target_hint}; + return GraphBuilder::add_depthwise_convolution_node( + s.graph(), common_params, input, Size2D(_conv_width, _conv_height), _conv_info, _depth_multiplier, + s.hints().depthwise_convolution_method_hint, std::move(_weights), std::move(_bias), + std::move(_weights_quant_info), std::move(_out_quant_info)); } private: @@ -489,6 +527,30 @@ private: const QuantizationInfo _weights_quant_info; const QuantizationInfo _out_quant_info; }; + +/** DepthToSpace Layer */ +class DepthToSpaceLayer final : public ILayer +{ +public: + /** Construct an DepthToSpace layer. + * + * @param[in] block_shape Block size to rearranged + */ + DepthToSpaceLayer(int32_t block_shape) : _block_shape(block_shape) + { + } + + NodeID create_layer(IStream &s) override + { + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; + return GraphBuilder::add_depth_to_space_node(s.graph(), common_params, input, _block_shape); + } + +private: + int32_t _block_shape; +}; + /** Dequantization Layer */ class DequantizationLayer final : public ILayer { @@ -502,8 +564,8 @@ public: NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_dequantization_node(s.graph(), common_params, input); } }; @@ -518,18 +580,21 @@ public: * @param[in] sub_stream_prior PriorBox graph sub-stream. * @param[in] detect_info DetectionOutput parameters. */ - DetectionOutputLayer(SubStream &&sub_stream_conf, SubStream &&sub_stream_prior, const DetectionOutputLayerInfo &detect_info) + DetectionOutputLayer(SubStream &&sub_stream_conf, + SubStream &&sub_stream_prior, + const DetectionOutputLayerInfo &detect_info) : _ss_conf(std::move(sub_stream_conf)), _ss_prior(std::move(sub_stream_prior)), _detect_info(detect_info) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input_loc = { s.tail_node(), 0 }; - NodeIdxPair input_conf = { _ss_conf.tail_node(), 0 }; - NodeIdxPair input_priorbox = { _ss_prior.tail_node(), 0 }; - return GraphBuilder::add_detection_output_node(s.graph(), common_params, input_loc, input_conf, input_priorbox, _detect_info); + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input_loc = {s.tail_node(), 0}; + NodeIdxPair input_conf = {_ss_conf.tail_node(), 0}; + NodeIdxPair input_priorbox = {_ss_prior.tail_node(), 0}; + return GraphBuilder::add_detection_output_node(s.graph(), common_params, input_loc, input_conf, input_priorbox, + _detect_info); } private: @@ -548,9 +613,14 @@ public: * @param[in] anchors Accessor to get anchors tensor data from. * @param[in] out_quant_info (Optional) Output quantization info */ - DetectionPostProcessLayer(SubStream &&sub_stream_class_prediction, DetectionPostProcessLayerInfo detect_info, ITensorAccessorUPtr anchors, - const QuantizationInfo out_quant_info = QuantizationInfo()) - : _sub_stream_class_prediction(std::move(sub_stream_class_prediction)), _detect_info(detect_info), _anchors(std::move(anchors)), _out_quant_info(std::move(out_quant_info)) + DetectionPostProcessLayer(SubStream &&sub_stream_class_prediction, + DetectionPostProcessLayerInfo detect_info, + ITensorAccessorUPtr anchors, + const QuantizationInfo out_quant_info = QuantizationInfo()) + : _sub_stream_class_prediction(std::move(sub_stream_class_prediction)), + _detect_info(detect_info), + _anchors(std::move(anchors)), + _out_quant_info(std::move(out_quant_info)) { } @@ -558,10 +628,12 @@ public: { ARM_COMPUTE_ERROR_ON(_anchors == nullptr); - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input_box_encoding = { s.tail_node(), 0 }; - NodeIdxPair input_class_prediction = { _sub_stream_class_prediction.tail_node(), 0 }; - return GraphBuilder::add_detection_post_process_node(s.graph(), common_params, input_box_encoding, input_class_prediction, _detect_info, std::move(_anchors), std::move(_out_quant_info)); + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input_box_encoding = {s.tail_node(), 0}; + NodeIdxPair input_class_prediction = {_sub_stream_class_prediction.tail_node(), 0}; + return GraphBuilder::add_detection_post_process_node(s.graph(), common_params, input_box_encoding, + input_class_prediction, _detect_info, std::move(_anchors), + std::move(_out_quant_info)); } private: @@ -578,15 +650,14 @@ public: * * @param[in] shape Output shape */ - DummyLayer(TensorShape shape) - : _shape(shape) + DummyLayer(TensorShape shape) : _shape(shape) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_dummy_node(s.graph(), common_params, input, _shape); } @@ -610,9 +681,9 @@ public: NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input0 = { _ss0.tail_node(), 0 }; - NodeIdxPair input1 = { _ss1.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input0 = {_ss0.tail_node(), 0}; + NodeIdxPair input1 = {_ss1.tail_node(), 0}; return GraphBuilder::add_elementwise_node(s.graph(), common_params, input0, input1, _op); } @@ -633,8 +704,8 @@ public: NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_flatten_node(s.graph(), common_params, input); } }; @@ -687,8 +758,8 @@ public: : _num_outputs(num_outputs), _weights(nullptr), _bias(nullptr), - _weights_ss(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream_weights))), - _bias_ss(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream_bias))), + _weights_ss(std::make_unique<SubStream>(std::move(sub_stream_weights))), + _bias_ss(std::make_unique<SubStream>(std::move(sub_stream_bias))), _fc_info(fc_info), _weights_quant_info(std::move(weights_quant_info)), _out_quant_info(std::move(out_quant_info)) @@ -703,13 +774,13 @@ public: */ NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; - if(_weights != nullptr) + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; + if (_weights != nullptr) { - return GraphBuilder::add_fully_connected_layer(s.graph(), common_params, input, _num_outputs, - std::move(_weights), std::move(_bias), _fc_info, - std::move(_weights_quant_info), std::move(_out_quant_info)); + return GraphBuilder::add_fully_connected_layer( + s.graph(), common_params, input, _num_outputs, std::move(_weights), std::move(_bias), _fc_info, + std::move(_weights_quant_info), std::move(_out_quant_info), s.hints().fast_math_hint); } else { @@ -718,7 +789,7 @@ public: NodeID bias_nid = (_bias_ss == nullptr) ? EmptyNodeID : _bias_ss->tail_node(); return GraphBuilder::add_fully_connected_layer(s.graph(), common_params, input, _num_outputs, _weights_ss->tail_node(), bias_nid, _fc_info, - std::move(_out_quant_info)); + std::move(_out_quant_info), s.hints().fast_math_hint); } } @@ -744,8 +815,14 @@ public: * @param[in] ss_anchors Graph sub-stream for the anchors. * @param[in] info Generate Proposals operation information. */ - GenerateProposalsLayer(SubStream &&ss_scores, SubStream &&ss_deltas, SubStream &&ss_anchors, GenerateProposalsInfo info) - : _ss_scores(std::move(ss_scores)), _ss_deltas(std::move(ss_deltas)), _ss_anchors(std::move(ss_anchors)), _info(info) + GenerateProposalsLayer(SubStream &&ss_scores, + SubStream &&ss_deltas, + SubStream &&ss_anchors, + GenerateProposalsInfo info) + : _ss_scores(std::move(ss_scores)), + _ss_deltas(std::move(ss_deltas)), + _ss_anchors(std::move(ss_anchors)), + _info(info) { } @@ -757,10 +834,10 @@ public: */ NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair scores = { _ss_scores.tail_node(), 0 }; - NodeIdxPair deltas = { _ss_deltas.tail_node(), 0 }; - NodeIdxPair anchors = { _ss_anchors.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair scores = {_ss_scores.tail_node(), 0}; + NodeIdxPair deltas = {_ss_deltas.tail_node(), 0}; + NodeIdxPair anchors = {_ss_anchors.tail_node(), 0}; return GraphBuilder::add_generate_proposals_node(s.graph(), common_params, scores, deltas, anchors, _info); } @@ -771,6 +848,31 @@ private: GenerateProposalsInfo _info; }; +/** L2 Normalize Layer */ +class L2NormalizeLayer final : public ILayer +{ +public: + /** Construct a L2 Normalize layer. + * + * @param[in] axis Axis to perform normalization on + * @param[in] epsilon Lower bound value for the normalization + */ + L2NormalizeLayer(int axis, float epsilon) : _axis(axis), _epsilon(epsilon) + { + } + + NodeID create_layer(IStream &s) override + { + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; + return GraphBuilder::add_l2_normalize_node(s.graph(), common_params, input, _axis, _epsilon); + } + +private: + int _axis; + float _epsilon; +}; + /** Normalization Layer */ class NormalizationLayer final : public ILayer { @@ -779,15 +881,14 @@ public: * * @param[in] norm_info Normalization information. */ - NormalizationLayer(NormalizationLayerInfo norm_info) - : _norm_info(norm_info) + NormalizationLayer(NormalizationLayerInfo norm_info) : _norm_info(norm_info) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_normalization_node(s.graph(), common_params, input, _norm_info); } @@ -804,8 +905,7 @@ public: * @param[in] mean Accessor to get mean tensor data from. * @param[in] std Accessor to get std tensor data from. */ - NormalizePlanarYUVLayer(ITensorAccessorUPtr mean, - ITensorAccessorUPtr std) + NormalizePlanarYUVLayer(ITensorAccessorUPtr mean, ITensorAccessorUPtr std) : _mean(std::move(mean)), _std(std::move(std)) { } @@ -815,10 +915,10 @@ public: ARM_COMPUTE_ERROR_ON(_mean == nullptr); ARM_COMPUTE_ERROR_ON(_std == nullptr); - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; - return GraphBuilder::add_normalize_planar_yuv_node(s.graph(), common_params, input, - std::move(_mean), std::move(_std)); + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; + return GraphBuilder::add_normalize_planar_yuv_node(s.graph(), common_params, input, std::move(_mean), + std::move(_std)); } private: @@ -836,15 +936,14 @@ public: * specifies the front and the end padding in the i-th dimension. * @param[in] pad_value Padding value to use. Defaults to 0. */ - PadLayer(PaddingList padding, PixelValue pad_value = PixelValue()) - : _padding(padding), _pad_value(pad_value) + PadLayer(PaddingList padding, PixelValue pad_value = PixelValue()) : _padding(padding), _pad_value(pad_value) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_pad_node(s.graph(), common_params, input, _padding, _pad_value); } @@ -863,15 +962,14 @@ public: * @param[in] layout (Optional) Data layout to assign to permuted tensor. * If UNKNOWN then the input's layout will be used. */ - PermuteLayer(PermutationVector perm, DataLayout layout = DataLayout::UNKNOWN) - : _perm(perm), _layout(layout) + PermuteLayer(PermutationVector perm, DataLayout layout = DataLayout::UNKNOWN) : _perm(perm), _layout(layout) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_permute_node(s.graph(), common_params, input, _perm, _layout); } @@ -888,15 +986,14 @@ public: * * @param[in] pool_info Pooling information. */ - PoolingLayer(PoolingLayerInfo pool_info) - : _pool_info(pool_info) + PoolingLayer(PoolingLayerInfo pool_info) : _pool_info(pool_info) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_pooling_node(s.graph(), common_params, input, _pool_info); } @@ -920,9 +1017,9 @@ public: NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { _ss0.tail_node(), 0 }; - NodeIdxPair alpha = { _ss1.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {_ss0.tail_node(), 0}; + NodeIdxPair alpha = {_ss1.tail_node(), 0}; return GraphBuilder::add_prelu_node(s.graph(), common_params, input, alpha); } @@ -971,15 +1068,17 @@ public: * @param[in] format_info (Optional) Format info. * @param[in] transform (Optional) Input transform function. */ - PrintLayer(std::ostream &stream, const IOFormatInfo &format_info = IOFormatInfo(), const std::function<ITensor *(ITensor *)> transform = nullptr) + PrintLayer(std::ostream &stream, + const IOFormatInfo &format_info = IOFormatInfo(), + const std::function<ITensor *(ITensor *)> transform = nullptr) : _stream(stream), _format_info(format_info), _transform(transform) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_print_node(s.graph(), common_params, input, _stream, _format_info, _transform); } @@ -1005,9 +1104,9 @@ public: NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input0 = { s.tail_node(), 0 }; - NodeIdxPair input1 = { _ss.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input0 = {s.tail_node(), 0}; + NodeIdxPair input1 = {_ss.tail_node(), 0}; return GraphBuilder::add_priorbox_node(s.graph(), common_params, input0, input1, _prior_info); } @@ -1024,15 +1123,14 @@ public: * * @param[in] out_quant_info Output tensor quantization info */ - QuantizationLayer(QuantizationInfo out_quant_info) - : _out_quant_info(out_quant_info) + QuantizationLayer(QuantizationInfo out_quant_info) : _out_quant_info(out_quant_info) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_quantization_node(s.graph(), common_params, input, _out_quant_info); } @@ -1040,6 +1138,34 @@ private: QuantizationInfo _out_quant_info; }; +/** Reduction Layer */ +class ReductionLayer final : public ILayer +{ +public: + /** Construct a reduction layer. + * + * @param[in] op Reduction operation + * @param[in] axis Reduction axis + * @param[in] keep_dims (Optional) Whether to keep the reduced dimension after the operation. Defaults to true. + */ + ReductionLayer(ReductionOperation op, unsigned int axis, bool keep_dims) + : _op(op), _axis(axis), _keep_dims(keep_dims) + { + } + + NodeID create_layer(IStream &s) override + { + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; + return GraphBuilder::add_reduction_operation_node(s.graph(), common_params, input, _op, _axis, _keep_dims); + } + +private: + ReductionOperation _op; + unsigned int _axis; + bool _keep_dims; +}; + /** Reorg Layer */ class ReorgLayer final : public ILayer { @@ -1049,15 +1175,14 @@ public: * @param[in] stride Stride value to use for reorganizing the values in the output tensor. * It defines the spatial distance between 2 consecutive pixels in the x and y direction */ - ReorgLayer(int stride) - : _stride(stride) + ReorgLayer(int stride) : _stride(stride) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_reorg_node(s.graph(), common_params, input, _stride); } @@ -1073,15 +1198,14 @@ public: * * @param[in] shape Target shape. */ - ReshapeLayer(TensorShape shape) - : _shape(shape) + ReshapeLayer(TensorShape shape) : _shape(shape) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_reshape_node(s.graph(), common_params, input, _shape); } @@ -1100,8 +1224,8 @@ public: NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_resize_node(s.graph(), common_params, input, _policy, _width_scale, _height_scale); } @@ -1133,9 +1257,9 @@ public: NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { _ss_input.tail_node(), 0 }; - NodeIdxPair rois = { _ss_rois.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {_ss_input.tail_node(), 0}; + NodeIdxPair rois = {_ss_rois.tail_node(), 0}; return GraphBuilder::add_roi_align_node(s.graph(), common_params, input, rois, _pool_info); } @@ -1154,16 +1278,15 @@ public: * @param[in] mul_w Accessor to get mul weight from. * @param[in] add_w Accessor to get add weight from. */ - ScaleLayer(ITensorAccessorUPtr mul_w, - ITensorAccessorUPtr add_w) + ScaleLayer(ITensorAccessorUPtr mul_w, ITensorAccessorUPtr add_w) : _mul_w(std::move(mul_w)), _add_w(std::move(add_w)) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_scale_layer(s.graph(), common_params, input, std::move(_mul_w), std::move(_add_w)); } @@ -1181,15 +1304,14 @@ public: * @param[in] starts The starts of the dimensions of the input tensor to be sliced. The length must be of rank(input). * @param[in] ends The ends of the dimensions of the input tensor to be sliced. The length must be of rank(input). */ - SliceLayer(Coordinates &starts, Coordinates &ends) - : _starts(starts), _ends(ends) + SliceLayer(Coordinates &starts, Coordinates &ends) : _starts(starts), _ends(ends) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_slice_node(s.graph(), common_params, input, _starts, _ends); } @@ -1206,15 +1328,14 @@ public: * * @param[in] beta (Optional) Beta value. Default 1.0. */ - SoftmaxLayer(float beta = 1.0f) - : _beta(beta) + SoftmaxLayer(float beta = 1.0f) : _beta(beta) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; return GraphBuilder::add_softmax_node(s.graph(), common_params, input, _beta); } @@ -1233,17 +1354,14 @@ public: * @param[in] rest_sub_streams Rest sub-graph branches */ template <typename... Ts> - StackLayer(SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&... rest_sub_streams) - : _sub_streams(), _axis(0) + StackLayer(SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&...rest_sub_streams) : _sub_streams(), _axis(0) { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream1))); - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream2))); + _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream1))); + _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream2))); - utility::for_each([&](SubStream && sub_stream) - { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream))); - }, - std::move(rest_sub_streams)...); + utility::for_each([&](SubStream &&sub_stream) + { _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream))); }, + std::move(rest_sub_streams)...); } /** Construct a concatenation layer * @@ -1253,33 +1371,30 @@ public: * @param[in] rest_sub_streams Rest sub-graph branches */ template <typename... Ts> - StackLayer(int axis, SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&... rest_sub_streams) + StackLayer(int axis, SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&...rest_sub_streams) : _sub_streams(), _axis(axis) { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream1))); - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream2))); + _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream1))); + _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream2))); - utility::for_each([&](SubStream && sub_stream) - { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream))); - }, - std::move(rest_sub_streams)...); + utility::for_each([&](SubStream &&sub_stream) + { _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream))); }, + std::move(rest_sub_streams)...); } /** Construct a concat layer * * @param[in] sub_stream Sub-stream */ template <typename... Ts> - StackLayer(SubStream &&sub_stream) - : _sub_streams(), _axis(0) + StackLayer(SubStream &&sub_stream) : _sub_streams(), _axis(0) { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream))); + _sub_streams.push_back(std::make_unique<SubStream>(std::move(sub_stream))); } NodeID create_layer(IStream &s) override { NodeID nid = EmptyNodeID; - NodeParams common_params = { name(), s.hints().target_hint }; - if(_sub_streams.size() == 1 && _sub_streams.at(0) != nullptr) + NodeParams common_params = {name(), s.hints().target_hint}; + if (_sub_streams.size() == 1 && _sub_streams.at(0) != nullptr) { nid = _sub_streams[0]->tail_node(); } @@ -1287,14 +1402,14 @@ public: { // Collect tail nodes and stack std::vector<NodeIdxPair> nodes; - for(auto &ss : _sub_streams) + for (auto &ss : _sub_streams) { - if(ss && (ss->tail_node() != EmptyNodeID)) + if (ss && (ss->tail_node() != EmptyNodeID)) { const auto tail_node = s.graph().node(ss->tail_node()); - if(tail_node != nullptr && tail_node->type() != NodeType::Output) + if (tail_node != nullptr && tail_node->type() != NodeType::Output) { - nodes.push_back({ ss->tail_node(), 0 }); + nodes.push_back({ss->tail_node(), 0}); } } } @@ -1308,30 +1423,37 @@ private: int _axis; }; -/** Upsample Layer */ -class UpsampleLayer final : public ILayer +/** StridedSlice Layer */ +class StridedSliceLayer final : public ILayer { public: - /** Construct a Upsample layer. + /** Construct a strided slice layer. * - * @param[in] info Stride info - * @param[in] upsampling_policy Upsampling policy + * @param[in] starts The starts of the dimensions of the input tensor to be sliced. The length must be of rank(input). + * @param[in] ends The ends of the dimensions of the input tensor to be sliced. The length must be of rank(input). + * @param[in] strides The strides of the dimensions of the input tensor to be sliced. The length must be of rank(input). + * @param[in] strided_slice_info Contains masks for the starts, ends and strides */ - UpsampleLayer(Size2D info, InterpolationPolicy upsampling_policy) - : _info(info), _upsampling_policy(upsampling_policy) + StridedSliceLayer(Coordinates &starts, + Coordinates &ends, + BiStrides &strides, + StridedSliceLayerInfo strided_slice_info) + : _starts(starts), _ends(ends), _strides(strides), _info(strided_slice_info) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; - return GraphBuilder::add_upsample_node(s.graph(), common_params, input, _info, _upsampling_policy); + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; + return GraphBuilder::add_strided_slice_node(s.graph(), common_params, input, _starts, _ends, _strides, _info); } private: - Size2D _info; - InterpolationPolicy _upsampling_policy; + Coordinates _starts; + Coordinates _ends; + BiStrides _strides; + StridedSliceLayerInfo _info; }; /** YOLO Layer */ @@ -1340,24 +1462,21 @@ class YOLOLayer final : public ILayer public: /** Construct a YOLO layer. * - * @param[in] act_info Activation info - * @param[in] num_classes Number of classes to activate + * @param[in] act_info Activation info */ - YOLOLayer(ActivationLayerInfo act_info, int32_t num_classes) - : _act_info(act_info), _num_classes(num_classes) + YOLOLayer(ActivationLayerInfo act_info) : _act_info(act_info) { } NodeID create_layer(IStream &s) override { - NodeParams common_params = { name(), s.hints().target_hint }; - NodeIdxPair input = { s.tail_node(), 0 }; - return GraphBuilder::add_yolo_node(s.graph(), common_params, input, _act_info, _num_classes); + NodeParams common_params = {name(), s.hints().target_hint}; + NodeIdxPair input = {s.tail_node(), 0}; + return GraphBuilder::add_yolo_node(s.graph(), common_params, input, _act_info); } private: ActivationLayerInfo _act_info; - int32_t _num_classes; }; } // namespace frontend } // namespace graph diff --git a/arm_compute/graph/frontend/Stream.h b/arm_compute/graph/frontend/Stream.h index b52274eeae..7e760b6373 100644 --- a/arm_compute/graph/frontend/Stream.h +++ b/arm_compute/graph/frontend/Stream.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -27,7 +27,6 @@ #include "arm_compute/graph/frontend/IStream.h" #include "arm_compute/graph/frontend/IStreamOperators.h" #include "arm_compute/graph/frontend/Types.h" - #include "arm_compute/graph/Graph.h" #include "arm_compute/graph/GraphContext.h" #include "arm_compute/graph/GraphManager.h" @@ -65,7 +64,7 @@ public: void run(); // Inherited overridden methods - void add_layer(ILayer &layer) override; + void add_layer(ILayer &layer) override; Graph &graph() override; const Graph &graph() const override; diff --git a/arm_compute/graph/frontend/SubStream.h b/arm_compute/graph/frontend/SubStream.h index 3df737997e..c54317c52b 100644 --- a/arm_compute/graph/frontend/SubStream.h +++ b/arm_compute/graph/frontend/SubStream.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -54,7 +54,7 @@ public: SubStream(IStream &s); // Inherited overridden methods - void add_layer(ILayer &layer) override; + void add_layer(ILayer &layer) override; Graph &graph() override; const Graph &graph() const override; diff --git a/arm_compute/graph/frontend/Types.h b/arm_compute/graph/frontend/Types.h index 741412d8f2..42b28b3cd2 100644 --- a/arm_compute/graph/frontend/Types.h +++ b/arm_compute/graph/frontend/Types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -33,39 +33,40 @@ namespace graph namespace frontend { // Import types for graph -using graph::DataType; using graph::DataLayout; using graph::DataLayoutDimension; -using graph::TensorShape; +using graph::DataType; using graph::PermutationVector; +using graph::TensorShape; using graph::ActivationLayerInfo; +using graph::ConvolutionMethod; +using graph::DepthwiseConvolutionMethod; +using graph::DimensionRoundingType; using graph::EltwiseOperation; +using graph::FastMathHint; using graph::FullyConnectedLayerInfo; +using graph::GraphConfig; +using graph::InterpolationPolicy; using graph::NormalizationLayerInfo; using graph::NormType; using graph::PadStrideInfo; using graph::PoolingLayerInfo; using graph::PoolingType; +using graph::Size2D; using graph::Target; -using graph::ConvolutionMethod; -using graph::FastMathHint; -using graph::DepthwiseConvolutionMethod; using graph::TensorDescriptor; -using graph::DimensionRoundingType; -using graph::GraphConfig; -using graph::InterpolationPolicy; -using graph::Size2D; /** Hints that can be passed to the stream to expose parameterization */ struct StreamHints { - Target target_hint = { Target::UNSPECIFIED }; /**< Target execution hint */ - ConvolutionMethod convolution_method_hint = { ConvolutionMethod::Default }; /**< Convolution method hint */ - DepthwiseConvolutionMethod depthwise_convolution_method_hint = { DepthwiseConvolutionMethod::Default }; /**< Depthwise Convolution method hint */ - FastMathHint fast_math_hint = { FastMathHint::Disabled }; /**< Fast math hint */ + Target target_hint = {Target::UNSPECIFIED}; /**< Target execution hint */ + ConvolutionMethod convolution_method_hint = {ConvolutionMethod::Default}; /**< Convolution method hint */ + DepthwiseConvolutionMethod depthwise_convolution_method_hint = { + DepthwiseConvolutionMethod::Default}; /**< Depthwise Convolution method hint */ + FastMathHint fast_math_hint = {FastMathHint::Disabled}; /**< Fast math hint */ }; } // namespace frontend } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_STREAM_TYPES_H */
\ No newline at end of file +#endif /* ARM_COMPUTE_GRAPH_STREAM_TYPES_H */ diff --git a/arm_compute/graph/mutators/DepthConcatSubTensorMutator.h b/arm_compute/graph/mutators/DepthConcatSubTensorMutator.h index 14a427ba7c..61d8854a61 100644 --- a/arm_compute/graph/mutators/DepthConcatSubTensorMutator.h +++ b/arm_compute/graph/mutators/DepthConcatSubTensorMutator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -40,7 +40,7 @@ public: // Inherited methods overridden virtual void mutate(Graph &g) override; MutationType type() const override; - const char *name() override; + const char *name() override; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/mutators/GraphMutators.h b/arm_compute/graph/mutators/GraphMutators.h index 6ae06990a4..155b3320c2 100644 --- a/arm_compute/graph/mutators/GraphMutators.h +++ b/arm_compute/graph/mutators/GraphMutators.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * diff --git a/arm_compute/graph/mutators/GroupedConvolutionMutator.h b/arm_compute/graph/mutators/GroupedConvolutionMutator.h index 01c9d0ee2c..3ed8d786fc 100644 --- a/arm_compute/graph/mutators/GroupedConvolutionMutator.h +++ b/arm_compute/graph/mutators/GroupedConvolutionMutator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -40,7 +40,7 @@ public: // Inherited methods overridden virtual void mutate(Graph &g) override; MutationType type() const override; - const char *name() override; + const char *name() override; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/mutators/InPlaceOperationMutator.h b/arm_compute/graph/mutators/InPlaceOperationMutator.h index 7932b6245c..86f62f1994 100644 --- a/arm_compute/graph/mutators/InPlaceOperationMutator.h +++ b/arm_compute/graph/mutators/InPlaceOperationMutator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -37,7 +37,7 @@ public: // Inherited methods overridden virtual void mutate(Graph &g) override; MutationType type() const override; - const char *name() override; + const char *name() override; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/mutators/NodeExecutionMethodMutator.h b/arm_compute/graph/mutators/NodeExecutionMethodMutator.h index 3de940654b..505d4ab300 100644 --- a/arm_compute/graph/mutators/NodeExecutionMethodMutator.h +++ b/arm_compute/graph/mutators/NodeExecutionMethodMutator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -42,7 +42,7 @@ public: // Inherited methods overridden virtual void mutate(Graph &g) override; MutationType type() const override; - const char *name() override; + const char *name() override; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/mutators/NodeFusionMutator.h b/arm_compute/graph/mutators/NodeFusionMutator.h index b99ee79f94..9d2d44f436 100644 --- a/arm_compute/graph/mutators/NodeFusionMutator.h +++ b/arm_compute/graph/mutators/NodeFusionMutator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -38,7 +38,7 @@ public: // Inherited methods overridden virtual void mutate(Graph &g) override; MutationType type() const override; - const char *name() override; + const char *name() override; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/mutators/SplitLayerSubTensorMutator.h b/arm_compute/graph/mutators/SplitLayerSubTensorMutator.h index c9747fd889..ab9746a29b 100644 --- a/arm_compute/graph/mutators/SplitLayerSubTensorMutator.h +++ b/arm_compute/graph/mutators/SplitLayerSubTensorMutator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -40,7 +40,7 @@ public: // Inherited methods overridden virtual void mutate(Graph &g) override; MutationType type() const override; - const char *name() override; + const char *name() override; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/mutators/SyntheticDataTypeMutator.h b/arm_compute/graph/mutators/SyntheticDataTypeMutator.h index 74f4b56acd..ce8af0a1d7 100644 --- a/arm_compute/graph/mutators/SyntheticDataTypeMutator.h +++ b/arm_compute/graph/mutators/SyntheticDataTypeMutator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited. + * Copyright (c) 2019-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -35,10 +35,15 @@ namespace graph class SyntheticDataTypeMutator final : public IGraphMutator { public: + // Constructor + SyntheticDataTypeMutator(DataType mutate_type = DataType::QASYMM8); // Inherited methods overridden virtual void mutate(Graph &g) override; MutationType type() const override; - const char *name() override; + const char *name() override; + +private: + DataType _mutate_type; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/nodes/ActivationLayerNode.h b/arm_compute/graph/nodes/ActivationLayerNode.h index 975bc8efb1..fe5f273db5 100644 --- a/arm_compute/graph/nodes/ActivationLayerNode.h +++ b/arm_compute/graph/nodes/ActivationLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -39,8 +39,7 @@ public: * @param[in] info Activation Layer information * @param[in] out_quant_info (Optional) Output quantization info */ - ActivationLayerNode(ActivationLayerInfo info, - QuantizationInfo out_quant_info = QuantizationInfo()); + ActivationLayerNode(ActivationLayerInfo info, QuantizationInfo out_quant_info = QuantizationInfo()); /** Activation metadata accessor * * @return The activation info of the layer @@ -51,7 +50,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; public: static constexpr NodeType node_type = NodeType::ActivationLayer; diff --git a/arm_compute/graph/nodes/ArgMinMaxLayerNode.h b/arm_compute/graph/nodes/ArgMinMaxLayerNode.h new file mode 100644 index 0000000000..65fbc36db6 --- /dev/null +++ b/arm_compute/graph/nodes/ArgMinMaxLayerNode.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef ARM_COMPUTE_GRAPH_ARGMINMAX_LAYER_NODE_H +#define ARM_COMPUTE_GRAPH_ARGMINMAX_LAYER_NODE_H + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Arg Min/Max Layer node */ +class ArgMinMaxLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] op Operation to perform: min or max + * @param[in] axis Axis along which to reduce. Supported reduction axis : 0,1,2,3 + * @param[in] out_data_type (Optional) Output data type + * @param[in] out_quant_info (Optional) Output quantization info + */ + ArgMinMaxLayerNode(ReductionOperation op, + unsigned int axis, + DataType out_data_type = DataType::UNKNOWN, + QuantizationInfo out_quant_info = QuantizationInfo()); + /** Operator accessor + * + * @return The operator the layer performs: min or max + */ + ReductionOperation reduction_operation() const; + /** Axis accessor + * + * @return The axis along which the reduction is operating + */ + unsigned int axis() const; + /** Output data type accessor + * + * @return The output data type + */ + DataType out_data_type() const; + + // Inherited overridden methods: + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; + +public: + static constexpr NodeType node_type = NodeType::ArgMinMaxLayer; + +private: + ReductionOperation _op; + unsigned int _axis; + DataType _out_data_type; + QuantizationInfo _out_quant_info; +}; +} // namespace graph +} // namespace arm_compute +#endif /* ARM_COMPUTE_GRAPH_ARGMINMAX_LAYER_NODE_H */ diff --git a/arm_compute/graph/nodes/BatchNormalizationLayerNode.h b/arm_compute/graph/nodes/BatchNormalizationLayerNode.h index b50b9550f6..8583ed87eb 100644 --- a/arm_compute/graph/nodes/BatchNormalizationLayerNode.h +++ b/arm_compute/graph/nodes/BatchNormalizationLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -60,7 +60,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; public: static constexpr NodeType node_type = NodeType::BatchNormalizationLayer; diff --git a/arm_compute/graph/nodes/BoundingBoxTransformLayerNode.h b/arm_compute/graph/nodes/BoundingBoxTransformLayerNode.h index 062054ef47..96c2544065 100644 --- a/arm_compute/graph/nodes/BoundingBoxTransformLayerNode.h +++ b/arm_compute/graph/nodes/BoundingBoxTransformLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -50,7 +50,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: BoundingBoxTransformInfo _bbox_info; diff --git a/arm_compute/graph/nodes/ChannelShuffleLayerNode.h b/arm_compute/graph/nodes/ChannelShuffleLayerNode.h index 830efb906a..d296a2dcc3 100644 --- a/arm_compute/graph/nodes/ChannelShuffleLayerNode.h +++ b/arm_compute/graph/nodes/ChannelShuffleLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -49,7 +49,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: unsigned int _num_groups; diff --git a/arm_compute/graph/nodes/ConcatenateLayerNode.h b/arm_compute/graph/nodes/ConcatenateLayerNode.h index 77ca6f6770..13398b1a61 100644 --- a/arm_compute/graph/nodes/ConcatenateLayerNode.h +++ b/arm_compute/graph/nodes/ConcatenateLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -47,7 +47,8 @@ public: * * @return Expected output descriptor */ - static TensorDescriptor compute_output_descriptor(const std::vector<TensorDescriptor> &input_descriptors, DataLayoutDimension axis); + static TensorDescriptor compute_output_descriptor(const std::vector<TensorDescriptor> &input_descriptors, + DataLayoutDimension axis); /** Disables or not the depth concatenate node * * @warning This is used when concatenate is performed using sub-tensors, where this node is used as a placeholder. @@ -78,7 +79,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: unsigned int _total_nodes; diff --git a/arm_compute/graph/nodes/ConstNode.h b/arm_compute/graph/nodes/ConstNode.h index 24dfaaae0b..400b9b4d9f 100644 --- a/arm_compute/graph/nodes/ConstNode.h +++ b/arm_compute/graph/nodes/ConstNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -44,7 +44,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: TensorDescriptor _desc; diff --git a/arm_compute/graph/nodes/ConvolutionLayerNode.h b/arm_compute/graph/nodes/ConvolutionLayerNode.h index eea43d7470..8a77b89f27 100644 --- a/arm_compute/graph/nodes/ConvolutionLayerNode.h +++ b/arm_compute/graph/nodes/ConvolutionLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019, 2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -90,6 +90,11 @@ public: * @param[in] fused_activation Fused activation to set */ void set_fused_activation(ActivationLayerInfo fused_activation); + /** Sets convolution info + * + * @param[in] info Convolution info to set + */ + void set_convolution_info(PadStrideInfo info); /** Computes convolution output descriptor * * @param[in] input_descriptor Input descriptor @@ -106,7 +111,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; public: static constexpr NodeType node_type = NodeType::ConvolutionLayer; diff --git a/arm_compute/graph/nodes/DeconvolutionLayerNode.h b/arm_compute/graph/nodes/DeconvolutionLayerNode.h index a5efdfb3bc..553d05985c 100644 --- a/arm_compute/graph/nodes/DeconvolutionLayerNode.h +++ b/arm_compute/graph/nodes/DeconvolutionLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -61,7 +61,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: descriptors::DeconvolutionLayerDescriptor descriptor; diff --git a/arm_compute/graph/nodes/UpsampleLayerNode.h b/arm_compute/graph/nodes/DepthToSpaceLayerNode.h index cdaf206173..5fbcc670ff 100644 --- a/arm_compute/graph/nodes/UpsampleLayerNode.h +++ b/arm_compute/graph/nodes/DepthToSpaceLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -21,8 +21,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_UPSAMPLE_LAYER_NODE_H -#define ARM_COMPUTE_GRAPH_UPSAMPLE_LAYER_NODE_H +#ifndef ARM_COMPUTE_GRAPH_DEPTH_TO_SPACE_LAYER_NODE_H +#define ARM_COMPUTE_GRAPH_DEPTH_TO_SPACE_LAYER_NODE_H #include "arm_compute/graph/INode.h" @@ -30,45 +30,37 @@ namespace arm_compute { namespace graph { -/** Upsample Layer node */ -class UpsampleLayerNode final : public INode +/** DepthToSpace Layer node */ +class DepthToSpaceLayerNode final : public INode { public: - /** Constructor + /** Default Constructor */ + DepthToSpaceLayerNode(int block_shape); + /** Block shape policy accessor * - * @param[in] info Stride info - * @param[in] upsampling_policy Upsampling policy + * @return Block shape */ - UpsampleLayerNode(Size2D info, InterpolationPolicy upsampling_policy); - /** Stride info metadata accessor + int block_shape() const; + /** Computes depth to space output descriptor * - * @return The stride info of the layer - */ - Size2D info() const; - /** Upsampling policy metadata accessor - * - * @return The upsampling policy of the layer - */ - InterpolationPolicy upsampling_policy() const; - /** Computes upsample output descriptor + * @warning block_shape must be greater than or equal to 2 * * @param[in] input_descriptor Input descriptor - * @param[in] info Stride information + * @param[in] block_shape Number of output neurons * * @return Output descriptor */ - static TensorDescriptor compute_output_descriptor(const TensorDescriptor &input_descriptor, Size2D info); + static TensorDescriptor compute_output_descriptor(const TensorDescriptor &input_descriptor, int block_shape); // Inherited overridden methods: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: - Size2D _info; - InterpolationPolicy _upsampling_policy; + int _block_shape; }; } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_UPSAMPLE_LAYER_NODE_H */ +#endif /* ARM_COMPUTE_GRAPH_DEPTH_TO_SPACE_LAYER_NODE_H */ diff --git a/arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h b/arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h index d8d36d9af2..441d68d2b8 100644 --- a/arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h +++ b/arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019, 2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -78,6 +78,11 @@ public: * @param[in] fused_activation Fused activation to set */ void set_fused_activation(ActivationLayerInfo fused_activation); + /** Sets convolution info + * + * @param[in] info Convolution info to set + */ + void set_convolution_info(PadStrideInfo info); /** Computes depthwise convolution output descriptor * * @param[in] input_descriptor Input descriptor @@ -96,7 +101,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; public: static constexpr NodeType node_type = NodeType::DepthwiseConvolutionLayer; diff --git a/arm_compute/graph/nodes/DequantizationLayerNode.h b/arm_compute/graph/nodes/DequantizationLayerNode.h index 8b3d4add65..1cce71373f 100644 --- a/arm_compute/graph/nodes/DequantizationLayerNode.h +++ b/arm_compute/graph/nodes/DequantizationLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited. + * Copyright (c) 2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -46,8 +46,8 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; }; } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_DEQUANTIZATION_NODE_H */
\ No newline at end of file +#endif /* ARM_COMPUTE_GRAPH_DEQUANTIZATION_NODE_H */ diff --git a/arm_compute/graph/nodes/DetectionOutputLayerNode.h b/arm_compute/graph/nodes/DetectionOutputLayerNode.h index 7732abfc79..c3e067e430 100644 --- a/arm_compute/graph/nodes/DetectionOutputLayerNode.h +++ b/arm_compute/graph/nodes/DetectionOutputLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -51,13 +51,14 @@ public: * * @return Output descriptor */ - static TensorDescriptor compute_output_descriptor(const TensorDescriptor &input_descriptor, const DetectionOutputLayerInfo &info); + static TensorDescriptor compute_output_descriptor(const TensorDescriptor &input_descriptor, + const DetectionOutputLayerInfo &info); // Inherited overridden methods: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: DetectionOutputLayerInfo _info; diff --git a/arm_compute/graph/nodes/DetectionPostProcessLayerNode.h b/arm_compute/graph/nodes/DetectionPostProcessLayerNode.h index 97d881d411..a53aaf2b9c 100644 --- a/arm_compute/graph/nodes/DetectionPostProcessLayerNode.h +++ b/arm_compute/graph/nodes/DetectionPostProcessLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited. + * Copyright (c) 2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -49,7 +49,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: DetectionPostProcessLayerInfo _info; @@ -59,4 +59,4 @@ private: }; } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_DETECTION_POST_PROCESS_LAYER_NODE_H */
\ No newline at end of file +#endif /* ARM_COMPUTE_GRAPH_DETECTION_POST_PROCESS_LAYER_NODE_H */ diff --git a/arm_compute/graph/nodes/DummyNode.h b/arm_compute/graph/nodes/DummyNode.h index e257641e8a..2263525a72 100644 --- a/arm_compute/graph/nodes/DummyNode.h +++ b/arm_compute/graph/nodes/DummyNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -51,11 +51,11 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: TensorShape _shape; }; } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_DUMMY_NODE_H */
\ No newline at end of file +#endif /* ARM_COMPUTE_GRAPH_DUMMY_NODE_H */ diff --git a/arm_compute/graph/nodes/EltwiseLayerNode.h b/arm_compute/graph/nodes/EltwiseLayerNode.h index d619ad2588..258298259f 100644 --- a/arm_compute/graph/nodes/EltwiseLayerNode.h +++ b/arm_compute/graph/nodes/EltwiseLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -63,6 +63,12 @@ public: */ ActivationLayerInfo fused_activation() const; + /** Returns output quantization info + * + * @return Output quantization info + */ + QuantizationInfo output_quant_info() const; + /** Sets fused activation * * @param[in] fused_activation Fused activation to set @@ -73,13 +79,47 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; static constexpr NodeType node_type = NodeType::EltwiseLayer; private: descriptors::EltwiseLayerDescriptor descriptor; }; + +/** Unary Eltwise Layer node */ +class UnaryEltwiseLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] descriptor Containing information for the node described in @ref descriptors::EltwiseLayerDescriptor + */ + UnaryEltwiseLayerNode(const descriptors::UnaryEltwiseLayerDescriptor &descriptor); + /** Unary eltwise layer descriptor + * + * @return Unary eltwise layer descriptor which containing information + */ + descriptors::UnaryEltwiseLayerDescriptor eltwise_descriptor() const; + + /** Sets fused activation + * + * @param[in] fused_activation Fused activation to set + */ + void set_fused_activation(ActivationLayerInfo fused_activation); + + // Inherited overridden methods: + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; + + static constexpr NodeType node_type = NodeType::UnaryEltwiseLayer; + +private: + descriptors::UnaryEltwiseLayerDescriptor descriptor; +}; + } // namespace graph } // namespace arm_compute #endif /* ARM_COMPUTE_GRAPH_ELTWISE_LAYER_NODE_H */ diff --git a/arm_compute/graph/nodes/FlattenLayerNode.h b/arm_compute/graph/nodes/FlattenLayerNode.h index fd9a525ea0..af104707a1 100644 --- a/arm_compute/graph/nodes/FlattenLayerNode.h +++ b/arm_compute/graph/nodes/FlattenLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -41,7 +41,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/nodes/FullyConnectedLayerNode.h b/arm_compute/graph/nodes/FullyConnectedLayerNode.h index 10c310dda2..3bcf386d64 100644 --- a/arm_compute/graph/nodes/FullyConnectedLayerNode.h +++ b/arm_compute/graph/nodes/FullyConnectedLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -39,10 +39,22 @@ public: * @param[in] num_outputs Number of neurons in the layer * @param[in] out_quant_info (Optional) Output quantization info * @param[in] fc_info (Optional) Additional information about the fully connected layer + * @param[in] fast_math_hint (Optional) Fast math hint */ FullyConnectedLayerNode(unsigned int num_outputs, QuantizationInfo out_quant_info = QuantizationInfo(), - FullyConnectedLayerInfo fc_info = FullyConnectedLayerInfo()); + FullyConnectedLayerInfo fc_info = FullyConnectedLayerInfo(), + FastMathHint fast_math_hint = FastMathHint::Disabled); + /** Sets the fast math fast hint + * + * @param[in] hint Hint to use for fullyconnected layer + */ + void set_fast_math_hint(FastMathHint hint); + /** Fast math hint accessor + * + * @return Fast math hint to be used by the node + */ + FastMathHint fast_math_hint() const; /** Sets fused activation * * @param[in] fused_activation Fused activation to set @@ -61,7 +73,7 @@ public: */ static TensorDescriptor compute_weights_descriptor(const TensorDescriptor &input_descriptor, unsigned int num_outputs, - FullyConnectedLayerInfo fc_info = FullyConnectedLayerInfo(), + FullyConnectedLayerInfo fc_info = FullyConnectedLayerInfo(), const QuantizationInfo &weights_quant_info = QuantizationInfo()); /** Computes fully connected layer output descriptor * @@ -86,7 +98,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; static constexpr NodeType node_type = NodeType::FullyConnectedLayer; @@ -94,6 +106,7 @@ private: unsigned int _num_outputs; QuantizationInfo _out_quant_info; FullyConnectedLayerInfo _info; + FastMathHint _fast_math_hint; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/nodes/FusedConvolutionBatchNormalizationNode.h b/arm_compute/graph/nodes/FusedConvolutionBatchNormalizationNode.h index 62ec55ee3b..d891ea49eb 100644 --- a/arm_compute/graph/nodes/FusedConvolutionBatchNormalizationNode.h +++ b/arm_compute/graph/nodes/FusedConvolutionBatchNormalizationNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited. + * Copyright (c) 2019, 2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -43,7 +43,8 @@ public: * @param[in] fast_math_hint (Optional) Fast math hint * @param[in] fused_activation (Optional) Fused activation layer. Disabled if not specified */ - FusedConvolutionBatchNormalizationNode(float epsilon, PadStrideInfo info, + FusedConvolutionBatchNormalizationNode(float epsilon, + PadStrideInfo info, unsigned int num_groups = 1, ConvolutionMethod method = ConvolutionMethod::Default, FastMathHint fast_math_hint = FastMathHint::Disabled, @@ -100,7 +101,7 @@ public: */ ConvolutionMethod convolution_method() const; - /** Sets the fast math fast hint + /** Sets the fast math hint * * @param[in] hint Hint to use for convolution */ @@ -122,7 +123,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; public: static constexpr NodeType node_type = NodeType::FusedConvolutionBatchNormalizationLayer; diff --git a/arm_compute/graph/nodes/FusedDepthwiseConvolutionBatchNormalizationNode.h b/arm_compute/graph/nodes/FusedDepthwiseConvolutionBatchNormalizationNode.h index 668f09e6b3..a61b155151 100644 --- a/arm_compute/graph/nodes/FusedDepthwiseConvolutionBatchNormalizationNode.h +++ b/arm_compute/graph/nodes/FusedDepthwiseConvolutionBatchNormalizationNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited. + * Copyright (c) 2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -46,7 +46,7 @@ public: PadStrideInfo info, unsigned int depth_multiplier, DepthwiseConvolutionMethod method, - ActivationLayerInfo fused_activation = ActivationLayerInfo()); + ActivationLayerInfo fused_activation = ActivationLayerInfo()); /** Sets the depthwise convolution layer method to use * @@ -117,7 +117,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; public: static constexpr NodeType node_type = NodeType::FusedDepthwiseConvolutionBatchNormalizationLayer; diff --git a/arm_compute/graph/nodes/GenerateProposalsLayerNode.h b/arm_compute/graph/nodes/GenerateProposalsLayerNode.h index 57cadf44f8..b5e4b9781c 100644 --- a/arm_compute/graph/nodes/GenerateProposalsLayerNode.h +++ b/arm_compute/graph/nodes/GenerateProposalsLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited. + * Copyright (c) 2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -50,7 +50,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: GenerateProposalsInfo _info; diff --git a/arm_compute/graph/nodes/InputNode.h b/arm_compute/graph/nodes/InputNode.h index 20fc27664b..0983d25a59 100644 --- a/arm_compute/graph/nodes/InputNode.h +++ b/arm_compute/graph/nodes/InputNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -44,7 +44,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: TensorDescriptor _desc; diff --git a/arm_compute/graph/backends/GLES/GCNodeValidator.h b/arm_compute/graph/nodes/L2NormalizeLayerNode.h index 89421f7860..ed11412b70 100644 --- a/arm_compute/graph/backends/GLES/GCNodeValidator.h +++ b/arm_compute/graph/nodes/L2NormalizeLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -21,32 +21,59 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_GCNODEVALIDATOR_H -#define ARM_COMPUTE_GRAPH_GCNODEVALIDATOR_H +#ifndef ARM_COMPUTE_GRAPH_L2_NORMALIZE_LAYER_NODE_H +#define ARM_COMPUTE_GRAPH_L2_NORMALIZE_LAYER_NODE_H -#include "arm_compute/core/Error.h" +#include "arm_compute/graph/INode.h" namespace arm_compute { namespace graph { -// Forward declarations -class INode; - -namespace backends -{ -class GCNodeValidator final +/** L2Normalize Layer node */ +class L2NormalizeLayerNode final : public INode { public: - /** Validate a node + /** Constructor + * + */ + L2NormalizeLayerNode(); + + /** Constructor * - * @param[in] node Node to validate + * @param[in] axis Axis to perform normalization on + */ + L2NormalizeLayerNode(int axis); + + /** Constructor * - * @return An error status + * @param[in] axis Axis to perform normalization on + * @param[in] epsilon Lower bound value for the normalization */ - static Status validate(INode *node); + L2NormalizeLayerNode(int axis, float epsilon); + + /** axis accessors + * + * @return Axis to perform normalization on + */ + int axis() const; + + /** epsilon accessors + * + * @return Lower bound value for the normalization + */ + float epsilon() const; + + // Inherited overridden methods: + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; + +private: + int _axis; + float _epsilon; }; -} // namespace backends } // namespace graph } // namespace arm_compute -#endif //ARM_COMPUTE_GRAPH_GCNODEVALIDATOR_H +#endif /* ARM_COMPUTE_GRAPH_L2_NORMALIZE_LAYER_NODE_H */ diff --git a/arm_compute/graph/nodes/Nodes.h b/arm_compute/graph/nodes/Nodes.h index e8852d247a..d4ad32b6f0 100644 --- a/arm_compute/graph/nodes/Nodes.h +++ b/arm_compute/graph/nodes/Nodes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2021, 2023 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -21,10 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_NODES_H -#define ARM_COMPUTE_GRAPH_NODES_H +#ifndef ACL_ARM_COMPUTE_GRAPH_NODES_NODES_H +#define ACL_ARM_COMPUTE_GRAPH_NODES_NODES_H #include "arm_compute/graph/nodes/ActivationLayerNode.h" +#include "arm_compute/graph/nodes/ArgMinMaxLayerNode.h" #include "arm_compute/graph/nodes/BatchNormalizationLayerNode.h" #include "arm_compute/graph/nodes/BoundingBoxTransformLayerNode.h" #include "arm_compute/graph/nodes/ChannelShuffleLayerNode.h" @@ -32,6 +33,7 @@ #include "arm_compute/graph/nodes/ConstNode.h" #include "arm_compute/graph/nodes/ConvolutionLayerNode.h" #include "arm_compute/graph/nodes/DeconvolutionLayerNode.h" +#include "arm_compute/graph/nodes/DepthToSpaceLayerNode.h" #include "arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h" #include "arm_compute/graph/nodes/DequantizationLayerNode.h" #include "arm_compute/graph/nodes/DetectionOutputLayerNode.h" @@ -44,25 +46,26 @@ #include "arm_compute/graph/nodes/FusedDepthwiseConvolutionBatchNormalizationNode.h" #include "arm_compute/graph/nodes/GenerateProposalsLayerNode.h" #include "arm_compute/graph/nodes/InputNode.h" +#include "arm_compute/graph/nodes/L2NormalizeLayerNode.h" #include "arm_compute/graph/nodes/NormalizationLayerNode.h" #include "arm_compute/graph/nodes/NormalizePlanarYUVLayerNode.h" #include "arm_compute/graph/nodes/OutputNode.h" -#include "arm_compute/graph/nodes/PReluLayerNode.h" #include "arm_compute/graph/nodes/PadLayerNode.h" #include "arm_compute/graph/nodes/PermuteLayerNode.h" #include "arm_compute/graph/nodes/PoolingLayerNode.h" +#include "arm_compute/graph/nodes/PReluLayerNode.h" #include "arm_compute/graph/nodes/PrintLayerNode.h" #include "arm_compute/graph/nodes/PriorBoxLayerNode.h" #include "arm_compute/graph/nodes/QuantizationLayerNode.h" -#include "arm_compute/graph/nodes/ROIAlignLayerNode.h" +#include "arm_compute/graph/nodes/ReductionLayerNode.h" #include "arm_compute/graph/nodes/ReorgLayerNode.h" #include "arm_compute/graph/nodes/ReshapeLayerNode.h" #include "arm_compute/graph/nodes/ResizeLayerNode.h" +#include "arm_compute/graph/nodes/ROIAlignLayerNode.h" #include "arm_compute/graph/nodes/SliceLayerNode.h" #include "arm_compute/graph/nodes/SoftmaxLayerNode.h" #include "arm_compute/graph/nodes/SplitLayerNode.h" #include "arm_compute/graph/nodes/StackLayerNode.h" -#include "arm_compute/graph/nodes/UpsampleLayerNode.h" -#include "arm_compute/graph/nodes/YOLOLayerNode.h" +#include "arm_compute/graph/nodes/StridedSliceLayerNode.h" -#endif /* ARM_COMPUTE_GRAPH_NODES_H */ +#endif // ACL_ARM_COMPUTE_GRAPH_NODES_NODES_H diff --git a/arm_compute/graph/nodes/NodesFwd.h b/arm_compute/graph/nodes/NodesFwd.h index 0ccf2433b8..580f339468 100644 --- a/arm_compute/graph/nodes/NodesFwd.h +++ b/arm_compute/graph/nodes/NodesFwd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2021, 2023 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -21,8 +21,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_NODES_FWD_H -#define ARM_COMPUTE_GRAPH_NODES_FWD_H +#ifndef ACL_ARM_COMPUTE_GRAPH_NODES_NODESFWD_H +#define ACL_ARM_COMPUTE_GRAPH_NODES_NODESFWD_H namespace arm_compute { @@ -31,6 +31,7 @@ namespace graph // Forward declarations class INode; class ActivationLayerNode; +class ArgMinMaxLayerNode; class BatchNormalizationLayerNode; class BoundingBoxTransformLayerNode; class ChannelShuffleLayerNode; @@ -38,6 +39,7 @@ class ConcatenateLayerNode; class ConstNode; class ConvolutionLayerNode; class DeconvolutionLayerNode; +class DepthToSpaceLayerNode; class DepthwiseConvolutionLayerNode; class DequantizationLayerNode; class DetectionOutputLayerNode; @@ -50,6 +52,7 @@ class FusedConvolutionBatchNormalizationNode; class FusedDepthwiseConvolutionBatchNormalizationNode; class GenerateProposalsLayerNode; class InputNode; +class L2NormalizeLayerNode; class NormalizationLayerNode; class NormalizePlanarYUVLayerNode; class OutputNode; @@ -60,6 +63,7 @@ class PReluLayerNode; class PrintLayerNode; class PriorBoxLayerNode; class QuantizationLayerNode; +class ReductionLayerNode; class ReorgLayerNode; class ReshapeLayerNode; class ResizeLayerNode; @@ -68,8 +72,7 @@ class SoftmaxLayerNode; class SliceLayerNode; class SplitLayerNode; class StackLayerNode; -class UpsampleLayerNode; -class YOLOLayerNode; +class StridedSliceLayerNode; } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_NODES_FWD_H */ +#endif // ACL_ARM_COMPUTE_GRAPH_NODES_NODESFWD_H diff --git a/arm_compute/graph/nodes/NormalizationLayerNode.h b/arm_compute/graph/nodes/NormalizationLayerNode.h index 3f5e781511..86f2fb9dba 100644 --- a/arm_compute/graph/nodes/NormalizationLayerNode.h +++ b/arm_compute/graph/nodes/NormalizationLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -49,7 +49,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: NormalizationLayerInfo _info; diff --git a/arm_compute/graph/nodes/NormalizePlanarYUVLayerNode.h b/arm_compute/graph/nodes/NormalizePlanarYUVLayerNode.h index 843ab9683d..158acc4c23 100644 --- a/arm_compute/graph/nodes/NormalizePlanarYUVLayerNode.h +++ b/arm_compute/graph/nodes/NormalizePlanarYUVLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -41,7 +41,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/nodes/OutputNode.h b/arm_compute/graph/nodes/OutputNode.h index 27902af717..75484ab328 100644 --- a/arm_compute/graph/nodes/OutputNode.h +++ b/arm_compute/graph/nodes/OutputNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -41,7 +41,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/nodes/PReluLayerNode.h b/arm_compute/graph/nodes/PReluLayerNode.h index f2055c2281..532fdccb3a 100644 --- a/arm_compute/graph/nodes/PReluLayerNode.h +++ b/arm_compute/graph/nodes/PReluLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 ARM Limited. + * Copyright (c) 2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -41,7 +41,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/nodes/PadLayerNode.h b/arm_compute/graph/nodes/PadLayerNode.h index 852427a593..dcb5ea595b 100644 --- a/arm_compute/graph/nodes/PadLayerNode.h +++ b/arm_compute/graph/nodes/PadLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 ARM Limited. + * Copyright (c) 2018-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -56,7 +56,10 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; + +public: + static constexpr NodeType node_type = NodeType::PadLayer; private: PaddingList _padding; diff --git a/arm_compute/graph/nodes/PermuteLayerNode.h b/arm_compute/graph/nodes/PermuteLayerNode.h index 555f2b5d16..62654e777c 100644 --- a/arm_compute/graph/nodes/PermuteLayerNode.h +++ b/arm_compute/graph/nodes/PermuteLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -51,7 +51,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: PermutationVector _perm; diff --git a/arm_compute/graph/nodes/PoolingLayerNode.h b/arm_compute/graph/nodes/PoolingLayerNode.h index 41342a8215..c81f3f98dc 100644 --- a/arm_compute/graph/nodes/PoolingLayerNode.h +++ b/arm_compute/graph/nodes/PoolingLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -57,7 +57,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: PoolingLayerInfo _info; diff --git a/arm_compute/graph/nodes/PrintLayerNode.h b/arm_compute/graph/nodes/PrintLayerNode.h index 78b7bf212c..e7accc8015 100644 --- a/arm_compute/graph/nodes/PrintLayerNode.h +++ b/arm_compute/graph/nodes/PrintLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 ARM Limited. + * Copyright (c) 2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -43,7 +43,9 @@ public: * @param[in] format_info (Optional) Format info. * @param[in] transform (Optional) Input transform function. */ - PrintLayerNode(std::ostream &stream, const IOFormatInfo &format_info = IOFormatInfo(), const std::function<ITensor *(ITensor *)> transform = nullptr); + PrintLayerNode(std::ostream &stream, + const IOFormatInfo &format_info = IOFormatInfo(), + const std::function<ITensor *(ITensor *)> transform = nullptr); /** Stream metadata accessor * @@ -67,7 +69,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: std::ostream &_stream; diff --git a/arm_compute/graph/nodes/PriorBoxLayerNode.h b/arm_compute/graph/nodes/PriorBoxLayerNode.h index f6cfa4779c..db36bfb1e0 100644 --- a/arm_compute/graph/nodes/PriorBoxLayerNode.h +++ b/arm_compute/graph/nodes/PriorBoxLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -51,13 +51,14 @@ public: * * @return Output descriptor */ - static TensorDescriptor compute_output_descriptor(const TensorDescriptor &input_descriptor, const PriorBoxLayerInfo &info); + static TensorDescriptor compute_output_descriptor(const TensorDescriptor &input_descriptor, + const PriorBoxLayerInfo &info); // Inherited overridden methods: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: PriorBoxLayerInfo _info; diff --git a/arm_compute/graph/nodes/QuantizationLayerNode.h b/arm_compute/graph/nodes/QuantizationLayerNode.h index f283c26996..b8e4c7d27b 100644 --- a/arm_compute/graph/nodes/QuantizationLayerNode.h +++ b/arm_compute/graph/nodes/QuantizationLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited. + * Copyright (c) 2019-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -40,16 +40,24 @@ public: */ QuantizationLayerNode(QuantizationInfo out_quant_info); + /** Constructor + * + * @param[in] out_quant_info Output quantization info + * @param[in] out_data_type Output data type + */ + QuantizationLayerNode(QuantizationInfo out_quant_info, DataType out_data_type); + // Inherited overridden methods: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; static constexpr NodeType node_type = NodeType::QuantizationLayer; private: QuantizationInfo _out_quant_info; + DataType _out_data_type; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/nodes/ROIAlignLayerNode.h b/arm_compute/graph/nodes/ROIAlignLayerNode.h index 445246844b..70309a551c 100644 --- a/arm_compute/graph/nodes/ROIAlignLayerNode.h +++ b/arm_compute/graph/nodes/ROIAlignLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -56,7 +56,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: ROIPoolingLayerInfo _pool_info; diff --git a/arm_compute/graph/nodes/YOLOLayerNode.h b/arm_compute/graph/nodes/ReductionLayerNode.h index 22e0cf5495..ff99466c8f 100644 --- a/arm_compute/graph/nodes/YOLOLayerNode.h +++ b/arm_compute/graph/nodes/ReductionLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -21,8 +21,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_YOLO_LAYER_NODE_H -#define ARM_COMPUTE_GRAPH_YOLO_LAYER_NODE_H +#ifndef ARM_COMPUTE_GRAPH_REDUCTION_LAYER_NODE_H +#define ARM_COMPUTE_GRAPH_REDUCTION_LAYER_NODE_H #include "arm_compute/graph/INode.h" @@ -30,37 +30,39 @@ namespace arm_compute { namespace graph { -/** YOLO Layer node */ -class YOLOLayerNode final : public INode +/** Reduction Operation node */ +class ReductionLayerNode final : public INode { public: - /** Constructor + /** Default Constructor */ + ReductionLayerNode(ReductionOperation op, unsigned int axis, bool keep_dims = true); + /** op accessor * - * @param[in] act_info Activation info - * @param[in] num_classes Number of classes to activate + * @return op */ - YOLOLayerNode(ActivationLayerInfo act_info, int32_t num_classes); - /** Activation metadata accessor + ReductionOperation op() const; + /** axis accessor * - * @return The activation info of the layer + * @return axis */ - ActivationLayerInfo activation_info() const; - /** Number of classes metadata accessor + unsigned int axis() const; + /** keep_dims accessor * - * @return The number of classes to activate of the layer + * @return keep_dims */ - int32_t num_classes() const; + bool keep_dims() const; // Inherited overridden methods: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: - ActivationLayerInfo _act_info; - int32_t _num_classes; + ReductionOperation _op; + unsigned int _axis; + bool _keep_dims; }; } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_YOLO_LAYER_NODE_H */ +#endif /* ARM_COMPUTE_GRAPH_REDUCTION_LAYER_NODE_H */ diff --git a/arm_compute/graph/nodes/ReorgLayerNode.h b/arm_compute/graph/nodes/ReorgLayerNode.h index 86f62522c3..a3bbcdb00f 100644 --- a/arm_compute/graph/nodes/ReorgLayerNode.h +++ b/arm_compute/graph/nodes/ReorgLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -57,7 +57,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: int _stride; diff --git a/arm_compute/graph/nodes/ReshapeLayerNode.h b/arm_compute/graph/nodes/ReshapeLayerNode.h index 57d399ac2f..992275c2b1 100644 --- a/arm_compute/graph/nodes/ReshapeLayerNode.h +++ b/arm_compute/graph/nodes/ReshapeLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -44,7 +44,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: TensorShape _shape; diff --git a/arm_compute/graph/nodes/ResizeLayerNode.h b/arm_compute/graph/nodes/ResizeLayerNode.h index 93b449502c..480d6e517f 100644 --- a/arm_compute/graph/nodes/ResizeLayerNode.h +++ b/arm_compute/graph/nodes/ResizeLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -51,7 +51,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: InterpolationPolicy _policy; diff --git a/arm_compute/graph/nodes/SliceLayerNode.h b/arm_compute/graph/nodes/SliceLayerNode.h index 7f3173e183..63f266b217 100644 --- a/arm_compute/graph/nodes/SliceLayerNode.h +++ b/arm_compute/graph/nodes/SliceLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -41,7 +41,7 @@ public: * @param[in] starts The starts of the dimensions of the input tensor to be sliced. The length must be of rank(input). * @param[in] ends The ends of the dimensions of the input tensor to be sliced. The length must be of rank(input). */ - SliceLayerNode(Coordinates &starts, Coordinates &ends); + SliceLayerNode(const Coordinates &starts, const Coordinates &ends); /** Computes slice layer output descriptor * * @param[in] input_descriptor Descriptor of the input tensor @@ -51,7 +51,8 @@ public: * @return Output descriptor */ static TensorDescriptor compute_output_descriptor(const TensorDescriptor &input_descriptor, - const Coordinates &starts, const Coordinates &ends); + const Coordinates &starts, + const Coordinates &ends); /** Start coordinates accessor * * @return Start coordinates of the dimensions @@ -67,7 +68,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: Coordinates _starts; diff --git a/arm_compute/graph/nodes/SoftmaxLayerNode.h b/arm_compute/graph/nodes/SoftmaxLayerNode.h index cbcd06a477..2cb1ac2cf4 100644 --- a/arm_compute/graph/nodes/SoftmaxLayerNode.h +++ b/arm_compute/graph/nodes/SoftmaxLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -49,7 +49,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; public: static constexpr NodeType node_type = NodeType::SoftmaxLayer; diff --git a/arm_compute/graph/nodes/SplitLayerNode.h b/arm_compute/graph/nodes/SplitLayerNode.h index 345260ab84..5e6df53c0f 100644 --- a/arm_compute/graph/nodes/SplitLayerNode.h +++ b/arm_compute/graph/nodes/SplitLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -38,10 +38,13 @@ class SplitLayerNode final : public INode public: /** Default Constructor * - * @param[in] num_splits Number of splits - * @param[in] axis (Optional) Axis to split on. Supported axis >= 2. Defaults to 0 + * @param[in] num_splits Number of splits + * @param[in] axis (Optional) Axis to split on. Defaults to 0 + * @param[in] size_splits (Optional) The sizes of each output tensor along the split dimension. + * Must sum to the dimension of value along split_dim. + * Can contain one -1 indicating that dimension is to be inferred. */ - SplitLayerNode(unsigned int num_splits, unsigned int axis = 0); + SplitLayerNode(unsigned int num_splits, int axis = 0, std::vector<int> size_splits = std::vector<int>()); /** Computes split layer output descriptor * * @param[in] input_descriptor Descriptor of the input tensor @@ -51,8 +54,10 @@ public: * * @return A pair with the descriptor of the split and the starting coordinates */ - static std::pair<TensorDescriptor, Coordinates> compute_output_descriptor(const TensorDescriptor &input_descriptor, - unsigned int num_splits, unsigned int axis, unsigned int idx); + std::pair<TensorDescriptor, Coordinates> compute_output_descriptor(const TensorDescriptor &input_descriptor, + unsigned int num_splits, + int axis, + unsigned int idx); /** Number of splits accessor * * @return Number of splits @@ -69,11 +74,12 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: - unsigned int _num_splits; - unsigned int _axis; + unsigned int _num_splits; + int _axis; + std::vector<int> _size_splits; }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/nodes/StackLayerNode.h b/arm_compute/graph/nodes/StackLayerNode.h index 52632f5577..9f0767c9f2 100644 --- a/arm_compute/graph/nodes/StackLayerNode.h +++ b/arm_compute/graph/nodes/StackLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited. + * Copyright (c) 2019 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -58,7 +58,7 @@ public: NodeType type() const override; bool forward_descriptors() override; TensorDescriptor configure_output(size_t idx) const override; - void accept(INodeVisitor &v) override; + void accept(INodeVisitor &v) override; private: unsigned int _total_nodes; diff --git a/arm_compute/graph/nodes/StridedSliceLayerNode.h b/arm_compute/graph/nodes/StridedSliceLayerNode.h new file mode 100644 index 0000000000..f521feb780 --- /dev/null +++ b/arm_compute/graph/nodes/StridedSliceLayerNode.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2020 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef ARM_COMPUTE_GRAPH_STRIDED_SLICE_LAYER_NODE_H +#define ARM_COMPUTE_GRAPH_STRIDED_SLICE_LAYER_NODE_H + +#include "arm_compute/graph/INode.h" + +#include <tuple> + +namespace arm_compute +{ +namespace graph +{ +/** Slice Layer node */ +class StridedSliceLayerNode final : public INode +{ +public: + /** Default Constructor + * + * @param[in] starts The starts of the dimensions of the input tensor to be sliced. The length must be of rank(input). + * @param[in] ends The ends of the dimensions of the input tensor to be sliced. The length must be of rank(input). + * @param[in] strides The strides of the dimensions of the input tensor to be sliced. The length must be of rank(input). + * @param[in] strided_slice_info Contains masks for the starts, ends and strides + */ + StridedSliceLayerNode(const Coordinates &starts, + const Coordinates &ends, + const BiStrides &strides, + StridedSliceLayerInfo strided_slice_info); + /** Computes slice layer output descriptor + * + * @param[in] input_descriptor Descriptor of the input tensor + * @param[in] starts The starts of the dimensions of the input tensor to be sliced. The length must be of rank(input). + * @param[in] ends The ends of the dimensions of the input tensor to be sliced. The length must be of rank(input). + * @param[in] strides The strides of the dimensions of the input tensor to be sliced. The length must be of rank(input). + * @param[in] info Contains masks for the starts, ends and strides + * + * @return Output descriptor + */ + static TensorDescriptor compute_output_descriptor(const TensorDescriptor &input_descriptor, + const Coordinates &starts, + const Coordinates &ends, + const BiStrides &strides, + StridedSliceLayerInfo info); + /** Start coordinates accessor + * + * @return Start coordinates of the dimensions + */ + Coordinates starts() const; + /** End coordinates accessor + * + * @return End coordinates of the dimensions + */ + Coordinates ends() const; + /** Strides vector accessor + * + * @return End coordinates of the dimensions + */ + BiStrides strides() const; + + StridedSliceLayerInfo strided_slice_info() const; + + // Inherited overridden methods: + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; + +private: + Coordinates _starts; + Coordinates _ends; + BiStrides _strides; + StridedSliceLayerInfo _info; +}; +} // namespace graph +} // namespace arm_compute +#endif /* ARM_COMPUTE_GRAPH_STRIDED_SLICE_LAYER_NODE_H */ diff --git a/arm_compute/graph/printers/DotGraphPrinter.h b/arm_compute/graph/printers/DotGraphPrinter.h index c763cb1a96..6638033044 100644 --- a/arm_compute/graph/printers/DotGraphPrinter.h +++ b/arm_compute/graph/printers/DotGraphPrinter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019,2021,2023 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -21,11 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_DOTGRAPHPRINTER_H -#define ARM_COMPUTE_GRAPH_DOTGRAPHPRINTER_H +#ifndef ACL_ARM_COMPUTE_GRAPH_PRINTERS_DOTGRAPHPRINTER_H +#define ACL_ARM_COMPUTE_GRAPH_PRINTERS_DOTGRAPHPRINTER_H #include "arm_compute/graph/IGraphPrinter.h" - #include "arm_compute/graph/INodeVisitor.h" #include <string> @@ -60,7 +59,7 @@ public: void visit(FusedDepthwiseConvolutionBatchNormalizationNode &n) override; void visit(NormalizationLayerNode &n) override; void visit(PoolingLayerNode &n) override; - void default_visit() override; + void default_visit(INode &n) override; private: std::string _info{}; @@ -104,4 +103,4 @@ private: }; } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_DOTGRAPHPRINTER_H */ +#endif // ACL_ARM_COMPUTE_GRAPH_PRINTERS_DOTGRAPHPRINTER_H diff --git a/arm_compute/graph/printers/Printers.h b/arm_compute/graph/printers/Printers.h index 631b63428e..81ecce7227 100644 --- a/arm_compute/graph/printers/Printers.h +++ b/arm_compute/graph/printers/Printers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2019 Arm Limited. * * SPDX-License-Identifier: MIT * |