IVGCVSW-4010 Add serialization support for StandInLayer
authorAron Virginas-Tar <Aron.Virginas-Tar@arm.com>
Wed, 23 Oct 2019 09:41:35 +0000 (10:41 +0100)
committerMatteo Martincigh <matteo.martincigh@arm.com>
Wed, 23 Oct 2019 13:19:45 +0000 (13:19 +0000)
Signed-off-by: Aron Virginas-Tar <Aron.Virginas-Tar@arm.com>
Change-Id: I2017c15b485b82437c6ffdac4d3112bcc2cbe9e9

include/armnn/Descriptors.hpp
src/armnn/layers/StandInLayer.cpp
src/armnnDeserializer/Deserializer.cpp
src/armnnDeserializer/Deserializer.hpp
src/armnnDeserializer/DeserializerSupport.md
src/armnnSerializer/ArmnnSchema.fbs
src/armnnSerializer/Serializer.cpp
src/armnnSerializer/SerializerSupport.md
src/armnnSerializer/test/SerializerTests.cpp

index 425c5261df14618712ee33b5fda0102f8649a7d6..ba9a56ad38f59a0fe1e80fd2f83932d06fe53586 100644 (file)
@@ -962,6 +962,12 @@ struct StandInDescriptor
         , m_NumOutputs(numOutputs)
     {}
 
+    bool operator ==(const StandInDescriptor& rhs) const
+    {
+        return m_NumInputs  == rhs.m_NumInputs &&
+               m_NumOutputs == rhs.m_NumOutputs;
+    }
+
     /// Number of input tensors
     uint32_t m_NumInputs = 0;
     /// Number of output tensors
index fdc905fea2835e246741078a8af72b8a320b08ee..7d693bfffbfa350c131ceb80e4c6ee0118c43f0f 100644 (file)
@@ -10,7 +10,7 @@ namespace armnn
 {
 
 StandInLayer::StandInLayer(const StandInDescriptor& param, const char* name)
-    : LayerWithParameters(param.m_NumInputs, 1, LayerType::StandIn, param, name)
+    : LayerWithParameters(param.m_NumInputs, param.m_NumOutputs, LayerType::StandIn, param, name)
 {
 }
 
@@ -42,6 +42,4 @@ void StandInLayer::Accept(ILayerVisitor& visitor) const
 {
     visitor.VisitStandInLayer(this, GetParameters(), GetName());
 }
-} //namespace armnn
-
-
+} // namespace armnn
index 6779f1eb068f0857fb03e5328bb34101c7dd5dd1..92212b654a24e8a334930efd9151dd3f256572a3 100644 (file)
@@ -232,6 +232,7 @@ m_ParserFunctions(Layer_MAX+1, &Deserializer::ParseUnsupportedLayer)
     m_ParserFunctions[Layer_SpaceToDepthLayer]           = &Deserializer::ParseSpaceToDepth;
     m_ParserFunctions[Layer_SplitterLayer]               = &Deserializer::ParseSplitter;
     m_ParserFunctions[Layer_StackLayer]                  = &Deserializer::ParseStack;
+    m_ParserFunctions[Layer_StandInLayer]                = &Deserializer::ParseStandIn;
     m_ParserFunctions[Layer_StridedSliceLayer]           = &Deserializer::ParseStridedSlice;
     m_ParserFunctions[Layer_SubtractionLayer]            = &Deserializer::ParseSubtraction;
     m_ParserFunctions[Layer_SwitchLayer]                 = &Deserializer::ParseSwitch;
@@ -342,6 +343,8 @@ Deserializer::LayerBaseRawPtr Deserializer::GetBaseLayer(const GraphPtr& graphPt
             return graphPtr->layers()->Get(layerIndex)->layer_as_SplitterLayer()->base();
         case Layer::Layer_StackLayer:
             return graphPtr->layers()->Get(layerIndex)->layer_as_StackLayer()->base();
+        case Layer::Layer_StandInLayer:
+            return graphPtr->layers()->Get(layerIndex)->layer_as_StandInLayer()->base();
         case Layer::Layer_StridedSliceLayer:
             return graphPtr->layers()->Get(layerIndex)->layer_as_StridedSliceLayer()->base();
         case Layer::Layer_SubtractionLayer:
@@ -2685,4 +2688,34 @@ void Deserializer::ParseStack(GraphPtr graph, unsigned int layerIndex)
     RegisterOutputSlots(graph, layerIndex, layer);
 }
 
