From 6e9d0e048b48712f4f72d4b0a5b94a277391a357 Mon Sep 17 00:00:00 2001 From: Giorgio Arena Date: Fri, 3 Jan 2020 15:02:04 +0000 Subject: COMPMID-2856 Add PrintLayer at graph level Signed-off-by: Giorgio Arena Change-Id: I8f02bb67adae8cc7d884f2417cc9c408985f0d5a Reviewed-on: https://review.mlplatform.org/c/2546 Reviewed-by: Manuel Bottini Reviewed-by: Michele Di Giorgio Comments-Addressed: Arm Jenkins Tested-by: Arm Jenkins Reviewed-by: Georgios Pinitas --- arm_compute/graph/GraphBuilder.h | 15 +++++- arm_compute/graph/INodeVisitor.h | 11 +++- arm_compute/graph/TypePrinter.h | 5 +- arm_compute/graph/Types.h | 3 +- arm_compute/graph/Utils.h | 8 ++- arm_compute/graph/Workload.h | 4 +- arm_compute/graph/backends/FunctionHelpers.h | 31 ++++++++++- arm_compute/graph/frontend/Layers.h | 59 ++++++++++++++++++++- arm_compute/graph/nodes/Nodes.h | 3 +- arm_compute/graph/nodes/NodesFwd.h | 3 +- arm_compute/graph/nodes/PrintLayerNode.h | 79 ++++++++++++++++++++++++++++ 11 files changed, 210 insertions(+), 11 deletions(-) create mode 100644 arm_compute/graph/nodes/PrintLayerNode.h (limited to 'arm_compute') diff --git a/arm_compute/graph/GraphBuilder.h b/arm_compute/graph/GraphBuilder.h index c178ae16e0..33c222dbd6 100644 --- a/arm_compute/graph/GraphBuilder.h +++ b/arm_compute/graph/GraphBuilder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -366,6 +366,19 @@ public: * @return Node ID of the created node, EmptyNodeID in case of error */ static NodeID add_pooling_node(Graph &g, NodeParams params, NodeIdxPair input, PoolingLayerInfo pool_info); + /** Adds a print 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 print layer node as a NodeID-Index pair + * @param[in] stream Output stream. + * @param[in] format_info (Optional) Format info. + * @param[in] transform (Optional) Transformation function to be applied to the input tensor before printing. + * + * @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 transform = nullptr); /** Adds a priorbox layer node to the graph * * @param[in] g Graph to add the node to diff --git a/arm_compute/graph/INodeVisitor.h b/arm_compute/graph/INodeVisitor.h index 59eddda4aa..25018d425a 100644 --- a/arm_compute/graph/INodeVisitor.h +++ b/arm_compute/graph/INodeVisitor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -136,6 +136,11 @@ public: * @param[in] n Node to visit. */ virtual void visit(PoolingLayerNode &n) = 0; + /** Visit PrintLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(PrintLayerNode &n) = 0; /** Visit PriorBoxLayerNode. * * @param[in] n Node to visit. @@ -261,6 +266,10 @@ public: { default_visit(); } + virtual void visit(PrintLayerNode &) override + { + default_visit(); + } virtual void visit(PriorBoxLayerNode &) override { default_visit(); diff --git a/arm_compute/graph/TypePrinter.h b/arm_compute/graph/TypePrinter.h index 243a8938d7..7072b556ae 100644 --- a/arm_compute/graph/TypePrinter.h +++ b/arm_compute/graph/TypePrinter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -128,6 +128,9 @@ inline ::std::ostream &operator<<(::std::ostream &os, const NodeType &node_type) case NodeType::PoolingLayer: os << "PoolingLayer"; break; + case NodeType::PrintLayer: + os << "PrintLayer"; + break; case NodeType::PriorBoxLayer: os << "PriorBoxLayer"; break; diff --git a/arm_compute/graph/Types.h b/arm_compute/graph/Types.h index cd4da694d2..6a488d109a 100644 --- a/arm_compute/graph/Types.h +++ b/arm_compute/graph/Types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -153,6 +153,7 @@ enum class NodeType PadLayer, PermuteLayer, PoolingLayer, + PrintLayer, PriorBoxLayer, QuantizationLayer, ReorgLayer, diff --git a/arm_compute/graph/Utils.h b/arm_compute/graph/Utils.h index 57a6f14bae..cb421fc55a 100644 --- a/arm_compute/graph/Utils.h +++ b/arm_compute/graph/Utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -34,6 +34,12 @@ namespace graph // Forward Declaration class GraphContext; +inline bool is_utility_node(INode *node) +{ + std::set utility_node_types = { NodeType::PrintLayer }; + return utility_node_types.find(node->type()) != utility_node_types.end(); +} + /** Returns the tensor descriptor of a given tensor * * @param[in] g Graph that the tensor belongs to diff --git a/arm_compute/graph/Workload.h b/arm_compute/graph/Workload.h index 3f70181f59..a36c28a181 100644 --- a/arm_compute/graph/Workload.h +++ b/arm_compute/graph/Workload.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -25,6 +25,7 @@ #define ARM_COMPUTE_GRAPH_WORKLOAD_H #include "arm_compute/graph/GraphContext.h" +#include "arm_compute/graph/Tensor.h" #include "arm_compute/runtime/IFunction.h" #include "arm_compute/runtime/IMemoryGroup.h" @@ -39,7 +40,6 @@ namespace graph // Forward declarations class ITensorHandle; class INode; -class Tensor; class Graph; struct ExecutionTask; diff --git a/arm_compute/graph/backends/FunctionHelpers.h b/arm_compute/graph/backends/FunctionHelpers.h index a02e323b8d..bf0250c623 100644 --- a/arm_compute/graph/backends/FunctionHelpers.h +++ b/arm_compute/graph/backends/FunctionHelpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -1149,6 +1149,35 @@ std::unique_ptr create_pooling_layer(PoolingLayerNode &node) return std::move(func); } +/** Create a backend print layer function + * + * @tparam TargetInfo Target-specific information + * + * @param[in] node Node to create the backend function for + * + * @return Backend print layer function + */ +template +std::unique_ptr create_print_layer(PrintLayerNode &node) +{ + validate_node(node, 1 /* expected inputs */, 1 /* expected outputs */); + + typename TargetInfo::TensorType *input = get_backing_tensor(node.input(0)); + ARM_COMPUTE_ERROR_ON(input == nullptr); + 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); + + return nullptr; +} + /** Create a backend priorbox layer function * * @tparam PriorBoxLayerFunction Backend priorbox function diff --git a/arm_compute/graph/frontend/Layers.h b/arm_compute/graph/frontend/Layers.h index ec69350f86..2b44d0e844 100644 --- a/arm_compute/graph/frontend/Layers.h +++ b/arm_compute/graph/frontend/Layers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -902,6 +902,63 @@ private: PoolingLayerInfo _pool_info; }; +/** Print Layer */ +class PrintLayer final : public ILayer +{ +public: + /** Construct a print layer. + * + * Example usage to locally dequantize and print a tensor: + * + * Tensor *output = new Tensor(); + * const auto transform = [output](ITensor *input) + * { + * output->allocator()->init(*input->info()); + * output->info()->set_data_type(DataType::F32); + * output->allocator()->allocate(); + * + * Window win; + * win.use_tensor_dimensions(input->info()->tensor_shape()); + * Iterator in(input, win); + * Iterator out(output, win); + * execute_window_loop(win, [&](const Coordinates &) + * { + * *(reinterpret_cast(out.ptr())) = dequantize_qasymm8(*in.ptr(), input->info()->quantization_info().uniform()); + * }, in, out); + * + * return output; + * }; + * + * graph << InputLayer(input_descriptor.set_quantization_info(in_quant_info), get_input_accessor(common_params, nullptr, false)) + * << ... + * << \\ CNN Layers + * << ... + * << PrintLayer(std::cout, IOFormatInfo(), transform) + * << ... + * << OutputLayer(get_output_accessor(common_params, 5)); + * + * @param[in] stream Output stream. + * @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 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 }; + return GraphBuilder::add_print_node(s.graph(), common_params, input, _stream, _format_info, _transform); + } + +private: + std::ostream &_stream; + const IOFormatInfo &_format_info; + const std::function _transform; +}; + /** PriorBox Layer */ class PriorBoxLayer final : public ILayer { diff --git a/arm_compute/graph/nodes/Nodes.h b/arm_compute/graph/nodes/Nodes.h index 830e8fad85..37cc9e46bd 100644 --- a/arm_compute/graph/nodes/Nodes.h +++ b/arm_compute/graph/nodes/Nodes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ #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/PrintLayerNode.h" #include "arm_compute/graph/nodes/PriorBoxLayerNode.h" #include "arm_compute/graph/nodes/QuantizationLayerNode.h" #include "arm_compute/graph/nodes/ROIAlignLayerNode.h" diff --git a/arm_compute/graph/nodes/NodesFwd.h b/arm_compute/graph/nodes/NodesFwd.h index f41523be10..0fe86b0970 100644 --- a/arm_compute/graph/nodes/NodesFwd.h +++ b/arm_compute/graph/nodes/NodesFwd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -56,6 +56,7 @@ class OutputNode; class PadLayerNode; class PermuteLayerNode; class PoolingLayerNode; +class PrintLayerNode; class PriorBoxLayerNode; class QuantizationLayerNode; class ReorgLayerNode; diff --git a/arm_compute/graph/nodes/PrintLayerNode.h b/arm_compute/graph/nodes/PrintLayerNode.h new file mode 100644 index 0000000000..78b7bf212c --- /dev/null +++ b/arm_compute/graph/nodes/PrintLayerNode.h @@ -0,0 +1,79 @@ +/* + * 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_PRINT_LAYER_NODE_H +#define ARM_COMPUTE_GRAPH_PRINT_LAYER_NODE_H + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +// Forward declarations +class ITensor; + +namespace graph +{ +/** Print Layer node */ +class PrintLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] stream Output stream. + * @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 transform = nullptr); + + /** Stream metadata accessor + * + * @return Print Layer stream + */ + std::ostream &stream() const; + + /** Formatting metadata accessor + * + * @return Print Layer format info + */ + const IOFormatInfo format_info() const; + + /** Transform function metadata accessor + * + * @return Print Layer transform function + */ + const std::function transform() 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: + std::ostream &_stream; + const IOFormatInfo _format_info; + const std::function _transform; +}; +} // namespace graph +} // namespace arm_compute +#endif /* ARM_COMPUTE_GRAPH_PRINT_LAYER_NODE_H */ -- cgit v1.2.1