IVGCVSW-3081 Quantizer min>=max error & missing layers
authorLes Bell <les.bell@arm.com>
Fri, 17 May 2019 15:17:12 +0000 (16:17 +0100)
committerRuomei Yan <ruomei.yan@arm.com>
Wed, 22 May 2019 10:42:15 +0000 (10:42 +0000)
* relaxed the check to min > max in the quantization schemes
* added missing layer support for resnet_v2_50 model
  * Pad, Rsqrt, Multipilcation, Subtraction, Mean
* sorted methods alphabetically in Quantizerlayer & LayerVisitorBase

Change-Id: I003401ff7ac89b60580c959ea8fd9d6fef66b88e
Signed-off-by: Les Bell <les.bell@arm.com>
include/armnn/LayerVisitorBase.hpp
src/armnn/NetworkQuantizationScheme.hpp
src/armnn/QuantizerVisitor.cpp
src/armnn/QuantizerVisitor.hpp
src/armnnSerializer/test/SerializerTests.cpp

index 62673ac..657051f 100644 (file)
@@ -12,12 +12,12 @@ namespace armnn
 
 struct VisitorThrowingPolicy
 {
-    static void Apply() { throw UnimplementedException(); }
+    static void Apply(const std::string& errorMessage = "") { throw UnimplementedException(errorMessage); }
 };
 
 struct VisitorNoThrowPolicy
 {
-    static void Apply() {}
+    static void Apply(const std::string& unusedMessage = "") {}
 };
 
 // Visitor base class with empty implementations.
@@ -29,162 +29,163 @@ protected:
     virtual ~LayerVisitorBase() {}
 
 public:
