aboutsummaryrefslogtreecommitdiff
path: root/src/armnn/Network.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/armnn/Network.cpp')
-rw-r--r--src/armnn/Network.cpp335
1 files changed, 335 insertions, 0 deletions
diff --git a/src/armnn/Network.cpp b/src/armnn/Network.cpp
new file mode 100644
index 0000000000..4ee68b3c48
--- /dev/null
+++ b/src/armnn/Network.cpp
@@ -0,0 +1,335 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#include "Network.hpp"
+#include "Graph.hpp"
+#include "Layer.hpp"
+#include "backends/CpuTensorHandle.hpp"
+#include "backends/WorkloadFactory.hpp"
+#include "Layers.hpp"
+#include "Optimizer.hpp"
+
+#include <armnn/Utils.hpp>
+
+#include <fcntl.h>
+#include <algorithm>
+#include <fstream>
+#include <memory>
+
+#include <boost/assert.hpp>
+#include <boost/format.hpp>
+#include <boost/log/trivial.hpp>
+#include <boost/numeric/conversion/converter_policies.hpp>
+#include <boost/cast.hpp>
+
+namespace armnn
+{
+
+armnn::INetwork* INetwork::CreateRaw()
+{
+ return new Network();
+}
+
+armnn::INetworkPtr INetwork::Create()
+{
+ return INetworkPtr(CreateRaw(), &INetwork::Destroy);
+}
+
+void INetwork::Destroy(INetwork* network)
+{
+ delete boost::polymorphic_downcast<Network*>(network);
+}
+
+Status Network::PrintGraph()
+{
+ m_Graph->Print();
+ return Status::Success;
+}
+
+void IOptimizedNetwork::Destroy(IOptimizedNetwork* network)
+{
+ delete boost::polymorphic_downcast<OptimizedNetwork*>(network);
+}
+
+Status OptimizedNetwork::PrintGraph()
+{
+ m_Graph->Print();
+ return Status::Success;
+}
+
+IOptimizedNetworkPtr Optimize(const INetwork& inNetwork, const DeviceSpec& deviceSpec)
+{
+ const Network& network = *boost::polymorphic_downcast<const Network*>(&inNetwork);
+ std::unique_ptr<Graph> graph = std::make_unique<Graph>(network.GetGraph());
+
+ OptimizedNetwork* optNet = new OptimizedNetwork(std::move(graph));
+
+ Optimizer::Get().Optimize(optNet->GetGraph());
+
+ // Infer the tensor infos for all output slots. Throws an exception on failure.
+ optNet->GetGraph().InferTensorInfos();
+
+ // Assign a compute device for all nodes
+ for (auto&& layer : optNet->GetGraph())
+ {
+ DataType dataType = layer->GetDataType();
+
+ // Default to the user-requested compute device from the Runtime
+ layer->SetComputeDevice(deviceSpec.DefaultComputeDevice);
+
+ // If the layer is unsupported by this device, fall back to reference
+ std::string reasonIfUnsupported;
+ if (!IWorkloadFactory::IsLayerSupported(*layer, dataType, reasonIfUnsupported))
+ {
+ BOOST_LOG_TRIVIAL(warning) << "Layer of type " << GetLayerTypeAsCString(layer->GetType()) <<
+ " is not supported on requested backend " << layer->GetComputeDevice() << " (reason: " <<
+ reasonIfUnsupported << "), falling back to CpuRef backend.";
+ layer->SetComputeDevice(Compute::CpuRef);
+ }
+
+ BOOST_ASSERT_MSG(IWorkloadFactory::IsLayerSupported(*layer, dataType, reasonIfUnsupported),
+ "Layer has no valid compute device");
+ }
+
+ optNet->GetGraph().AddCopyLayers();
+
+ return {optNet, &IOptimizedNetwork::Destroy};
+}
+
+Network::Network()
+: m_Graph(std::make_unique<Graph>())
+{
+}
+
+Network::~Network()
+{
+}
+
+IConnectableLayer* Network::AddInputLayer(LayerBindingId id, const char* name)
+{
+ return m_Graph->AddLayer<InputLayer>(id, name);
+}
+
+IConnectableLayer* Network::AddFullyConnectedLayerImpl(const FullyConnectedDescriptor& fullyConnectedDescriptor,
+ const ConstTensor& weights,
+ const ConstTensor* biases,
+ const char* name)
+{
+ if (fullyConnectedDescriptor.m_BiasEnabled && (biases == nullptr))
+ {
+ throw InvalidArgumentException("AddFullyConnectedLayer: biases cannot be NULL");
+ }
+
+ const auto layer = m_Graph->AddLayer<FullyConnectedLayer>(fullyConnectedDescriptor, name);
+
+ layer->m_Weight = std::make_unique<ScopedCpuTensorHandle>(weights);
+
+ if (fullyConnectedDescriptor.m_BiasEnabled)
+ {
+ layer->m_Bias = std::make_unique<ScopedCpuTensorHandle>(*biases);
+ }
+
+ return layer;
+}
+
+IConnectableLayer* Network::AddFullyConnectedLayer(const FullyConnectedDescriptor& fullyConnectedDescriptor,
+ const ConstTensor& weights,
+ const char* name)
+{
+ return AddFullyConnectedLayerImpl(fullyConnectedDescriptor, weights, nullptr, name);
+}
+
+IConnectableLayer* Network::AddFullyConnectedLayer(const FullyConnectedDescriptor& fullyConnectedDescriptor,
+ const ConstTensor& weights,
+ const ConstTensor& biases,
+ const char* name)
+{
+ return AddFullyConnectedLayerImpl(fullyConnectedDescriptor, weights, &biases, name);
+}
+
+IConnectableLayer* Network::AddConvolution2dLayerImpl(const Convolution2dDescriptor& convolution2dDescriptor,
+ const ConstTensor& weights,
+ const ConstTensor* biases,
+ const char* name)
+{
+ if (convolution2dDescriptor.m_BiasEnabled && (biases == nullptr))
+ {
+ throw InvalidArgumentException("AddConvolution2dLayer: biases cannot be NULL");
+ }
+
+ const auto layer = m_Graph->AddLayer<Convolution2dLayer>(convolution2dDescriptor, name);
+
+ layer->m_Weight = std::make_unique<ScopedCpuTensorHandle>(weights);
+
+ if (convolution2dDescriptor.m_BiasEnabled)
+ {
+ layer->m_Bias = std::make_unique<ScopedCpuTensorHandle>(*biases);
+ }
+
+ return layer;
+}
+
+IConnectableLayer* Network::AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
+ const ConstTensor& weights,
+ const char* name)
+{
+ return AddConvolution2dLayerImpl(convolution2dDescriptor, weights, nullptr, name);
+}
+IConnectableLayer* Network::AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
+ const ConstTensor& weights,
+ const ConstTensor& biases,
+ const char* name)
+{
+ return AddConvolution2dLayerImpl(convolution2dDescriptor, weights, &biases, name);
+}
+
+IConnectableLayer* Network::AddDepthwiseConvolution2dLayerImpl(
+ const DepthwiseConvolution2dDescriptor& convolution2dDescriptor,
+ const ConstTensor& weights,
+ const ConstTensor* biases,
+ const char* name)
+{
+ if (convolution2dDescriptor.m_BiasEnabled && (biases == nullptr))
+ {
+ throw InvalidArgumentException("AddDepthwiseConvolution2dLayer: biases cannot be NULL");
+ }
+
+ const auto layer = m_Graph->AddLayer<DepthwiseConvolution2dLayer>(convolution2dDescriptor, name);
+
+ layer->m_Weight = std::make_unique<ScopedCpuTensorHandle>(weights);
+
+ if (convolution2dDescriptor.m_BiasEnabled)
+ {
+ layer->m_Bias = std::make_unique<ScopedCpuTensorHandle>(*biases);
+ }
+
+ return layer;
+}
+
+IConnectableLayer* Network::AddDepthwiseConvolution2dLayer(
+ const DepthwiseConvolution2dDescriptor& convolution2dDescriptor,
+ const ConstTensor& weights,
+ const char* name)
+{
+ return AddDepthwiseConvolution2dLayerImpl(convolution2dDescriptor, weights, nullptr, name);
+}
+IConnectableLayer* Network::AddDepthwiseConvolution2dLayer(
+ const DepthwiseConvolution2dDescriptor& convolution2dDescriptor,
+ const ConstTensor& weights,
+ const ConstTensor& biases,
+ const char* name)
+{
+ return AddDepthwiseConvolution2dLayerImpl(convolution2dDescriptor, weights, &biases, name);
+}
+
+IConnectableLayer* Network::AddPermuteLayer(const PermuteDescriptor& permuteDescriptor,
+ const char* name)
+{
+ return m_Graph->AddLayer<PermuteLayer>(permuteDescriptor, name);
+}
+
+IConnectableLayer* Network::AddPooling2dLayer(const Pooling2dDescriptor& pooling2dDescriptor,
+ const char* name)
+{
+ return m_Graph->AddLayer<Pooling2dLayer>(pooling2dDescriptor, name);
+}
+
+IConnectableLayer* Network::AddActivationLayer(const ActivationDescriptor& activationDescriptor,
+ const char* name)
+{
+ return m_Graph->AddLayer<ActivationLayer>(activationDescriptor, name);
+}
+
+IConnectableLayer* Network::AddNormalizationLayer(const NormalizationDescriptor& normalizationDescriptor,
+ const char* name)
+{
+ return m_Graph->AddLayer<NormalizationLayer>(normalizationDescriptor, name);
+}
+
+IConnectableLayer* Network::AddSoftmaxLayer(const SoftmaxDescriptor& softmaxDescriptor,
+ const char* name)
+{
+ return m_Graph->AddLayer<SoftmaxLayer>(softmaxDescriptor, name);
+}
+
+IConnectableLayer* Network::AddSplitterLayer(const ViewsDescriptor& splitterDescriptor,
+ const char* name)
+{
+ return m_Graph->AddLayer<SplitterLayer>(splitterDescriptor, name);
+}
+
+IConnectableLayer* Network::AddMergerLayer(const OriginsDescriptor& mergerDescriptor,
+ const char* name)
+{
+ return m_Graph->AddLayer<MergerLayer>(mergerDescriptor, name);
+}
+
+IConnectableLayer* Network::AddAdditionLayer(const char* name)
+{
+ return m_Graph->AddLayer<AdditionLayer>(name);
+}
+
+IConnectableLayer* Network::AddMultiplicationLayer(const char* name)
+{
+ return m_Graph->AddLayer<MultiplicationLayer>(name);
+}
+
+IConnectableLayer* Network::AddOutputLayer(LayerBindingId id, const char* name)
+{
+ return m_Graph->AddLayer<OutputLayer>(id, name);
+}
+
+IConnectableLayer* Network::AddBatchNormalizationLayer(const BatchNormalizationDescriptor& desc,
+ const ConstTensor& mean,
+ const ConstTensor& variance,
+ const ConstTensor& beta,
+ const ConstTensor& gamma,
+ const char* name)
+{
+ const auto layer = m_Graph->AddLayer<BatchNormalizationLayer>(desc, name);
+
+ layer->m_Mean = std::make_unique<ScopedCpuTensorHandle>(mean);
+ layer->m_Variance = std::make_unique<ScopedCpuTensorHandle>(variance);
+ layer->m_Beta = std::make_unique<ScopedCpuTensorHandle>(beta);
+ layer->m_Gamma = std::make_unique<ScopedCpuTensorHandle>(gamma);
+
+ return layer;
+}
+
+IConnectableLayer* Network::AddResizeBilinearLayer(const ResizeBilinearDescriptor& resizeDescriptor, const char* name)
+{
+ return m_Graph->AddLayer<ResizeBilinearLayer>(resizeDescriptor,name);
+}
+
+IConnectableLayer* Network::AddL2NormalizationLayer(const char* name)
+{
+ return m_Graph->AddLayer<L2NormalizationLayer>(name);
+}
+
+IConnectableLayer* Network::AddConstantLayer(const ConstTensor& input, const char* name)
+{
+ return m_Graph->AddLayer<ConstantLayer>(std::make_shared<ScopedCpuTensorHandle>(input), name);
+}
+
+IConnectableLayer* Network::AddReshapeLayer(const ReshapeDescriptor& reshapeDescriptor, const char* name)
+{
+ return m_Graph->AddLayer<ReshapeLayer>(reshapeDescriptor, name);
+}
+
+IConnectableLayer* Network::AddFloorLayer(const char* name)
+{
+ return m_Graph->AddLayer<FloorLayer>(name);
+}
+
+OptimizedNetwork::OptimizedNetwork(std::unique_ptr<Graph> graph)
+ : m_Graph(std::move(graph))
+{
+}
+
+OptimizedNetwork::~OptimizedNetwork()
+{
+}
+
+} // namespace armnn
+