aboutsummaryrefslogtreecommitdiff
path: root/src/armnnSerializer
diff options
context:
space:
mode:
Diffstat (limited to 'src/armnnSerializer')
-rw-r--r--src/armnnSerializer/ArmnnSchema.fbs4
-rw-r--r--src/armnnSerializer/ArmnnSchema_generated.h34
-rw-r--r--src/armnnSerializer/Serializer.cpp26
-rw-r--r--src/armnnSerializer/Serializer.hpp1
-rw-r--r--src/armnnSerializer/test/SerializerTests.cpp91
5 files changed, 120 insertions, 36 deletions
diff --git a/src/armnnSerializer/ArmnnSchema.fbs b/src/armnnSerializer/ArmnnSchema.fbs
index a544161c53..85435a366f 100644
--- a/src/armnnSerializer/ArmnnSchema.fbs
+++ b/src/armnnSerializer/ArmnnSchema.fbs
@@ -69,6 +69,7 @@ table TensorInfo {
quantizationDim:uint;
dimensionality:uint = 1;
dimensionSpecificity:[bool];
+ isConstant:bool = false;
}
struct Connection {
@@ -324,7 +325,7 @@ table FloorLayer{
table FullyConnectedLayer {
base:LayerBase;
descriptor:FullyConnectedDescriptor;
- weights:ConstTensor;
+ weights:ConstTensor; // ConstTensors are now passed as inputs.
biases:ConstTensor;
}
@@ -1007,6 +1008,7 @@ table AnyLayer {
table FeatureCompatibilityVersions {
bindingIdsScheme:uint = 0;
weightsLayoutScheme:uint = 0;
+ constantTensorsAsInputs:uint = 0;
}
// Root type for serialized data is the graph of the network
diff --git a/src/armnnSerializer/ArmnnSchema_generated.h b/src/armnnSerializer/ArmnnSchema_generated.h
index 27550f0682..ca2bf0c003 100644
--- a/src/armnnSerializer/ArmnnSchema_generated.h
+++ b/src/armnnSerializer/ArmnnSchema_generated.h
@@ -1685,7 +1685,8 @@ struct TensorInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_QUANTIZATIONSCALES = 12,
VT_QUANTIZATIONDIM = 14,
VT_DIMENSIONALITY = 16,
- VT_DIMENSIONSPECIFICITY = 18
+ VT_DIMENSIONSPECIFICITY = 18,
+ VT_ISCONSTANT = 20
};
const flatbuffers::Vector<uint32_t> *dimensions() const {
return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_DIMENSIONS);
@@ -1711,6 +1712,9 @@ struct TensorInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const flatbuffers::Vector<uint8_t> *dimensionSpecificity() const {
return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_DIMENSIONSPECIFICITY);
}
+ bool isConstant() const {
+ return GetField<uint8_t>(VT_ISCONSTANT, 0) != 0;
+ }
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyOffset(verifier, VT_DIMENSIONS) &&
@@ -1724,6 +1728,7 @@ struct TensorInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField<uint32_t>(verifier, VT_DIMENSIONALITY) &&
VerifyOffset(verifier, VT_DIMENSIONSPECIFICITY) &&
verifier.VerifyVector(dimensionSpecificity()) &&
+ VerifyField<uint8_t>(verifier, VT_ISCONSTANT) &&
verifier.EndTable();
}
};
@@ -1756,6 +1761,9 @@ struct TensorInfoBuilder {
void add_dimensionSpecificity(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> dimensionSpecificity) {
fbb_.AddOffset(TensorInfo::VT_DIMENSIONSPECIFICITY, dimensionSpecificity);
}
+ void add_isConstant(bool isConstant) {
+ fbb_.AddElement<uint8_t>(TensorInfo::VT_ISCONSTANT, static_cast<uint8_t>(isConstant), 0);
+ }
explicit TensorInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
@@ -1777,7 +1785,8 @@ inline flatbuffers::Offset<TensorInfo> CreateTensorInfo(
flatbuffers::Offset<flatbuffers::Vector<float>> quantizationScales = 0,
uint32_t quantizationDim = 0,
uint32_t dimensionality = 1,
- flatbuffers::Offset<flatbuffers::Vector<uint8_t>> dimensionSpecificity = 0) {
+ flatbuffers::Offset<flatbuffers::Vector<uint8_t>> dimensionSpecificity = 0,
+ bool isConstant = false) {
TensorInfoBuilder builder_(_fbb);
builder_.add_dimensionSpecificity(dimensionSpecificity);
builder_.add_dimensionality(dimensionality);
@@ -1786,6 +1795,7 @@ inline flatbuffers::Offset<TensorInfo> CreateTensorInfo(
builder_.add_quantizationOffset(quantizationOffset);
builder_.add_quantizationScale(quantizationScale);
builder_.add_dimensions(dimensions);
+ builder_.add_isConstant(isConstant);
builder_.add_dataType(dataType);
return builder_.Finish();
}
@@ -1799,7 +1809,8 @@ inline flatbuffers::Offset<TensorInfo> CreateTensorInfoDirect(
const std::vector<float> *quantizationScales = nullptr,
uint32_t quantizationDim = 0,
uint32_t dimensionality = 1,
- const std::vector<uint8_t> *dimensionSpecificity = nullptr) {
+ const std::vector<uint8_t> *dimensionSpecificity = nullptr,
+ bool isConstant = false) {
auto dimensions__ = dimensions ? _fbb.CreateVector<uint32_t>(*dimensions) : 0;
auto quantizationScales__ = quantizationScales ? _fbb.CreateVector<float>(*quantizationScales) : 0;
auto dimensionSpecificity__ = dimensionSpecificity ? _fbb.CreateVector<uint8_t>(*dimensionSpecificity) : 0;
@@ -1812,7 +1823,8 @@ inline flatbuffers::Offset<TensorInfo> CreateTensorInfoDirect(
quantizationScales__,
quantizationDim,
dimensionality,
- dimensionSpecificity__);
+ dimensionSpecificity__,
+ isConstant);
}
struct ByteData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@@ -10124,7 +10136,8 @@ struct FeatureCompatibilityVersions FLATBUFFERS_FINAL_CLASS : private flatbuffer
typedef FeatureCompatibilityVersionsBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_BINDINGIDSSCHEME = 4,
- VT_WEIGHTSLAYOUTSCHEME = 6
+ VT_WEIGHTSLAYOUTSCHEME = 6,
+ VT_CONSTANTTENSORSASINPUTS = 8
};
uint32_t bindingIdsScheme() const {
return GetField<uint32_t>(VT_BINDINGIDSSCHEME, 0);
@@ -10132,10 +10145,14 @@ struct FeatureCompatibilityVersions FLATBUFFERS_FINAL_CLASS : private flatbuffer
uint32_t weightsLayoutScheme() const {
return GetField<uint32_t>(VT_WEIGHTSLAYOUTSCHEME, 0);
}
+ uint32_t constantTensorsAsInputs() const {
+ return GetField<uint32_t>(VT_CONSTANTTENSORSASINPUTS, 0);
+ }
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<uint32_t>(verifier, VT_BINDINGIDSSCHEME) &&
VerifyField<uint32_t>(verifier, VT_WEIGHTSLAYOUTSCHEME) &&
+ VerifyField<uint32_t>(verifier, VT_CONSTANTTENSORSASINPUTS) &&
verifier.EndTable();
}
};
@@ -10150,6 +10167,9 @@ struct FeatureCompatibilityVersionsBuilder {
void add_weightsLayoutScheme(uint32_t weightsLayoutScheme) {
fbb_.AddElement<uint32_t>(FeatureCompatibilityVersions::VT_WEIGHTSLAYOUTSCHEME, weightsLayoutScheme, 0);
}
+ void add_constantTensorsAsInputs(uint32_t constantTensorsAsInputs) {
+ fbb_.AddElement<uint32_t>(FeatureCompatibilityVersions::VT_CONSTANTTENSORSASINPUTS, constantTensorsAsInputs, 0);
+ }
explicit FeatureCompatibilityVersionsBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
@@ -10165,8 +10185,10 @@ struct FeatureCompatibilityVersionsBuilder {
inline flatbuffers::Offset<FeatureCompatibilityVersions> CreateFeatureCompatibilityVersions(
flatbuffers::FlatBufferBuilder &_fbb,
uint32_t bindingIdsScheme = 0,
- uint32_t weightsLayoutScheme = 0) {
+ uint32_t weightsLayoutScheme = 0,
+ uint32_t constantTensorsAsInputs = 0) {
FeatureCompatibilityVersionsBuilder builder_(_fbb);
+ builder_.add_constantTensorsAsInputs(constantTensorsAsInputs);
builder_.add_weightsLayoutScheme(weightsLayoutScheme);
builder_.add_bindingIdsScheme(bindingIdsScheme);
return builder_.Finish();
diff --git a/src/armnnSerializer/Serializer.cpp b/src/armnnSerializer/Serializer.cpp
index 44cd1800c4..195b41657a 100644
--- a/src/armnnSerializer/Serializer.cpp
+++ b/src/armnnSerializer/Serializer.cpp
@@ -1126,7 +1126,6 @@ void SerializerStrategy::SerializeQuantizeLayer(const armnn::IConnectableLayer *
// Build FlatBuffer for FullyConnected Layer
void SerializerStrategy::SerializeFullyConnectedLayer(const armnn::IConnectableLayer* layer,
const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
- const std::vector<armnn::ConstTensor>& constants,
const char*)
{
// Create FlatBuffer BaseLayer
@@ -1139,28 +1138,10 @@ void SerializerStrategy::SerializeFullyConnectedLayer(const armnn::IConnectableL
fullyConnectedDescriptor.m_TransposeWeightMatrix,
fullyConnectedDescriptor.m_ConstantWeights);
- // Create FlatBuffer weights data
- flatbuffers::Offset<serializer::ConstTensor> flatBufferWeights;
- // Create FlatBuffer bias data
- flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
- if (fullyConnectedDescriptor.m_ConstantWeights && !constants.empty())
- {
- armnn::ConstTensor weights = constants.at(0);
- flatBufferWeights = CreateConstTensorInfo(weights);
-
- if (fullyConnectedDescriptor.m_BiasEnabled)
- {
- armnn::ConstTensor biases = constants.at(1);
- flatBufferBiases = CreateConstTensorInfo(biases);
- }
- }
-
// Create FlatBuffer FullyConnectedLayer
auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
flatBufferBaseLayer,
- flatBufferDescriptor,
- flatBufferWeights,
- flatBufferBiases);
+ flatBufferDescriptor);
// Add created FullyConnectedLayer to the FlatBufferLayers
CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
@@ -1916,7 +1897,8 @@ flatbuffers::Offset<armnnSerializer::FeatureCompatibilityVersions> SerializerStr
serializer::CreateFeatureCompatibilityVersions(
m_flatBufferBuilder,
1, // Binding ids scheme version
- 1 // Weights layout scheme version
+ 1, // Weights layout scheme version
+ 1 // Constant tensors as inputs version
);
return versionsTable;
}
@@ -2110,7 +2092,7 @@ void SerializerStrategy::ExecuteStrategy(const armnn::IConnectableLayer* layer,
{
const armnn::FullyConnectedDescriptor& layerDescriptor =
static_cast<const armnn::FullyConnectedDescriptor&>(descriptor);
- SerializeFullyConnectedLayer(layer, layerDescriptor, constants, name);
+ SerializeFullyConnectedLayer(layer, layerDescriptor, name);
break;
}
case armnn::LayerType::Gather :
diff --git a/src/armnnSerializer/Serializer.hpp b/src/armnnSerializer/Serializer.hpp
index dead8739cc..18b2cc77ac 100644
--- a/src/armnnSerializer/Serializer.hpp
+++ b/src/armnnSerializer/Serializer.hpp
@@ -184,7 +184,6 @@ private:
void SerializeFullyConnectedLayer(const armnn::IConnectableLayer* layer,
const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
- const std::vector<armnn::ConstTensor>& constants,
const char* name = nullptr);
void SerializeGatherLayer(const armnn::IConnectableLayer* layer,
diff --git a/src/armnnSerializer/test/SerializerTests.cpp b/src/armnnSerializer/test/SerializerTests.cpp
index 98532d0cec..9e9df0d1ea 100644
--- a/src/armnnSerializer/test/SerializerTests.cpp
+++ b/src/armnnSerializer/test/SerializerTests.cpp
@@ -789,6 +789,41 @@ TEST_CASE("SerializeFloor")
deserializedNetwork->ExecuteStrategy(verifier);
}
+using FullyConnectedDescriptor = armnn::FullyConnectedDescriptor;
+class FullyConnectedLayerVerifier : public LayerVerifierBaseWithDescriptor<FullyConnectedDescriptor>
+{
+public:
+ FullyConnectedLayerVerifier(const std::string& layerName,
+ const std::vector<armnn::TensorInfo>& inputInfos,
+ const std::vector<armnn::TensorInfo>& outputInfos,
+ const FullyConnectedDescriptor& descriptor)
+ : LayerVerifierBaseWithDescriptor<FullyConnectedDescriptor>(layerName, inputInfos, outputInfos, descriptor) {}
+
+ void ExecuteStrategy(const armnn::IConnectableLayer* layer,
+ const armnn::BaseDescriptor& descriptor,
+ const std::vector<armnn::ConstTensor>& constants,
+ const char* name,
+ const armnn::LayerBindingId id = 0) override
+ {
+ armnn::IgnoreUnused(constants, id);
+ switch (layer->GetType())
+ {
+ case armnn::LayerType::Input: break;
+ case armnn::LayerType::Output: break;
+ case armnn::LayerType::Constant: break;
+ default:
+ {
+ VerifyNameAndConnections(layer, name);
+ const FullyConnectedDescriptor& layerDescriptor =
+ static_cast<const FullyConnectedDescriptor&>(descriptor);
+ CHECK(layerDescriptor.m_ConstantWeights == m_Descriptor.m_ConstantWeights);
+ CHECK(layerDescriptor.m_BiasEnabled == m_Descriptor.m_BiasEnabled);
+ CHECK(layerDescriptor.m_TransposeWeightMatrix == m_Descriptor.m_TransposeWeightMatrix);
+ }
+ }
+ }
+};
+
TEST_CASE("SerializeFullyConnected")
{
const std::string layerName("fullyConnected");
@@ -809,11 +844,16 @@ TEST_CASE("SerializeFullyConnected")
armnn::INetworkPtr network = armnn::INetwork::Create();
armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
+
+ // Old way of handling constant tensors.
+ ARMNN_NO_DEPRECATE_WARN_BEGIN
armnn::IConnectableLayer* const fullyConnectedLayer =
network->AddFullyConnectedLayer(descriptor,
weights,
armnn::Optional<armnn::ConstTensor>(biases),
layerName.c_str());
+ ARMNN_NO_DEPRECATE_WARN_END
+
armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
inputLayer->GetOutputSlot(0).Connect(fullyConnectedLayer->GetInputSlot(0));
@@ -825,13 +865,11 @@ TEST_CASE("SerializeFullyConnected")
armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
CHECK(deserializedNetwork);
- const std::vector<armnn::ConstTensor> constants {weights, biases};
- LayerVerifierBaseWithDescriptorAndConstants<armnn::FullyConnectedDescriptor> verifier(
- layerName, {inputInfo}, {outputInfo}, descriptor, constants);
+ FullyConnectedLayerVerifier verifier(layerName, {inputInfo, weightsInfo, biasesInfo}, {outputInfo}, descriptor);
deserializedNetwork->ExecuteStrategy(verifier);
}
-TEST_CASE("SerializeFullyConnectedWeightsAsInputs")
+TEST_CASE("SerializeFullyConnectedWeightsAndBiasesAsInputs")
{
const std::string layerName("fullyConnected_weights_as_inputs");
const armnn::TensorInfo inputInfo ({ 2, 5, 1, 1 }, armnn::DataType::Float32);
@@ -854,8 +892,6 @@ TEST_CASE("SerializeFullyConnectedWeightsAsInputs")
armnn::IConnectableLayer* const biasInputLayer = network->AddInputLayer(2);
armnn::IConnectableLayer* const fullyConnectedLayer =
network->AddFullyConnectedLayer(descriptor,
- weights,
- bias,
layerName.c_str());
armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
@@ -878,6 +914,49 @@ TEST_CASE("SerializeFullyConnectedWeightsAsInputs")
deserializedNetwork->ExecuteStrategy(verifier);
}
+TEST_CASE("SerializeFullyConnectedWeightsAndBiasesAsConstantLayers")
+{
+ const std::string layerName("fullyConnected_weights_as_inputs");
+ const armnn::TensorInfo inputInfo ({ 2, 5, 1, 1 }, armnn::DataType::Float32);
+ const armnn::TensorInfo outputInfo({ 2, 3 }, armnn::DataType::Float32);
+
+ const armnn::TensorInfo weightsInfo({ 5, 3 }, armnn::DataType::Float32);
+ const armnn::TensorInfo biasesInfo ({ 3 }, armnn::DataType::Float32);
+
+ std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
+ std::vector<float> biasesData = GenerateRandomData<float>(biasesInfo.GetNumElements());
+ armnn::ConstTensor weights(weightsInfo, weightsData);
+ armnn::ConstTensor biases(biasesInfo, biasesData);
+
+ armnn::FullyConnectedDescriptor descriptor;
+ descriptor.m_BiasEnabled = true;
+ descriptor.m_TransposeWeightMatrix = false;
+ descriptor.m_ConstantWeights = true;
+
+ armnn::INetworkPtr network = armnn::INetwork::Create();
+ armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
+ armnn::IConnectableLayer* const weightsLayer = network->AddConstantLayer(weights, "Weights");
+ armnn::IConnectableLayer* const biasesLayer = network->AddConstantLayer(biases, "Biases");
+ armnn::IConnectableLayer* const fullyConnectedLayer = network->AddFullyConnectedLayer(descriptor,layerName.c_str());
+ armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
+
+ inputLayer->GetOutputSlot(0).Connect(fullyConnectedLayer->GetInputSlot(0));
+ weightsLayer->GetOutputSlot(0).Connect(fullyConnectedLayer->GetInputSlot(1));
+ biasesLayer->GetOutputSlot(0).Connect(fullyConnectedLayer->GetInputSlot(2));
+ fullyConnectedLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
+
+ inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
+ weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsInfo);
+ biasesLayer->GetOutputSlot(0).SetTensorInfo(biasesInfo);
+ fullyConnectedLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
+
+ armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
+ CHECK(deserializedNetwork);
+
+ FullyConnectedLayerVerifier verifier(layerName, {inputInfo, weightsInfo, biasesInfo}, {outputInfo}, descriptor);
+ deserializedNetwork->ExecuteStrategy(verifier);
+}
+
TEST_CASE("SerializeGather")
{
using GatherDescriptor = armnn::GatherDescriptor;