From c577f2c6a3b4ddb6ba87a882723c53a248afbeba Mon Sep 17 00:00:00 2001 From: telsoa01 Date: Fri, 31 Aug 2018 09:22:23 +0100 Subject: Release 18.08 --- src/armnnOnnxParser/OnnxParser.hpp | 183 +++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 src/armnnOnnxParser/OnnxParser.hpp (limited to 'src/armnnOnnxParser/OnnxParser.hpp') diff --git a/src/armnnOnnxParser/OnnxParser.hpp b/src/armnnOnnxParser/OnnxParser.hpp new file mode 100644 index 0000000000..ee75f8e322 --- /dev/null +++ b/src/armnnOnnxParser/OnnxParser.hpp @@ -0,0 +1,183 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// See LICENSE file in the project root for full license information. +// +#pragma once + +#include "armnnOnnxParser/IOnnxParser.hpp" +#include "google/protobuf/repeated_field.h" +#include + +#include + + +namespace armnn +{ +class TensorInfo; +} + +namespace armnnOnnxParser +{ + +using BindingPointInfo = std::pair; +using ModelPtr = std::unique_ptr; + +class OnnxParser : public IOnnxParser +{ + +using OperationParsingFunction = void(OnnxParser::*)(const onnx::NodeProto& NodeProto); + +public: + + using GraphPtr = std::unique_ptr; + + /// Create the network from a protobuf binary file on disk + virtual armnn::INetworkPtr CreateNetworkFromBinaryFile(const char* graphFile) override; + + /// Create the network from a protobuf text file on disk + virtual armnn::INetworkPtr CreateNetworkFromTextFile(const char* graphFile) override; + + /// Create the network directly from protobuf text in a string. Useful for debugging/testing + virtual armnn::INetworkPtr CreateNetworkFromString(const std::string& protoText) override; + + /// 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 override; + + /// 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 override; + +public: + + OnnxParser(); + + static ModelPtr LoadModelFromBinaryFile(const char * fileName); + static ModelPtr LoadModelFromTextFile(const char * fileName); + static ModelPtr LoadModelFromString(const std::string& inputString); + + ///Retrieve inputs names + static std::vector GetInputs(ModelPtr& model); + + ///Retrieve outputs names + static std::vector GetOutputs(ModelPtr& model); + +private: + + /// Parses a ModelProto loaded into memory from one of the other CreateNetwork* + armnn::INetworkPtr CreateNetworkFromModel(onnx::ModelProto& model); + + ///Parse every node and make the connection between the resulting tensors + void LoadGraph(); + + void SetupInfo(const google::protobuf::RepeatedPtrField* list); + + std::vector ComputeOutputInfo(std::vector outNames, + const armnn::IConnectableLayer* layer, + std::vector inputShapes); + + void DetectFullyConnected(); + + template + void GetInputAndParam(const onnx::NodeProto& node, + std::string* inputName, + std::string* constName, + const Location& location); + + template + void To1DTensor(const std::string &name, const Location& location); + + //Broadcast Preparation functions + std::pair AddPrepareBroadcast(const std::string& input0, const std::string& input1); + void PrependForBroadcast(const std::string& outputName, const std::string& input0, const std::string& input1); + + void CreateConstantLayer(const std::string& tensorName, const std::string& layerName); + void CreateReshapeLayer(const std::string& inputName, + const std::string& outputName, + const std::string& layerName); + + void ParseBatchNormalization(const onnx::NodeProto& node); + void ParseConstant(const onnx::NodeProto& nodeProto); + + void ParseMaxPool(const onnx::NodeProto& nodeProto); + void ParseAveragePool(const onnx::NodeProto& nodeProto); + void ParseGlobalAveragePool(const onnx::NodeProto& node); + + void AddPoolingLayer(const onnx::NodeProto& nodeProto, armnn::Pooling2dDescriptor& desc); + + void ParseReshape(const onnx::NodeProto& nodeProto); + void ParseRelu(const onnx::NodeProto& nodeProto); + + void AddConvLayerWithDepthwiseConv(const onnx::NodeProto& node, const armnn::Convolution2dDescriptor& convDesc); + void ParseConv(const onnx::NodeProto& nodeProto); + + void ParseAdd(const onnx::NodeProto& nodeProto); + void AddFullyConnected(const onnx::NodeProto& matmulNode, const onnx::NodeProto* addNode = nullptr); + + void RegisterInputSlots(armnn::IConnectableLayer* layer, const std::vector& tensorIndexes); + void RegisterOutputSlots(armnn::IConnectableLayer* layer, const std::vector& tensorIndexes); + + void SetupInputLayers(); + void SetupOutputLayers(); + + void ResetParser(); + void Cleanup(); + + std::pair> CreateConstTensor(const std::string name); + + template + void ValidateInputs(const onnx::NodeProto& node, + TypeList validInputs, + const Location& location); + + /// The network we're building. Gets cleared after it is passed to the user + armnn::INetworkPtr m_Network; + + ///Ptr to the graph we're building the network from + GraphPtr m_Graph; + + ///Map of the information for every tensor + struct OnnxTensor + { + std::unique_ptr m_info; + std::unique_ptr m_tensor; + onnx::TensorProto::DataType m_dtype; + + OnnxTensor() : m_info(nullptr), m_tensor(nullptr), m_dtype(onnx::TensorProto::FLOAT) { } + bool isConstant() { return m_tensor != nullptr; } + + }; + + std::unordered_map m_TensorsInfo; + + /// map of onnx operation names to parsing member functions + static const std::map m_ParserFunctions; + + /// A mapping of an output slot to each of the input slots it should be connected to + /// The outputSlot is from the layer that creates this tensor as one of its ouputs + /// The inputSlots are from the layers that use this tensor as one of their inputs + struct TensorSlots + { + armnn::IOutputSlot* outputSlot; + std::vector inputSlots; + + TensorSlots() : outputSlot(nullptr) { } + }; + ///Map of the tensor names to their connections for the connections of the layers of the graph + std::unordered_map m_TensorConnections; + + //Map of the tensor names to their node and index in graph.node() + std::unordered_map> m_OutputsMap; + + /// Number of times a specific node (identified by his index number) was used as input + /// and list of the nodes it was fused with + struct UsageSummary + { + std::vector fusedWithNodes; + size_t inputForNodes; + + UsageSummary() : fusedWithNodes({}), inputForNodes(0) { } + + }; + + std::vector m_OutputsFusedAndUsed; +}; +} -- cgit v1.2.1