aboutsummaryrefslogtreecommitdiff
path: root/arm_compute/graph
diff options
context:
space:
mode:
authorIsabella Gottardi <isabella.gottardi@arm.com>2019-01-08 13:48:44 +0000
committerIsabella Gottardi <isabella.gottardi@arm.com>2019-08-06 07:58:16 +0000
commita7acb3cbabeb66ce647684466a04c96b2963c9c9 (patch)
tree7988b75372c8ad1dfa3c8d028ab3a603a5e5a047 /arm_compute/graph
parent4746326ecb075dcfa123aaa8b38de5ec3e534b60 (diff)
downloadComputeLibrary-a7acb3cbabeb66ce647684466a04c96b2963c9c9.tar.gz
COMPMID-1849: Implement CPPDetectionPostProcessLayer
* Add DetectionPostProcessLayer * Add DetectionPostProcessLayer at the graph Change-Id: I7e56f6cffc26f112d26dfe74853085bb8ec7d849 Signed-off-by: Isabella Gottardi <isabella.gottardi@arm.com> Reviewed-on: https://review.mlplatform.org/c/1639 Reviewed-by: Giuseppe Rossini <giuseppe.rossini@arm.com> Tested-by: Arm Jenkins <bsgcomp@arm.com>
Diffstat (limited to 'arm_compute/graph')
-rw-r--r--arm_compute/graph/GraphBuilder.h15
-rw-r--r--arm_compute/graph/INodeVisitor.h9
-rw-r--r--arm_compute/graph/TypePrinter.h3
-rw-r--r--arm_compute/graph/Types.h2
-rw-r--r--arm_compute/graph/backends/FunctionHelpers.h56
-rw-r--r--arm_compute/graph/backends/ValidateHelpers.h27
-rw-r--r--arm_compute/graph/frontend/Layers.h33
-rw-r--r--arm_compute/graph/nodes/DetectionPostProcessLayerNode.h62
-rw-r--r--arm_compute/graph/nodes/Nodes.h1
-rw-r--r--arm_compute/graph/nodes/NodesFwd.h1
10 files changed, 209 insertions, 0 deletions
diff --git a/arm_compute/graph/GraphBuilder.h b/arm_compute/graph/GraphBuilder.h
index e1049ca938..dc41ed5367 100644
--- a/arm_compute/graph/GraphBuilder.h
+++ b/arm_compute/graph/GraphBuilder.h
@@ -217,6 +217,21 @@ 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);
+ /** Adds a detection post process layer node to the graph
+ *
+ * @param[in] g Graph to add the node to
+ * @param[in] params Common node parameters
+ * @param[in] input_box_encoding Boxes input to the detection output layer node as a NodeID-Index pair
+ * @param[in] input_class_prediction Class prediction input to the detection output layer node as a NodeID-Index pair
+ * @param[in] detect_info Detection output layer parameters
+ * @param[in] anchors_accessor (Optional) Const Node ID that contains the anchor values
+ * @param[in] anchor_quant_info (Optional) Anchor quantization info
+ *
+ * @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,
+ const QuantizationInfo &anchor_quant_info = QuantizationInfo());
/** Adds a Dummy node to the graph
*
* @note this node if for debugging purposes. Just alters the shape of the graph pipeline as requested.
diff --git a/arm_compute/graph/INodeVisitor.h b/arm_compute/graph/INodeVisitor.h
index 5c5b777ac9..f97906d02a 100644
--- a/arm_compute/graph/INodeVisitor.h
+++ b/arm_compute/graph/INodeVisitor.h
@@ -76,6 +76,11 @@ public:
* @param[in] n Node to visit.
*/
virtual void visit(DetectionOutputLayerNode &n) = 0;
+ /** Visit DetectionPostProcessLayerNode.
+ *
+ * @param[in] n Node to visit.
+ */
+ virtual void visit(DetectionPostProcessLayerNode &n) = 0;
/** Visit EltwiseLayerNode.
*
* @param[in] n Node to visit.
@@ -199,6 +204,10 @@ public:
{
default_visit();
}
+ virtual void visit(DetectionPostProcessLayerNode &n) override
+ {
+ default_visit();
+ }
virtual void visit(DepthwiseConvolutionLayerNode &n) override
{
default_visit();
diff --git a/arm_compute/graph/TypePrinter.h b/arm_compute/graph/TypePrinter.h
index 9da0e6157c..e4188125b9 100644
--- a/arm_compute/graph/TypePrinter.h
+++ b/arm_compute/graph/TypePrinter.h
@@ -86,6 +86,9 @@ inline ::std::ostream &operator<<(::std::ostream &os, const NodeType &node_type)
case NodeType::DetectionOutputLayer:
os << "DetectionOutputLayer";
break;
+ case NodeType::DetectionPostProcessLayer:
+ os << "DetectionPostProcessLayer";
+ break;
case NodeType::DepthwiseConvolutionLayer:
os << "DepthwiseConvolutionLayer";
break;
diff --git a/arm_compute/graph/Types.h b/arm_compute/graph/Types.h
index 9f962425b3..8b97708a63 100644
--- a/arm_compute/graph/Types.h
+++ b/arm_compute/graph/Types.h
@@ -48,6 +48,7 @@ using arm_compute::PermutationVector;
using arm_compute::ActivationLayerInfo;
using arm_compute::DetectionOutputLayerInfo;
+using arm_compute::DetectionPostProcessLayerInfo;
using arm_compute::NormType;
using arm_compute::NormalizationLayerInfo;
using arm_compute::FullyConnectedLayerInfo;
@@ -137,6 +138,7 @@ enum class NodeType
DeconvolutionLayer,
DepthwiseConvolutionLayer,
DetectionOutputLayer,
+ DetectionPostProcessLayer,
EltwiseLayer,
FlattenLayer,
FullyConnectedLayer,
diff --git a/arm_compute/graph/backends/FunctionHelpers.h b/arm_compute/graph/backends/FunctionHelpers.h
index ed5b35c0d1..dd833061a9 100644
--- a/arm_compute/graph/backends/FunctionHelpers.h
+++ b/arm_compute/graph/backends/FunctionHelpers.h
@@ -644,6 +644,62 @@ std::unique_ptr<IFunction> create_detection_output_layer(DetectionOutputLayerNod
return std::move(func);
}
+
+/** Create a backend detection post process layer function
+ *
+ * @tparam DetectionPostProcessLayerFunction Backend detection output function
+ * @tparam TargetInfo Target-specific information
+ *
+ * @param[in] node Node to create the backend function for
+ *
+ * @return Backend detection post process layer function
+ */
+template <typename DetectionPostProcessLayerFunction, typename TargetInfo>
+std::unique_ptr<IFunction> create_detection_post_process_layer(DetectionPostProcessLayerNode &node)
+{
+ validate_node<TargetInfo>(node, 3 /* expected inputs */, 4 /* expected outputs */);
+
+ // Extract IO and info
+ typename TargetInfo::TensorType *input0 = get_backing_tensor<TargetInfo>(node.input(0));
+ typename TargetInfo::TensorType *input1 = get_backing_tensor<TargetInfo>(node.input(1));
+ typename TargetInfo::TensorType *input2 = get_backing_tensor<TargetInfo>(node.input(2));
+ typename TargetInfo::TensorType *output0 = get_backing_tensor<TargetInfo>(node.output(0));
+ typename TargetInfo::TensorType *output1 = get_backing_tensor<TargetInfo>(node.output(1));
+ typename TargetInfo::TensorType *output2 = get_backing_tensor<TargetInfo>(node.output(2));
+ typename TargetInfo::TensorType *output3 = get_backing_tensor<TargetInfo>(node.output(3));
+ const DetectionPostProcessLayerInfo detect_info = node.detection_post_process_info();
+
+ ARM_COMPUTE_ERROR_ON(input0 == nullptr);
+ ARM_COMPUTE_ERROR_ON(input1 == nullptr);
+ ARM_COMPUTE_ERROR_ON(input2 == nullptr);
+ ARM_COMPUTE_ERROR_ON(output0 == nullptr);
+ ARM_COMPUTE_ERROR_ON(output1 == nullptr);
+ ARM_COMPUTE_ERROR_ON(output2 == nullptr);
+ ARM_COMPUTE_ERROR_ON(output3 == nullptr);
+
+ // Create and configure function
+ auto func = support::cpp14::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()
+ << " 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);
+
+ return std::move(func);
+}
+
/** Create a backend element-wise operation layer function
*
* @tparam EltwiseFunctions Backend element-wise function
diff --git a/arm_compute/graph/backends/ValidateHelpers.h b/arm_compute/graph/backends/ValidateHelpers.h
index 3a5686336b..13de273bdf 100644
--- a/arm_compute/graph/backends/ValidateHelpers.h
+++ b/arm_compute/graph/backends/ValidateHelpers.h
@@ -228,6 +228,33 @@ Status validate_detection_output_layer(DetectionOutputLayerNode &node)
return DetectionOutputLayer::validate(input0, input1, input2, output, detect_info);
}
+/** Validates a detection post process layer node
+ *
+ * @tparam DetectionPostProcessLayer DetectionOutput layer type
+ *
+ * @param[in] node Node to validate
+ *
+ * @return Status
+ */
+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_RETURN_ERROR_ON(node.num_inputs() != 3);
+ ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 4);
+
+ // Extract IO and info
+ arm_compute::ITensorInfo *input0 = get_backing_tensor_info(node.input(0));
+ arm_compute::ITensorInfo *input1 = get_backing_tensor_info(node.input(1));
+ arm_compute::ITensorInfo *input2 = get_backing_tensor_info(node.input(2));
+ arm_compute::ITensorInfo *output0 = get_backing_tensor_info(node.output(0));
+ arm_compute::ITensorInfo *output1 = get_backing_tensor_info(node.output(1));
+ arm_compute::ITensorInfo *output2 = get_backing_tensor_info(node.output(2));
+ arm_compute::ITensorInfo *output3 = get_backing_tensor_info(node.output(3));
+ const DetectionPostProcessLayerInfo detect_info = node.detection_post_process_info();
+
+ return DetectionPostProcessLayer::validate(input0, input1, input2, output0, output1, output2, output3, detect_info);
+}
/** Validates a Generate Proposals layer node
*
diff --git a/arm_compute/graph/frontend/Layers.h b/arm_compute/graph/frontend/Layers.h
index 3fc4af46d5..27a0cd3026 100644
--- a/arm_compute/graph/frontend/Layers.h
+++ b/arm_compute/graph/frontend/Layers.h
@@ -493,6 +493,39 @@ private:
SubStream _ss_prior;
DetectionOutputLayerInfo _detect_info;
};
+/** DetectionOutputPostProcess Layer */
+class DetectionPostProcessLayer final : public ILayer
+{
+public:
+ /** Construct a detection output layer.
+ *
+ * @param[in] sub_stream_class_prediction Class prediction graph sub-stream.
+ * @param[in] detect_info DetectionOutput parameters.
+ * @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))
+ {
+ }
+
+ NodeID create_layer(IStream &s) override
+ {
+ 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));
+ }
+
+private:
+ SubStream _sub_stream_class_prediction;
+ DetectionPostProcessLayerInfo _detect_info;
+ ITensorAccessorUPtr _anchors;
+ const QuantizationInfo _out_quant_info;
+};
/** Dummy Layer */
class DummyLayer final : public ILayer
{
diff --git a/arm_compute/graph/nodes/DetectionPostProcessLayerNode.h b/arm_compute/graph/nodes/DetectionPostProcessLayerNode.h
new file mode 100644
index 0000000000..76b1d8ce98
--- /dev/null
+++ b/arm_compute/graph/nodes/DetectionPostProcessLayerNode.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 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_DETECTION_POST_PROCESS_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_DETECTION_POST_PROCESS_LAYER_NODE_H__
+
+#include "arm_compute/graph/INode.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+/** DetectionPostProcess Layer node */
+class DetectionPostProcessLayerNode final : public INode
+{
+public:
+ /** Constructor
+ *
+ * @param[in] detection_info DetectionPostProcess Layer information
+ */
+ DetectionPostProcessLayerNode(DetectionPostProcessLayerInfo detection_info);
+ /** DetectionPostProcess metadata accessor
+ *
+ * @return DetectionPostProcess Layer info
+ */
+ DetectionPostProcessLayerInfo detection_post_process_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:
+ DetectionPostProcessLayerInfo _info;
+
+ static const int kNumCoordBox = 4;
+ static const int kBatchSize = 1;
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_DETECTION_POST_PROCESS_LAYER_NODE_H__ */ \ No newline at end of file
diff --git a/arm_compute/graph/nodes/Nodes.h b/arm_compute/graph/nodes/Nodes.h
index 52e2f88528..1586270093 100644
--- a/arm_compute/graph/nodes/Nodes.h
+++ b/arm_compute/graph/nodes/Nodes.h
@@ -34,6 +34,7 @@
#include "arm_compute/graph/nodes/DeconvolutionLayerNode.h"
#include "arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h"
#include "arm_compute/graph/nodes/DetectionOutputLayerNode.h"
+#include "arm_compute/graph/nodes/DetectionPostProcessLayerNode.h"
#include "arm_compute/graph/nodes/DummyNode.h"
#include "arm_compute/graph/nodes/EltwiseLayerNode.h"
#include "arm_compute/graph/nodes/FlattenLayerNode.h"
diff --git a/arm_compute/graph/nodes/NodesFwd.h b/arm_compute/graph/nodes/NodesFwd.h
index 2c89679902..53f2a6a1b5 100644
--- a/arm_compute/graph/nodes/NodesFwd.h
+++ b/arm_compute/graph/nodes/NodesFwd.h
@@ -40,6 +40,7 @@ class ConvolutionLayerNode;
class DeconvolutionLayerNode;
class DepthwiseConvolutionLayerNode;
class DetectionOutputLayerNode;
+class DetectionPostProcessLayerNode;
class DummyNode;
class EltwiseLayerNode;
class FlattenLayerNode;