From 427bbbf939a37150fd6768c29c9753771806dab3 Mon Sep 17 00:00:00 2001 From: Georgios Pinitas Date: Tue, 28 Aug 2018 13:32:02 +0100 Subject: COMPMID-1522: Add ElementWiseOperation node in the graph API Change-Id: Icb428bf3b5d3634fdddc57562cce670776e7f7a3 Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/145814 Tested-by: Jenkins Reviewed-by: Anthony Barbier --- arm_compute/graph/frontend/Layers.h | 167 ++++++++++++++++++++---------------- arm_compute/graph/frontend/Types.h | 8 +- 2 files changed, 94 insertions(+), 81 deletions(-) (limited to 'arm_compute/graph') diff --git a/arm_compute/graph/frontend/Layers.h b/arm_compute/graph/frontend/Layers.h index cf80dd9f4e..054410e4ad 100644 --- a/arm_compute/graph/frontend/Layers.h +++ b/arm_compute/graph/frontend/Layers.h @@ -178,6 +178,71 @@ private: unsigned int _num_groups; }; +/** Concat Layer */ +class ConcatLayer final : public ILayer +{ +public: + /** Construct a concatenation layer + * + * @param[in] sub_stream1 First graph branch + * @param[in] sub_stream2 Second graph branch + * @param[in] rest_sub_streams Rest sub-graph branches + */ + template + ConcatLayer(SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&... rest_sub_streams) + : _sub_streams() + { + _sub_streams.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_stream1))); + _sub_streams.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_stream2))); + + utility::for_each([&](SubStream && sub_stream) + { + _sub_streams.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_stream))); + }, + std::move(rest_sub_streams)...); + } + /** Construct a concat layer + * + * @param[in] sub_stream Sub-stream + */ + template + ConcatLayer(SubStream &&sub_stream) + : _sub_streams() + { + _sub_streams.push_back(arm_compute::support::cpp14::make_unique(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) + { + nid = _sub_streams[0]->tail_node(); + } + else + { + // Collect tail nodes and concatenate + std::vector nodes; + for(auto &ss : _sub_streams) + { + 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) + { + nodes.push_back({ ss->tail_node(), 0 }); + } + } + } + nid = GraphBuilder::add_concatenate_node(s.graph(), common_params, nodes, DataLayoutDimension::CHANNEL); + } + return nid; + } + +private: + std::vector> _sub_streams; +}; + /** Convolution Layer */ class ConvolutionLayer final : public ILayer { @@ -358,6 +423,34 @@ private: TensorShape _shape; }; +class EltwiseLayer final : public ILayer +{ +public: + /** Construct an element-wise operation layer + * + * @param[in] sub_stream0 First graph sub-stream + * @param[in] sub_stream1 First graph sub-stream + * @param[in] op Element-wise operation to perform + */ + EltwiseLayer(SubStream &&sub_stream0, SubStream &&sub_stream1, EltwiseOperation op) + : _ss0(std::move(sub_stream0)), _ss1(std::move(sub_stream1)), _op(op) + { + } + + 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 }; + + return GraphBuilder::add_elementwise_node(s.graph(), common_params, input0, input1, _op); + } + +private: + SubStream _ss0; + SubStream _ss1; + EltwiseOperation _op; +}; /** Flatten Layer */ class FlattenLayer final : public ILayer { @@ -592,80 +685,6 @@ public: private: float _beta; }; - -/** Branch Layer */ -class BranchLayer final : public ILayer -{ -public: - /** Construct a branch layer - * - * @param[in] merge_method Branch merging method - * @param[in] sub_stream1 First graph branch - * @param[in] sub_stream2 Second graph branch - * @param[in] rest_sub_streams Rest sub-graph branches - */ - template - BranchLayer(BranchMergeMethod merge_method, SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&... rest_sub_streams) - : _branch_merge_method(merge_method), _sub_streams() - { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_stream1))); - _sub_streams.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_stream2))); - - utility::for_each([&](SubStream && sub_stream) - { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_stream))); - }, - std::move(rest_sub_streams)...); - } - /** Construct a branch layer - * - * @param[in] sub_stream Sub-stream - */ - template - BranchLayer(SubStream &&sub_stream) - : _branch_merge_method(BranchMergeMethod::DEPTH_CONCATENATE), _sub_streams() - { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique(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) - { - nid = _sub_streams[0]->tail_node(); - } - else if(_branch_merge_method == BranchMergeMethod::DEPTH_CONCATENATE) - { - // Collect tail nodes and concatenate - std::vector nodes; - for(auto &ss : _sub_streams) - { - 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) - { - nodes.push_back({ ss->tail_node(), 0 }); - } - } - } - nid = GraphBuilder::add_concatenate_node(s.graph(), common_params, nodes, DataLayoutDimension::CHANNEL); - } - else - { - ARM_COMPUTE_ERROR_ON(_sub_streams.size() != 2); - NodeIdxPair input0 = { _sub_streams[0]->tail_node(), 0 }; - NodeIdxPair input1 = { _sub_streams[1]->tail_node(), 0 }; - nid = GraphBuilder::add_elementwise_node(s.graph(), common_params, input0, input1, EltwiseOperation::Add); - } - return nid; - } - -private: - BranchMergeMethod _branch_merge_method; - std::vector> _sub_streams; -}; } // namespace frontend } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/frontend/Types.h b/arm_compute/graph/frontend/Types.h index f9505e264c..79ce52e8d1 100644 --- a/arm_compute/graph/frontend/Types.h +++ b/arm_compute/graph/frontend/Types.h @@ -40,6 +40,7 @@ using graph::TensorShape; using graph::PermutationVector; using graph::ActivationLayerInfo; +using graph::EltwiseOperation; using graph::FullyConnectedLayerInfo; using graph::NormalizationLayerInfo; using graph::NormType; @@ -56,13 +57,6 @@ using graph::GraphConfig; using graph::InterpolationPolicy; using graph::Size2D; -/** Branch layer merging method */ -enum class BranchMergeMethod -{ - DEPTH_CONCATENATE, /**< Concatenate across depth */ - ADD /**< Adds the results of each stream */ -}; - /** Hints that can be passed to the stream to expose parameterization */ struct StreamHints { -- cgit v1.2.1