From cfd30e9fea93c601a77eba55957c72a746cab962 Mon Sep 17 00:00:00 2001 From: Johan Gunnarsson Date: Tue, 8 Apr 2025 15:18:02 +0200 Subject: [PATCH 1/4] MLBEDSW-10650: Add argument to skip OfflineMemoryAllocation This is useful for unit test purposes. Signed-off-by: Johan Gunnarsson Change-Id: I8dcf23c1679d933dbfc0ce12314638469beea10d --- ethosu/regor/tflite/tflite_writer.cpp | 5 ++++- ethosu/regor/tflite/tflite_writer.hpp | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ethosu/regor/tflite/tflite_writer.cpp b/ethosu/regor/tflite/tflite_writer.cpp index ca707e7a..3e539b29 100644 --- a/ethosu/regor/tflite/tflite_writer.cpp +++ b/ethosu/regor/tflite/tflite_writer.cpp @@ -256,7 +256,10 @@ std::unique_ptr TfLiteWriter::SerialiseImpl(const std::vector _offset_buffers; bool _useBufferOffset = false; const size_t _fbSizeCap; + const bool _skipOfflineMemoryAllocation; // Skip writing the OfflineMemoryAllocation TFLite metadata. The purpose + // of this is primarily for unit testing. static constexpr size_t BUFFER_ALIGNMENT = 16ULL; -- GitLab From 5c442598effa17135d7031d73ddd14a39bc19b8a Mon Sep 17 00:00:00 2001 From: Johan Gunnarsson Date: Tue, 8 Apr 2025 15:18:50 +0200 Subject: [PATCH 2/4] MLBEDSW-10678: Add argument to skip the TFLite semantics checker This is useful for unit test purpose. Signed-off-by: Johan Gunnarsson Change-Id: If07c753644123be2c1f0fc0c8ff56fb5281a4bbc --- ethosu/regor/tflite/tflite_reader.cpp | 14 +++++++++----- ethosu/regor/tflite/tflite_reader.hpp | 4 ++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ethosu/regor/tflite/tflite_reader.cpp b/ethosu/regor/tflite/tflite_reader.cpp index 2228ef4d..9710d50a 100644 --- a/ethosu/regor/tflite/tflite_reader.cpp +++ b/ethosu/regor/tflite/tflite_reader.cpp @@ -105,12 +105,15 @@ const tflite::Model *TfLiteReader::LoadModel(const void *input, size_t size) } void TfLiteReader::LoadGraphs(const uint8_t *input, const tflite::Model *model, - std::vector> &graphs, OptimiserDatabase *optDb) + std::vector> &graphs, OptimiserDatabase *optDb, bool skipSemanticsCheck) { assert(model); - auto semanticsChecker = tflite::TFLiteModelSemantics(model); - semanticsChecker.Check(); + if ( !skipSemanticsCheck ) + { + auto semanticsChecker = tflite::TFLiteModelSemantics(model); + semanticsChecker.Check(); + } std::unordered_map tensorQuantization{}; std::vector opcodes; @@ -342,9 +345,10 @@ void TfLiteReader::LoadGraphs(const uint8_t *input, const tflite::Model *model, } } -void TfLiteReader::LoadGraphs(const void *input, size_t size, std::vector> &graphs, OptimiserDatabase *optDb) +void TfLiteReader::LoadGraphs(const void *input, size_t size, std::vector> &graphs, + OptimiserDatabase *optDb, bool skipSemanticsCheck) { - LoadGraphs(reinterpret_cast(input), LoadModel(input, size), graphs, optDb); + LoadGraphs(reinterpret_cast(input), LoadModel(input, size), graphs, optDb, skipSemanticsCheck); } std::shared_ptr TfLiteReader::ParseTensor(const tflite::Tensor *tflite_tensor, std::shared_ptr &buffer, diff --git a/ethosu/regor/tflite/tflite_reader.hpp b/ethosu/regor/tflite/tflite_reader.hpp index 1104c2e9..81ae0c89 100644 --- a/ethosu/regor/tflite/tflite_reader.hpp +++ b/ethosu/regor/tflite/tflite_reader.hpp @@ -39,11 +39,11 @@ public: TfLiteReader() {} static void LoadGraphs(const void *input, size_t size, std::vector> &graphs, - OptimiserDatabase *optDb); // From buffer + OptimiserDatabase *optDb, bool skipSemanticsCheck = false); // From buffer private: static void LoadGraphs(const uint8_t *input, const tflite::Model *model, std::vector> &graphs, - OptimiserDatabase *optDb); // From model + OptimiserDatabase *optDb, bool skipSemanticsCheck = false); // From model static const tflite::Model *LoadModel(const void *input, size_t size); static std::shared_ptr ParseTensor(const tflite::Tensor *tflite_tensor, std::shared_ptr &buffer, std::unordered_map &tensorQuantization); -- GitLab From d51140c2c71e2f8e921999b10556f78c2619f612 Mon Sep 17 00:00:00 2001 From: Johan Gunnarsson Date: Tue, 8 Apr 2025 19:00:47 +0200 Subject: [PATCH 3/4] MLBEDSW-10655: Add more BuiltinOptions from schema Signed-off-by: Johan Gunnarsson Change-Id: I12dfbf7e1c1f61cf7c16464e0e45b6534b469117 --- ethosu/regor/tflite/tflite_mapping.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/ethosu/regor/tflite/tflite_mapping.cpp b/ethosu/regor/tflite/tflite_mapping.cpp index 769e2bbf..6fb01d22 100644 --- a/ethosu/regor/tflite/tflite_mapping.cpp +++ b/ethosu/regor/tflite/tflite_mapping.cpp @@ -349,11 +349,27 @@ const std::map TfLiteMapping::_ {tflite::BuiltinOperator::HASHTABLE_IMPORT, tflite::BuiltinOptions::HashtableImportOptions}, {tflite::BuiltinOperator::HASHTABLE_SIZE, tflite::BuiltinOptions::HashtableSizeOptions}, {tflite::BuiltinOperator::REDUCE_ALL, tflite::BuiltinOptions::ReducerOptions}, - // TODO: {tflite::BuiltinOperator::CONV_3D_TRANSPOSE, tflite::BuiltinOptions::???}, + {tflite::BuiltinOperator::CONV_3D_TRANSPOSE, tflite::BuiltinOptions::Conv3DOptions}, {tflite::BuiltinOperator::VAR_HANDLE, tflite::BuiltinOptions::VarHandleOptions}, {tflite::BuiltinOperator::READ_VARIABLE, tflite::BuiltinOptions::ReadVariableOptions}, {tflite::BuiltinOperator::ASSIGN_VARIABLE, tflite::BuiltinOptions::AssignVariableOptions}, {tflite::BuiltinOperator::BROADCAST_ARGS, tflite::BuiltinOptions::NONE}, + {tflite::BuiltinOperator::RANDOM_STANDARD_NORMAL, tflite::BuiltinOptions::RandomOptions}, + {tflite::BuiltinOperator::BUCKETIZE, tflite::BuiltinOptions::BucketizeOptions}, + {tflite::BuiltinOperator::RANDOM_UNIFORM, tflite::BuiltinOptions::RandomOptions}, + {tflite::BuiltinOperator::MULTINOMIAL, tflite::BuiltinOptions::NONE}, + {tflite::BuiltinOperator::GELU, tflite::BuiltinOptions::GeluOptions}, + {tflite::BuiltinOperator::DYNAMIC_UPDATE_SLICE, tflite::BuiltinOptions::DynamicUpdateSliceOptions}, + {tflite::BuiltinOperator::RELU_0_TO_1, tflite::BuiltinOptions::NONE}, + {tflite::BuiltinOperator::UNSORTED_SEGMENT_PROD, tflite::BuiltinOptions::UnsortedSegmentProdOptions}, + {tflite::BuiltinOperator::UNSORTED_SEGMENT_MAX, tflite::BuiltinOptions::UnsortedSegmentMaxOptions}, + {tflite::BuiltinOperator::UNSORTED_SEGMENT_SUM, tflite::BuiltinOptions::UnsortedSegmentSumOptions}, + {tflite::BuiltinOperator::ATAN2, tflite::BuiltinOptions::ATan2Options}, + {tflite::BuiltinOperator::UNSORTED_SEGMENT_MIN, tflite::BuiltinOptions::UnsortedSegmentMinOptions}, + {tflite::BuiltinOperator::SIGN, tflite::BuiltinOptions::SignOptions}, + {tflite::BuiltinOperator::BITCAST, tflite::BuiltinOptions::BitcastOptions}, + {tflite::BuiltinOperator::BITWISE_XOR, tflite::BuiltinOptions::BitwiseXorOptions}, + {tflite::BuiltinOperator::RIGHT_SHIFT, tflite::BuiltinOptions::RightShiftOptions}, // clang-format on }; @@ -689,6 +705,10 @@ bool TfLiteMapping::CanFuseActivationFunction(const Operation *operation) { activation = GetBuiltinFaf(passthrough); } + else if ( type == tflite::BuiltinOptions::TransposeConvOptions ) + { + activation = GetBuiltinFaf(passthrough); + } else { return false; // Operator type does not support fused activations -- GitLab From ae118b3b0e6a634e5c4e67832033ccbb04fec3e8 Mon Sep 17 00:00:00 2001 From: Johan Gunnarsson Date: Tue, 8 Apr 2025 16:35:03 +0200 Subject: [PATCH 4/4] MLBEDSW-10654: Add BuiltinOptions2 support to tflite_writer * Add builtin_options2 to tflite_writer and tflite_mapping. * Remove OpTypeToBuiltinOptions. Use builtin options type from passthrough data or BuiltinOperatorToBuiltin{Options,Options2} instead. Signed-off-by: Johan Gunnarsson Change-Id: Ie475593a1c365f2fec964d2dccbca21a862e9647 --- ethosu/regor/tflite/tflite_mapping.cpp | 29 +++++++++++++++++++- ethosu/regor/tflite/tflite_mapping.hpp | 37 +++++++++++++++----------- ethosu/regor/tflite/tflite_writer.cpp | 34 +++++++++++++++++++++-- ethosu/regor/tflite/tflite_writer.hpp | 1 + 4 files changed, 83 insertions(+), 18 deletions(-) diff --git a/ethosu/regor/tflite/tflite_mapping.cpp b/ethosu/regor/tflite/tflite_mapping.cpp index 6fb01d22..27c31c39 100644 --- a/ethosu/regor/tflite/tflite_mapping.cpp +++ b/ethosu/regor/tflite/tflite_mapping.cpp @@ -373,6 +373,33 @@ const std::map TfLiteMapping::_ // clang-format on }; +const std::map TfLiteMapping::_builtinOperatorToBuiltinOptions2 = { + // clang-format off + {tflite::BuiltinOperator::STABLEHLO_CONCATENATE, tflite::BuiltinOptions2::StablehloConcatenateOptions}, + {tflite::BuiltinOperator::STABLEHLO_BROADCAST_IN_DIM, tflite::BuiltinOptions2::StablehloBroadcastInDimOptions}, + {tflite::BuiltinOperator::STABLEHLO_CONVOLUTION, tflite::BuiltinOptions2::StablehloConvolutionOptions}, + {tflite::BuiltinOperator::STABLEHLO_SLICE, tflite::BuiltinOptions2::StablehloSliceOptions}, + {tflite::BuiltinOperator::STABLEHLO_CUSTOM_CALL, tflite::BuiltinOptions2::StablehloCustomCallOptions}, + {tflite::BuiltinOperator::STABLEHLO_REDUCE, tflite::BuiltinOptions2::StablehloReduceOptions}, + {tflite::BuiltinOperator::STABLEHLO_SCATTER, tflite::BuiltinOptions2::StablehloScatterOptions}, + {tflite::BuiltinOperator::STABLEHLO_COMPARE, tflite::BuiltinOptions2::StablehloCompareOptions}, + {tflite::BuiltinOperator::STABLEHLO_DYNAMIC_SLICE, tflite::BuiltinOptions2::StablehloDynamicSliceOptions}, + {tflite::BuiltinOperator::STABLEHLO_PAD, tflite::BuiltinOptions2::StablehloPadOptions}, + {tflite::BuiltinOperator::STABLEHLO_IOTA, tflite::BuiltinOptions2::StablehloIotaOptions}, + {tflite::BuiltinOperator::STABLEHLO_DOT_GENERAL, tflite::BuiltinOptions2::StablehloDotGeneralOptions}, + {tflite::BuiltinOperator::STABLEHLO_REDUCE_WINDOW, tflite::BuiltinOptions2::StablehloReduceWindowOptions}, + {tflite::BuiltinOperator::STABLEHLO_SORT, tflite::BuiltinOptions2::StablehloSortOptions}, + {tflite::BuiltinOperator::STABLEHLO_WHILE, tflite::BuiltinOptions2::StablehloWhileOptions}, + {tflite::BuiltinOperator::STABLEHLO_GATHER, tflite::BuiltinOptions2::StablehloGatherOptions}, + {tflite::BuiltinOperator::STABLEHLO_TRANSPOSE, tflite::BuiltinOptions2::StablehloTransposeOptions}, + {tflite::BuiltinOperator::DILATE, tflite::BuiltinOptions2::DilateOptions}, + {tflite::BuiltinOperator::STABLEHLO_RNG_BIT_GENERATOR, tflite::BuiltinOptions2::StablehloRngBitGeneratorOptions}, + {tflite::BuiltinOperator::REDUCE_WINDOW, tflite::BuiltinOptions2::ReduceWindowOptions}, + {tflite::BuiltinOperator::STABLEHLO_COMPOSITE, tflite::BuiltinOptions2::StableHLOCompositeOptions}, + {tflite::BuiltinOperator::STABLEHLO_SHIFT_LEFT, tflite::BuiltinOptions2::StablehloShiftLeftOptions}, + // clang-format on +}; + const std::multimap TfLiteMapping::_inputTensorIndices = { // clang-format off {OpType::Abs, TensorUsage::IFM0}, @@ -629,8 +656,8 @@ bool TfLiteMapping::CanFuseActivationFunction(const Operation *operation) return false; // Only fuse operators which came in fused } - const auto type = TfLiteMapping::OpTypeToBuiltinOptions(operation->Type()); const tflite::Operator *const passthrough = static_cast(operation->Passthrough()); + const tflite::BuiltinOptions type = passthrough->builtin_options_type(); tflite::ActivationFunctionType activation; if ( type == tflite::BuiltinOptions::Conv2DOptions ) diff --git a/ethosu/regor/tflite/tflite_mapping.hpp b/ethosu/regor/tflite/tflite_mapping.hpp index 7e6f0aee..7e040cd8 100644 --- a/ethosu/regor/tflite/tflite_mapping.hpp +++ b/ethosu/regor/tflite/tflite_mapping.hpp @@ -1,5 +1,5 @@ // -// SPDX-FileCopyrightText: Copyright 2021, 2023-2024 Arm Limited and/or its affiliates +// SPDX-FileCopyrightText: Copyright 2021, 2023-2025 Arm Limited and/or its affiliates // // SPDX-License-Identifier: Apache-2.0 // @@ -54,6 +54,26 @@ public: static std::string BuiltinOperatorToString(tflite::BuiltinOperator &type) { return EnumNameBuiltinOperator(type); } + static tflite::BuiltinOptions BuiltinOperatorToBuiltinOptions(tflite::BuiltinOperator op) + { + auto it1 = _builtinOperatorToBuiltinOptions.find(op); + if ( it1 == _builtinOperatorToBuiltinOptions.end() ) + { + return tflite::BuiltinOptions::NONE; + } + return it1->second; + } + + static tflite::BuiltinOptions2 BuiltinOperatorToBuiltinOptions2(tflite::BuiltinOperator op) + { + auto it1 = _builtinOperatorToBuiltinOptions2.find(op); + if ( it1 == _builtinOperatorToBuiltinOptions2.end() ) + { + return tflite::BuiltinOptions2::NONE; + } + return it1->second; + } + // // Conversions from Regor types to TensorFlow Lite types // @@ -78,20 +98,6 @@ public: return type == OpType::CustomNpuOp ? tflite::BuiltinOperator::CUSTOM : _opTypeToBuiltinOperator.at(type); } - static tflite::BuiltinOptions OpTypeToBuiltinOptions(OpType type) - { - auto it1 = _opTypeToBuiltinOperator.find(type); - if ( it1 == _opTypeToBuiltinOperator.end() ) - { - return tflite::BuiltinOptions::NONE; - } - auto it2 = _builtinOperatorToBuiltinOptions.find(it1->second); - if ( it2 == _builtinOperatorToBuiltinOptions.end() ) - { - return tflite::BuiltinOptions::NONE; - } - return it2->second; - } class InputTensorIndices; // Usage: for (const auto& map_entry : InputTensorIndices(op_type)) {} @@ -117,6 +123,7 @@ private: // Mapping from TensorFlow Lite operator type to TensorFlow Lite options type is N:1 static const std::map _builtinOperatorToBuiltinOptions; + static const std::map _builtinOperatorToBuiltinOptions2; // The number of input tensors to a TensorFlow Lite operator depends on the operator type, // as does the order in which the different kinds of input tensor are listed. diff --git a/ethosu/regor/tflite/tflite_writer.cpp b/ethosu/regor/tflite/tflite_writer.cpp index 3e539b29..b01ec963 100644 --- a/ethosu/regor/tflite/tflite_writer.cpp +++ b/ethosu/regor/tflite/tflite_writer.cpp @@ -124,6 +124,7 @@ std::unique_ptr TfLiteWriter::SerialiseImpl(const std::vectorType(); tflite::BuiltinOperator builtin_code; tflite::BuiltinOptions builtin_options_type; + tflite::BuiltinOptions2 builtin_options_2_type; if ( type == OpType::Passthrough ) { assert(tflite_model); @@ -137,11 +138,13 @@ std::unique_ptr TfLiteWriter::SerialiseImpl(const std::vector(deprecated_builtin_code); } builtin_options_type = tflite_operator->builtin_options_type(); + builtin_options_2_type = tflite_operator->builtin_options_2_type(); } else { builtin_code = TfLiteMapping::OpTypeToBuiltinOperator(type); - builtin_options_type = TfLiteMapping::OpTypeToBuiltinOptions(type); + builtin_options_type = TfLiteMapping::BuiltinOperatorToBuiltinOptions(builtin_code); + builtin_options_2_type = TfLiteMapping::BuiltinOperatorToBuiltinOptions2(builtin_code); } // Set deprecated_builtin_code for backwards compatibility @@ -203,6 +206,8 @@ std::unique_ptr TfLiteWriter::SerialiseImpl(const std::vector> custom_options = 0; flatbuffers::Offset> mvi = 0; // mutating_variable_inputs flatbuffers::Offset> intermediates = 0; + uint64_t large_custom_options_offset = 0; + uint64_t large_custom_options_size = 0; if ( type == OpType::CustomNpuOp ) { @@ -230,9 +235,11 @@ std::unique_ptr TfLiteWriter::SerialiseImpl(const std::vector(inputs); auto serialised_outputs = _flatbuffer.CreateVector(outputs); auto serialised_options = SerialiseOptions(operation, type); + auto serialised_options2 = SerialiseOptions2(operation, type); _serialised_operations.push_back(tflite::CreateOperator(_flatbuffer, opcode_index, serialised_inputs, serialised_outputs, - builtin_options_type, serialised_options, custom_options, custom_options_format, mvi, intermediates)); + builtin_options_type, serialised_options, custom_options, custom_options_format, mvi, intermediates, + large_custom_options_offset, large_custom_options_size, builtin_options_2_type, serialised_options2)); } std::vector inputs, outputs; @@ -892,6 +899,29 @@ flatbuffers::Offset TfLiteWriter::SerialiseOptions(const Operation *operat return offset; } +flatbuffers::Offset TfLiteWriter::SerialiseOptions2(const Operation *operation, OpType opType) +{ + if ( opType == OpType::CustomNpuOp ) + { + return 0; + } + + flatbuffers::Offset offset = 0; + const tflite::Operator *const passthrough = static_cast(operation->Passthrough()); + assert(passthrough); + const auto type = passthrough->builtin_options_2_type(); + + switch ( type ) + { + case tflite::BuiltinOptions2::NONE: + break; + default: + break; + } + + return offset; +} + flatbuffers::Offset TfLiteWriter::SerialiseTensorAddresses(int subgraphs) { const int32_t version = 0; diff --git a/ethosu/regor/tflite/tflite_writer.hpp b/ethosu/regor/tflite/tflite_writer.hpp index 46f9ac53..40fe51cd 100644 --- a/ethosu/regor/tflite/tflite_writer.hpp +++ b/ethosu/regor/tflite/tflite_writer.hpp @@ -113,6 +113,7 @@ private: flatbuffers::Offset SerialiseTensor(const Tensor *tensor, const Graph &graph); flatbuffers::Offset SerialiseOptions(const Operation *operation, OpType type); + flatbuffers::Offset SerialiseOptions2(const Operation *operation, OpType type); flatbuffers::Offset SerialiseTensorAddresses(int subgraphs); void SerialiseTensorBuffer(const Tensor *tensor); -- GitLab