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 +++++++++++++++++++ .../CL/kernels/CLChannelShuffleLayerKernel.cpp | 2 +- src/core/utils/io/FileHandler.cpp | 3 +- src/graph/GraphBuilder.cpp | 7 +- src/graph/Workload.cpp | 17 +++- src/graph/backends/CL/CLFunctionsFactory.cpp | 6 +- src/graph/backends/GLES/GCFunctionsFactory.cpp | 4 +- src/graph/backends/NEON/NEFunctionFactory.cpp | 4 +- .../detail/CrossLayerMemoryManagerHelpers.cpp | 5 +- src/graph/detail/ExecutionHelpers.cpp | 5 +- src/graph/mutators/InPlaceOperationMutator.cpp | 4 +- src/graph/nodes/PrintLayerNode.cpp | 91 ++++++++++++++++++++++ tests/validate_examples/graph_validate_utils.h | 3 +- tests/validation/CL/GenerateProposalsLayer.cpp | 6 +- tests/validation/NEON/GenerateProposalsLayer.cpp | 6 +- 25 files changed, 348 insertions(+), 36 deletions(-) create mode 100644 arm_compute/graph/nodes/PrintLayerNode.h create mode 100644 src/graph/nodes/PrintLayerNode.cpp 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 */ diff --git a/src/core/CL/kernels/CLChannelShuffleLayerKernel.cpp b/src/core/CL/kernels/CLChannelShuffleLayerKernel.cpp index 3b533be649..666f8880b0 100644 --- a/src/core/CL/kernels/CLChannelShuffleLayerKernel.cpp +++ b/src/core/CL/kernels/CLChannelShuffleLayerKernel.cpp @@ -114,7 +114,7 @@ void CLChannelShuffleLayerKernel::configure(const ICLTensor *input, ICLTensor *o // Create kernel std::string kernel_name = "channel_shuffle_" + lower_string(string_from_data_layout(data_layout)); - ; + _kernel = static_cast(CLKernelLibrary::get().create_kernel(kernel_name, build_opts.options())); // Configure kernel window diff --git a/src/core/utils/io/FileHandler.cpp b/src/core/utils/io/FileHandler.cpp index 70bce42b0b..a6c16fff4b 100644 --- a/src/core/utils/io/FileHandler.cpp +++ b/src/core/utils/io/FileHandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -43,7 +43,6 @@ FileHandler::~FileHandler() void FileHandler::open(const std::string &filename, std::ios_base::openmode mode) { close(); - ; _filestream.open(filename, mode); ARM_COMPUTE_ERROR_ON(!_filestream.good()); _filename = filename; diff --git a/src/graph/GraphBuilder.cpp b/src/graph/GraphBuilder.cpp index 89c8c20de8..14f919d057 100644 --- a/src/graph/GraphBuilder.cpp +++ b/src/graph/GraphBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -586,6 +586,11 @@ NodeID GraphBuilder::add_pooling_node(Graph &g, NodeParams params, NodeIdxPair i return create_simple_single_input_output_node(g, params, input, pool_info); } +NodeID GraphBuilder::add_print_node(Graph &g, NodeParams params, NodeIdxPair input, std::ostream &stream, const IOFormatInfo &format_info, const std::function transform) +{ + return create_simple_single_input_output_node(g, params, input, stream, format_info, transform); +} + NodeID GraphBuilder::add_priorbox_node(Graph &g, NodeParams params, NodeIdxPair input0, NodeIdxPair input1, const PriorBoxLayerInfo &prior_info) { check_nodeidx_pair(input0, g); diff --git a/src/graph/Workload.cpp b/src/graph/Workload.cpp index d8046c3511..0d2a405288 100644 --- a/src/graph/Workload.cpp +++ b/src/graph/Workload.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -25,6 +25,7 @@ #include "arm_compute/graph/INode.h" #include "arm_compute/graph/ITensorHandle.h" +#include "arm_compute/graph/nodes/PrintLayerNode.h" namespace arm_compute { @@ -41,6 +42,20 @@ void execute_task(ExecutionTask &task) { task.task->run(); } +#ifdef ARM_COMPUTE_ASSERTS_ENABLED + // COMPMID-3012 - Hide the printing logic from the execute_task method in the graph API + else if(task.node->type() == NodeType::PrintLayer) + { + auto print_node = dynamic_cast(task.node); + auto input_handle = print_node->input(0)->handle(); + auto transform = print_node->transform(); + + input_handle->map(true); + ITensor *input = transform ? transform(&input_handle->tensor()) : &input_handle->tensor(); + input->print(print_node->stream(), print_node->format_info()); + input_handle->unmap(); + } +#endif // ARM_COMPUTE_ASSERTS_ENABLED } void ExecutionTask::prepare() diff --git a/src/graph/backends/CL/CLFunctionsFactory.cpp b/src/graph/backends/CL/CLFunctionsFactory.cpp index 57b48b0c67..c841126b1c 100644 --- a/src/graph/backends/CL/CLFunctionsFactory.cpp +++ b/src/graph/backends/CL/CLFunctionsFactory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -151,7 +151,7 @@ std::unique_ptr create_detection_output_layer(); - ; + wrap_function->register_function(std::move(func)); wrap_function->register_tensor(input0); wrap_function->register_tensor(input1); @@ -272,6 +272,8 @@ std::unique_ptr CLFunctionFactory::create(INode *node, GraphContext & return detail::create_permute_layer(*polymorphic_downcast(node)); case NodeType::PoolingLayer: return detail::create_pooling_layer(*polymorphic_downcast(node)); + case NodeType::PrintLayer: + return detail::create_print_layer(*polymorphic_downcast(node)); case NodeType::PriorBoxLayer: return detail::create_priorbox_layer(*polymorphic_downcast(node)); case NodeType::QuantizationLayer: diff --git a/src/graph/backends/GLES/GCFunctionsFactory.cpp b/src/graph/backends/GLES/GCFunctionsFactory.cpp index b9562c70cb..075e7af12b 100644 --- a/src/graph/backends/GLES/GCFunctionsFactory.cpp +++ b/src/graph/backends/GLES/GCFunctionsFactory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -259,6 +259,8 @@ std::unique_ptr GCFunctionFactory::create(INode *node, GraphContext & return detail::create_normalize_planar_yuv_layer(*polymorphic_downcast(node)); case NodeType::PoolingLayer: return detail::create_pooling_layer(*polymorphic_downcast(node)); + case NodeType::PrintLayer: + return detail::create_print_layer(*polymorphic_downcast(node)); case NodeType::ResizeLayer: return detail::create_resize_layer(*polymorphic_downcast(node)); case NodeType::SoftmaxLayer: diff --git a/src/graph/backends/NEON/NEFunctionFactory.cpp b/src/graph/backends/NEON/NEFunctionFactory.cpp index 7ff68b5a40..d72cffabd6 100644 --- a/src/graph/backends/NEON/NEFunctionFactory.cpp +++ b/src/graph/backends/NEON/NEFunctionFactory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -229,6 +229,8 @@ std::unique_ptr NEFunctionFactory::create(INode *node, GraphContext & return detail::create_permute_layer(*polymorphic_downcast(node)); case NodeType::PoolingLayer: return detail::create_pooling_layer(*polymorphic_downcast(node)); + case NodeType::PrintLayer: + return detail::create_print_layer(*polymorphic_downcast(node)); case NodeType::PriorBoxLayer: return detail::create_priorbox_layer(*polymorphic_downcast(node)); case NodeType::QuantizationLayer: diff --git a/src/graph/detail/CrossLayerMemoryManagerHelpers.cpp b/src/graph/detail/CrossLayerMemoryManagerHelpers.cpp index 5e31309c3d..d5192e9b78 100644 --- a/src/graph/detail/CrossLayerMemoryManagerHelpers.cpp +++ b/src/graph/detail/CrossLayerMemoryManagerHelpers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -29,6 +29,7 @@ #include "arm_compute/graph/INode.h" #include "arm_compute/graph/Tensor.h" #include "arm_compute/graph/Types.h" +#include "arm_compute/graph/Utils.h" #include "arm_compute/graph/backends/BackendRegistry.h" #include "arm_compute/core/ITensor.h" @@ -121,7 +122,7 @@ TaskHandles get_transition_handles(GraphContext &ctx, ExecutionTask &task, const std::set &const_tensors) { - ARM_COMPUTE_ERROR_ON(task.node == nullptr || task.task == nullptr); + ARM_COMPUTE_ERROR_ON(task.node == nullptr || (task.task == nullptr && !is_utility_node(task.node))); INode &node = *task.node; TaskHandles transition_handles; diff --git a/src/graph/detail/ExecutionHelpers.cpp b/src/graph/detail/ExecutionHelpers.cpp index 900be42e3f..e9aeb00365 100644 --- a/src/graph/detail/ExecutionHelpers.cpp +++ b/src/graph/detail/ExecutionHelpers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -27,6 +27,7 @@ #include "arm_compute/graph/GraphContext.h" #include "arm_compute/graph/GraphManager.h" #include "arm_compute/graph/Tensor.h" +#include "arm_compute/graph/Utils.h" #include "arm_compute/graph/backends/BackendRegistry.h" namespace arm_compute @@ -147,7 +148,7 @@ ExecutionWorkload configure_all_nodes(Graph &g, GraphContext &ctx, const std::ve Target assigned_target = node->assigned_target(); backends::IDeviceBackend &backend = backends::BackendRegistry::get().get_backend(assigned_target); std::unique_ptr func = backend.configure_node(*node, ctx); - if(func != nullptr) + if(func != nullptr || is_utility_node(node)) { workload.tasks.emplace_back(ExecutionTask(std::move(func), node)); } diff --git a/src/graph/mutators/InPlaceOperationMutator.cpp b/src/graph/mutators/InPlaceOperationMutator.cpp index ef4ca47e48..3b06537cd9 100644 --- a/src/graph/mutators/InPlaceOperationMutator.cpp +++ b/src/graph/mutators/InPlaceOperationMutator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. + * Copyright (c) 2018-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -42,7 +42,7 @@ IGraphMutator::MutationType InPlaceOperationMutator::type() const void InPlaceOperationMutator::mutate(Graph &g) { - std::set in_place_nodes = { NodeType::BatchNormalizationLayer, NodeType::ActivationLayer }; + std::set in_place_nodes = { NodeType::BatchNormalizationLayer, NodeType::ActivationLayer, NodeType::PrintLayer }; // Not interested in the order of nodes for(auto &node : g.nodes()) diff --git a/src/graph/nodes/PrintLayerNode.cpp b/src/graph/nodes/PrintLayerNode.cpp new file mode 100644 index 0000000000..6a1a9933df --- /dev/null +++ b/src/graph/nodes/PrintLayerNode.cpp @@ -0,0 +1,91 @@ +/* + * 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. + */ +#include "arm_compute/graph/nodes/PrintLayerNode.h" + +#include "arm_compute/core/Utils.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" +#include "arm_compute/graph/Utils.h" + +namespace arm_compute +{ +namespace graph +{ +PrintLayerNode::PrintLayerNode(std::ostream &stream, const IOFormatInfo &format_info, const std::function transform) + : _stream(stream), _format_info(format_info), _transform(transform) +{ + _input_edges.resize(1, EmptyEdgeID); + _outputs.resize(1, NullTensorID); +} + +std::ostream &PrintLayerNode::stream() const +{ + return _stream; +} + +const IOFormatInfo PrintLayerNode::format_info() const +{ + return _format_info; +} + +const std::function PrintLayerNode::transform() const +{ + return _transform; +} + +bool PrintLayerNode::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 PrintLayerNode::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); + + TensorDescriptor output_desc = src->desc(); + return output_desc; +} + +NodeType PrintLayerNode::type() const +{ + return NodeType::PrintLayer; +} + +void PrintLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/tests/validate_examples/graph_validate_utils.h b/tests/validate_examples/graph_validate_utils.h index c429072e3b..edc3a6514a 100644 --- a/tests/validate_examples/graph_validate_utils.h +++ b/tests/validate_examples/graph_validate_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited. + * Copyright (c) 2019-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -259,7 +259,6 @@ public: absolute_tolerance->set_help("Absolute tolerance used for verification"); relative_tolerance->set_help("Absolute tolerance used for verification"); tolerance_number->set_help("Absolute tolerance used for verification"); - ; } /** Prevent instances of this class from being copied (As this class contains pointers) */ diff --git a/tests/validation/CL/GenerateProposalsLayer.cpp b/tests/validation/CL/GenerateProposalsLayer.cpp index bfad8e8381..c5ce710c81 100644 --- a/tests/validation/CL/GenerateProposalsLayer.cpp +++ b/tests/validation/CL/GenerateProposalsLayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited. + * Copyright (c) 2019-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -285,9 +285,7 @@ DATA_TEST_CASE(IntegrationTestCaseGenerateProposals, framework::DatasetMode::ALL -2.071168373801788e-03, 8.613893943683627e-03, 9.411190295341036e-03, -6.129018930548372e-03 }; - std::vector anchors_vector{ -26, -19, 87, 86, -81, -27, 58, 63 }; - ; - + std::vector anchors_vector{ -26, -19, 87, 86, -81, -27, 58, 63 }; SimpleTensor proposals_expected(TensorShape(5, 9), DataType::F32); fill_tensor(proposals_expected, std::vector { diff --git a/tests/validation/NEON/GenerateProposalsLayer.cpp b/tests/validation/NEON/GenerateProposalsLayer.cpp index 4ca2d57863..dd9c1eff0a 100644 --- a/tests/validation/NEON/GenerateProposalsLayer.cpp +++ b/tests/validation/NEON/GenerateProposalsLayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited. + * Copyright (c) 2019-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -286,9 +286,7 @@ DATA_TEST_CASE(IntegrationTestCaseGenerateProposals, framework::DatasetMode::ALL }; const std::vector anchors_vector{ -26, -19, 87, 86, -81, -27, 58, 63 }; - ; - - SimpleTensor proposals_expected(TensorShape(5, 9), DataType::F32); + SimpleTensor proposals_expected(TensorShape(5, 9), DataType::F32); fill_tensor(proposals_expected, std::vector { 0, 0, 0, 75.269, 64.4388, -- cgit v1.2.1