diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/graph/NodeContext.cpp | 70 | ||||
-rw-r--r-- | src/graph/OperationRegistry.cpp | 61 | ||||
-rw-r--r-- | src/graph/nodes/ActivationLayer.cpp | 63 | ||||
-rw-r--r-- | src/graph/nodes/ConvolutionLayer.cpp | 6 | ||||
-rw-r--r-- | src/graph/operations/CL/CLActivationLayerOperation.cpp | 73 | ||||
-rw-r--r-- | src/graph/operations/NEON/NEActivationLayerOperation.cpp | 73 |
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 |