aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiorgio Arena <giorgio.arena@arm.com>2020-01-03 15:02:04 +0000
committerMichele Di Giorgio <michele.digiorgio@arm.com>2020-01-16 10:19:25 +0000
commit6e9d0e048b48712f4f72d4b0a5b94a277391a357 (patch)
tree5a2d181062a5ed7d61f8d3621b34022f03e45dd8
parent8c837ca85c06c53ccca20937be9dfd74d00d597a (diff)
downloadComputeLibrary-6e9d0e048b48712f4f72d4b0a5b94a277391a357.tar.gz
COMPMID-2856 Add PrintLayer at graph level
Signed-off-by: Giorgio Arena <giorgio.arena@arm.com> Change-Id: I8f02bb67adae8cc7d884f2417cc9c408985f0d5a Reviewed-on: https://review.mlplatform.org/c/2546 Reviewed-by: Manuel Bottini <manuel.bottini@arm.com> Reviewed-by: Michele Di Giorgio <michele.digiorgio@arm.com> Comments-Addressed: Arm Jenkins <bsgcomp@arm.com> Tested-by: Arm Jenkins <bsgcomp@arm.com> Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
-rw-r--r--arm_compute/graph/GraphBuilder.h15
-rw-r--r--arm_compute/graph/INodeVisitor.h11
-rw-r--r--arm_compute/graph/TypePrinter.h5
-rw-r--r--arm_compute/graph/Types.h3
-rw-r--r--arm_compute/graph/Utils.h8
-rw-r--r--arm_compute/graph/Workload.h4
-rw-r--r--arm_compute/graph/backends/FunctionHelpers.h31
-rw-r--r--arm_compute/graph/frontend/Layers.h59
-rw-r--r--arm_compute/graph/nodes/Nodes.h3
-rw-r--r--arm_compute/graph/nodes/NodesFwd.h3
-rw-r--r--arm_compute/graph/nodes/PrintLayerNode.h79
-rw-r--r--src/core/CL/kernels/CLChannelShuffleLayerKernel.cpp2
-rw-r--r--src/core/utils/io/FileHandler.cpp3
-rw-r--r--src/graph/GraphBuilder.cpp7
-rw-r--r--src/graph/Workload.cpp17
-rw-r--r--src/graph/backends/CL/CLFunctionsFactory.cpp6
-rw-r--r--src/graph/backends/GLES/GCFunctionsFactory.cpp4
-rw-r--r--src/graph/backends/NEON/NEFunctionFactory.cpp4
-rw-r--r--src/graph/detail/CrossLayerMemoryManagerHelpers.cpp5
-rw-r--r--src/graph/detail/ExecutionHelpers.cpp5
-rw-r--r--src/graph/mutators/InPlaceOperationMutator.cpp4
-rw-r--r--src/graph/nodes/PrintLayerNode.cpp91
-rw-r--r--tests/validate_examples/graph_validate_utils.h3
-rw-r--r--tests/validation/CL/GenerateProposalsLayer.cpp6
-rw-r--r--tests/validation/NEON/GenerateProposalsLayer.cpp6
25 files changed, 348 insertions, 36 deletions
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<ITensor *(ITensor *)> 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<NodeType> 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<IFunction> 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 <typename TargetInfo>
+std::unique_ptr<IFunction> create_print_layer(PrintLayerNode &node)
+{
+ validate_node<TargetInfo>(node, 1 /* expected inputs */, 1 /* expected outputs */);
+
+ typename TargetInfo::TensorType *input = get_backing_tensor<TargetInfo>(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<float *>(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<ITensor *(ITensor *)> 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<ITensor *(ITensor *)> _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<ITensor *(ITensor *)> 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<ITensor *(ITensor *)> 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<ITensor *(ITensor *)> _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<cl::Kernel>(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<PoolingLayerNode>(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<ITensor *(ITensor *)> transform)
+{
+ return create_simple_single_input_output_node<PrintLayerNode>(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<PrintLayerNode *>(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<IFunction> create_detection_output_layer<CPPDetectionOutputLayer
<< std::endl);
auto wrap_function = support::cpp14::make_unique<CPPWrapperFunction>();
- ;
+
wrap_function->register_function(std::move(func));
wrap_function->register_tensor(input0);
wrap_function->register_tensor(input1);
@@ -272,6 +272,8 @@ std::unique_ptr<IFunction> CLFunctionFactory::create(INode *node, GraphContext &
return detail::create_permute_layer<CLPermute, CLTargetInfo>(*polymorphic_downcast<PermuteLayerNode *>(node));
case NodeType::PoolingLayer:
return detail::create_pooling_layer<CLPoolingLayer, CLTargetInfo>(*polymorphic_downcast<PoolingLayerNode *>(node));
+ case NodeType::PrintLayer:
+ return detail::create_print_layer<CLTargetInfo>(*polymorphic_downcast<PrintLayerNode *>(node));
case NodeType::PriorBoxLayer:
return detail::create_priorbox_layer<CLPriorBoxLayer, CLTargetInfo>(*polymorphic_downcast<PriorBoxLayerNode *>(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<IFunction> GCFunctionFactory::create(INode *node, GraphContext &
return detail::create_normalize_planar_yuv_layer<GCNormalizePlanarYUVLayer, GCTargetInfo>(*polymorphic_downcast<NormalizePlanarYUVLayerNode *>(node));
case NodeType::PoolingLayer:
return detail::create_pooling_layer<GCPoolingLayer, GCTargetInfo>(*polymorphic_downcast<PoolingLayerNode *>(node));
+ case NodeType::PrintLayer:
+ return detail::create_print_layer<GCTargetInfo>(*polymorphic_downcast<PrintLayerNode *>(node));
case NodeType::ResizeLayer:
return detail::create_resize_layer<GCScale, GCTargetInfo>(*polymorphic_downcast<ResizeLayerNode *>(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<IFunction> NEFunctionFactory::create(INode *node, GraphContext &
return detail::create_permute_layer<NEPermute, NETargetInfo>(*polymorphic_downcast<PermuteLayerNode *>(node));
case NodeType::PoolingLayer:
return detail::create_pooling_layer<NEPoolingLayer, NETargetInfo>(*polymorphic_downcast<PoolingLayerNode *>(node));
+ case NodeType::PrintLayer:
+ return detail::create_print_layer<NETargetInfo>(*polymorphic_downcast<PrintLayerNode *>(node));
case NodeType::PriorBoxLayer:
return detail::create_priorbox_layer<NEPriorBoxLayer, NETargetInfo>(*polymorphic_downcast<PriorBoxLayerNode *>(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<ITensorHandle *> &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<IFunction> 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<NodeType> in_place_nodes = { NodeType::BatchNormalizationLayer, NodeType::ActivationLayer };
+ std::set<NodeType> 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<ITensor *(ITensor *)> 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<ITensor *(ITensor *)> 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<float> anchors_vector{ -26, -19, 87, 86, -81, -27, 58, 63 };
- ;
-
+ std::vector<float> anchors_vector{ -26, -19, 87, 86, -81, -27, 58, 63 };
SimpleTensor<float> proposals_expected(TensorShape(5, 9), DataType::F32);
fill_tensor(proposals_expected, std::vector<float>
{
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<float> anchors_vector{ -26, -19, 87, 86, -81, -27, 58, 63 };
- ;
-
- SimpleTensor<float> proposals_expected(TensorShape(5, 9), DataType::F32);
+ SimpleTensor<float> proposals_expected(TensorShape(5, 9), DataType::F32);
fill_tensor(proposals_expected, std::vector<float>
{
0, 0, 0, 75.269, 64.4388,