aboutsummaryrefslogtreecommitdiff
path: root/src/armnn/Layer.cpp
diff options
context:
space:
mode:
authorJim Flynn <jim.flynn@arm.com>2020-03-19 17:03:14 +0000
committerJim Flynn <jim.flynn@arm.com>2020-03-19 17:03:14 +0000
commit0e2bab81442ee6cc2b94e4f7881ed0c5c6af65e7 (patch)
treeb0af08b5a0b74149fca422151127ac6310385399 /src/armnn/Layer.cpp
parent8c3259fa007d43fcc5ea56fe6928526dbe79f3c0 (diff)
downloadarmnn-0e2bab81442ee6cc2b94e4f7881ed0c5c6af65e7.tar.gz
Creating gh-pages documentation for ArmNN
Signed-off-by: Jim Flynn <jim.flynn@arm.com>
Diffstat (limited to 'src/armnn/Layer.cpp')
-rw-r--r--src/armnn/Layer.cpp415
1 files changed, 0 insertions, 415 deletions
diff --git a/src/armnn/Layer.cpp b/src/armnn/Layer.cpp
deleted file mode 100644
index dee47f2cba..0000000000
--- a/src/armnn/Layer.cpp
+++ /dev/null
@@ -1,415 +0,0 @@
-//
-// Copyright © 2017 Arm Ltd. All rights reserved.
-// SPDX-License-Identifier: MIT
-//
-#include "Layer.hpp"
-
-#include "Graph.hpp"
-#include <ProfilingService.hpp>
-#include <backendsCommon/WorkloadData.hpp>
-#include <backendsCommon/CpuTensorHandle.hpp>
-
-#include <boost/cast.hpp>
-#include <boost/format.hpp>
-
-#include <numeric>
-
-namespace armnn
-{
-
-void InputSlot::Insert(Layer& layer)
-{
- BOOST_ASSERT(layer.GetNumOutputSlots() == 1);
-
- OutputSlot* const prevSlot = GetConnectedOutputSlot();
-
- if (prevSlot != nullptr)
- {
- // Disconnects parent from this.
- prevSlot->Disconnect(*this);
-
- // Connects inserted layer to parent.
- BOOST_ASSERT(layer.GetNumInputSlots() == 1);
- int idx = prevSlot->Connect(layer.GetInputSlot(0));
- prevSlot->SetEdgeStrategy(boost::numeric_cast<unsigned int>(idx), EdgeStrategy::Undefined);
-
- // Sets tensor info for inserted layer.
- const TensorInfo& tensorInfo = prevSlot->GetTensorInfo();
- layer.GetOutputHandler().SetTensorInfo(tensorInfo);
- }
-
- // Connects inserted layer to this.
- layer.GetOutputSlot(0).Connect(*this);
- layer.GetOutputSlot(0).SetEdgeStrategy(0, EdgeStrategy::Undefined);
-}
-
-const InputSlot* OutputSlot::GetConnection(unsigned int index) const
-{
- ValidateConnectionIndex(index);
- return m_Connections[index];
-}
-
-InputSlot* OutputSlot::GetConnection(unsigned int index)
-{
- ValidateConnectionIndex(index);
- return m_Connections[index];
-}
-
-void OutputSlot::SetTensorInfo(const TensorInfo& tensorInfo)
-{
- GetOutputHandler().SetTensorInfo(tensorInfo);
-}
-
-const TensorInfo& OutputSlot::GetTensorInfo() const
-{
- return GetOutputHandler().GetTensorInfo();
-}
-
-bool OutputSlot::IsTensorInfoSet() const
-{
- return GetOutputHandler().IsTensorInfoSet();
-}
-
-bool OutputSlot::ValidateTensorShape(const TensorShape& shape) const
-{
- BOOST_ASSERT_MSG(IsTensorInfoSet(), "TensorInfo must be set in order to validate the shape.");
- return shape == m_OutputHandler.GetTensorInfo().GetShape();
-}
-
-int OutputSlot::Connect(InputSlot& destination)
-{
- destination.SetConnection(this);
- m_Connections.push_back(&destination);
- m_EdgeStrategies.push_back(EdgeStrategy::Undefined);
- return boost::numeric_cast<int>(m_Connections.size() - 1);
-}
-
-void OutputSlot::Disconnect(InputSlot& slot)
-{
- slot.SetConnection(nullptr);
- auto it = std::find(m_Connections.begin(), m_Connections.end(), &slot);
-
- if (it == m_Connections.end())
- {
- return;
- }
-
- auto idx = std::distance(m_Connections.begin(), it);
- m_Connections.erase(std::remove(m_Connections.begin(), m_Connections.end(), &slot), m_Connections.end());
-
- m_EdgeStrategies.erase(m_EdgeStrategies.begin() + idx);
-}
-
-void OutputSlot::DisconnectAll()
-{
- while (GetNumConnections() > 0)
- {
- InputSlot& connection = *GetConnection(0);
- Disconnect(connection);
- }
-}
-
-void OutputSlot::MoveAllConnections(OutputSlot& destination)
-{
- while (GetNumConnections() > 0)
- {
- BOOST_ASSERT_MSG(m_EdgeStrategies[0] == EdgeStrategy::Undefined,
- "Cannot move connections once memory strategies have be established.");
-
- InputSlot& connection = *GetConnection(0);
- Disconnect(connection);
- destination.Connect(connection);
- }
-}
-
-unsigned int OutputSlot::CalculateIndexOnOwner() const
-{
- for (unsigned int i = 0; i < GetOwningLayer().GetNumOutputSlots(); i++)
- {
- if (GetOwningLayer().GetOutputSlot(i) == (*this))
- {
- return i;
- }
- }
- BOOST_ASSERT_MSG(false, "Did not find slot on owner.");
- return 0; // Error
-}
-
-bool OutputSlot::operator==(const OutputSlot& other) const
-{
- bool isSame = other.GetNumConnections() == GetNumConnections();
- if (!isSame)
- {
- return false;
- }
-
- for (unsigned int i = 0; i < GetNumConnections(); i++)
- {
- isSame &= other.GetConnection(i) == GetConnection(i);
- }
- return isSame;
-}
-
-void OutputSlot::ValidateConnectionIndex(unsigned int index) const
-{
- if (boost::numeric_cast<std::size_t>(index) >= m_Connections.size())
- {
- throw InvalidArgumentException(
- boost::str(boost::format("GetConnection: Invalid index %1% provided") % index));
- }
-}
-
-LayerGuid OutputSlot::GetOwningLayerGuid() const
-{
- return GetOwningLayer().GetGuid();
-}
-
-void OutputSlot::SetTensorHandleFactory(const ITensorHandleFactory::FactoryId& id)
-{
- m_TensorHandleFactoryId = id;
-}
-
-ITensorHandleFactory::FactoryId OutputSlot::GetTensorHandleFactoryId() const
-{
- return m_TensorHandleFactoryId;
-}
-
-void OutputSlot::SetEdgeStrategy(unsigned int connectionIndex, EdgeStrategy strategy)
-{
- m_EdgeStrategies[connectionIndex] = strategy;
-}
-
-EdgeStrategy OutputSlot::GetEdgeStrategyForConnection(unsigned int connectionIdx) const
-{
- return m_EdgeStrategies[connectionIdx];
-}
-
-Layer::Layer(unsigned int numInputSlots,
- unsigned int numOutputSlots,
- LayerType type,
- DataLayout layout,
- const char* name)
-: m_OutputHandlers(numOutputSlots)
-, m_LayerName(name ? name : "")
-, m_Type(type)
-, m_BackendId()
-, m_Guid(profiling::ProfilingService::Instance().NextGuid())
-{
- boost::ignore_unused(layout);
- m_InputSlots.reserve(numInputSlots);
- for (unsigned int i = 0; i < numInputSlots; ++i)
- {
- m_InputSlots.emplace_back(*this, i);
- }
-
- m_OutputSlots.reserve(numOutputSlots);
- for (unsigned int i = 0; i < numOutputSlots; ++i)
- {
- m_OutputSlots.emplace_back(*this, m_OutputHandlers[i]);
- }
-}
-
-Layer::Layer(unsigned int numInputSlots,
- unsigned int numOutputSlots,
- LayerType type,
- const char* name)
-: Layer(numInputSlots, numOutputSlots, type, DataLayout::NCHW, name)
-{
-}
-
-void Layer::CollectWorkloadInputs(WorkloadDataCollector& dataCollector) const
-{
- for (auto&& inputSlot : GetInputSlots())
- {
- // The graph must be well-formed at this point.
- BOOST_ASSERT(inputSlot.GetConnection());
- const OutputHandler& outputHandler = inputSlot.GetConnectedOutputSlot()->GetOutputHandler();
- dataCollector.Push(outputHandler.GetData(), outputHandler.GetTensorInfo());
- }
-}
-
-void Layer::CollectWorkloadOutputs(WorkloadDataCollector& dataCollector) const
-{
- for (auto&& outputHandler : m_OutputHandlers)
- {
- outputHandler.CollectWorkloadOutputs(dataCollector);
- }
-}
-
-void Layer::CreateTensorHandles(const TensorHandleFactoryRegistry& registry,
- const IWorkloadFactory& workloadFactory,
- const bool IsMemoryManaged)
-{
- for (unsigned int idx=0; idx < GetNumOutputSlots(); idx++)
- {
-
- OutputSlot& slot = GetOutputSlot(idx);
- ITensorHandleFactory::FactoryId factoryId = slot.GetTensorHandleFactoryId();
-
- OutputHandler& handler = GetOutputHandler(idx);
- if (factoryId == ITensorHandleFactory::LegacyFactoryId)
- {
- handler.CreateTensorHandles(workloadFactory, IsMemoryManaged);
- }
- else
- {
- ITensorHandleFactory* handleFactory = registry.GetFactory(factoryId);
- BOOST_ASSERT(handleFactory);
- handler.CreateTensorHandles(*handleFactory, IsMemoryManaged);
- }
- }
-}
-
-void Layer::ReleaseConstantData()
-{
- // Now free up the static data.
- OperateOnConstantTensors([](std::unique_ptr<ScopedCpuTensorHandle>& handle)
- {
- handle.reset(nullptr);
- });
-}
-
-DataType Layer::GetDataType() const
-{
- if (GetNumInputSlots() > 0) // Ignore the input layer.
- {
- return GetInputSlot(0).GetConnection()->GetTensorInfo().GetDataType();
- }
- return GetOutputSlot(0).GetTensorInfo().GetDataType();
-}
-
-void Layer::ResetPriority() const
-{
- m_Priority = 0;
- m_Visiting = false;
-}
-
-LayerPriority Layer::GetPriority() const
-{
- constexpr LayerPriority inputPrio = std::numeric_limits<LayerPriority>::lowest();
- constexpr LayerPriority outputPrio = std::numeric_limits<LayerPriority>::max();
-
- if (GetType() == LayerType::Input)
- {
- m_Priority = inputPrio;
- }
- else if (GetType() == LayerType::Output)
- {
- m_Priority = outputPrio;
- }
- else if (m_Priority == 0)
- {
- if (m_Visiting)
- {
- throw GraphValidationException("Graph has circular dependencies: cannot walk");
- }
-
- auto maxPrio = [](const LayerPriority prio, const InputSlot& slot) -> LayerPriority
- {
- const OutputSlot *outputSlot = slot.GetConnectedOutputSlot();
- if (outputSlot)
- {
- const Layer& input = outputSlot->GetOwningLayer();
- return std::max(prio, input.GetPriority());
- }
- else
- {
- // unconnected input slot
- return prio;
- }
- };
-
- m_Visiting = true;
- LayerPriority parentPrio = std::accumulate(GetInputSlots().cbegin(), GetInputSlots().cend(), 0U, maxPrio);
- m_Visiting = false;
-
- if (parentPrio >= outputPrio)
- {
- throw GraphValidationException("Graph has too many edges");
- }
-
- m_Priority = parentPrio + 1U;
- }
-
- return m_Priority;
-}
-
-void Layer::VerifyLayerConnections(unsigned int expectedConnections, const CheckLocation& location) const
-{
- BOOST_ASSERT(GetNumInputSlots() == expectedConnections);
-
- for (unsigned int i=0; i<expectedConnections; ++i)
- {
- if (GetInputSlot(i).GetConnection() == nullptr)
- {
- throw LayerValidationException(
- boost::str(
- boost::format(
- "Input connection #%1% must be connected "
- "for %2% layer %3% %4%")
- % i
- % GetLayerTypeAsCString(this->GetType())
- % GetNameStr()
- % location.AsString()));
- }
- if(! GetInputSlot(i).GetConnection()->IsTensorInfoSet())
- {
- throw LayerValidationException(
- boost::str(
- boost::format(
- "TensorInfo of Input connection #%1% must be set on connected OutputSlot for "
- "%2% layer %3% %4%")
- % i
- % GetLayerTypeAsCString(this->GetType())
- % GetNameStr()
- % location.AsString()));
- }
- }
-}
-
-std::vector<TensorShape> Layer::InferOutputShapes(const std::vector<TensorShape>& inputShapes) const
-{
- BOOST_ASSERT(GetNumInputSlots() != 0);
- BOOST_ASSERT(GetNumOutputSlots() != 0);
-
- // By default we return what we got, meaning the output shape(s) are the same as the input(s).
- // This only works if the number of inputs and outputs are the same. Since we are in the Layer
- // base class, this means the implementation needs to be overridden in the specific layers for
- // the other cases. So the missing implementation justifies the UnimplementedException.
-
- if (GetNumInputSlots() != GetNumOutputSlots())
- {
- throw UnimplementedException(
- boost::str(
- boost::format(
- "Default implementation for InferOutputShapes can only be used for "
- "layers with the same number of input and output slots. This doesn't "
- "hold for %1% layer %2% (#inputs=%3% #outputs=%4%) %5%")
- % GetLayerTypeAsCString(this->GetType())
- % GetNameStr()
- % GetNumInputSlots()
- % GetNumOutputSlots()
- % CHECK_LOCATION().AsString()));
- }
- return inputShapes;
-}
-
-void Layer::SerializeLayerParameters(ParameterStringifyFunction& fn) const
-{
- std::string layerType = GetLayerTypeAsCString(m_Type);
- std::string backendId = std::string(m_BackendId);
- if(!(m_LayerName.compare("") == 0) && !m_LayerName.empty())
- {
- fn("LayerName",m_LayerName);
- }
- if(!(layerType.compare("") == 0) && !layerType.empty())
- {
- fn("LayerType",layerType);
- }
- if(!(backendId.compare("") == 0) && !backendId.empty())
- {
- fn("BackendID",backendId);
- }
-}
-
-} // namespace armnn