aboutsummaryrefslogtreecommitdiff
path: root/src/graph
diff options
context:
space:
mode:
authorGeorgios Pinitas <georgios.pinitas@arm.com>2017-10-18 17:29:27 +0100
committerAnthony Barbier <anthony.barbier@arm.com>2018-11-02 16:35:24 +0000
commit0c29cd3aac40e512d648506b1b3b8332bb45f063 (patch)
treed1ca728a9adf233f590ab7dfff8e627166c30b83 /src/graph
parentdaaa1fa506834c9d9ff44e5b38f05781ec416912 (diff)
downloadComputeLibrary-0c29cd3aac40e512d648506b1b3b8332bb45f063.tar.gz
COMPMID-630 : Rework nodes for selective target compilation.
Reworked nodes: -ActivationLayer Change-Id: Iaa394531ef208db48caa2c18a41ad9a845471f94 Reviewed-on: http://mpd-gerrit.cambridge.arm.com/92281 Tested-by: Kaizen <jeremy.johnson+kaizengerrit@arm.com> Reviewed-by: Anthony Barbier <anthony.barbier@arm.com>
Diffstat (limited to 'src/graph')
-rw-r--r--src/graph/NodeContext.cpp70
-rw-r--r--src/graph/OperationRegistry.cpp61
-rw-r--r--src/graph/nodes/ActivationLayer.cpp63
-rw-r--r--src/graph/nodes/ConvolutionLayer.cpp6
-rw-r--r--src/graph/operations/CL/CLActivationLayerOperation.cpp73
-rw-r--r--src/graph/operations/NEON/NEActivationLayerOperation.cpp73
6 files changed, 291 insertions, 55 deletions
diff --git a/src/graph/NodeContext.cpp b/src/graph/NodeContext.cpp
new file mode 100644
index 0000000000..5b0dc6c5d8
--- /dev/null
+++ b/src/graph/NodeContext.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017 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/NodeContext.h"
+
+using namespace arm_compute::graph;
+
+void NodeContext::add_input(arm_compute::ITensor *input)
+{
+ ARM_COMPUTE_ERROR_ON(input == nullptr);
+ _inputs.emplace_back(input);
+}
+
+void NodeContext::add_output(arm_compute::ITensor *output)
+{
+ ARM_COMPUTE_ERROR_ON(output == nullptr);
+ _outputs.emplace_back(output);
+}
+
+std::string NodeContext::operation() const
+{
+ return _operation;
+}
+
+TargetHint NodeContext::target() const
+{
+ return _target;
+}
+
+arm_compute::ITensor *NodeContext::input(size_t idx) const
+{
+ ARM_COMPUTE_ERROR_ON(idx >= _inputs.size());
+ return _inputs[idx];
+}
+
+arm_compute::ITensor *NodeContext::output(size_t idx) const
+{
+ ARM_COMPUTE_ERROR_ON(idx >= _outputs.size());
+ return _outputs[idx];
+}
+
+size_t NodeContext::num_inputs() const
+{
+ return _inputs.size();
+}
+
+size_t NodeContext::num_outputs() const
+{
+ return _outputs.size();
+} \ No newline at end of file
diff --git a/src/graph/OperationRegistry.cpp b/src/graph/OperationRegistry.cpp
new file mode 100644
index 0000000000..7de714b214
--- /dev/null
+++ b/src/graph/OperationRegistry.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017 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/OperationRegistry.h"
+
+using namespace arm_compute::graph;
+
+OperationRegistry::OperationRegistry()
+ : _registered_ops()
+{
+}
+
+OperationRegistry &OperationRegistry::get()
+{
+ static OperationRegistry instance;
+ return instance;
+}
+
+IOperation *OperationRegistry::find_operation(const std::string &operation, TargetHint target)
+{
+ ARM_COMPUTE_ERROR_ON(!contains(operation, target));
+ auto it = std::find_if(_registered_ops[operation].begin(), _registered_ops[operation].end(), [&](const std::unique_ptr<IOperation> &op)
+ {
+ return (op->target() == target);
+ });
+ ARM_COMPUTE_ERROR_ON(it == _registered_ops[operation].end());
+ return (*it).get();
+}
+
+bool OperationRegistry::contains(const std::string &operation, TargetHint target) const
+{
+ auto it = _registered_ops.find(operation);
+ if(it != _registered_ops.end())
+ {
+ return std::any_of(it->second.begin(), it->second.end(), [&](const std::unique_ptr<IOperation> &op)
+ {
+ return (op->target() == target);
+ });
+ }
+ return false;
+}
diff --git a/src/graph/nodes/ActivationLayer.cpp b/src/graph/nodes/ActivationLayer.cpp
index df73ba7078..ea87fd9592 100644
--- a/src/graph/nodes/ActivationLayer.cpp
+++ b/src/graph/nodes/ActivationLayer.cpp
@@ -23,45 +23,11 @@
*/
#include "arm_compute/graph/nodes/ActivationLayer.h"
-#include "arm_compute/runtime/CL/CLTensor.h"
-#include "arm_compute/runtime/CL/functions/CLActivationLayer.h"
-#include "arm_compute/runtime/NEON/functions/NEActivationLayer.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "support/ToolchainSupport.h"
-#include "utils/TypePrinter.h"
+#include "arm_compute/graph/NodeContext.h"
+#include "arm_compute/graph/OperationRegistry.h"
using namespace arm_compute::graph;
-namespace
-{
-template <typename ActivationType, typename TensorType, TargetHint target_hint>
-std::unique_ptr<arm_compute::IFunction> instantiate_function(arm_compute::ITensor *input, arm_compute::ITensor *output, const ActivationLayerInfo &activation_info)
-{
- auto activation = arm_compute::support::cpp14::make_unique<ActivationType>();
- activation->configure(
- dynamic_cast<TensorType *>(input),
- dynamic_cast<TensorType *>(output),
- activation_info);
-
- return std::move(activation);
-}
-
-template <TargetHint target_hint>
-std::unique_ptr<arm_compute::IFunction> instantiate(arm_compute::ITensor *input, arm_compute::ITensor *output, const ActivationLayerInfo &activation_info);
-
-template <>
-std::unique_ptr<arm_compute::IFunction> instantiate<TargetHint::OPENCL>(arm_compute::ITensor *input, arm_compute::ITensor *output, const ActivationLayerInfo &activation_info)
-{
- return instantiate_function<arm_compute::CLActivationLayer, arm_compute::ICLTensor, TargetHint::OPENCL>(input, output, activation_info);
-}
-
-template <>
-std::unique_ptr<arm_compute::IFunction> instantiate<TargetHint::NEON>(arm_compute::ITensor *input, arm_compute::ITensor *output, const ActivationLayerInfo &activation_info)
-{
- return instantiate_function<arm_compute::NEActivationLayer, arm_compute::ITensor, TargetHint::NEON>(input, output, activation_info);
-}
-} // namespace
-
ActivationLayer::ActivationLayer(const ActivationLayerInfo activation_info)
: _activation_info(activation_info)
{
@@ -78,23 +44,14 @@ std::unique_ptr<arm_compute::IFunction> ActivationLayer::instantiate_node(GraphC
arm_compute::ITensor *in = input->tensor();
arm_compute::ITensor *out = output->tensor();
- if(_target_hint == TargetHint::OPENCL)
- {
- func = instantiate<TargetHint::OPENCL>(in, out, _activation_info);
- ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLActivationLayer");
- }
- else
- {
- func = instantiate<TargetHint::NEON>(in, out, _activation_info);
- ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEActivationLayer");
- }
+ // Create node context
+ NodeContext node_ctx("ActivationLayer");
+ node_ctx.add_input(in);
+ node_ctx.add_output(out);
+ node_ctx.add_parameter<ActivationLayerInfo>("ActivationLayerInfo", _activation_info);
+
+ // Get function
+ func = OperationRegistry::get().find_operation("ActivationLayer", _target_hint)->configure(node_ctx);
- ARM_COMPUTE_LOG_GRAPH_INFO(" Data Type: " << in->info()->data_type()
- << " Input shape: " << in->info()->tensor_shape()
- << " Output shape: " << out->info()->tensor_shape()
- << " Activation function: " << _activation_info.activation()
- << " a: " << _activation_info.a()
- << " b: " << _activation_info.b()
- << std::endl);
return func;
}
diff --git a/src/graph/nodes/ConvolutionLayer.cpp b/src/graph/nodes/ConvolutionLayer.cpp
index 07d42617e2..d3ab97fb2d 100644
--- a/src/graph/nodes/ConvolutionLayer.cpp
+++ b/src/graph/nodes/ConvolutionLayer.cpp
@@ -216,12 +216,10 @@ std::unique_ptr<arm_compute::IFunction> ConvolutionLayer::instantiate_node(Graph
if(_num_groups == 1)
{
func = instantiate_convolution(in, out, conv_method_hint);
- ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLConvolutionLayer");
}
else
{
func = instantiate_grouped_convolution(in, out, conv_method_hint);
- ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEConvolutionLayer");
}
// Fill weights
@@ -253,10 +251,12 @@ std::unique_ptr<arm_compute::IFunction> ConvolutionLayer::instantiate_convolutio
std::unique_ptr<arm_compute::IFunction> func;
if(_target_hint == TargetHint::OPENCL)
{
+ ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLConvolutionLayer");
func = instantiate<TargetHint::OPENCL>(input, _weights.tensor(), _biases.tensor(), output, _conv_info, _weights_info, conv_method_hint);
}
else
{
+ ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEConvolutionLayer");
func = instantiate<TargetHint::NEON>(input, _weights.tensor(), _biases.tensor(), output, _conv_info, _weights_info, conv_method_hint);
}
return func;
@@ -318,10 +318,12 @@ std::unique_ptr<arm_compute::IFunction> ConvolutionLayer::instantiate_grouped_co
// Instantiate convolution function
if(_target_hint == TargetHint::OPENCL)
{
+ ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLConvolutionLayer");
func = instantiate<TargetHint::OPENCL>(_is[i].tensor(), _ws[i].tensor(), _bs[i].tensor(), _os[i].tensor(), _conv_info, _weights_info, conv_method_hint);
}
else
{
+ ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEConvolutionLayer");
func = instantiate<TargetHint::NEON>(_is[i].tensor(), _ws[i].tensor(), _bs[i].tensor(), _os[i].tensor(), _conv_info, _weights_info, conv_method_hint);
}
diff --git a/src/graph/operations/CL/CLActivationLayerOperation.cpp b/src/graph/operations/CL/CLActivationLayerOperation.cpp
new file mode 100644
index 0000000000..d0045e2500
--- /dev/null
+++ b/src/graph/operations/CL/CLActivationLayerOperation.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017 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/operations/CL/CLActivationLayerOperation.h"
+
+#include "arm_compute/core/CL/ICLTensor.h"
+#include "arm_compute/core/Error.h"
+#include "arm_compute/graph/OperationRegistrar.h"
+#include "arm_compute/graph/Types.h"
+#include "arm_compute/runtime/CL/functions/CLActivationLayer.h"
+#include "support/ToolchainSupport.h"
+#include "utils/GraphTypePrinter.h"
+#include "utils/TypePrinter.h"
+
+#include <memory>
+
+using namespace arm_compute::graph;
+
+std::unique_ptr<arm_compute::IFunction> CLActivationLayerOperation::configure(NodeContext &ctx)
+{
+ ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1);
+ ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
+ ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0)) == nullptr);
+ ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0)) == nullptr);
+
+ // Extract IO and info
+ auto *in = dynamic_cast<arm_compute::ICLTensor *>(ctx.input(0));
+ auto *out = dynamic_cast<arm_compute::ICLTensor *>(ctx.output(0));
+ const auto act_info = ctx.parameter<ActivationLayerInfo>("ActivationLayerInfo");
+
+ // Create and configure function
+ auto activation = arm_compute::support::cpp14::make_unique<CLActivationLayer>();
+ activation->configure(in, out, act_info);
+
+ // Log info
+ ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLActivationLayer"
+ << " Data Type: " << in->info()->data_type()
+ << " Input shape: " << in->info()->tensor_shape()
+ << " Output shape: " << out->info()->tensor_shape()
+ << " Activation function: " << act_info.activation()
+ << " a: " << act_info.a()
+ << " b: " << act_info.b()
+ << std::endl);
+
+ return std::move(activation);
+}
+
+TargetHint CLActivationLayerOperation::target() const
+{
+ return TargetHint::OPENCL;
+}
+
+static detail::OperationRegistrar<CLActivationLayerOperation> registrar("ActivationLayer"); \ No newline at end of file
diff --git a/src/graph/operations/NEON/NEActivationLayerOperation.cpp b/src/graph/operations/NEON/NEActivationLayerOperation.cpp
new file mode 100644
index 0000000000..355fd38f67
--- /dev/null
+++ b/src/graph/operations/NEON/NEActivationLayerOperation.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017 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/operations/NEON/NEActivationLayerOperation.h"
+
+#include "arm_compute/core/Error.h"
+#include "arm_compute/core/ITensor.h"
+#include "arm_compute/graph/OperationRegistrar.h"
+#include "arm_compute/graph/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEActivationLayer.h"
+#include "support/ToolchainSupport.h"
+#include "utils/GraphTypePrinter.h"
+#include "utils/TypePrinter.h"
+
+#include <memory>
+
+using namespace arm_compute::graph;
+
+std::unique_ptr<arm_compute::IFunction> NEActivationLayerOperation::configure(NodeContext &ctx)
+{
+ ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1);
+ ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1);
+ ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ITensor *>(ctx.input(0)) == nullptr);
+ ARM_COMPUTE_ERROR_ON(dynamic_cast<arm_compute::ITensor *>(ctx.output(0)) == nullptr);
+
+ // Extract IO and info
+ auto *in = dynamic_cast<arm_compute::ITensor *>(ctx.input(0));
+ auto *out = dynamic_cast<arm_compute::ITensor *>(ctx.output(0));
+ const auto act_info = ctx.parameter<ActivationLayerInfo>("ActivationLayerInfo");
+
+ // Create and configure function
+ auto activation = arm_compute::support::cpp14::make_unique<NEActivationLayer>();
+ activation->configure(in, out, act_info);
+
+ // Log info
+ ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEActivationLayer"
+ << " Data Type: " << in->info()->data_type()
+ << " Input shape: " << in->info()->tensor_shape()
+ << " Output shape: " << out->info()->tensor_shape()
+ << " Activation function: " << act_info.activation()
+ << " a: " << act_info.a()
+ << " b: " << act_info.b()
+ << std::endl);
+
+ return std::move(activation);
+}
+
+TargetHint NEActivationLayerOperation::target() const
+{
+ return TargetHint::NEON;
+}
+
+static detail::OperationRegistrar<NEActivationLayerOperation> registrar("ActivationLayer"); \ No newline at end of file