+void Deserializer::ParseStandIn(GraphPtr graph, unsigned int layerIndex)
+{
+    CHECK_LAYERS(graph, 0, layerIndex);
+
+    auto inputs  = GetInputs(graph, layerIndex);
+    auto outputs = GetOutputs(graph, layerIndex);
+
+    auto fbLayer      = graph->layers()->Get(layerIndex)->layer_as_StandInLayer();
+    auto fbDescriptor = fbLayer->descriptor();
+
+    armnn::StandInDescriptor descriptor;
+    descriptor.m_NumInputs  = fbDescriptor->numInputs();
+    descriptor.m_NumOutputs = fbDescriptor->numOutputs();
+
+    CHECK_VALID_SIZE(inputs.size(),  descriptor.m_NumInputs);
+    CHECK_VALID_SIZE(outputs.size(), descriptor.m_NumOutputs);
+
+    const std::string layerName     = GetLayerName(graph, layerIndex);
+    armnn::IConnectableLayer* layer = m_Network->AddStandInLayer(descriptor, layerName.c_str());
+
+    for (unsigned int i = 0u; i < descriptor.m_NumOutputs; ++i)
+    {
+        armnn::TensorInfo outputInfo = ToTensorInfo(outputs[i]);
+        layer->GetOutputSlot(i).SetTensorInfo(outputInfo);
+    }
+
+    RegisterInputSlots(graph, layerIndex, layer);
+    RegisterOutputSlots(graph, layerIndex, layer);
+}
+
 } // namespace armnnDeserializer
index b95148392678880347a5d92f6dc0f8be031d0225..babb56e70eacbeed2b1ebd774adbbd27a4422f25 100644 (file)
@@ -123,6 +123,7 @@ private:
     void ParseSpaceToDepth(GraphPtr graph, unsigned int layerIndex);
     void ParseSplitter(GraphPtr graph, unsigned int layerIndex);
     void ParseStack(GraphPtr graph, unsigned int layerIndex);
+    void ParseStandIn(GraphPtr graph, unsigned int layerIndex);
     void ParseStridedSlice(GraphPtr graph, unsigned int layerIndex);
     void ParseSubtraction(GraphPtr graph, unsigned int layerIndex);
     void ParseSwitch(GraphPtr graph, unsigned int layerIndex);
index fce706433773c91f798eba12bc20941ac3d87906..fcadaccb793e25a915322663a19f56c3bcaf7ba1 100644 (file)
@@ -50,6 +50,7 @@ The Arm NN SDK Deserialize parser currently supports the following layers:
 * SpaceToDepth
 * Splitter
 * Stack
+* StandIn
 * StridedSlice
 * Subtraction
 * Switch
index 0756784cd313013f31819dfd7fe1928a1d8ce72c..bad95cfc560282184c27f051af7e7ed101be4eaf 100644 (file)
@@ -144,7 +144,8 @@ enum LayerType : uint {
     DepthToSpace = 49,
     InstanceNormalization = 50,
     LogSoftmax = 51,
-    Comparison = 52
+    Comparison = 52,
+    StandIn = 53
 }
 
 // Base layer table to be used as part of other layers
@@ -731,6 +732,16 @@ table StackDescriptor {
     inputShape:[uint];
 }
 