-    void VisitInputLayer(const IConnectableLayer*,
-                         LayerBindingId,
-                         const char*) override { DefaultPolicy::Apply(); }
+
+    void VisitActivationLayer(const IConnectableLayer*,
+                              const ActivationDescriptor&,
+                              const char*) override { DefaultPolicy::Apply(__func__); }
+
+    void VisitAdditionLayer(const IConnectableLayer*,
+                            const char*) override { DefaultPolicy::Apply(__func__); }
+
+    void VisitBatchNormalizationLayer(const IConnectableLayer*,
+                                      const BatchNormalizationDescriptor&,
+                                      const ConstTensor&,
+                                      const ConstTensor&,
+                                      const ConstTensor&,
+                                      const ConstTensor&,
+                                      const char*) override { DefaultPolicy::Apply(__func__); }
+
+    void VisitBatchToSpaceNdLayer(const IConnectableLayer*,
+                                  const BatchToSpaceNdDescriptor&,
+                                  const char*) override { DefaultPolicy::Apply(__func__); }
 
     void VisitConcatLayer(const IConnectableLayer*,
                           const OriginsDescriptor&,
-                          const char*) override { DefaultPolicy::Apply(); }
+                          const char*) override { DefaultPolicy::Apply(__func__); }
+
+    void VisitConstantLayer(const IConnectableLayer*,
+                            const ConstTensor&,
+                            const char*) override { DefaultPolicy::Apply(__func__); }
 
     void VisitConvolution2dLayer(const IConnectableLayer*,
                                  const Convolution2dDescriptor&,
                                  const ConstTensor&,
                                  const Optional<ConstTensor>&,
-                                 const char*) override { DefaultPolicy::Apply(); }
+                                 const char*) override { DefaultPolicy::Apply(__func__); }
 
     void VisitDepthwiseConvolution2dLayer(const IConnectableLayer*,
                                           const DepthwiseConvolution2dDescriptor&,
                                           const ConstTensor&,
                                           const Optional<ConstTensor>&,
-                                          const char*) override { DefaultPolicy::Apply(); }
+                                          const char*) override { DefaultPolicy::Apply(__func__); }
 
     void VisitDequantizeLayer(const IConnectableLayer*,
-                              const char*) override { DefaultPolicy::Apply(); }
+                              const char*) override { DefaultPolicy::Apply(__func__); }
 
     void VisitDetectionPostProcessLayer(const IConnectableLayer*,
                                         const DetectionPostProcessDescriptor&,
                                         const ConstTensor&,
-                                        const char*) override { DefaultPolicy::Apply(); }
+                                        const char*) override { DefaultPolicy::Apply(__func__); }
+
+    void VisitDivisionLayer(const IConnectableLayer*,
+                            const char*) override { DefaultPolicy::Apply(__func__); }
+
+    void VisitEqualLayer(const IConnectableLayer*,
+                         const char*) override { DefaultPolicy::Apply(__func__); }
+
+    void VisitFloorLayer(const IConnectableLayer*,
+                         const char*) override { DefaultPolicy::Apply(__func__); }
 
     void VisitFullyConnectedLayer(const IConnectableLayer*,
                                   const FullyConnectedDescriptor&,
                                   const ConstTensor&,
                                   const Optional<ConstTensor>&,
-                                  const char*) override { DefaultPolicy::Apply(); }
+                                  const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitPermuteLayer(const IConnectableLayer*,
-                           const PermuteDescriptor&,
-                           const char*) override { DefaultPolicy::Apply(); }
+    void VisitGatherLayer(const IConnectableLayer*,
+                          const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitBatchToSpaceNdLayer(const IConnectableLayer*,
-                                  const BatchToSpaceNdDescriptor&,
-                                  const char*) override { DefaultPolicy::Apply(); }
+    void VisitGreaterLayer(const IConnectableLayer*,
+                           const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitPooling2dLayer(const IConnectableLayer*,
-                             const Pooling2dDescriptor&,
-                             const char*) override { DefaultPolicy::Apply(); }
+    void VisitInputLayer(const IConnectableLayer*,
+                         LayerBindingId,
+                         const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitActivationLayer(const IConnectableLayer*,
-                              const ActivationDescriptor&,
-                              const char*) override { DefaultPolicy::Apply(); }
+    void VisitL2NormalizationLayer(const IConnectableLayer*,
+                                   const L2NormalizationDescriptor&,
+                                   const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitNormalizationLayer(const IConnectableLayer*,
-                                 const NormalizationDescriptor&,
-                                 const char*) override { DefaultPolicy::Apply(); }
+    void VisitLstmLayer(const IConnectableLayer*,
+                        const LstmDescriptor&,
+                        const LstmInputParams&,
+                        const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitSoftmaxLayer(const IConnectableLayer*,
-                           const SoftmaxDescriptor&,
-                           const char*) override { DefaultPolicy::Apply(); }
+    void VisitMaximumLayer(const IConnectableLayer*,
+                           const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitSplitterLayer(const IConnectableLayer*,
-                            const ViewsDescriptor&,
-                            const char*) override { DefaultPolicy::Apply(); }
+    void VisitMeanLayer(const IConnectableLayer*,
+                        const MeanDescriptor&,
+                        const char*) override { DefaultPolicy::Apply(__func__); }
 
     void VisitMergeLayer(const IConnectableLayer*,
-                         const char*) override { DefaultPolicy::Apply(); }
+                         const char*) override { DefaultPolicy::Apply(__func__); }
 
     void VisitMergerLayer(const IConnectableLayer*,
                           const OriginsDescriptor&,
-                          const char*) override { DefaultPolicy::Apply(); }
+                          const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitAdditionLayer(const IConnectableLayer*,
-                            const char*) override { DefaultPolicy::Apply(); }
+    void VisitMinimumLayer(const IConnectableLayer*,
+                           const char*) override { DefaultPolicy::Apply(__func__); }
 
     void VisitMultiplicationLayer(const IConnectableLayer*,
-                                  const char*) override { DefaultPolicy::Apply(); }
+                                  const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitBatchNormalizationLayer(const IConnectableLayer*,
-                                      const BatchNormalizationDescriptor&,
-                                      const ConstTensor&,
-                                      const ConstTensor&,
-                                      const ConstTensor&,
-                                      const ConstTensor&,
-                                      const char*) override { DefaultPolicy::Apply(); }
-
-    void VisitResizeBilinearLayer(const IConnectableLayer*,
-                                  const ResizeBilinearDescriptor&,
-                                  const char*) override { DefaultPolicy::Apply(); }
-
-    void VisitL2NormalizationLayer(const IConnectableLayer*,
-                                   const L2NormalizationDescriptor&,
-                                   const char*) override { DefaultPolicy::Apply(); }
-
-    void VisitConstantLayer(const IConnectableLayer*,
-                            const ConstTensor&,
-                            const char*) override { DefaultPolicy::Apply(); }
-
-    void VisitReshapeLayer(const IConnectableLayer*,
-                           const ReshapeDescriptor&,
-                           const char*) override { DefaultPolicy::Apply(); }
-
-    void VisitSpaceToBatchNdLayer(const IConnectableLayer*,
-                                  const SpaceToBatchNdDescriptor&,
-                                  const char*) override { DefaultPolicy::Apply(); }
-
-    void VisitFloorLayer(const IConnectableLayer*,
-                         const char*) override { DefaultPolicy::Apply(); }
+    void VisitNormalizationLayer(const IConnectableLayer*,
+                                 const NormalizationDescriptor&,
+                                 const char*) override { DefaultPolicy::Apply(__func__); }
 
     void VisitOutputLayer(const IConnectableLayer*,
                           LayerBindingId id,
-                          const char*) override { DefaultPolicy::Apply(); }
-
-    void VisitLstmLayer(const IConnectableLayer*,
-                        const LstmDescriptor&,
-                        const LstmInputParams&,
-                        const char*) override { DefaultPolicy::Apply(); }
+                          const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitDivisionLayer(const IConnectableLayer*,
-                            const char*) override { DefaultPolicy::Apply(); }
+    void VisitPadLayer(const IConnectableLayer*,
+                       const PadDescriptor&,
+                       const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitSubtractionLayer(const IConnectableLayer*,
-                               const char*) override { DefaultPolicy::Apply(); }
+    void VisitPermuteLayer(const IConnectableLayer*,
+                           const PermuteDescriptor&,
+                           const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitMaximumLayer(const IConnectableLayer*,
-                           const char*) override { DefaultPolicy::Apply(); }
+    void VisitPooling2dLayer(const IConnectableLayer*,
+                             const Pooling2dDescriptor&,
+                             const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitMeanLayer(const IConnectableLayer*,
-                        const MeanDescriptor&,
-                        const char*) override { DefaultPolicy::Apply(); }
+    void VisitQuantizeLayer(const IConnectableLayer*,
+                            const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitPadLayer(const IConnectableLayer*,
-                       const PadDescriptor&,
-                       const char*) override { DefaultPolicy::Apply(); }
+    void VisitReshapeLayer(const IConnectableLayer*,
+                           const ReshapeDescriptor&,
+                           const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitQuantizeLayer(const IConnectableLayer*,
-                            const char*) override { DefaultPolicy::Apply(); }
+    void VisitResizeBilinearLayer(const IConnectableLayer*,
+                                  const ResizeBilinearDescriptor&,
+                                  const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitStridedSliceLayer(const IConnectableLayer*,
-                                const StridedSliceDescriptor&,
-                                const char*) override { DefaultPolicy::Apply(); }
+    void VisitRsqrtLayer(const IConnectableLayer*,
+                         const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitMinimumLayer(const IConnectableLayer*,
-                           const char*) override { DefaultPolicy::Apply(); }
+    void VisitSoftmaxLayer(const IConnectableLayer*,
+                           const SoftmaxDescriptor&,
+                           const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitGreaterLayer(const IConnectableLayer*,
-                           const char*) override { DefaultPolicy::Apply(); }
+    void VisitSpaceToBatchNdLayer(const IConnectableLayer*,
+                                  const SpaceToBatchNdDescriptor&,
+                                  const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitEqualLayer(const IConnectableLayer*,
-                         const char*) override { DefaultPolicy::Apply(); }
+    void VisitSplitterLayer(const IConnectableLayer*,
+                            const ViewsDescriptor&,
+                            const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitRsqrtLayer(const IConnectableLayer*,
-                         const char*) override { DefaultPolicy::Apply(); }
+    void VisitStridedSliceLayer(const IConnectableLayer*,
+                                const StridedSliceDescriptor&,
+                                const char*) override { DefaultPolicy::Apply(__func__); }
 
-    void VisitGatherLayer(const IConnectableLayer*,
-                          const char*) override { DefaultPolicy::Apply(); }
+    void VisitSubtractionLayer(const IConnectableLayer*,
+                               const char*) override { DefaultPolicy::Apply(__func__); }
 
     void VisitSwitchLayer(const IConnectableLayer*,
-                          const char*) override { DefaultPolicy::Apply(); }
+                          const char*) override { DefaultPolicy::Apply(__func__); }
 };
 
 } //namespace armnn
index 065205d..a5f96a1 100644 (file)
@@ -30,9 +30,9 @@ struct QAsymm8QuantizationScheme : IQuantizationScheme
 {
     OffsetScalePair ComputeScheme(double min, double max) const override
     {
-        if (min >= max)
+        if (min > max)
         {
-            throw InvalidArgumentException("min >= max will result in invalid quantization.");
+            throw InvalidArgumentException("min > max will result in invalid quantization.");
         }
 
         double highest = (1 << NumBits()) - 1;
@@ -59,9 +59,9 @@ struct QSymm16QuantizationScheme : IQuantizationScheme
 {
     OffsetScalePair ComputeScheme(double min, double max) const override
     {
-        if (min >= max)
+        if (min > max)
         {
-            throw InvalidArgumentException("min >= max will result in invalid quantization.");
+            throw InvalidArgumentException("min > max will result in invalid quantization.");
         }
 
         double highest = (1 << (NumBits()-1)) - 1; // (numbits-1) accounts for the sign bit
index 4a87ca1..f30ab52 100644 (file)
@@ -66,13 +66,6 @@ void QuantizerVisitor::RecordLayer(const IConnectableLayer* srcLayer, IConnectab
     m_QuantizedGuidToLayerMap[quantizedLayer->GetGuid()] = quantizedLayer;
 }
 
-void QuantizerVisitor::VisitAdditionLayer(const IConnectableLayer* layer, const char* name)
-{
-    IConnectableLayer* newLayer = m_QuantizedNetwork->AddAdditionLayer(name);
-    RecordLayer(layer, newLayer);
-    SetQuantizedInputConnections(layer, newLayer);
-}
-
 void QuantizerVisitor::VisitActivationLayer(const IConnectableLayer* layer,
                                             const ActivationDescriptor& activationDescriptor,
                                             const char* name)
@@ -82,71 +75,13 @@ void QuantizerVisitor::VisitActivationLayer(const IConnectableLayer* layer,
     SetQuantizedInputConnections(layer, newLayer);
 }
 
-void QuantizerVisitor::VisitFullyConnectedLayer(const IConnectableLayer *layer,
-                                                const FullyConnectedDescriptor& desc,
-                                                const ConstTensor& weights,
-                                                const Optional<ConstTensor>& biases,
-                                                const char *name)
+void QuantizerVisitor::VisitAdditionLayer(const IConnectableLayer* layer, const char* name)
 {
-    std::vector<uint8_t> weightsBacking;
-    ConstTensor qWeights = CreateQuantizedConst(weights, weightsBacking);
-    Optional<ConstTensor> optionalQBiases;
-    std::vector<uint8_t> biasesBacking;
-
-    if (biases.has_value())
-    {
-        ConstTensor qBiases = CreateQuantizedConst(biases.value(), biasesBacking);
-        optionalQBiases = Optional<ConstTensor>(qBiases);
-    }
-
-    IConnectableLayer* newLayer = m_QuantizedNetwork->AddFullyConnectedLayer(desc,
-                                                                             qWeights,
-                                                                             optionalQBiases,
-                                                                             name);
-
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddAdditionLayer(name);
     RecordLayer(layer, newLayer);
     SetQuantizedInputConnections(layer, newLayer);
 }
 
-void QuantizerVisitor::VisitInputLayer(const IConnectableLayer *layer, LayerBindingId id, const char *name)
-{
-    const DataType dataType = layer->GetOutputSlot(0).GetTensorInfo().GetDataType();
-    IConnectableLayer* inputLayer = m_QuantizedNetwork->AddInputLayer(id, name);
-
-    if (m_PreserveType && (dataType == DataType::Float32 || dataType == DataType::Float16))
-    {
-        IConnectableLayer* quantizeLayer = m_QuantizedNetwork->AddQuantizeLayer();
-        inputLayer->GetOutputSlot(0).Connect(quantizeLayer->GetInputSlot(0));
-        inputLayer->GetOutputSlot(0).SetTensorInfo(layer->GetOutputSlot(0).GetTensorInfo());
-        RecordLayer(layer, quantizeLayer);
-    }
-    else
-    {
-        RecordLayer(layer, inputLayer);
-    }
-}
-
-void QuantizerVisitor::VisitOutputLayer(const IConnectableLayer* layer, LayerBindingId id, const char* name)
-{
-    const TensorInfo& info = layer->GetInputSlot(0).GetConnection()->GetTensorInfo();
-    const DataType& dataType = info.GetDataType();
-    IConnectableLayer* outputLayer = m_QuantizedNetwork->AddOutputLayer(id, name);
-
-    if (m_PreserveType  && (dataType == DataType::Float32 || dataType == DataType::Float16))
-    {
-        IConnectableLayer* dequantizeLayer = m_QuantizedNetwork->AddDequantizeLayer();
-        RecordLayer(layer, dequantizeLayer);
-        SetQuantizedInputConnections(layer, dequantizeLayer);
-        dequantizeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
-        dequantizeLayer->GetOutputSlot(0).SetTensorInfo(info);
-    }
-    else
-    {
-        RecordLayer(layer, outputLayer);
-        SetQuantizedInputConnections(layer, outputLayer);
-    }
-}
-
 void QuantizerVisitor::VisitBatchNormalizationLayer(const IConnectableLayer* layer,
                                                     const BatchNormalizationDescriptor& desc,
                                                     const ConstTensor& mean,
@@ -178,6 +113,26 @@ void QuantizerVisitor::VisitBatchNormalizationLayer(const IConnectableLayer* lay
     SetQuantizedInputConnections(layer, newLayer);
 }
 
+void QuantizerVisitor::VisitBatchToSpaceNdLayer(const IConnectableLayer* layer,
+                                                const BatchToSpaceNdDescriptor& batchToSpaceNdDescriptor,
+                                                const char* name)
+{
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddBatchToSpaceNdLayer(batchToSpaceNdDescriptor, name);
+    RecordLayer(layer, newLayer);
+    SetQuantizedInputConnections(layer, newLayer);
+}
+
+void QuantizerVisitor::VisitConstantLayer(const IConnectableLayer* layer,
+                                          const ConstTensor& input,
+                                          const char* name)
+{
+    std::vector<uint8_t> inputBacking;
+    ConstTensor qInput = CreateQuantizedConst(input, inputBacking);
+
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddConstantLayer(qInput, name);
+    RecordLayer(layer, newLayer);
+}
+
 void QuantizerVisitor::VisitConvolution2dLayer(const IConnectableLayer* layer,
                                                const Convolution2dDescriptor& convolution2dDescriptor,
                                                const ConstTensor& weights,
@@ -230,30 +185,55 @@ void QuantizerVisitor::VisitDepthwiseConvolution2dLayer(const IConnectableLayer*
     SetQuantizedInputConnections(layer, newLayer);
 }
 
-
-void QuantizerVisitor::VisitPermuteLayer(const IConnectableLayer* layer,
-                                         const PermuteDescriptor& permuteDescriptor,
-                                         const char* name)
+void QuantizerVisitor::VisitFullyConnectedLayer(const IConnectableLayer *layer,
+                                                const FullyConnectedDescriptor& desc,
+                                                const ConstTensor& weights,
+                                                const Optional<ConstTensor>& biases,
+                                                const char *name)
 {
-    IConnectableLayer* newLayer = m_QuantizedNetwork->AddPermuteLayer(permuteDescriptor, name);
+    std::vector<uint8_t> weightsBacking;
+    ConstTensor qWeights = CreateQuantizedConst(weights, weightsBacking);
+    Optional<ConstTensor> optionalQBiases;
+    std::vector<uint8_t> biasesBacking;
+
+    if (biases.has_value())
+    {
+        ConstTensor qBiases = CreateQuantizedConst(biases.value(), biasesBacking);
+        optionalQBiases = Optional<ConstTensor>(qBiases);
+    }
+
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddFullyConnectedLayer(desc,
+                                                                             qWeights,
+                                                                             optionalQBiases,
+                                                                             name);
+
     RecordLayer(layer, newLayer);
     SetQuantizedInputConnections(layer, newLayer);
 }
 
-void QuantizerVisitor::VisitSpaceToBatchNdLayer(const IConnectableLayer* layer,
-                                                const SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
-                                                const char* name)
+void QuantizerVisitor::VisitInputLayer(const IConnectableLayer *layer, LayerBindingId id, const char *name)
 {
-    IConnectableLayer* newLayer = m_QuantizedNetwork->AddSpaceToBatchNdLayer(spaceToBatchNdDescriptor, name);
-    RecordLayer(layer, newLayer);
-    SetQuantizedInputConnections(layer, newLayer);
+    const DataType dataType = layer->GetOutputSlot(0).GetTensorInfo().GetDataType();
+    IConnectableLayer* inputLayer = m_QuantizedNetwork->AddInputLayer(id, name);
+
+    if (m_PreserveType && (dataType == DataType::Float32 || dataType == DataType::Float16))
+    {
+        IConnectableLayer* quantizeLayer = m_QuantizedNetwork->AddQuantizeLayer();
+        inputLayer->GetOutputSlot(0).Connect(quantizeLayer->GetInputSlot(0));
+        inputLayer->GetOutputSlot(0).SetTensorInfo(layer->GetOutputSlot(0).GetTensorInfo());
+        RecordLayer(layer, quantizeLayer);
+    }
+    else
+    {
+        RecordLayer(layer, inputLayer);
+    }
 }
 
-void QuantizerVisitor::VisitPooling2dLayer(const IConnectableLayer* layer,
-                                           const Pooling2dDescriptor& pooling2dDescriptor,
-                                           const char* name)
+void QuantizerVisitor::VisitMeanLayer(const IConnectableLayer* layer,
+                                        const MeanDescriptor& meanDescriptor,
+                                        const char* name)
 {
-    IConnectableLayer* newLayer = m_QuantizedNetwork->AddPooling2dLayer(pooling2dDescriptor, name);
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddMeanLayer(meanDescriptor, name);
     RecordLayer(layer, newLayer);
     SetQuantizedInputConnections(layer, newLayer);
 }
@@ -267,31 +247,58 @@ void QuantizerVisitor::VisitMergerLayer(const IConnectableLayer* layer,
     SetQuantizedInputConnections(layer, newLayer);
 }
 
-void QuantizerVisitor::VisitSoftmaxLayer(const IConnectableLayer* layer,
-                                         const SoftmaxDescriptor& softmaxDescriptor,
-                                         const char* name)
+void QuantizerVisitor::VisitMultiplicationLayer(const IConnectableLayer* layer,
+                                                const char* name)
 {
-    IConnectableLayer* newLayer = m_QuantizedNetwork->AddSoftmaxLayer(softmaxDescriptor, name);
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddMultiplicationLayer(name);
     RecordLayer(layer, newLayer);
     SetQuantizedInputConnections(layer, newLayer);
 }
 
-void QuantizerVisitor::VisitConstantLayer(const IConnectableLayer* layer,
-                                          const ConstTensor& input,
-                                          const char* name)
+void QuantizerVisitor::VisitOutputLayer(const IConnectableLayer* layer, LayerBindingId id, const char* name)
 {
-    std::vector<uint8_t> inputBacking;
-    ConstTensor qInput = CreateQuantizedConst(input, inputBacking);
+    const TensorInfo& info = layer->GetInputSlot(0).GetConnection()->GetTensorInfo();
+    const DataType& dataType = info.GetDataType();
+    IConnectableLayer* outputLayer = m_QuantizedNetwork->AddOutputLayer(id, name);
 
-    IConnectableLayer* newLayer = m_QuantizedNetwork->AddConstantLayer(qInput, name);
+    if (m_PreserveType  && (dataType == DataType::Float32 || dataType == DataType::Float16))
+    {
+        IConnectableLayer* dequantizeLayer = m_QuantizedNetwork->AddDequantizeLayer();
+        RecordLayer(layer, dequantizeLayer);
+        SetQuantizedInputConnections(layer, dequantizeLayer);
+        dequantizeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
+        dequantizeLayer->GetOutputSlot(0).SetTensorInfo(info);
+    }
+    else
+    {
+        RecordLayer(layer, outputLayer);
+        SetQuantizedInputConnections(layer, outputLayer);
+    }
+}
+
+void QuantizerVisitor::VisitPadLayer(const IConnectableLayer* layer,
+                                     const PadDescriptor& padDescriptor,
+                                     const char* name)
+{
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddPadLayer(padDescriptor, name);
     RecordLayer(layer, newLayer);
+    SetQuantizedInputConnections(layer, newLayer);
 }
 
-void QuantizerVisitor::VisitSplitterLayer(const IConnectableLayer* layer,
-                                          const SplitterDescriptor& splitterDescriptor,
-                                          const char* name)
+void QuantizerVisitor::VisitPermuteLayer(const IConnectableLayer* layer,
+                                         const PermuteDescriptor& permuteDescriptor,
+                                         const char* name)
 {
-    IConnectableLayer* newLayer = m_QuantizedNetwork->AddSplitterLayer(splitterDescriptor, name);
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddPermuteLayer(permuteDescriptor, name);
+    RecordLayer(layer, newLayer);
+    SetQuantizedInputConnections(layer, newLayer);
+}
+
+void QuantizerVisitor::VisitPooling2dLayer(const IConnectableLayer* layer,
+                                           const Pooling2dDescriptor& pooling2dDescriptor,
+                                           const char* name)
+{
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddPooling2dLayer(pooling2dDescriptor, name);
     RecordLayer(layer, newLayer);
     SetQuantizedInputConnections(layer, newLayer);
 }
@@ -314,6 +321,41 @@ void QuantizerVisitor::VisitResizeBilinearLayer(const IConnectableLayer* layer,
     SetQuantizedInputConnections(layer, newLayer);
 }
 
+void QuantizerVisitor::VisitRsqrtLayer(const IConnectableLayer* layer,
+                                       const char* name)
+{
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddRsqrtLayer(name);
+    RecordLayer(layer, newLayer);
+    SetQuantizedInputConnections(layer, newLayer);
+}
+
+void QuantizerVisitor::VisitSpaceToBatchNdLayer(const IConnectableLayer* layer,
+                                                const SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
+                                                const char* name)
+{
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddSpaceToBatchNdLayer(spaceToBatchNdDescriptor, name);
+    RecordLayer(layer, newLayer);
+    SetQuantizedInputConnections(layer, newLayer);
+}
+
+void QuantizerVisitor::VisitSplitterLayer(const IConnectableLayer* layer,
+                                          const SplitterDescriptor& splitterDescriptor,
+                                          const char* name)
+{
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddSplitterLayer(splitterDescriptor, name);
+    RecordLayer(layer, newLayer);
+    SetQuantizedInputConnections(layer, newLayer);
+}
+
+void QuantizerVisitor::VisitSoftmaxLayer(const IConnectableLayer* layer,
+                                         const SoftmaxDescriptor& softmaxDescriptor,
+                                         const char* name)
+{
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddSoftmaxLayer(softmaxDescriptor, name);
+    RecordLayer(layer, newLayer);
+    SetQuantizedInputConnections(layer, newLayer);
+}
+
 void QuantizerVisitor::VisitStridedSliceLayer(const IConnectableLayer* layer,
                                               const StridedSliceDescriptor& stridedSliceDescriptor,
                                               const char* name)
@@ -323,11 +365,10 @@ void QuantizerVisitor::VisitStridedSliceLayer(const IConnectableLayer* layer,
     SetQuantizedInputConnections(layer, newLayer);
 }
 
-void QuantizerVisitor::VisitBatchToSpaceNdLayer(const IConnectableLayer* layer,
-                                                const BatchToSpaceNdDescriptor& batchToSpaceNdDescriptor,
+void QuantizerVisitor::VisitSubtractionLayer(const IConnectableLayer* layer,
                                                 const char* name)
 {
-    IConnectableLayer* newLayer = m_QuantizedNetwork->AddBatchToSpaceNdLayer(batchToSpaceNdDescriptor, name);
+    IConnectableLayer* newLayer = m_QuantizedNetwork->AddSubtractionLayer(name);
     RecordLayer(layer, newLayer);
     SetQuantizedInputConnections(layer, newLayer);
 }
index 300ac16..5d00e31 100644 (file)
@@ -22,7 +22,7 @@ namespace armnn
 class StaticRangeVisitor;
 
 /// Visitor object for quantizing layers in a network
-class QuantizerVisitor : public LayerVisitorBase<VisitorNoThrowPolicy>
+class QuantizerVisitor : public LayerVisitorBase<VisitorThrowingPolicy>
 {
 public:
     QuantizerVisitor(const RangeTracker& rangeTracker,
@@ -32,15 +32,11 @@ public:
     ~QuantizerVisitor() = default;
 
     /// Functions to quantize the individual layers, overridden from ILayerVisitor
-    void VisitInputLayer(const IConnectableLayer* layer, LayerBindingId id, const char* name = nullptr) override;
-
-    void VisitAdditionLayer(const IConnectableLayer* layer, const char* name = nullptr) override;
-
     void VisitActivationLayer(const IConnectableLayer* layer,
                               const ActivationDescriptor& activationDescriptor,
                               const char* name = nullptr) override;
 
-    void VisitOutputLayer(const IConnectableLayer* layer, LayerBindingId id, const char* name = nullptr)  override;
+    void VisitAdditionLayer(const IConnectableLayer* layer, const char* name = nullptr) override;
 
     void VisitBatchNormalizationLayer(const IConnectableLayer* layer,
                                       const BatchNormalizationDescriptor& desc,
@@ -50,11 +46,13 @@ public:
                                       const ConstTensor& gamma,
                                       const char* name = nullptr) override;
 
-    void VisitFullyConnectedLayer(const IConnectableLayer *layer,
-                                  const FullyConnectedDescriptor& desc,
-                                  const ConstTensor& weights,
-                                  const Optional<ConstTensor>& biases,
-                                  const char *name = nullptr)  override;
+    void VisitBatchToSpaceNdLayer(const IConnectableLayer* layer,
+                                  const BatchToSpaceNdDescriptor& batchToSpaceNdDescriptor,
+                                  const char* name = nullptr) override;
+
+    void VisitConstantLayer(const IConnectableLayer* layer,
+                            const ConstTensor& input,
+                            const char* name = nullptr) override;
 
     void VisitConvolution2dLayer(const IConnectableLayer* layer,
                                  const Convolution2dDescriptor& convolution2dDescriptor,
@@ -68,34 +66,39 @@ public:
                                           const Optional<ConstTensor>& biases,
                                           const char* name = nullptr) override;
 
-    void VisitSoftmaxLayer(const IConnectableLayer* layer,
-                           const SoftmaxDescriptor& softmaxDescriptor,
-                           const char* name = nullptr) override;
+    void VisitFullyConnectedLayer(const IConnectableLayer *layer,
+                                  const FullyConnectedDescriptor& desc,
+                                  const ConstTensor& weights,
+                                  const Optional<ConstTensor>& biases,
+                                  const char *name = nullptr)  override;
 
-    void VisitPermuteLayer(const IConnectableLayer* layer,
-                           const PermuteDescriptor& permuteDescriptor,
-                           const char* name = nullptr) override;
+    void VisitInputLayer(const IConnectableLayer* layer, LayerBindingId id, const char* name = nullptr) override;
 
-    void VisitSpaceToBatchNdLayer(const IConnectableLayer* layer,
-                                  const SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
+    void VisitMeanLayer(const IConnectableLayer* layer,
+                          const MeanDescriptor& meanDescriptor,
+                          const char* name = nullptr) override;
+
+    void VisitMergerLayer(const IConnectableLayer* layer,
+                          const OriginsDescriptor& mergerDescriptor,
+                          const char* name = nullptr) override;
+
+    void VisitMultiplicationLayer(const IConnectableLayer* layer,
                                   const char* name = nullptr) override;
 
-    void VisitSplitterLayer(const IConnectableLayer* layer,
-                            const SplitterDescriptor& splitterDescriptor,
-                            const char* name = nullptr) override;
+    void VisitOutputLayer(const IConnectableLayer* layer, LayerBindingId id, const char* name = nullptr)  override;
+
+    void VisitPadLayer(const IConnectableLayer*,
+                       const PadDescriptor&,
+                       const char* name = nullptr) override;
+
+    void VisitPermuteLayer(const IConnectableLayer* layer,
+                           const PermuteDescriptor& permuteDescriptor,
+                           const char* name = nullptr) override;
 
     void VisitPooling2dLayer(const IConnectableLayer* layer,
                              const Pooling2dDescriptor& pooling2dDescriptor,
                              const char* name = nullptr) override;
 
-    void VisitConstantLayer(const IConnectableLayer* layer,
-                            const ConstTensor& input,
-                            const char* name = nullptr) override;
-
-    void VisitMergerLayer(const IConnectableLayer* layer,
-                          const OriginsDescriptor& mergerDescriptor,
-                          const char* name = nullptr) override;
-
     void VisitReshapeLayer(const IConnectableLayer* layer,
                            const ReshapeDescriptor& reshapeDescriptor,
                            const char* name = nullptr) override;
@@ -104,13 +107,27 @@ public:
                                   const ResizeBilinearDescriptor& resizeDesc,
                                   const char* name = nullptr) override;
 
+    void VisitRsqrtLayer(const IConnectableLayer*,
+                         const char* name = nullptr) override;
+
+    void VisitSoftmaxLayer(const IConnectableLayer* layer,
+                           const SoftmaxDescriptor& softmaxDescriptor,
+                           const char* name = nullptr) override;
+
+    void VisitSpaceToBatchNdLayer(const IConnectableLayer* layer,
+                                  const SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
+                                  const char* name = nullptr) override;
+
+    void VisitSplitterLayer(const IConnectableLayer* layer,
+                            const SplitterDescriptor& splitterDescriptor,
+                            const char* name = nullptr) override;
+
     void VisitStridedSliceLayer(const IConnectableLayer* layer,
                                 const StridedSliceDescriptor& stridedSliceDescriptor,
                                 const char* name = nullptr) override;
 
-    void VisitBatchToSpaceNdLayer(const IConnectableLayer* layer,
-                                  const BatchToSpaceNdDescriptor& batchToSpaceNdDescriptor,
-                                  const char* name = nullptr) override;
+    void VisitSubtractionLayer(const IConnectableLayer* layer,
+                               const char* name = nullptr) override;
 
     /// Extract the quantized network
     INetworkPtr RetrieveFinalNetwork() { return std::move(m_QuantizedNetwork); }
index 01eae2e..b21ae58 100644 (file)
@@ -21,7 +21,7 @@ namespace
 
 struct DefaultLayerVerifierPolicy
 {
-    static void Apply()
+    static void Apply(const std::string s = "")
     {
         BOOST_TEST_MESSAGE("Unexpected layer found in network");
         BOOST_TEST(false);