diff options
author | Georgios Pinitas <georgios.pinitas@arm.com> | 2020-12-04 15:51:34 +0000 |
---|---|---|
committer | Michele Di Giorgio <michele.digiorgio@arm.com> | 2020-12-10 10:44:54 +0000 |
commit | 0b1c2db5c29ed80b7f4dd0c4fd6d4ed91b3d1538 (patch) | |
tree | 4d59e2627ad5d094ff80976488a5488982764d85 /src/graph | |
parent | ec2256b81e6d6f655dcfbc76683738fbfeb82bcc (diff) | |
download | ComputeLibrary-0b1c2db5c29ed80b7f4dd0c4fd6d4ed91b3d1538.tar.gz |
Remove (NE/CL)YoloLayer support
YOLO layer is too specialized and specific to a single model type. Can
be decomposed using split, activation and concatenate layers
Partially Resolves: COMPMID-3996
Signed-off-by: Georgios Pinitas <georgios.pinitas@arm.com>
Change-Id: I3cde88f8d4cc7d8c70ce1bb3b32b00f8d09bdca2
Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/4678
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Reviewed-by: Michele Di Giorgio <michele.digiorgio@arm.com>
Diffstat (limited to 'src/graph')
-rw-r--r-- | src/graph/GraphBuilder.cpp | 45 | ||||
-rw-r--r-- | src/graph/backends/CL/CLFunctionsFactory.cpp | 2 | ||||
-rw-r--r-- | src/graph/backends/CL/CLNodeValidator.cpp | 2 | ||||
-rw-r--r-- | src/graph/backends/NEON/NEFunctionFactory.cpp | 4 | ||||
-rw-r--r-- | src/graph/backends/NEON/NENodeValidator.cpp | 4 | ||||
-rw-r--r-- | src/graph/nodes/SliceLayerNode.cpp | 4 | ||||
-rw-r--r-- | src/graph/nodes/YOLOLayerNode.cpp | 84 |
7 files changed, 48 insertions, 97 deletions
diff --git a/src/graph/GraphBuilder.cpp b/src/graph/GraphBuilder.cpp index 2f74f065d5..2afc1e2533 100644 --- a/src/graph/GraphBuilder.cpp +++ b/src/graph/GraphBuilder.cpp @@ -737,9 +737,50 @@ NodeID GraphBuilder::add_upsample_node(Graph &g, NodeParams params, NodeIdxPair return create_simple_single_input_output_node<UpsampleLayerNode>(g, params, input, info, upsampling_policy); } -NodeID GraphBuilder::add_yolo_node(Graph &g, NodeParams params, NodeIdxPair input, ActivationLayerInfo act_info, int32_t num_classes) +NodeID GraphBuilder::add_yolo_node(Graph &g, NodeParams params, NodeIdxPair input, ActivationLayerInfo act_info) { - return create_simple_single_input_output_node<YOLOLayerNode>(g, params, input, act_info, num_classes); + check_nodeidx_pair(input, g); + + // Get input tensor descriptor + const TensorDescriptor input_tensor_desc = get_tensor_descriptor(g, g.node(input.node_id)->outputs()[0]); + const bool is_nhwc = input_tensor_desc.layout == DataLayout::NHWC; + + // Box format: [Objectness:1][Box:4][Classes:N] + + // Activate objectness and front part of the box + const Coordinates box_start(0, 0, 0); + const Coordinates box_end = is_nhwc ? Coordinates(3, -1, -1) : Coordinates(-1, -1, 3); + NodeID box = g.add_node<SliceLayerNode>(box_start, box_end); + NodeID act_box = g.add_node<ActivationLayerNode>(act_info); + set_node_params(g, box, params); + set_node_params(g, act_box, params); + g.add_connection(input.node_id, input.index, box, 0); + g.add_connection(box, 0, act_box, 0); + + // Immutable part + const Coordinates imm_start = is_nhwc ? Coordinates(3, 0, 0) : Coordinates(0, 0, 3); + const Coordinates imm_end = is_nhwc ? Coordinates(5, -1, -1) : Coordinates(-1, -1, 5); + NodeID imm = g.add_node<SliceLayerNode>(imm_start, imm_end); + set_node_params(g, imm, params); + g.add_connection(input.node_id, input.index, imm, 0); + + // Activation classes and end part of box + const Coordinates cls_start = is_nhwc ? Coordinates(5, 0, 0) : Coordinates(0, 0, 5); + const Coordinates cls_end = is_nhwc ? Coordinates(-1, -1, -1) : Coordinates(-1, -1, -1); + NodeID cls = g.add_node<SliceLayerNode>(cls_start, cls_end); + NodeID cls_act = g.add_node<ActivationLayerNode>(act_info); + set_node_params(g, cls, params); + set_node_params(g, cls_act, params); + g.add_connection(input.node_id, input.index, cls, 0); + g.add_connection(cls, 0, cls_act, 0); + + NodeID concat = g.add_node<ConcatenateLayerNode>(3, descriptors::ConcatLayerDescriptor(DataLayoutDimension::CHANNEL)); + set_node_params(g, concat, params); + g.add_connection(act_box, 0, concat, 0); + g.add_connection(imm, 0, concat, 1); + g.add_connection(cls_act, 0, concat, 2); + + return concat; } } // namespace graph } // namespace arm_compute diff --git a/src/graph/backends/CL/CLFunctionsFactory.cpp b/src/graph/backends/CL/CLFunctionsFactory.cpp index 641dcc36ce..eec01ff686 100644 --- a/src/graph/backends/CL/CLFunctionsFactory.cpp +++ b/src/graph/backends/CL/CLFunctionsFactory.cpp @@ -317,8 +317,6 @@ std::unique_ptr<IFunction> CLFunctionFactory::create(INode *node, GraphContext & return detail::create_strided_slice_layer<CLStridedSlice, CLTargetInfo>(*polymorphic_downcast<StridedSliceLayerNode *>(node)); case NodeType::UpsampleLayer: return detail::create_upsample_layer<CLUpsampleLayer, CLTargetInfo>(*polymorphic_downcast<UpsampleLayerNode *>(node), ctx); - case NodeType::YOLOLayer: - return detail::create_yolo_layer<CLYOLOLayer, CLTargetInfo>(*polymorphic_downcast<YOLOLayerNode *>(node), ctx); default: return nullptr; } diff --git a/src/graph/backends/CL/CLNodeValidator.cpp b/src/graph/backends/CL/CLNodeValidator.cpp index 830f54ce3f..aef93c6543 100644 --- a/src/graph/backends/CL/CLNodeValidator.cpp +++ b/src/graph/backends/CL/CLNodeValidator.cpp @@ -125,8 +125,6 @@ Status CLNodeValidator::validate(INode *node) return detail::validate_strided_slice_layer<CLStridedSlice>(*polymorphic_downcast<StridedSliceLayerNode *>(node)); case NodeType::UpsampleLayer: return detail::validate_upsample_layer<CLUpsampleLayer>(*polymorphic_downcast<UpsampleLayerNode *>(node)); - case NodeType::YOLOLayer: - return detail::validate_yolo_layer<CLYOLOLayer>(*polymorphic_downcast<YOLOLayerNode *>(node)); case NodeType::EltwiseLayer: return detail::validate_eltwise_Layer<CLEltwiseLayerFunctions>(*polymorphic_downcast<EltwiseLayerNode *>(node)); case NodeType::UnaryEltwiseLayer: diff --git a/src/graph/backends/NEON/NEFunctionFactory.cpp b/src/graph/backends/NEON/NEFunctionFactory.cpp index d070433e4d..1115851b49 100644 --- a/src/graph/backends/NEON/NEFunctionFactory.cpp +++ b/src/graph/backends/NEON/NEFunctionFactory.cpp @@ -192,6 +192,8 @@ std::unique_ptr<IFunction> NEFunctionFactory::create(INode *node, GraphContext & return detail::create_reshape_layer<NEReshapeLayer, NETargetInfo>(*polymorphic_downcast<ReshapeLayerNode *>(node)); case NodeType::ResizeLayer: return detail::create_resize_layer<NEScale, NETargetInfo>(*polymorphic_downcast<ResizeLayerNode *>(node)); + case NodeType::SliceLayer: + return detail::create_slice_layer<NESlice, NETargetInfo>(*polymorphic_downcast<SliceLayerNode *>(node)); case NodeType::SoftmaxLayer: return detail::create_softmax_layer<NESoftmaxLayer, NETargetInfo>(*polymorphic_downcast<SoftmaxLayerNode *>(node), ctx); case NodeType::StackLayer: @@ -200,8 +202,6 @@ std::unique_ptr<IFunction> NEFunctionFactory::create(INode *node, GraphContext & return detail::create_strided_slice_layer<NEStridedSlice, NETargetInfo>(*polymorphic_downcast<StridedSliceLayerNode *>(node)); case NodeType::UpsampleLayer: return detail::create_upsample_layer<NEUpsampleLayer, NETargetInfo>(*polymorphic_downcast<UpsampleLayerNode *>(node), ctx); - case NodeType::YOLOLayer: - return detail::create_yolo_layer<NEYOLOLayer, NETargetInfo>(*polymorphic_downcast<YOLOLayerNode *>(node), ctx); default: return nullptr; } diff --git a/src/graph/backends/NEON/NENodeValidator.cpp b/src/graph/backends/NEON/NENodeValidator.cpp index a9e5a86249..9fa61bc311 100644 --- a/src/graph/backends/NEON/NENodeValidator.cpp +++ b/src/graph/backends/NEON/NENodeValidator.cpp @@ -122,13 +122,11 @@ Status NENodeValidator::validate(INode *node) case NodeType::ROIAlignLayer: return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : ROIAlignLayer"); case NodeType::SliceLayer: - return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation : SliceLayer"); + return detail::validate_slice_layer<NESlice>(*polymorphic_downcast<SliceLayerNode *>(node)); case NodeType::StridedSliceLayer: return detail::validate_strided_slice_layer<NEStridedSlice>(*polymorphic_downcast<StridedSliceLayerNode *>(node)); case NodeType::UpsampleLayer: return detail::validate_upsample_layer<NEUpsampleLayer>(*polymorphic_downcast<UpsampleLayerNode *>(node)); - case NodeType::YOLOLayer: - return detail::validate_yolo_layer<NEYOLOLayer>(*polymorphic_downcast<YOLOLayerNode *>(node)); case NodeType::EltwiseLayer: return detail::validate_eltwise_Layer<NEEltwiseLayerFunctions>(*polymorphic_downcast<EltwiseLayerNode *>(node)); case NodeType::UnaryEltwiseLayer: diff --git a/src/graph/nodes/SliceLayerNode.cpp b/src/graph/nodes/SliceLayerNode.cpp index 3bd6752420..b7655b9eae 100644 --- a/src/graph/nodes/SliceLayerNode.cpp +++ b/src/graph/nodes/SliceLayerNode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Arm Limited. + * Copyright (c) 2018-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -32,7 +32,7 @@ namespace arm_compute { namespace graph { -SliceLayerNode::SliceLayerNode(Coordinates &starts, Coordinates &ends) +SliceLayerNode::SliceLayerNode(const Coordinates &starts, const Coordinates &ends) : _starts(starts), _ends(ends) { _input_edges.resize(1, EmptyEdgeID); diff --git a/src/graph/nodes/YOLOLayerNode.cpp b/src/graph/nodes/YOLOLayerNode.cpp deleted file mode 100644 index b29dd0380f..0000000000 --- a/src/graph/nodes/YOLOLayerNode.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2018 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. - */ -#include "arm_compute/graph/nodes/YOLOLayerNode.h" - -#include "arm_compute/graph/Graph.h" -#include "arm_compute/graph/INodeVisitor.h" -#include "arm_compute/graph/Utils.h" - -namespace arm_compute -{ -namespace graph -{ -YOLOLayerNode::YOLOLayerNode(ActivationLayerInfo act_info, int32_t num_classes) - : _act_info(act_info), _num_classes(num_classes) -{ - _input_edges.resize(1, EmptyEdgeID); - _outputs.resize(1, NullTensorID); -} - -ActivationLayerInfo YOLOLayerNode::activation_info() const -{ - return _act_info; -} - -int32_t YOLOLayerNode::num_classes() const -{ - return _num_classes; -} - -bool YOLOLayerNode::forward_descriptors() -{ - if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) - { - Tensor *dst = output(0); - ARM_COMPUTE_ERROR_ON(dst == nullptr); - dst->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor YOLOLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); - - const Tensor *src = input(0); - ARM_COMPUTE_ERROR_ON(src == nullptr); - - return src->desc(); -} - -NodeType YOLOLayerNode::type() const -{ - return NodeType::YOLOLayer; -} - -void YOLOLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph -} // namespace arm_compute
\ No newline at end of file |