+table StandInDescriptor {
+    numInputs:uint;
+    numOutputs:uint;
+}
+
+table StandInLayer {
+    base:LayerBase;
+    descriptor:StandInDescriptor;
+}
+
 union Layer {
     ActivationLayer,
     AdditionLayer,
@@ -784,7 +795,8 @@ union Layer {
     DepthToSpaceLayer,
     InstanceNormalizationLayer,
     LogSoftmaxLayer,
-    ComparisonLayer
+    ComparisonLayer,
+    StandInLayer
 }
 
 table AnyLayer {
index d147d47f41f1a846661618a07e1800750c0f673e..81091bca85fba70153a469e68fdffbec299a43a5 100644 (file)
@@ -1094,7 +1094,14 @@ void SerializerVisitor::VisitStandInLayer(const armnn::IConnectableLayer *layer,
                                           const armnn::StandInDescriptor& standInDescriptor,
                                           const char *name)
 {
-    // TODO: IVGCVSW-4010 Implement serialization
+    auto fbDescriptor = serializer::CreateStandInDescriptor(m_flatBufferBuilder,
+                                                            standInDescriptor.m_NumInputs,
+                                                            standInDescriptor.m_NumOutputs);
+
+    auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StandIn);
+    auto fbLayer     = serializer::CreateStandInLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
+
+    CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_StandInLayer);
 }
 
 void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
index 4b12f9ca231864f58aa7c65ef8effa01638ed4cd..4fc880a85630908d6b99e42295190b020ad2ed51 100644 (file)
@@ -50,6 +50,7 @@ The Arm NN SDK Serializer currently supports the following layers:
 * SpaceToDepth
 * Splitter
 * Stack
+* StandIn
 * StridedSlice
 * Subtraction
 * Switch
index 10627d08ba595f3bc3ad8f248bfb6c7efe35acb9..1f97e935adf6dac1a3ca08df1e81cceb2671135f 100644 (file)
@@ -2289,6 +2289,41 @@ BOOST_AUTO_TEST_CASE(SerializeStack)
     deserializedNetwork->Accept(verifier);
 }
 
+BOOST_AUTO_TEST_CASE(SerializeStandIn)
+{
+    DECLARE_LAYER_VERIFIER_CLASS_WITH_DESCRIPTOR(StandIn)
+
+    const std::string layerName("standIn");
+
+    armnn::TensorInfo tensorInfo({ 1u }, armnn::DataType::Float32);
+    armnn::StandInDescriptor descriptor(2u, 2u);
+
+    armnn::INetworkPtr network = armnn::INetwork::Create();
+    armnn::IConnectableLayer* const inputLayer0  = network->AddInputLayer(0);
+    armnn::IConnectableLayer* const inputLayer1  = network->AddInputLayer(1);
+    armnn::IConnectableLayer* const standInLayer = network->AddStandInLayer(descriptor, layerName.c_str());
+    armnn::IConnectableLayer* const outputLayer0 = network->AddOutputLayer(0);
+    armnn::IConnectableLayer* const outputLayer1 = network->AddOutputLayer(1);
+
+    inputLayer0->GetOutputSlot(0).Connect(standInLayer->GetInputSlot(0));
+    inputLayer0->GetOutputSlot(0).SetTensorInfo(tensorInfo);
+
+    inputLayer1->GetOutputSlot(0).Connect(standInLayer->GetInputSlot(1));
+    inputLayer1->GetOutputSlot(0).SetTensorInfo(tensorInfo);
+
+    standInLayer->GetOutputSlot(0).Connect(outputLayer0->GetInputSlot(0));
+    standInLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
+
+    standInLayer->GetOutputSlot(1).Connect(outputLayer1->GetInputSlot(0));
+    standInLayer->GetOutputSlot(1).SetTensorInfo(tensorInfo);
+
+    armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
+    BOOST_CHECK(deserializedNetwork);
+
+    StandInLayerVerifier verifier(layerName, { tensorInfo, tensorInfo }, { tensorInfo, tensorInfo }, descriptor);
+    deserializedNetwork->Accept(verifier);
+}
+
 BOOST_AUTO_TEST_CASE(SerializeStridedSlice)
 {
     DECLARE_LAYER_VERIFIER_CLASS_WITH_DESCRIPTOR(StridedSlice)