IVGCVSW-3725 Adding quantization support for ArgMinMax
authorNikhil Raj <nikhil.raj@arm.com>
Wed, 18 Sep 2019 16:16:31 +0000 (17:16 +0100)
committerNikhil Raj Arm <nikhil.raj@arm.com>
Thu, 19 Sep 2019 07:34:56 +0000 (07:34 +0000)
Change-Id: I7582a9ee36b4d1764a5a137cefe9b7b7dfe30254
Signed-off-by: Nikhil Raj <nikhil.raj@arm.com>
src/armnn/QuantizerVisitor.cpp
src/armnn/QuantizerVisitor.hpp
src/armnn/test/QuantizerTest.cpp

index 5a86264..564b7bb 100644 (file)
@@ -136,6 +136,15 @@ void QuantizerVisitor::VisitAdditionLayer(const IConnectableLayer* layer, const
     SetQuantizedInputConnections(layer, newLayer);
 }
 
+void QuantizerVisitor::VisitArgMinMaxLayer(const IConnectableLayer* layer,
+                                           const ArgMinMaxDescriptor& argMinMaxDescriptor,
+                                           const char* name)
+{
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddArgMinMaxLayer(argMinMaxDescriptor, name);
+    RecordLayer(layer, newLayer);
+    SetQuantizedInputConnections(layer, newLayer);
+}
+
 void QuantizerVisitor::VisitBatchNormalizationLayer(const IConnectableLayer* layer,
                                                     const BatchNormalizationDescriptor& desc,
                                                     const ConstTensor& mean,
index 3a1e300..db1a669 100644 (file)
@@ -40,6 +40,10 @@ public:
 
     void VisitAdditionLayer(const IConnectableLayer* layer, const char* name = nullptr) override;
 
+    void VisitArgMinMaxLayer(const IConnectableLayer* layer,
+                             const ArgMinMaxDescriptor& argMinMaxDescriptor,
+                             const char* name = nullptr) override;
+
     void VisitBatchNormalizationLayer(const IConnectableLayer* layer,
                                       const BatchNormalizationDescriptor& desc,
                                       const ConstTensor& mean,
index d902b8d..a569c24 100644 (file)
@@ -1348,6 +1348,78 @@ BOOST_AUTO_TEST_CASE(QuantizeAbs)
     VisitLayersTopologically(quantizedNetworkQSymm16.get(), validatorQSymm16);
 }
 
+BOOST_AUTO_TEST_CASE(QuantizeArgMinMax)
+{
+    class TestArgMinMaxQuantization : public TestQuantization
+    {
+    public:
+        TestArgMinMaxQuantization(const TensorShape& inputShape, const TensorShape& outputShape)  :
+                TestQuantization(inputShape, outputShape) {}
+
+        TestArgMinMaxQuantization(const QuantizerOptions& options,
+                                  const TensorShape& inputShape,
+                                  const TensorShape& outputShape) :
+                TestQuantization(options, inputShape, outputShape)
+        {}
+
+        void VisitInputLayer(const IConnectableLayer* layer,
+                             LayerBindingId id,
+                             const char* name = nullptr) override
+        {}
+
+        void VisitOutputLayer(const IConnectableLayer* layer,
+                              LayerBindingId id,
+                              const char* name = nullptr) override
+        {}
+        void VisitArgMinMaxLayer(const IConnectableLayer* layer,
+                                 const ArgMinMaxDescriptor& argMinMaxDescriptor,
+                                 const char* name = nullptr) override
+        {
+                TensorInfo outputInfo = layer->GetOutputSlot(0).GetTensorInfo();
+
+                TestQuantizationParams(outputInfo,
+                                       { 30.0f / g_Asymm8QuantizationBase, 128 },
+                                       { 15.0f / g_Symm16QuantizationBase, 0 });
+        }
+    };
+
+    INetworkPtr network = INetwork::Create();
+
+    const TensorShape inputShape{ 1, 1, 1, 5 };
+    const TensorShape outputShape{ 1, 1, 1 };
+
+    TensorInfo inputInfo(inputShape, DataType::Float32);
+    TensorInfo outputInfo(outputShape, DataType::Float32);
+
+    // Add the input layers
+    IConnectableLayer* input = network->AddInputLayer(0);
+
+    // Add the layer under test
+    ArgMinMaxDescriptor argMinMaxDescriptor;
+    argMinMaxDescriptor.m_Function = ArgMinMaxFunction::Max;
+    IConnectableLayer* argMinMaxLayer = network->AddArgMinMaxLayer(argMinMaxDescriptor);
+
+    // Add the output layers
+    IConnectableLayer* output = network->AddOutputLayer(1);
+
+    // Establish connections
+    input->GetOutputSlot(0).Connect(argMinMaxLayer->GetInputSlot(0));
+    argMinMaxLayer->GetOutputSlot(0).Connect(output->GetInputSlot(0));
+
+    // Set tensor info
+    input->GetOutputSlot(0).SetTensorInfo(inputInfo);
+    argMinMaxLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
+
+    INetworkPtr quantizedNetworkQAsymm8 = INetworkQuantizer::Create(network.get())->ExportNetwork();
+    TestArgMinMaxQuantization validatorQAsymm8(inputShape, outputShape);
+    VisitLayersTopologically(quantizedNetworkQAsymm8.get(), validatorQAsymm8);
+
+    const QuantizerOptions options(DataType::QuantisedSymm16);
+    INetworkPtr quantizedNetworkQSymm16 = INetworkQuantizer::Create(network.get(), options)->ExportNetwork();
+    TestArgMinMaxQuantization validatorQSymm16(options, inputShape, outputShape);
+    VisitLayersTopologically(quantizedNetworkQSymm16.get(), validatorQSymm16);
+}
+
 BOOST_AUTO_TEST_CASE(QuantizeConcat)
 {
     class TestConcatQuantization : public TestQuantization