aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authortelsoa01 <telmo.soares@arm.com>2018-03-09 14:13:49 +0000
committertelsoa01 <telmo.soares@arm.com>2018-03-09 14:13:49 +0000
commit4fcda0101ec3d110c1d6d7bee5c83416b645528a (patch)
treec9a70aeb2887006160c1b3d265c27efadb7bdbae /include
downloadarmnn-4fcda0101ec3d110c1d6d7bee5c83416b645528a.tar.gz
Release 18.02
Change-Id: Id3c11dc5ee94ef664374a988fcc6901e9a232fa6
Diffstat (limited to 'include')
-rw-r--r--include/armnn/ArmNN.hpp16
-rw-r--r--include/armnn/Descriptors.hpp307
-rw-r--r--include/armnn/DescriptorsFwd.hpp26
-rw-r--r--include/armnn/Exceptions.hpp75
-rw-r--r--include/armnn/INetwork.hpp281
-rw-r--r--include/armnn/IRuntime.hpp116
-rw-r--r--include/armnn/LayerSupport.hpp140
-rw-r--r--include/armnn/NetworkFwd.hpp16
-rw-r--r--include/armnn/Tensor.hpp179
-rw-r--r--include/armnn/TensorFwd.hpp15
-rw-r--r--include/armnn/Types.hpp155
-rw-r--r--include/armnn/TypesUtils.hpp182
-rw-r--r--include/armnn/Utils.hpp27
-rw-r--r--include/armnn/Version.hpp12
-rw-r--r--include/armnnCaffeParser/ICaffeParser.hpp59
15 files changed, 1606 insertions, 0 deletions
diff --git a/include/armnn/ArmNN.hpp b/include/armnn/ArmNN.hpp
new file mode 100644
index 0000000000..d1cb7a8488
--- /dev/null
+++ b/include/armnn/ArmNN.hpp
@@ -0,0 +1,16 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+#include "Descriptors.hpp"
+#include "Exceptions.hpp"
+#include "IRuntime.hpp"
+#include "INetwork.hpp"
+#include "LayerSupport.hpp"
+#include "Tensor.hpp"
+#include "Types.hpp"
+#include "TypesUtils.hpp"
+#include "Utils.hpp"
+#include "Version.hpp"
diff --git a/include/armnn/Descriptors.hpp b/include/armnn/Descriptors.hpp
new file mode 100644
index 0000000000..2595656c70
--- /dev/null
+++ b/include/armnn/Descriptors.hpp
@@ -0,0 +1,307 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+#include "DescriptorsFwd.hpp"
+
+#include <cstdint>
+#include <initializer_list>
+
+#include "Tensor.hpp"
+#include "Types.hpp"
+
+namespace armnn
+{
+
+struct ActivationDescriptor
+{
+ ActivationDescriptor() : m_Function(ActivationFunction::Sigmoid), m_A(0), m_B(0) {};
+
+ ActivationFunction m_Function;
+ float m_A;
+ float m_B;
+};
+
+struct PermuteDescriptor
+{
+ PermuteDescriptor()
+ : m_DimMappings{}
+ {
+ }
+ PermuteDescriptor(const PermutationVector& dimMappings)
+ : m_DimMappings(dimMappings)
+ {
+ }
+
+ PermutationVector m_DimMappings;
+};
+
+struct SoftmaxDescriptor
+{
+ SoftmaxDescriptor() : m_Beta(1.0f) {};
+
+ float m_Beta;
+};
+
+
+struct OriginsDescriptor
+{
+ OriginsDescriptor();
+ OriginsDescriptor(uint32_t numViews, uint32_t numDimensions = 4);
+ OriginsDescriptor(const OriginsDescriptor& other);
+ OriginsDescriptor(OriginsDescriptor&& other);
+
+ ~OriginsDescriptor();
+
+ OriginsDescriptor& operator=(OriginsDescriptor rhs);
+
+ Status SetViewOriginCoord(uint32_t view, uint32_t coord, uint32_t value);
+ uint32_t GetNumViews() const;
+ uint32_t GetNumDimensions() const;
+ const uint32_t* GetViewOrigin(uint32_t idx) const;
+ void ReorderOrigins(unsigned int* newOrdering, unsigned int numNewOrdering);
+ friend void swap(OriginsDescriptor& first, OriginsDescriptor& second);
+
+private:
+ uint32_t m_NumViews;
+ uint32_t m_NumDimensions;
+ uint32_t** m_ViewOrigins;
+};
+
+struct ViewsDescriptor
+{
+ ViewsDescriptor(uint32_t numViews, uint32_t numDimensions = 4);
+ ViewsDescriptor(const ViewsDescriptor& other);
+ ViewsDescriptor();
+ ViewsDescriptor(ViewsDescriptor&& other);
+
+ ~ViewsDescriptor();
+
+ ViewsDescriptor& operator=(ViewsDescriptor rhs);
+
+ Status SetViewOriginCoord(uint32_t view, uint32_t coord, uint32_t value);
+ Status SetViewSize(uint32_t view, uint32_t coord, uint32_t value);
+
+ uint32_t GetNumViews() const;
+ uint32_t GetNumDimensions() const;
+ const uint32_t* GetViewOrigin(uint32_t idx) const;
+ const uint32_t* GetViewSizes(uint32_t idx) const;
+
+ friend void swap(ViewsDescriptor& first, ViewsDescriptor& second);
+private:
+ OriginsDescriptor m_Origins;
+ uint32_t** m_ViewSizes;
+};
+
+// Convenience template to create a OriginsDescriptor to use when creating a Merger layer for performing concatenation
+// of a number of input tensors
+template <typename TensorShapeIt>
+OriginsDescriptor CreateMergerDescriptorForConcatenation(TensorShapeIt first, TensorShapeIt last,
+ unsigned int concatenationDimension)
+{
+ auto numInputs = std::distance(first, last);
+
+ if (numInputs < 2)
+ {
+ throw InvalidArgumentException("Concatenation requires at least 2 inputs");
+ }
+
+ const auto& firstInputShape = *first;
+
+ const unsigned int numDimensions = firstInputShape.GetNumDimensions();
+ for (auto it = first + 1; it != last; ++it)
+ {
+ if (it->GetNumDimensions() != numDimensions)
+ {
+ throw InvalidArgumentException("All inputs to concatenation must have the same number of dimensions");
+ }
+ }
+
+ if (concatenationDimension >= numDimensions)
+ {
+ throw InvalidArgumentException("concatenationDimension must be between 0 and the number of dimensions.");
+ }
+
+ for (auto it = first; it != last; ++it)
+ {
+ for (unsigned int d = 0; d < numDimensions; ++d)
+ {
+ const bool dimSizeOk = (d == concatenationDimension) || (firstInputShape[d] == (*it)[d]);
+ if (!dimSizeOk)
+ {
+ throw InvalidArgumentException("All inputs to concatenation must be the same size along all dimensions "
+ " except the concatenation dimension");
+ }
+ }
+ }
+
+ OriginsDescriptor viewsDescriptor(static_cast<uint32_t>(numInputs), numDimensions);
+
+ uint32_t viewIndex = 0u;
+ uint32_t coordAlongConcatDim = 0u;
+ for (auto it = first; it != last; ++it)
+ {
+ const auto& inputShape = *it;
+
+ for (unsigned int i = 0; i < concatenationDimension; ++i)
+ {
+ viewsDescriptor.SetViewOriginCoord(viewIndex, i, 0);
+ }
+
+ viewsDescriptor.SetViewOriginCoord(viewIndex, concatenationDimension, coordAlongConcatDim);
+ unsigned int dimSize = inputShape[concatenationDimension];
+ coordAlongConcatDim += dimSize;
+
+
+ for (unsigned int i = concatenationDimension + 1; i < numDimensions; ++i)
+ {
+ viewsDescriptor.SetViewOriginCoord(viewIndex, i, 0);
+ }
+
+ ++viewIndex;
+ }
+
+ return viewsDescriptor;
+}
+
+struct Pooling2dDescriptor
+{
+ Pooling2dDescriptor()
+ : m_PoolType(PoolingAlgorithm::Max)
+ , m_PadLeft(0)
+ , m_PadRight(0)
+ , m_PadTop(0)
+ , m_PadBottom(0)
+ , m_PoolWidth(0)
+ , m_PoolHeight(0)
+ , m_StrideX(0)
+ , m_StrideY(0)
+ , m_OutputShapeRounding(OutputShapeRounding::Floor)
+ , m_PaddingMethod(PaddingMethod::Exclude)
+ {};
+
+ PoolingAlgorithm m_PoolType;
+ uint32_t m_PadLeft;
+ uint32_t m_PadRight;
+ uint32_t m_PadTop;
+ uint32_t m_PadBottom;
+ uint32_t m_PoolWidth;
+ uint32_t m_PoolHeight;
+ uint32_t m_StrideX;
+ uint32_t m_StrideY;
+ OutputShapeRounding m_OutputShapeRounding;
+ PaddingMethod m_PaddingMethod;
+};
+
+struct FullyConnectedDescriptor
+{
+ FullyConnectedDescriptor()
+ : m_BiasEnabled(false)
+ , m_TransposeWeightMatrix(false)
+ {};
+
+ bool m_BiasEnabled;
+ bool m_TransposeWeightMatrix;
+};
+
+struct Convolution2dDescriptor
+{
+ Convolution2dDescriptor()
+ : m_PadLeft(0)
+ , m_PadRight(0)
+ , m_PadTop(0)
+ , m_PadBottom(0)
+ , m_StrideX(0)
+ , m_StrideY(0)
+ , m_BiasEnabled(false)
+ {};
+
+ uint32_t m_PadLeft;
+ uint32_t m_PadRight;
+ uint32_t m_PadTop;
+ uint32_t m_PadBottom;
+ uint32_t m_StrideX;
+ uint32_t m_StrideY;
+ bool m_BiasEnabled;
+};
+
+struct DepthwiseConvolution2dDescriptor
+{
+ DepthwiseConvolution2dDescriptor()
+ : m_PadLeft(0)
+ , m_PadRight(0)
+ , m_PadTop(0)
+ , m_PadBottom(0)
+ , m_StrideX(0)
+ , m_StrideY(0)
+ , m_BiasEnabled(false)
+ {}
+
+ uint32_t m_PadLeft;
+ uint32_t m_PadRight;
+ uint32_t m_PadTop;
+ uint32_t m_PadBottom;
+ uint32_t m_StrideX;
+ uint32_t m_StrideY;
+ bool m_BiasEnabled;
+};
+
+
+struct NormalizationDescriptor
+{
+ NormalizationDescriptor()
+ : m_NormChannelType(NormalizationAlgorithmChannel::Across)
+ , m_NormMethodType(NormalizationAlgorithmMethod::LocalBrightness)
+ , m_NormSize(0)
+ , m_Alpha(0.f)
+ , m_Beta(0.f)
+ , m_K(0.f)
+ {}
+
+ NormalizationAlgorithmChannel m_NormChannelType;
+ NormalizationAlgorithmMethod m_NormMethodType;
+ uint32_t m_NormSize;
+ float m_Alpha;
+ float m_Beta;
+ float m_K;
+};
+
+struct BatchNormalizationDescriptor
+{
+ BatchNormalizationDescriptor()
+ : m_Eps(0.0001f)
+ {}
+
+ float m_Eps;
+};
+
+struct FakeQuantizationDescriptor
+{
+ FakeQuantizationDescriptor()
+ : m_Min(-6.0f)
+ , m_Max(6.0f)
+ {}
+
+ float m_Min;
+ float m_Max;
+};
+
+struct ResizeBilinearDescriptor
+{
+ ResizeBilinearDescriptor()
+ : m_TargetWidth(0)
+ , m_TargetHeight(0)
+ {}
+
+ uint32_t m_TargetWidth;
+ uint32_t m_TargetHeight;
+};
+
+struct ReshapeDescriptor
+{
+ TensorShape m_TargetShape;
+};
+
+}
diff --git a/include/armnn/DescriptorsFwd.hpp b/include/armnn/DescriptorsFwd.hpp
new file mode 100644
index 0000000000..58b4bcc626
--- /dev/null
+++ b/include/armnn/DescriptorsFwd.hpp
@@ -0,0 +1,26 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+namespace armnn
+{
+struct ActivationDescriptor;
+struct BatchNormalizationDescriptor;
+struct Convolution2dDescriptor;
+struct DepthwiseConvolution2dDescriptor;
+struct FakeQuantizationDescriptor;
+struct FullyConnectedDescriptor;
+struct PermuteDescriptor;
+struct NormalizationDescriptor;
+struct Pooling2dDescriptor;
+struct ReshapeDescriptor;
+struct ResizeBilinearDescriptor;
+struct SoftmaxDescriptor;
+struct OriginsDescriptor;
+struct ViewsDescriptor;
+
+using MergerDescriptor = OriginsDescriptor;
+using SplitterDescriptor = ViewsDescriptor;
+}
diff --git a/include/armnn/Exceptions.hpp b/include/armnn/Exceptions.hpp
new file mode 100644
index 0000000000..0b043997c4
--- /dev/null
+++ b/include/armnn/Exceptions.hpp
@@ -0,0 +1,75 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+#include <stdexcept>
+#include <string>
+
+namespace armnn
+{
+
+// base class for all ArmNN exceptions so that users can filter to just those
+class Exception : public std::exception
+{
+public:
+ explicit Exception(const std::string& message);
+
+ virtual const char* what() const noexcept override;
+
+private:
+ std::string m_Message;
+};
+
+class ClRuntimeUnavailableException : public Exception
+{
+public:
+ using Exception::Exception;
+};
+
+class InvalidArgumentException : public Exception
+{
+public:
+ using Exception::Exception;
+};
+
+class FileNotFoundException : public Exception
+{
+public:
+ using Exception::Exception;
+};
+
+class ParseException : public Exception
+{
+public:
+ using Exception::Exception;
+};
+
+class UnimplementedException : public Exception
+{
+public:
+ using Exception::Exception;
+ UnimplementedException();
+};
+
+class LayerValidationException : public Exception
+{
+ using Exception::Exception;
+};
+
+class GraphValidationException : public Exception
+{
+ using Exception::Exception;
+};
+
+template <typename ExceptionType>
+void ConditionalThrow(bool condition, const std::string& message)
+{
+ if (!condition)
+ {
+ throw ExceptionType(message);
+ }
+}
+
+}
diff --git a/include/armnn/INetwork.hpp b/include/armnn/INetwork.hpp
new file mode 100644
index 0000000000..8545629c96
--- /dev/null
+++ b/include/armnn/INetwork.hpp
@@ -0,0 +1,281 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+#include "armnn/NetworkFwd.hpp"
+#include "armnn/DescriptorsFwd.hpp"
+#include "armnn/TensorFwd.hpp"
+
+#include "armnn/Types.hpp"
+
+#include <memory>
+
+namespace armnn
+{
+
+/// @brief An input connection slot for a layer.
+/// The input slot can be connected to an output slot of the preceding layer in the graph.
+/// Only one connection to the input slot is allowed.
+class IInputSlot
+{
+public:
+ virtual const IOutputSlot* GetConnection() const = 0;
+ virtual IOutputSlot* GetConnection() = 0;
+
+protected:
+ ~IInputSlot() {} /// Not user deletable
+};
+
+/// @brief An output connection slot for a layer.
+/// The output slot may be connected to 1 or more input slots of subsequent layers in the graph.
+class IOutputSlot
+{
+public:
+ virtual unsigned int GetNumConnections() const = 0;
+ virtual const IInputSlot* GetConnection(unsigned int index) const = 0;
+ virtual IInputSlot* GetConnection(unsigned int index) = 0;
+
+ virtual void SetTensorInfo(const TensorInfo& tensorInfo) = 0;
+ virtual const TensorInfo& GetTensorInfo() const = 0;
+ virtual bool IsTensorInfoSet() const = 0;
+
+ virtual int Connect(IInputSlot& destination) = 0;
+ virtual void Disconnect(IInputSlot& slot) = 0;
+
+protected:
+ ~IOutputSlot() {} /// Not user deletable
+};
+
+/// @brief Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
+class IConnectableLayer
+{
+public:
+ virtual const char* GetName() const = 0;
+
+ virtual unsigned int GetNumInputSlots() const = 0;
+ virtual unsigned int GetNumOutputSlots() const = 0;
+
+ virtual const IInputSlot& GetInputSlot(unsigned int index) const = 0;
+ virtual IInputSlot& GetInputSlot(unsigned int index) = 0;
+
+ virtual const IOutputSlot& GetOutputSlot(unsigned int index) const = 0;
+ virtual IOutputSlot& GetOutputSlot(unsigned int index) = 0;
+
+protected:
+ ~IConnectableLayer() {} // Objects are not deletable via the handle
+};
+
+using INetworkPtr = std::unique_ptr<INetwork, void(*)(INetwork* network)>;
+
+/// Main network class which provides the interface for building up a neural network.
+/// This object is subsequently required by the IRuntime::Load() method.
+class INetwork
+{
+public:
+ static INetwork* CreateRaw();
+ static INetworkPtr Create();
+ static void Destroy(INetwork* network);
+
+ virtual Status PrintGraph() = 0;
+
+ /// Add an input layer to the network.
+ /// @param id User generated id to uniquely identify a particular input. The same id needs to be specified
+ /// when passing the inputs to the IRuntime::EnqueueWorkload() function.
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddInputLayer(LayerBindingId id, const char* name = nullptr) = 0;
+
+ /// Add a 2D convolution layer to the network.
+ /// @param convolution2dDescriptor Description of the 2D convolution layer
+ /// @param weights Tensor for the weights data.
+ /// @param biases (Optional) Tensor for the bias data. Must match the output tensor shape.
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
+ const ConstTensor& weights,
+ const char* name = nullptr) = 0;
+
+ virtual IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
+ const ConstTensor& weights,
+ const ConstTensor& biases,
+ const char* name = nullptr) = 0;
+
+ /// Add a 2D depthwise convolution layer to the network.
+ /// @param convolution2dDescriptor Description of the 2D depthwise convolution layer
+ /// @param weights Tensor for the weights data. Expected format: [1, outputChannels, height, width]
+ /// @param biases (Optional) Tensor for the bias data. Must match the output tensor shape.
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddDepthwiseConvolution2dLayer(
+ const DepthwiseConvolution2dDescriptor& convolution2dDescriptor,
+ const ConstTensor& weights,
+ const char* name = nullptr) = 0;
+
+ virtual IConnectableLayer* AddDepthwiseConvolution2dLayer(
+ const DepthwiseConvolution2dDescriptor& convolution2dDescriptor,
+ const ConstTensor& weights,
+ const ConstTensor& biases,
+ const char* name = nullptr) = 0;
+
+ /// Add a fully connected layer to the network.
+ /// @param fullyConnectedDescriptor Description of the fully connected layer
+ /// @param weights Tensor for the weights data.
+ /// @param biases (Optional) Tensor for the bias data.
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddFullyConnectedLayer(const FullyConnectedDescriptor& fullyConnectedDescriptor,
+ const ConstTensor& weights,
+ const char* name = nullptr) = 0;
+
+ virtual IConnectableLayer* AddFullyConnectedLayer(const FullyConnectedDescriptor& fullyConnectedDescriptor,
+ const ConstTensor& weights,
+ const ConstTensor& biases,
+ const char* name = nullptr) = 0;
+
+ /// Add a permute layer to the network.
+ /// @param permuteDescriptor PermuteDescriptor to configure the permute
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddPermuteLayer(const PermuteDescriptor& permuteDescriptor,
+ const char* name = nullptr) = 0;
+
+ /// Add a pooling layer to the network.
+ /// @param pooling2dDescriptor Pooling2dDescriptor to configure the pooling
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddPooling2dLayer(const Pooling2dDescriptor& pooling2dDescriptor,
+ const char* name = nullptr) = 0;
+
+ /// Add an activation layer to the network.
+ /// @param activationDescriptor ActivationDescriptor to configure the activation
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddActivationLayer(const ActivationDescriptor& activationDescriptor,
+ const char* name = nullptr) = 0;
+
+ /// Add a normalization layer to the network.
+ /// @param normalizationDescriptor NormalizationDescriptor to configure the normalization
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddNormalizationLayer(const NormalizationDescriptor& normalizationDescriptor,
+ const char* name = nullptr) = 0;
+
+ /// Add a softmax layer to the network.
+ /// @param softmaxDescriptor SoftmaxDescriptor to configure the softmax
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddSoftmaxLayer(const SoftmaxDescriptor& softmaxDescriptor,
+ const char* name = nullptr) = 0;
+
+ /// Add a splitter layer to the network.
+ /// @param splitterDescriptor WindowsDescriptor to configure the splitting process. Number of Views must be equal to
+ /// the number of outputs, and their order must match - e.g. first view corresponds to
+ /// the first output, second view to the second output, etc....
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddSplitterLayer(const ViewsDescriptor& splitterDescriptor
+ , const char* name = nullptr) = 0;
+
+ /// Add a merger layer to the network.
+ /// @param mergerDescriptor WindowsDescriptor to configure the merging process. Number of Views must be equal to
+ /// the number of inputs, and their order must match - e.g. first view corresponds to
+ /// the first input, second view to the second input, etc....
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddMergerLayer(const OriginsDescriptor& mergerDescriptor,
+ const char* name = nullptr) = 0;
+
+ /// Add an addition layer to the network.
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddAdditionLayer(const char* name = nullptr) = 0;
+
+ /// Add a multiplication layer to the network.
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddMultiplicationLayer(const char* name = nullptr) = 0;
+
+ /// Add a batch normalization layer to the network.
+ /// @param mean Pre-calculated mean for each channel
+ /// @param variance Pre-calculated variance for each channel
+ /// @param beta Per-channel additive factor
+ /// @param gamma Per-channel multiplicative factor
+ /// @return Interface for configuring the layer.
+ /// @param name Optional name for the layer
+ virtual IConnectableLayer* AddBatchNormalizationLayer(const BatchNormalizationDescriptor& desc,
+ const ConstTensor& mean,
+ const ConstTensor& variance,
+ const ConstTensor& beta,
+ const ConstTensor& gamma,
+ const char* name = nullptr) = 0;
+
+ /// Add a resize bilinear layer to the network.
+ /// @param resizeDesc Parameters for the resize operation
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer
+ virtual IConnectableLayer* AddResizeBilinearLayer(const ResizeBilinearDescriptor& resizeDesc,
+ const char* name = nullptr) = 0;
+
+ /// Add an L2 normalization layer to the network.
+ /// Normalization is performed along dimension 1, but requires a 4d input.
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer
+ virtual IConnectableLayer* AddL2NormalizationLayer(const char* name = nullptr) = 0;
+
+ /// Adds a layer with no inputs and a single output, which always corresponds to
+ /// the passed in constant tensor.
+ /// @param input Tensor to be provided as the only output of the layer. The layer will maintain its own copy of the
+ /// tensor data, meaning the memory referenced by @a input can be freed or reused after this function is
+ /// called.
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer
+ virtual IConnectableLayer* AddConstantLayer(const ConstTensor& input,
+ const char* name = nullptr) = 0;
+
+ /// Add a reshape layer to the network.
+ /// @param reshapeDescriptor Parameters for the reshape operation
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddReshapeLayer(const ReshapeDescriptor& reshapeDescriptor,
+ const char* name = nullptr) = 0;
+
+ /// Add a floor layer to the network.
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddFloorLayer(const char* name = nullptr) = 0;
+
+ /// Add an output layer to the network.
+ /// @param id User generated id to uniquely identify a particular output. The same id needs to be specified
+ /// when passing the outputs to the IRuntime::EnqueueWorkload() function.
+ /// @param name Optional name for the layer
+ /// @return Interface for configuring the layer.
+ virtual IConnectableLayer* AddOutputLayer(LayerBindingId id, const char* name = nullptr) = 0;
+
+protected:
+ ~INetwork() {}
+};
+
+using IOptimizedNetworkPtr = std::unique_ptr<IOptimizedNetwork, void(*)(IOptimizedNetwork* network)>;
+
+class IOptimizedNetwork
+{
+public:
+ static void Destroy(IOptimizedNetwork* network);
+
+ virtual Status PrintGraph() = 0;
+
+protected:
+ ~IOptimizedNetwork() {}
+};
+
+
+/// Create an optimized version of the network
+/// @param network INetwork description of the network to be optimized.
+/// @param deviceSpec The choice of the default computation backend.
+/// @return An IOptimizedNetworkPtr interface to the optimized network, throws an exception derived from
+/// armnn::Exception if process fails.
+IOptimizedNetworkPtr Optimize(const INetwork& network, const DeviceSpec& deviceSpec);
+
+} //namespace armnn
diff --git a/include/armnn/IRuntime.hpp b/include/armnn/IRuntime.hpp
new file mode 100644
index 0000000000..a1a3f0fda9
--- /dev/null
+++ b/include/armnn/IRuntime.hpp
@@ -0,0 +1,116 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+#include <memory>
+
+#include "Types.hpp"
+#include "Tensor.hpp"
+#include "INetwork.hpp"
+#include "TypesUtils.hpp"
+
+namespace armnn
+{
+
+using NetworkId = int;
+
+class IClTunedParameters;
+
+class IRuntime;
+using IRuntimePtr = std::unique_ptr<IRuntime, void(*)(IRuntime* runtime)>;
+
+class IRuntime
+{
+public:
+ struct CreationOptions
+ {
+ Compute m_DefaultComputeDevice;
+ bool m_UseCpuRefAsFallback;
+ /// If set, uses the CL tuned parameters from the given object when executing CL workloads.
+ /// It will also be updated with new tuned parameters if it is configured to do so.
+ IClTunedParameters* m_ClTunedParameters;
+
+ CreationOptions(Compute defaultComputeDevice)
+ : m_DefaultComputeDevice(defaultComputeDevice)
+ , m_UseCpuRefAsFallback(true)
+ , m_ClTunedParameters(nullptr)
+ {
+ }
+ };
+
+ static IRuntime* CreateRaw(const CreationOptions& options);
+ static IRuntimePtr Create(const CreationOptions& options);
+ static void Destroy(IRuntime* runtime);
+
+ /// Load a complete network into the IRuntime.
+ /// @param [out] networkIdOut Unique identifier for the network is returned in this reference.
+ /// @param [in] network Complete network to load into the IRuntime.
+ /// The runtime takes ownership of the network once passed in.
+ /// @return armnn::Status
+ virtual Status LoadNetwork(NetworkId& networkIdOut, IOptimizedNetworkPtr network) = 0;
+
+ virtual TensorInfo GetInputTensorInfo(NetworkId networkId, LayerBindingId layerId) const = 0;
+ virtual TensorInfo GetOutputTensorInfo(NetworkId networkId, LayerBindingId layerId) const = 0;
+
+ // Evaluate network using input in inputTensors, outputs filled into outputTensors
+ virtual Status EnqueueWorkload(NetworkId networkId,
+ const InputTensors& inputTensors,
+ const OutputTensors& outputTensors) = 0;
+
+ /// Unload a network from the IRuntime.
+ /// At the moment this only removes the network from the m_Impl->m_Network.
+ /// This might need more work in the future to be AndroidNN compliant.
+ /// @param [in] networkId Unique identifier for the network to be unloaded. Generated in LoadNetwork().
+ /// @return armnn::Status
+ virtual Status UnloadNetwork(NetworkId networkId) = 0;
+
+ virtual const DeviceSpec& GetDeviceSpec() const = 0;
+
+protected:
+ ~IRuntime() {}
+};
+
+using IClTunedParametersPtr = std::unique_ptr<IClTunedParameters, void(*)(IClTunedParameters* params)>;
+
+/// Manages a set of Open CL parameters which have been tuned for maximum performance.
+/// Pass an instance of this object to the IRuntime::Create() method (via IRuntime::CreationOptions) to use it
+/// for all CL workload execution.
+///
+/// Can be created in two modes:
+/// - In UseTunedParameters mode the parameters stored in this object are used to execute CL workloads.
+/// - In UpdateTunedParameters mode, additionally, whenever a CL workload is executed for the first time the
+/// optimum parameters will be found and stored in this object. WARNING - This tuning can be slow.
+///
+/// The parameters can be loaded from and saved to a file so that you first run a slow initial read-write
+/// execution, save the parameters for later and then run fast read-only executions using the optimised parameters.
+class IClTunedParameters
+{
+public:
+ enum class Mode
+ {
+ UseTunedParameters,
+ UpdateTunedParameters
+ };
+
+ /// Creates an IClTunedParameters with the given mode.
+ /// @{
+ static IClTunedParameters* CreateRaw(Mode mode);
+ static IClTunedParametersPtr Create(Mode mode);
+ /// @}
+ static void Destroy(IClTunedParameters* params);
+
+ /// Loads an existing set of tuned parameters from the given file.
+ /// If there is an error loading the file, an armnn::Exception is thrown.
+ virtual void Load(const char* filename) = 0;
+
+ /// Saves the current set of tuned parameters to the given file.
+ /// If there is an error saving to the file, an armnn::Exception is thrown.
+ virtual void Save(const char* filename) const = 0;
+
+protected:
+ virtual ~IClTunedParameters() {};
+};
+
+}
diff --git a/include/armnn/LayerSupport.hpp b/include/armnn/LayerSupport.hpp
new file mode 100644
index 0000000000..d9de76f89c
--- /dev/null
+++ b/include/armnn/LayerSupport.hpp
@@ -0,0 +1,140 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+#include <armnn/DescriptorsFwd.hpp>
+#include <armnn/Types.hpp>
+#include <armnn/Tensor.hpp>
+
+namespace armnn
+{
+
+bool IsActivationSupported(Compute compute,
+ const TensorInfo& input,
+ const ActivationDescriptor& descriptor,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsAdditionSupported(Compute compute,
+ const TensorInfo& input0,
+ const TensorInfo& input1,
+ const TensorInfo& output,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsBatchNormalizationSupported(Compute compute,
+ const TensorInfo& input,
+ const BatchNormalizationDescriptor& descriptor,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsConstantSupported(Compute compute,
+ const TensorInfo& output,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsConvolution2dSupported(Compute compute,
+ const TensorInfo& input,
+ const Convolution2dDescriptor& descriptor,
+ const TensorInfo& weights,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsDepthwiseConvolutionSupported(Compute compute,
+ const TensorInfo& input,
+ const DepthwiseConvolution2dDescriptor& descriptor,
+ const TensorInfo& weights,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsInputSupported(Compute compute,
+ const TensorInfo& input,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsFullyConnectedSupported(Compute compute,
+ const TensorInfo& input,const
+ FullyConnectedDescriptor& descriptor,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsL2NormalizationSupported(Compute compute,
+ const TensorInfo& input,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsMergerSupported(Compute compute,
+ const std::vector<const TensorInfo*> inputs,
+ const OriginsDescriptor& descriptor,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsMultiplicationSupported(Compute compute,
+ const TensorInfo& input0,
+ const TensorInfo& input1,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsNormalizationSupported(Compute compute,
+ const TensorInfo& input,
+ const TensorInfo& output,
+ const NormalizationDescriptor& descriptor,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsOutputSupported(Compute compute,
+ const TensorInfo& output,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsPermuteSupported(Compute compute,
+ const TensorInfo& input,
+ const TensorInfo& output,
+ const PermuteDescriptor& descriptor,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsPooling2dSupported(Compute compute,
+ const TensorInfo& input,
+ const TensorInfo& output,
+ const Pooling2dDescriptor& descriptor,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsResizeBilinearSupported(Compute compute,
+ const TensorInfo& input,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsSoftmaxSupported(Compute compute,
+ const TensorInfo& input,
+ const SoftmaxDescriptor& descriptor,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsSplitterSupported(Compute compute,
+ const TensorInfo& input,
+ const ViewsDescriptor& descriptor,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsFakeQuantizationSupported(Compute compute,
+ const TensorInfo& input,
+ const FakeQuantizationDescriptor& descriptor,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsReshapeSupported(Compute compute,
+ const TensorInfo& input,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+bool IsFloorSupported(Compute compute,
+ const TensorInfo& input,
+ const TensorInfo& output,
+ char* reasonIfUnsupported = nullptr,
+ size_t reasonIfUnsupportedMaxLength = 1024);
+
+}
diff --git a/include/armnn/NetworkFwd.hpp b/include/armnn/NetworkFwd.hpp
new file mode 100644
index 0000000000..75667fdfd0
--- /dev/null
+++ b/include/armnn/NetworkFwd.hpp
@@ -0,0 +1,16 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+namespace armnn
+{
+class INetwork;
+class IOptimizedNetwork;
+class Graph;
+class IInputSlot;
+class IOutputSlot;
+class IConnectableLayer;
+class IDataLayer;
+} \ No newline at end of file
diff --git a/include/armnn/Tensor.hpp b/include/armnn/Tensor.hpp
new file mode 100644
index 0000000000..910278f33f
--- /dev/null
+++ b/include/armnn/Tensor.hpp
@@ -0,0 +1,179 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+#include "TensorFwd.hpp"
+
+#include "Types.hpp"
+#include "Exceptions.hpp"
+
+#include <array>
+#include <initializer_list>
+#include <vector>
+
+namespace armnn
+{
+
+class TensorShape
+{
+public:
+ /// Empty (invalid) constructor
+ TensorShape();
+
+ TensorShape(unsigned int numDimensions, const unsigned int* dimensionSizes);
+
+ TensorShape(std::initializer_list<unsigned int> dimensionSizeList);
+
+ TensorShape(const TensorShape& other);
+
+ TensorShape& operator=(const TensorShape& other);
+
+ unsigned int operator[](unsigned int i) const
+ {
+ return m_Dimensions.at(i);
+ }
+
+ unsigned int& operator[](unsigned int i)
+ {
+ return m_Dimensions.at(i);
+ }
+
+ bool operator==(const TensorShape& other) const;
+ bool operator!=(const TensorShape& other) const;
+
+ unsigned int GetNumDimensions() const { return m_NumDimensions; }
+ unsigned int GetNumElements() const;
+
+private:
+ std::array<unsigned int, MaxNumOfTensorDimensions> m_Dimensions;
+ unsigned int m_NumDimensions;
+};
+
+class TensorInfo
+{
+public:
+ /// Empty (invalid) constructor
+ TensorInfo();
+
+ TensorInfo(const TensorShape& shape, DataType dataType,
+ float quantizationScale = 0.0f, int32_t quantizationOffset = 0);
+ TensorInfo(unsigned int numDimensions, const unsigned int* dimensionSizes, DataType dataType,
+ float quantizationScale = 0.0f, int32_t quantizationOffset = 0);
+
+ TensorInfo(const TensorInfo& other);
+
+ TensorInfo& operator=(const TensorInfo& other);
+
+ bool operator==(const TensorInfo& other) const;
+ bool operator!=(const TensorInfo& other) const;
+
+ const TensorShape& GetShape() const { return m_Shape; }
+ TensorShape& GetShape() { return m_Shape; }
+ void SetShape(const TensorShape& newShape) { m_Shape = newShape; }
+
+ unsigned int GetNumDimensions() const { return m_Shape.GetNumDimensions(); }
+ unsigned int GetNumElements() const { return m_Shape.GetNumElements(); }
+
+ DataType GetDataType() const { return m_DataType; }
+ void SetDataType(DataType type) { m_DataType = type; }
+
+ float GetQuantizationScale() const { return m_Quantization.m_Scale; }
+ int32_t GetQuantizationOffset() const { return m_Quantization.m_Offset; }
+ void SetQuantizationScale(float scale) { m_Quantization.m_Scale = scale; }
+ void SetQuantizationOffset(int32_t offset) { m_Quantization.m_Offset = offset; }
+
+ unsigned int GetNumBytes() const;
+
+private:
+ TensorShape m_Shape;
+ DataType m_DataType;
+ /// Scale and offset values used for quantization
+ struct Quantization
+ {
+ Quantization() : m_Scale(0.f), m_Offset(0) {}
+ bool operator==(const Quantization& o) const {return ((m_Scale == o.m_Scale) && (m_Offset == o.m_Offset));}
+ float m_Scale;
+ int32_t m_Offset;
+ } m_Quantization;
+};
+
+template<typename MemoryType>
+class BaseTensor
+{
+public:
+ /// Empty (invalid) constructor
+ BaseTensor();
+
+ /// Constructor from a raw memory pointer.
+ /// @param memoryArea Region of CPU-addressable memory where tensor data will be stored. Must be valid while
+ /// workloads are on the fly. Tensor instances do not claim ownership of referenced memory regions, that is,
+ /// no attempt will be made by ArmNN to free these memory regions automatically.
+ BaseTensor(const TensorInfo& info, MemoryType memoryArea);
+
+ /// Tensors are copyable.
+ BaseTensor(const BaseTensor& other);
+
+ /// Tensors are copyable.
+ BaseTensor& operator=(const BaseTensor&);
+
+ const TensorInfo& GetInfo() const { return m_Info; }
+ TensorInfo& GetInfo() { return m_Info; }
+ const TensorShape& GetShape() const { return m_Info.GetShape(); }
+ TensorShape& GetShape() { return m_Info.GetShape(); }
+
+ DataType GetDataType() const { return m_Info.GetDataType(); }
+ unsigned int GetNumDimensions() const { return m_Info.GetNumDimensions(); }
+ unsigned int GetNumBytes() const { return m_Info.GetNumBytes(); }
+ unsigned int GetNumElements() const { return m_Info.GetNumElements(); }
+
+ MemoryType GetMemoryArea() const { return m_MemoryArea; }
+
+protected:
+ // protected destructor to stop users from making these
+ // (could still new one on the heap and then leak it...)
+ ~BaseTensor() {}
+
+ MemoryType m_MemoryArea;
+
+private:
+ TensorInfo m_Info;
+};
+
+/// A tensor defined by a TensorInfo (shape and data type) and a mutable backing store.
+class Tensor : public BaseTensor<void*>
+{
+public:
+ using BaseTensor<void*>::BaseTensor; // Bring in the constructors and assignment operator
+};
+
+/// A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
+class ConstTensor : public BaseTensor<const void*>
+{
+public:
+ using BaseTensor<const void*>::BaseTensor; // Bring in the constructors and assignment operator
+ ConstTensor() : BaseTensor<const void*>() {} // This needs to be redefined explicitly??
+
+ // Can be implicitly constructed from non-const Tensor
+ ConstTensor(const Tensor& other) : BaseTensor<const void*>(other.GetInfo(), other.GetMemoryArea()) {}
+
+ /// Constructor from a backing container.
+ /// @param container An stl-like container type which implements data() and size() methods.
+ /// Presence of data() and size() is a strong indicator of the continuous memory layout of the container,
+ /// which is a requirement for Tensor data. Tensor instances do not claim ownership of referenced memory regions,
+ /// that is, no attempt will be made by ArmNN to free these memory regions automatically.
+ template < template<typename, typename...> class ContainerType, typename T, typename...ContainerArgs >
+ ConstTensor(const TensorInfo& info, const ContainerType<T, ContainerArgs...>& container)
+ : BaseTensor<const void*>(info, container.data())
+ {
+ if (container.size() * sizeof(T) != info.GetNumBytes())
+ {
+ throw InvalidArgumentException("Container size is not correct");
+ }
+ }
+};
+
+using InputTensors = std::vector<std::pair<LayerBindingId, class ConstTensor>>;
+using OutputTensors = std::vector<std::pair<LayerBindingId, class Tensor>>;
+
+} // namespace armnn
diff --git a/include/armnn/TensorFwd.hpp b/include/armnn/TensorFwd.hpp
new file mode 100644
index 0000000000..5ea035c877
--- /dev/null
+++ b/include/armnn/TensorFwd.hpp
@@ -0,0 +1,15 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+namespace armnn
+{
+
+class TensorShape;
+class TensorInfo;
+class Tensor;
+class ConstTensor;
+
+}
diff --git a/include/armnn/Types.hpp b/include/armnn/Types.hpp
new file mode 100644
index 0000000000..e1aa393ecc
--- /dev/null
+++ b/include/armnn/Types.hpp
@@ -0,0 +1,155 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+#include <array>
+
+namespace armnn
+{
+
+constexpr unsigned int MaxNumOfTensorDimensions = 4U;
+
+/// @enum Status enumeration
+/// @var Status::Successful
+/// @var Status::Failure
+enum class Status
+{
+ Success = 0,
+ Failure = 1
+};
+
+enum class DataType
+{
+ Float32 = 0,
+ QuantisedAsymm8 = 1,
+ Signed32 = 2
+};
+
+enum class ActivationFunction
+{
+ Sigmoid = 0,
+ TanH = 1,
+ Linear = 2,
+ ReLu = 3,
+ BoundedReLu = 4, //< min(a, max(b, input))
+ SoftReLu = 5,
+ LeakyReLu = 6,
+ Abs = 7,
+ Sqrt = 8,
+ Square = 9
+};
+
+enum class PoolingAlgorithm
+{
+ Max = 0,
+ Average = 1,
+ L2 = 2
+};
+
+///
+/// The padding method modifies the output of pooling layers.
+/// In both supported methods, the values are ignored (they are
+/// not even zeros which would make a difference for max pooling
+/// a tensor with negative values). The difference between
+/// IgnoreValue and Exclude is that the former count the padding
+/// fields in the divisor of Average and L2 pooling, while
+/// Exclude does not.
+///
+enum class PaddingMethod
+{
+ IgnoreValue = 0, // The padding fields count, but ignored
+ Exclude = 1 // The padding fields don't count and ignored
+};
+
+enum class NormalizationAlgorithmChannel
+{
+ Across = 0,
+ Within = 1
+};
+
+enum class NormalizationAlgorithmMethod
+{
+ LocalBrightness = 0, /* Krichevsky 2012: Local Brightness Normalization */
+ LocalContrast = 1 /* Jarret 2009: Local Contrast Normalization */
+};
+
+enum class OutputShapeRounding
+{
+ Floor = 0,
+ Ceiling = 1
+};
+
+enum class Compute
+{
+ CpuRef = 0, // CPU Execution: Reference C++ kernels
+ CpuAcc = 1, // CPU Execution: NEON: ArmCompute
+ GpuAcc = 2, // GPU Execution: OpenCL: ArmCompute
+ Undefined = 5
+};
+
+struct DeviceSpec
+{
+ Compute DefaultComputeDevice;
+};
+
+/// Type of identifiers for bindable layers (inputs, outputs).
+using LayerBindingId = int;
+
+class PermutationVector
+{
+public:
+ using ValueType = unsigned int;
+ using SizeType = unsigned int;
+ using ArrayType = std::array<ValueType, MaxNumOfTensorDimensions>;
+ using ConstIterator = typename ArrayType::const_iterator;
+
+ /// @param dimMappings Indicates how to translate tensor elements from a given source into the target destination,
+ /// when source and target potentially have different memory layouts.
+ ///
+ /// E.g. For a 4-d tensor laid out in memory with format (Batch Element, Height, Width, Channels),
+ /// which is to be passed as an input to ArmNN, each source dimension is mapped to the corresponding
+ /// ArmNN dimension. The Batch dimension remains the same (0 -> 0). The source Height dimension is mapped
+ /// to the location of the ArmNN Height dimension (1 -> 2). Similar arguments are made for the Width and
+ /// Channels (2 -> 3 and 3 -> 1). This will lead to @ref m_DimMappings pointing to the following array:
+ /// [ 0, 2, 3, 1 ].
+ ///
+ /// Note that the mapping should be reversed if considering the case of ArmNN 4-d outputs (Batch Element,
+ /// Channels, Height, Width) being written to a destination with the format mentioned above. We now have
+ /// 0 -> 0, 2 -> 1, 3 -> 2, 1 -> 3, which, when reordered, lead to the following @ref m_DimMappings contents:
+ /// [ 0, 3, 1, 2 ].
+ ///
+ PermutationVector(const ValueType *dimMappings, SizeType numDimMappings);
+
+ PermutationVector(std::initializer_list<ValueType> dimMappings);
+
+ ValueType operator[](SizeType i) const { return m_DimMappings.at(i); }
+
+ SizeType GetSize() const { return m_NumDimMappings; }
+
+ ConstIterator begin() const { return m_DimMappings.begin(); }
+ ConstIterator end() const { return m_DimMappings.end(); }
+
+ bool IsEqual(const PermutationVector& other) const
+ {
+ return std::equal(begin(), end(), other.begin(), other.end());
+ }
+
+ bool IsInverse(const PermutationVector& other) const
+ {
+ bool isInverse = (GetSize() == other.GetSize());
+ for (SizeType i = 0; isInverse && (i < GetSize()); ++i)
+ {
+ isInverse = (m_DimMappings[other.m_DimMappings[i]] == i);
+ }
+ return isInverse;
+ }
+
+private:
+ ArrayType m_DimMappings;
+ /// Number of valid entries in @ref m_DimMappings
+ SizeType m_NumDimMappings;
+};
+
+}
diff --git a/include/armnn/TypesUtils.hpp b/include/armnn/TypesUtils.hpp
new file mode 100644
index 0000000000..a851b66b28
--- /dev/null
+++ b/include/armnn/TypesUtils.hpp
@@ -0,0 +1,182 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+#include "Types.hpp"
+#include <cmath>
+#include <ostream>
+#include <boost/assert.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+namespace armnn
+{
+
+constexpr char const* GetStatusAsCString(Status compute)
+{
+ switch (compute)
+ {
+ case armnn::Status::Success: return "Status::Success";
+ case armnn::Status::Failure: return "Status::Failure";
+ default: return "Unknown";
+ }
+}
+
+constexpr char const* GetComputeDeviceAsCString(Compute compute)
+{
+ switch (compute)
+ {
+ case armnn::Compute::CpuRef: return "CpuRef";
+ case armnn::Compute::CpuAcc: return "CpuAcc";
+ case armnn::Compute::GpuAcc: return "GpuAcc";
+ default: return "Unknown";
+ }
+}
+
+constexpr unsigned int GetDataTypeSize(DataType dataType)
+{
+ switch (dataType)
+ {
+ case DataType::Signed32:
+ case DataType::Float32: return 4U;
+ case DataType::QuantisedAsymm8: return 1U;
+ default: return 0U;
+ }
+}
+
+template <int N>
+constexpr bool StrEqual(const char* strA, const char (&strB)[N])
+{
+ bool isEqual = true;
+ for (int i = 0; isEqual && (i < N); ++i)
+ {
+ isEqual = (strA[i] == strB[i]);
+ }
+ return isEqual;
+}
+
+constexpr Compute ParseComputeDevice(const char* str)
+{
+ if (StrEqual(str, "CpuAcc"))
+ {
+ return armnn::Compute::CpuAcc;
+ }
+ else if (StrEqual(str, "CpuRef"))
+ {
+ return armnn::Compute::CpuRef;
+ }
+ else if (StrEqual(str, "GpuAcc"))
+ {
+ return armnn::Compute::GpuAcc;
+ }
+ else
+ {
+ return armnn::Compute::Undefined;
+ }
+}
+
+constexpr const char* GetDataTypeName(DataType dataType)
+{
+ switch (dataType)
+ {
+ case DataType::Float32: return "Float32";
+ case DataType::QuantisedAsymm8: return "Unsigned8";
+ case DataType::Signed32: return "Signed32";
+ default: return "Unknown";
+ }
+}
+
+template <typename T>
+constexpr DataType GetDataType();
+
+template <>
+constexpr DataType GetDataType<float>()
+{
+ return DataType::Float32;
+}
+
+template <>
+constexpr DataType GetDataType<uint8_t>()
+{
+ return DataType::QuantisedAsymm8;
+}
+
+template <>
+constexpr DataType GetDataType<int32_t>()
+{
+ return DataType::Signed32;
+}
+
+template<typename T>
+constexpr bool IsQuantizedType()
+{
+ return std::is_integral<T>::value;
+}
+
+
+template<DataType DT>
+struct ResolveTypeImpl;
+
+template<>
+struct ResolveTypeImpl<DataType::QuantisedAsymm8>
+{
+ using Type = uint8_t;
+};
+
+template<>
+struct ResolveTypeImpl<DataType::Float32>
+{
+ using Type = float;
+};
+
+template<DataType DT>
+using ResolveType = typename ResolveTypeImpl<DT>::Type;
+
+
+inline std::ostream& operator<<(std::ostream& os, Status stat)
+{
+ os << GetStatusAsCString(stat);
+ return os;
+}
+
+inline std::ostream& operator<<(std::ostream& os, Compute compute)
+{
+ os << GetComputeDeviceAsCString(compute);
+ return os;
+}
+
+/// Quantize a floating point data type into an 8-bit data type
+/// @param value The value to quantize
+/// @param scale The scale (must be non-zero)
+/// @param offset The offset
+/// @return The quantized value calculated as round(value/scale)+offset
+///
+template<typename QuantizedType>
+inline QuantizedType Quantize(float value, float scale, int32_t offset)
+{
+ static_assert(IsQuantizedType<QuantizedType>(), "Not an integer type.");
+ constexpr QuantizedType max = std::numeric_limits<QuantizedType>::max();
+ constexpr QuantizedType min = std::numeric_limits<QuantizedType>::lowest();
+ BOOST_ASSERT(scale != 0.f);
+ int quantized = boost::numeric_cast<int>(round(value / scale)) + offset;
+ QuantizedType quantizedBits = quantized < min ? min : quantized > max ? max : static_cast<QuantizedType>(quantized);
+ return quantizedBits;
+}
+
+/// Dequantize an 8-bit data type into a floating point data type
+/// @param value The value to dequantize
+/// @param scale The scale (must be non-zero)
+/// @param offset The offset
+/// @return The dequantized value calculated as (value-offset)*scale
+///
+template <typename QuantizedType>
+inline float Dequantize(QuantizedType value, float scale, int32_t offset)
+{
+ static_assert(IsQuantizedType<QuantizedType>(), "Not an integer type.");
+ BOOST_ASSERT(scale != 0.f);
+ float dequantized = boost::numeric_cast<float>(value - offset) * scale;
+ return dequantized;
+}
+
+} //namespace armnn \ No newline at end of file
diff --git a/include/armnn/Utils.hpp b/include/armnn/Utils.hpp
new file mode 100644
index 0000000000..1a0c34baad
--- /dev/null
+++ b/include/armnn/Utils.hpp
@@ -0,0 +1,27 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+namespace armnn
+{
+
+enum class LogSeverity
+{
+ Trace,
+ Debug,
+ Info,
+ Warning,
+ Error,
+ Fatal
+};
+
+/// Configures the logging behaviour of the ARMNN library.
+/// printToStandardOutput: Set to true if log messages should be printed to the standard output.
+/// printToDebugOutput: Set to true if log messages be printed to a platform-specific debug output
+/// (where supported).
+/// severity: All log messages that are at this severity level or higher will be printed, others will be ignored.
+void ConfigureLogging(bool printToStandardOutput, bool printToDebugOutput, LogSeverity severity);
+
+}
diff --git a/include/armnn/Version.hpp b/include/armnn/Version.hpp
new file mode 100644
index 0000000000..6ce8256faa
--- /dev/null
+++ b/include/armnn/Version.hpp
@@ -0,0 +1,12 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+// YYYYMMPP
+// where:
+// YYYY = 4-digit year number
+// MM = 2-digit month number
+// PP = 2-digit patch number
+#define ARMNN_VERSION "20180200"
diff --git a/include/armnnCaffeParser/ICaffeParser.hpp b/include/armnnCaffeParser/ICaffeParser.hpp
new file mode 100644
index 0000000000..55fc85052b
--- /dev/null
+++ b/include/armnnCaffeParser/ICaffeParser.hpp
@@ -0,0 +1,59 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#pragma once
+
+#include "armnn/Types.hpp"
+#include "armnn/NetworkFwd.hpp"
+#include "armnn/Tensor.hpp"
+#include "armnn/INetwork.hpp"
+
+#include <memory>
+#include <map>
+#include <vector>
+
+namespace armnnCaffeParser
+{
+
+using BindingPointInfo = std::pair<armnn::LayerBindingId, armnn::TensorInfo>;
+
+class ICaffeParser;
+using ICaffeParserPtr = std::unique_ptr<ICaffeParser, void(*)(ICaffeParser* parser)>;
+
+class ICaffeParser
+{
+public:
+ static ICaffeParser* CreateRaw();
+ static ICaffeParserPtr Create();
+ static void Destroy(ICaffeParser* parser);
+
+ /// Create the network from a protobuf text file on disk
+ virtual armnn::INetworkPtr CreateNetworkFromTextFile(
+ const char* graphFile,
+ const std::map<std::string, armnn::TensorShape>& inputShapes,
+ const std::vector<std::string>& requestedOutputs) = 0;
+
+ /// Create the network from a protobuf binary file on disk
+ virtual armnn::INetworkPtr CreateNetworkFromBinaryFile(
+ const char* graphFile,
+ const std::map<std::string, armnn::TensorShape>& inputShapes,
+ const std::vector<std::string>& requestedOutputs) = 0;
+
+ /// Create the network directly from protobuf text in a string. Useful for debugging/testing
+ virtual armnn::INetworkPtr CreateNetworkFromString(
+ const char* protoText,
+ const std::map<std::string, armnn::TensorShape>& inputShapes,
+ const std::vector<std::string>& requestedOutputs) = 0;
+
+ /// Retrieve binding info (layer id and tensor info) for the network input identified by the given layer name
+ virtual BindingPointInfo GetNetworkInputBindingInfo(const std::string& name) const = 0;
+
+ /// Retrieve binding info (layer id and tensor info) for the network output identified by the given layer name
+ virtual BindingPointInfo GetNetworkOutputBindingInfo(const std::string& name) const = 0;
+
+protected:
+ virtual ~ICaffeParser() {};
+};
+
+} \ No newline at end of file