diff options
author | Keith Davis <keith.davis@arm.com> | 2021-05-21 16:33:48 +0100 |
---|---|---|
committer | Keith Davis <keith.davis@arm.com> | 2021-06-16 17:27:59 +0100 |
commit | 3ae3f978cf9ce3174609b7152af87acb410b0fe0 (patch) | |
tree | 9c71ea6aafbacfeba6938b5e0e29cdc97a784b70 /src/armnnSerializer | |
parent | 50de4fa4e7e0dd02a442ba350a1b40f293cb5a01 (diff) | |
download | armnn-3ae3f978cf9ce3174609b7152af87acb410b0fe0.tar.gz |
MLCE-510 Add CpuRef Shape Operator to ArmNN
* Add front end
* Add reference workload
* Serialization/Deserialization
* Add unit tests
* Update ArmNN Versioning
Signed-off-by: Keith Davis <keith.davis@arm.com>
Change-Id: I6fcb1fa341d6f08dea4003b13544e6e9f53fefd3
Diffstat (limited to 'src/armnnSerializer')
-rw-r--r-- | src/armnnSerializer/ArmnnSchema.fbs | 12 | ||||
-rw-r--r-- | src/armnnSerializer/ArmnnSchema_generated.h | 88 | ||||
-rw-r--r-- | src/armnnSerializer/Serializer.cpp | 16 | ||||
-rw-r--r-- | src/armnnSerializer/Serializer.hpp | 3 | ||||
-rw-r--r-- | src/armnnSerializer/test/SerializerTests.cpp | 25 |
5 files changed, 131 insertions, 13 deletions
diff --git a/src/armnnSerializer/ArmnnSchema.fbs b/src/armnnSerializer/ArmnnSchema.fbs index 753c2443a4..32a9bba5ab 100644 --- a/src/armnnSerializer/ArmnnSchema.fbs +++ b/src/armnnSerializer/ArmnnSchema.fbs @@ -171,7 +171,8 @@ enum LayerType : uint { Rank = 58, LogicalBinary = 59, Reduce = 60, - Cast = 61 + Cast = 61, + Shape = 62 } // Base layer table to be used as part of other layers @@ -487,7 +488,7 @@ table ReshapeLayer { } table ReshapeDescriptor { - targetShape:[uint]; + targetShape:[uint]; } table PermuteLayer { @@ -499,6 +500,10 @@ table PermuteDescriptor { dimMappings:[uint]; } +table ShapeLayer { + base:LayerBase; +} + table SpaceToBatchNdLayer { base:LayerBase; descriptor:SpaceToBatchNdDescriptor; @@ -972,7 +977,8 @@ union Layer { RankLayer, LogicalBinaryLayer, ReduceLayer, - CastLayer + CastLayer, + ShapeLayer } table AnyLayer { diff --git a/src/armnnSerializer/ArmnnSchema_generated.h b/src/armnnSerializer/ArmnnSchema_generated.h index 675fcc6490..4a352ddb6c 100644 --- a/src/armnnSerializer/ArmnnSchema_generated.h +++ b/src/armnnSerializer/ArmnnSchema_generated.h @@ -4,6 +4,7 @@ // // automatically generated by the FlatBuffers compiler, do not modify + #ifndef FLATBUFFERS_GENERATED_ARMNNSCHEMA_ARMNNSERIALIZER_H_ #define FLATBUFFERS_GENERATED_ARMNNSCHEMA_ARMNNSERIALIZER_H_ @@ -193,6 +194,9 @@ struct PermuteLayerBuilder; struct PermuteDescriptor; struct PermuteDescriptorBuilder; +struct ShapeLayer; +struct ShapeLayerBuilder; + struct SpaceToBatchNdLayer; struct SpaceToBatchNdLayerBuilder; @@ -735,11 +739,12 @@ enum LayerType { LayerType_LogicalBinary = 59, LayerType_Reduce = 60, LayerType_Cast = 61, + LayerType_Shape = 62, LayerType_MIN = LayerType_Addition, - LayerType_MAX = LayerType_Cast + LayerType_MAX = LayerType_Shape }; -inline const LayerType (&EnumValuesLayerType())[62] { +inline const LayerType (&EnumValuesLayerType())[63] { static const LayerType values[] = { LayerType_Addition, LayerType_Input, @@ -802,13 +807,14 @@ inline const LayerType (&EnumValuesLayerType())[62] { LayerType_Rank, LayerType_LogicalBinary, LayerType_Reduce, - LayerType_Cast + LayerType_Cast, + LayerType_Shape }; return values; } inline const char * const *EnumNamesLayerType() { - static const char * const names[63] = { + static const char * const names[64] = { "Addition", "Input", "Multiplication", @@ -871,13 +877,14 @@ inline const char * const *EnumNamesLayerType() { "LogicalBinary", "Reduce", "Cast", + "Shape", nullptr }; return names; } inline const char *EnumNameLayerType(LayerType e) { - if (flatbuffers::IsOutRange(e, LayerType_Addition, LayerType_Cast)) return ""; + if (flatbuffers::IsOutRange(e, LayerType_Addition, LayerType_Shape)) return ""; const size_t index = static_cast<size_t>(e); return EnumNamesLayerType()[index]; } @@ -1219,11 +1226,12 @@ enum Layer { Layer_LogicalBinaryLayer = 60, Layer_ReduceLayer = 61, Layer_CastLayer = 62, + Layer_ShapeLayer = 63, Layer_MIN = Layer_NONE, - Layer_MAX = Layer_CastLayer + Layer_MAX = Layer_ShapeLayer }; -inline const Layer (&EnumValuesLayer())[63] { +inline const Layer (&EnumValuesLayer())[64] { static const Layer values[] = { Layer_NONE, Layer_ActivationLayer, @@ -1287,13 +1295,14 @@ inline const Layer (&EnumValuesLayer())[63] { Layer_RankLayer, Layer_LogicalBinaryLayer, Layer_ReduceLayer, - Layer_CastLayer + Layer_CastLayer, + Layer_ShapeLayer }; return values; } inline const char * const *EnumNamesLayer() { - static const char * const names[64] = { + static const char * const names[65] = { "NONE", "ActivationLayer", "AdditionLayer", @@ -1357,13 +1366,14 @@ inline const char * const *EnumNamesLayer() { "LogicalBinaryLayer", "ReduceLayer", "CastLayer", + "ShapeLayer", nullptr }; return names; } inline const char *EnumNameLayer(Layer e) { - if (flatbuffers::IsOutRange(e, Layer_NONE, Layer_CastLayer)) return ""; + if (flatbuffers::IsOutRange(e, Layer_NONE, Layer_ShapeLayer)) return ""; const size_t index = static_cast<size_t>(e); return EnumNamesLayer()[index]; } @@ -1620,6 +1630,10 @@ template<> struct LayerTraits<armnnSerializer::CastLayer> { static const Layer enum_value = Layer_CastLayer; }; +template<> struct LayerTraits<armnnSerializer::ShapeLayer> { + static const Layer enum_value = Layer_ShapeLayer; +}; + bool VerifyLayer(flatbuffers::Verifier &verifier, const void *obj, Layer type); bool VerifyLayerVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types); @@ -5180,6 +5194,49 @@ inline flatbuffers::Offset<PermuteDescriptor> CreatePermuteDescriptorDirect( dimMappings__); } +struct ShapeLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ShapeLayerBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_BASE = 4 + }; + const armnnSerializer::LayerBase *base() const { + return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_BASE) && + verifier.VerifyTable(base()) && + verifier.EndTable(); + } +}; + +struct ShapeLayerBuilder { + typedef ShapeLayer Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) { + fbb_.AddOffset(ShapeLayer::VT_BASE, base); + } + explicit ShapeLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ShapeLayerBuilder &operator=(const ShapeLayerBuilder &); + flatbuffers::Offset<ShapeLayer> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<ShapeLayer>(end); + return o; + } +}; + +inline flatbuffers::Offset<ShapeLayer> CreateShapeLayer( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) { + ShapeLayerBuilder builder_(_fbb); + builder_.add_base(base); + return builder_.Finish(); +} + struct SpaceToBatchNdLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef SpaceToBatchNdLayerBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { @@ -9567,6 +9624,9 @@ struct AnyLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const armnnSerializer::CastLayer *layer_as_CastLayer() const { return layer_type() == armnnSerializer::Layer_CastLayer ? static_cast<const armnnSerializer::CastLayer *>(layer()) : nullptr; } + const armnnSerializer::ShapeLayer *layer_as_ShapeLayer() const { + return layer_type() == armnnSerializer::Layer_ShapeLayer ? static_cast<const armnnSerializer::ShapeLayer *>(layer()) : nullptr; + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_LAYER_TYPE) && @@ -9824,6 +9884,10 @@ template<> inline const armnnSerializer::CastLayer *AnyLayer::layer_as<armnnSeri return layer_as_CastLayer(); } +template<> inline const armnnSerializer::ShapeLayer *AnyLayer::layer_as<armnnSerializer::ShapeLayer>() const { + return layer_as_ShapeLayer(); +} + struct AnyLayerBuilder { typedef AnyLayer Table; flatbuffers::FlatBufferBuilder &fbb_; @@ -10292,6 +10356,10 @@ inline bool VerifyLayer(flatbuffers::Verifier &verifier, const void *obj, Layer auto ptr = reinterpret_cast<const armnnSerializer::CastLayer *>(obj); return verifier.VerifyTable(ptr); } + case Layer_ShapeLayer: { + auto ptr = reinterpret_cast<const armnnSerializer::ShapeLayer *>(obj); + return verifier.VerifyTable(ptr); + } default: return true; } } diff --git a/src/armnnSerializer/Serializer.cpp b/src/armnnSerializer/Serializer.cpp index 30a7e74a58..fd7f8dc7dc 100644 --- a/src/armnnSerializer/Serializer.cpp +++ b/src/armnnSerializer/Serializer.cpp @@ -1309,6 +1309,17 @@ void SerializerStrategy::SerializeNormalizationLayer(const armnn::IConnectableLa CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer); } +void SerializerStrategy::SerializeShapeLayer(const armnn::IConnectableLayer* layer, + const char* name) +{ + IgnoreUnused(name); + + auto shapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Shape); + auto shapeLayer = serializer::CreateShapeLayer(m_flatBufferBuilder, shapeBaseLayer); + + CreateAnyLayer(shapeLayer.o, serializer::Layer::Layer_ShapeLayer); +} + void SerializerStrategy::SerializeStackLayer(const armnn::IConnectableLayer* layer, const armnn::StackDescriptor& stackDescriptor, const char* name) @@ -2138,6 +2149,11 @@ void SerializerStrategy::ExecuteStrategy(const armnn::IConnectableLayer* layer, SerializeResizeLayer(layer, layerDescriptor, name); break; } + case armnn::LayerType::Shape: + { + SerializeShapeLayer(layer, name); + break; + } case armnn::LayerType::Slice: { const armnn::SliceDescriptor& layerDescriptor = diff --git a/src/armnnSerializer/Serializer.hpp b/src/armnnSerializer/Serializer.hpp index 7bbcc2464e..c99e87d3e9 100644 --- a/src/armnnSerializer/Serializer.hpp +++ b/src/armnnSerializer/Serializer.hpp @@ -315,6 +315,9 @@ private: const armnn::NormalizationDescriptor& normalizationDescriptor, const char* name = nullptr); + void SerializeShapeLayer(const armnn::IConnectableLayer* layer, + const char* name = nullptr); + void SerializeSplitterLayer(const armnn::IConnectableLayer* layer, const armnn::ViewsDescriptor& viewsDescriptor, const char* name = nullptr); diff --git a/src/armnnSerializer/test/SerializerTests.cpp b/src/armnnSerializer/test/SerializerTests.cpp index 8e7ca37cfa..98532d0cec 100644 --- a/src/armnnSerializer/test/SerializerTests.cpp +++ b/src/armnnSerializer/test/SerializerTests.cpp @@ -1951,6 +1951,31 @@ TEST_CASE("EnsureResizeBilinearBackwardCompatibility") deserializedNetwork->ExecuteStrategy(verifier); } +TEST_CASE("SerializeShape") +{ + const std::string layerName("shape"); + const armnn::TensorInfo inputInfo({1, 3, 3, 1}, armnn::DataType::Signed32); + const armnn::TensorInfo outputInfo({ 4 }, armnn::DataType::Signed32); + + armnn::INetworkPtr network = armnn::INetwork::Create(); + armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0); + armnn::IConnectableLayer* const shapeLayer = network->AddShapeLayer(layerName.c_str()); + armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0); + + inputLayer->GetOutputSlot(0).Connect(shapeLayer->GetInputSlot(0)); + shapeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); + + inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo); + shapeLayer->GetOutputSlot(0).SetTensorInfo(outputInfo); + + armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network)); + CHECK(deserializedNetwork); + + LayerVerifierBase verifier(layerName, {inputInfo}, {outputInfo}); + + deserializedNetwork->ExecuteStrategy(verifier); +} + TEST_CASE("SerializeSlice") { const std::string layerName{"slice"}; |