aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLes Bell <les.bell@arm.com>2019-05-17 16:17:12 +0100
committerRuomei Yan <ruomei.yan@arm.com>2019-05-22 10:42:15 +0000
commite0ca861a5846cb5039b2d4760ce70d03e5efd8f3 (patch)
tree687b9300a1e9e197c06473d2eac63ab1d3363ffe
parented735043d679e5697f99badbec9c89fb29e9b6aa (diff)
downloadarmnn-e0ca861a5846cb5039b2d4760ce70d03e5efd8f3.tar.gz
IVGCVSW-3081 Quantizer min>=max error & missing layers
* 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>
-rw-r--r--include/armnn/LayerVisitorBase.hpp203
-rw-r--r--src/armnn/NetworkQuantizationScheme.hpp8
-rw-r--r--src/armnn/QuantizerVisitor.cpp239
-rw-r--r--src/armnn/QuantizerVisitor.hpp83
-rw-r--r--src/armnnSerializer/test/SerializerTests.cpp2
5 files changed, 297 insertions, 238 deletions
diff --git a/include/armnn/LayerVisitorBase.hpp b/include/armnn/LayerVisitorBase.hpp
index 62673ace07..657051f2fa 100644
--- a/include/armnn/LayerVisitorBase.hpp
+++ b/include/armnn/LayerVisitorBase.hpp
@@ -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
diff --git a/src/armnn/NetworkQuantizationScheme.hpp b/src/armnn/NetworkQuantizationScheme.hpp
index 065205dada..a5f96a106b 100644
--- a/src/armnn/NetworkQuantizationScheme.hpp
+++ b/src/armnn/NetworkQuantizationScheme.hpp
@@ -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
diff --git a/src/armnn/QuantizerVisitor.cpp b/src/armnn/QuantizerVisitor.cpp
index 4a87ca16ce..f30ab5247c 100644
--- a/src/armnn/QuantizerVisitor.cpp
+++ b/src/armnn/QuantizerVisitor.cpp
@@ -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);
}
diff --git a/src/armnn/QuantizerVisitor.hpp b/src/armnn/QuantizerVisitor.hpp
index 300ac164de..5d00e31fba 100644
--- a/src/armnn/QuantizerVisitor.hpp
+++ b/src/armnn/QuantizerVisitor.hpp
@@ -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); }
diff --git a/src/armnnSerializer/test/SerializerTests.cpp b/src/armnnSerializer/test/SerializerTests.cpp
index 01eae2ebbf..b21ae5841d 100644
--- a/src/armnnSerializer/test/SerializerTests.cpp
+++ b/src/armnnSerializer/test/SerializerTests.cpp
@@ -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);