From 30f3741ddf2e518362e3e4217583f75189872665 Mon Sep 17 00:00:00 2001 From: Haoliang Zhang <haoliang@google.com> Date: Mon, 9 Mar 2020 11:47:39 -0700 Subject: [PATCH] Export min_runtime_version in MLIR converter This change fixes the issue for missing min_runtime_version in flatbuffers exported by MLIR converter. Specifically: *Export `min_runtime_version` in metadata of flatbuffer (fixed-length byte array). *Update all related mlir tests to have metadata. PiperOrigin-RevId: 299894972 Change-Id: Ic79f3ab05b593882362f5baf62493861961acbe3 --- tensorflow/compiler/mlir/lite/BUILD | 2 +- .../mlir/lite/flatbuffer_translate.cc | 32 +- .../mlir/lite/tests/end2end/add.pbtxt | 8 +- .../tests/mlir2flatbuffer/basic_lstm.mlir | 6 + .../convolution_2d_transpose_bias.mlir | 8 +- .../custom_op_with_tflite_op.mlir | 8 +- .../mlir2flatbuffer/depthwise_conv2d.mlir | 6 + .../mlir2flatbuffer/depthwise_conv2d_v2.mlir | 6 + .../disable_flex_enable_builtin.mlir | 8 +- .../tests/mlir2flatbuffer/fake_quant.mlir | 8 +- .../mlir2flatbuffer/flex_exclusively.mlir | 8 +- .../flex_op_with_tflite_op.mlir | 8 +- .../mlir2flatbuffer/fully_connected.mlir | 6 + .../mlir2flatbuffer/fully_connected_v2.mlir | 6 + .../lite/tests/mlir2flatbuffer/if_op.mlir | 6 + .../lite/tests/mlir2flatbuffer/logical.mlir | 8 +- .../mlir/lite/tests/mlir2flatbuffer/lstm.mlir | 8 +- .../mlir/lite/tests/mlir2flatbuffer/math.mlir | 6 + .../max_pooling_with_arg_max_2d.mlir | 8 +- .../tests/mlir2flatbuffer/max_unpool_2d.mlir | 8 +- .../lite/tests/mlir2flatbuffer/metadata.mlir | 6 + .../lite/tests/mlir2flatbuffer/mul_v2.mlir | 6 + .../lite/tests/mlir2flatbuffer/mul_v3.mlir | 6 + .../mlir/lite/tests/mlir2flatbuffer/nn.mlir | 8 +- .../tests/mlir2flatbuffer/numeric_verify.mlir | 8 +- .../tests/mlir2flatbuffer/quantization.mlir | 8 +- .../lite/tests/mlir2flatbuffer/reshape.mlir | 8 +- .../lite/tests/mlir2flatbuffer/simple.mlir | 6 + .../mlir/lite/tests/mlir2flatbuffer/svdf.mlir | 8 +- .../lite/tests/mlir2flatbuffer/svdf_v2.mlir | 8 +- .../tests/mlir2flatbuffer/tfl_while_op.mlir | 6 + .../unidirectional_sequence_lstm.mlir | 8 +- .../unidirectional_sequence_rnn.mlir | 8 +- .../lite/tests/mlir2flatbuffer/while_op.mlir | 8 +- tensorflow/lite/g3doc/guide/ops_version.md | 5 +- tensorflow/lite/kernels/BUILD | 2 +- tensorflow/lite/model.cc | 16 +- tensorflow/lite/model_test.cc | 2 +- tensorflow/lite/testdata/test_min_runtime.bin | Bin 580 -> 536 bytes tensorflow/lite/toco/tflite/BUILD | 3 +- tensorflow/lite/toco/tflite/op_version.cc | 22 +- tensorflow/lite/toco/tflite/op_version.h | 5 - .../lite/toco/tflite/op_version_test.cc | 13 +- tensorflow/lite/tools/versioning/BUILD | 19 +- .../lite/tools/versioning/runtime_version.cc | 285 ++++++++++++++++++ .../lite/tools/versioning/runtime_version.h | 33 ++ .../tools/versioning/runtime_version_test.cc | 34 +++ 47 files changed, 625 insertions(+), 80 deletions(-) create mode 100644 tensorflow/lite/tools/versioning/runtime_version.cc create mode 100644 tensorflow/lite/tools/versioning/runtime_version.h create mode 100644 tensorflow/lite/tools/versioning/runtime_version_test.cc diff --git a/tensorflow/compiler/mlir/lite/BUILD b/tensorflow/compiler/mlir/lite/BUILD index 3b59ae32d41..be641c1a8f1 100644 --- a/tensorflow/compiler/mlir/lite/BUILD +++ b/tensorflow/compiler/mlir/lite/BUILD @@ -580,7 +580,7 @@ cc_library( "//tensorflow/lite/delegates/flex:whitelisted_flex_ops_lib", "//tensorflow/lite/kernels/internal:kernel_utils", "//tensorflow/lite/schema:schema_fbs", - "//tensorflow/lite/tools/versioning:op_version", + "//tensorflow/lite/tools/versioning", "@com_google_absl//absl/base", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", diff --git a/tensorflow/compiler/mlir/lite/flatbuffer_translate.cc b/tensorflow/compiler/mlir/lite/flatbuffer_translate.cc index 5db951cd640..4f6de71c315 100644 --- a/tensorflow/compiler/mlir/lite/flatbuffer_translate.cc +++ b/tensorflow/compiler/mlir/lite/flatbuffer_translate.cc @@ -76,6 +76,7 @@ limitations under the License. #include "tensorflow/lite/schema/schema_generated.h" #include "tensorflow/lite/string_util.h" #include "tensorflow/lite/tools/versioning/op_version.h" +#include "tensorflow/lite/tools/versioning/runtime_version.h" #include "tensorflow/lite/version.h" using llvm::dyn_cast; @@ -1230,21 +1231,27 @@ BufferOffset<tflite::Metadata> Translator::BuildMetadata(StringRef name, Optional<VectorBufferOffset<BufferOffset<tflite::Metadata>>> Translator::CreateMetadataVector() { auto dict_attr = module_.getAttrOfType<mlir::DictionaryAttr>("tfl.metadata"); - if (!dict_attr) return VectorBufferOffset<BufferOffset<tflite::Metadata>>(); - std::vector<BufferOffset<tflite::Metadata>> metadata; - for (const auto& named_attr : dict_attr) { - StringRef name = named_attr.first; - mlir::Attribute attr = named_attr.second; - if (auto content = attr.dyn_cast<StringAttr>()) { - metadata.push_back(BuildMetadata(name, content.getValue())); - } else { - module_.emitError( - "all values in tfl.metadata's dictionary key-value pairs should be " - "string attributes"); - return llvm::None; + if (dict_attr) { + for (const auto& named_attr : dict_attr) { + StringRef name = named_attr.first; + mlir::Attribute attr = named_attr.second; + if (auto content = attr.dyn_cast<StringAttr>()) { + metadata.push_back(BuildMetadata(name, content.getValue())); + } else { + module_.emitError( + "all values in tfl.metadata's dictionary key-value pairs should be " + "string attributes"); + return llvm::None; + } } } + // Runtime version string is generated after we update the op + // versions. Here we put a 16-byte dummy string as a placeholder. We choose + // 16-byte because it's the alignment of buffers in flatbuffer, so it won't + // cause any waste of space if the actual string is shorter than 16 bytes. + metadata.push_back( + BuildMetadata("min_runtime_version", std::string(16, '\0'))); return builder_.CreateVector(metadata); } @@ -1359,6 +1366,7 @@ Optional<std::string> Translator::TranslateInternal() { builder_.CreateVector(buffers_), metadata_buffer, *metadata); tflite::FinishModelBuffer(builder_, model); tflite::UpdateOpVersion(builder_.GetBufferPointer()); + tflite::UpdateMinimumRuntimeVersionForModel(builder_.GetBufferPointer()); // Return serialized string for the built FlatBuffer. return std::string(reinterpret_cast<const char*>(builder_.GetBufferPointer()), diff --git a/tensorflow/compiler/mlir/lite/tests/end2end/add.pbtxt b/tensorflow/compiler/mlir/lite/tests/end2end/add.pbtxt index 44ef85bfac2..902d1c98cab 100644 --- a/tensorflow/compiler/mlir/lite/tests/end2end/add.pbtxt +++ b/tensorflow/compiler/mlir/lite/tests/end2end/add.pbtxt @@ -1,4 +1,4 @@ -# RUN: tf_tfl_translate -tf-input-arrays=input0,input1 -tf-input-shapes=4:4 -tf-input-data-types=DT_INT32,DT_INT32 -tf-output-arrays=Add %s -o - | flatbuffer_to_string - | FileCheck %s +# RUN: tf_tfl_translate -tf-input-arrays=input0,input1 -tf-input-shapes=4:4 -tf-input-data-types=DT_INT32,DT_INT32 -tf-output-arrays=Add %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s # Add two tensor<4xi32> inputs and return the result @@ -90,5 +90,11 @@ versions { # CHECK-EMPTY: # CHECK-NEXT: }, { # CHECK-EMPTY: +# CHECK-NEXT: }, { +# CHECK-NEXT: data: [ 49, 46, 53, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +# CHECK-NEXT: } ], +# CHECK-NEXT: metadata: [ { +# CHECK-NEXT: name: "min_runtime_version", +# CHECK-NEXT: buffer: 4 # CHECK-NEXT: } ] # CHECK-NEXT: } diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/basic_lstm.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/basic_lstm.mlir index 5ede7c05234..47e1ccee3c9 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/basic_lstm.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/basic_lstm.mlir @@ -108,6 +108,12 @@ func @main(tensor<1x384xf32>, tensor<1x96xf32>, tensor<384x480xf32>, tensor<384x // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 49, 48, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 10 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/convolution_2d_transpose_bias.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/convolution_2d_transpose_bias.mlir index 8d4c93fccc0..9d134a3fcad 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/convolution_2d_transpose_bias.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/convolution_2d_transpose_bias.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -emit-custom-ops -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -emit-custom-ops -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s // RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_translate --tflite-flatbuffer-to-mlir -o - | FileCheck --check-prefix=MLIR %s @@ -61,6 +61,12 @@ func @main(%arg0: tensor<32x4x4x128xf32>, %arg1: tensor<1x32x42x128xf32>, %arg2: // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 5 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/custom_op_with_tflite_op.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/custom_op_with_tflite_op.mlir index ec6b9e313f6..1b46fa3d0e5 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/custom_op_with_tflite_op.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/custom_op_with_tflite_op.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -emit-custom-ops -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -emit-custom-ops -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s func @main(tensor<4xf32>) -> tensor<4xf32> { ^bb0(%arg0: tensor<4xf32>): @@ -90,6 +90,12 @@ func @main(tensor<4xf32>) -> tensor<4xf32> { // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 55, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 6 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/depthwise_conv2d.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/depthwise_conv2d.mlir index 10a62121485..ffa379124e6 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/depthwise_conv2d.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/depthwise_conv2d.mlir @@ -82,6 +82,12 @@ func @main(tensor<1x224x224x3xf32>) -> tensor<1x112x112x32xf32> { // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: + // CHECK-NEXT: }, { + // CHECK-NEXT: data: [ 49, 46, 49, 51, 46, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + // CHECK-NEXT: } ], + // CHECK-NEXT: metadata: [ { + // CHECK-NEXT: name: "min_runtime_version", + // CHECK-NEXT: buffer: 6 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/depthwise_conv2d_v2.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/depthwise_conv2d_v2.mlir index ce079ccccf7..627de564931 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/depthwise_conv2d_v2.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/depthwise_conv2d_v2.mlir @@ -84,6 +84,12 @@ func @main(tensor<1x224x224x3xf32>) -> tensor<1x112x112x32xf32> { // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: + // CHECK-NEXT: }, { + // CHECK-NEXT: data: [ 49, 46, 49, 51, 46, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + // CHECK-NEXT: } ], + // CHECK-NEXT: metadata: [ { + // CHECK-NEXT: name: "min_runtime_version", + // CHECK-NEXT: buffer: 6 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/disable_flex_enable_builtin.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/disable_flex_enable_builtin.mlir index 236fc605c9d..13f8b998fff 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/disable_flex_enable_builtin.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/disable_flex_enable_builtin.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s func @main(tensor<4xf32>) -> tensor<4xf32> { ^bb0(%arg0: tensor<4xf32>): @@ -88,6 +88,12 @@ func @main(tensor<4xf32>) -> tensor<4xf32> { // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 55, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 6 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/fake_quant.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/fake_quant.mlir index 2505f73ee31..48994bf4617 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/fake_quant.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/fake_quant.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s // RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_translate -tflite-flatbuffer-to-mlir - -o - | FileCheck --check-prefix=IMPORT %s func @main(tensor<4xf32>) -> tensor<4xf32> { @@ -46,6 +46,12 @@ func @main(tensor<4xf32>) -> tensor<4xf32> { // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 53, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 3 // CHECK-NEXT: } ] // CHECK-NEXT: } diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/flex_exclusively.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/flex_exclusively.mlir index c98fdeb514e..9c4524586a5 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/flex_exclusively.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/flex_exclusively.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -emit-select-tf-ops=true -emit-builtin-tflite-ops=false -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -emit-select-tf-ops=true -emit-builtin-tflite-ops=false -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s func @main(%arg0: tensor<3x2xf32>) -> tensor<3x2xf32> { // CHECK: { @@ -39,6 +39,12 @@ func @main(%arg0: tensor<3x2xf32>) -> tensor<3x2xf32> { // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 3 // CHECK-NEXT: } ] // CHECK-NEXT: } diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/flex_op_with_tflite_op.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/flex_op_with_tflite_op.mlir index 0bde1879b10..6f1bafcd7a9 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/flex_op_with_tflite_op.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/flex_op_with_tflite_op.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -emit-select-tf-ops -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -emit-select-tf-ops -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s func @main(tensor<4xf32>) -> tensor<4xf32> { ^bb0(%arg0: tensor<4xf32>): @@ -89,6 +89,12 @@ func @main(tensor<4xf32>) -> tensor<4xf32> { // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 55, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 6 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/fully_connected.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/fully_connected.mlir index 85ad8f01dbe..2015d694e7f 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/fully_connected.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/fully_connected.mlir @@ -61,6 +61,12 @@ func @main(tensor<40x37xf32>, tensor<40x37xf32>) -> tensor<40x40xf32> { // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: + // CHECK-NEXT: }, { + // CHECK-NEXT: data: [ 49, 46, 53, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + // CHECK-NEXT: } ], + // CHECK-NEXT: metadata: [ { + // CHECK-NEXT: name: "min_runtime_version", + // CHECK-NEXT: buffer: 5 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/fully_connected_v2.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/fully_connected_v2.mlir index 6f7fc9c967d..44c757d2fa8 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/fully_connected_v2.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/fully_connected_v2.mlir @@ -61,6 +61,12 @@ func @main(tensor<40x37xf32>, tensor<40x37xf32>) -> tensor<40x40xf32> { // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: + // CHECK-NEXT: }, { + // CHECK-NEXT: data: [ 49, 46, 49, 48, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + // CHECK-NEXT: } ], + // CHECK-NEXT: metadata: [ { + // CHECK-NEXT: name: "min_runtime_version", + // CHECK-NEXT: buffer: 5 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/if_op.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/if_op.mlir index 8ad0e1b0278..e325262eaa4 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/if_op.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/if_op.mlir @@ -156,6 +156,12 @@ // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 49, 52, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 11 // CHECK-NEXT: } ] // CHECK-NEXT: } diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/logical.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/logical.mlir index fd3f37eec73..4cedc6a218e 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/logical.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/logical.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s func @main(tensor<4xi1>) -> tensor<4xi1> { ^bb0(%arg0: tensor<4xi1>): @@ -78,6 +78,12 @@ func @main(tensor<4xi1>) -> tensor<4xi1> { // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: + // CHECK-NEXT: }, { + // CHECK-NEXT: data: [ 49, 46, 49, 49, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + // CHECK-NEXT: } ], + // CHECK-NEXT: metadata: [ { + // CHECK-NEXT: name: "min_runtime_version", + // CHECK-NEXT: buffer: 6 // CHECK-NEXT: } ] // CHECK-NEXT: } // CHECK-EMPTY: diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/lstm.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/lstm.mlir index ed3c8a6f702..f0ec274ad03 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/lstm.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/lstm.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s func @main(tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>) -> tensor<4 x f32> { // CHECK: { @@ -249,6 +249,12 @@ func @main(tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, t // CHECK-NEXT: data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 55, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 26 // CHECK-NEXT: } ] // CHECK-NEXT: } // CHECK-EMPTY: diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/math.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/math.mlir index d39a8353c6f..6c9dd515ca8 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/math.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/math.mlir @@ -128,6 +128,12 @@ func @main(tensor<4xf32>) -> tensor<4xf32> { // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: + // CHECK-NEXT: }, { + // CHECK-NEXT: data: [ 49, 46, 49, 51, 46, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + // CHECK-NEXT: } ], + // CHECK-NEXT: metadata: [ { + // CHECK-NEXT: name: "min_runtime_version", + // CHECK-NEXT: buffer: 8 // CHECK-NEXT: } ] // CHECK-NEXT: } diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/max_pooling_with_arg_max_2d.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/max_pooling_with_arg_max_2d.mlir index 47935358512..fc7ef307bae 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/max_pooling_with_arg_max_2d.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/max_pooling_with_arg_max_2d.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -emit-custom-ops -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -emit-custom-ops -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s // RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_translate --tflite-flatbuffer-to-mlir -o - | FileCheck --check-prefix=MLIR %s func @main(%arg0: tensor<1x64x64x32xf32>) -> (tensor<1x32x32x32xf32>, tensor<1x32x32x32xf32>) { @@ -50,6 +50,12 @@ func @main(%arg0: tensor<1x64x64x32xf32>) -> (tensor<1x32x32x32xf32>, tensor<1x3 // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 4 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/max_unpool_2d.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/max_unpool_2d.mlir index be2cc62e156..0dc6f7ea165 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/max_unpool_2d.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/max_unpool_2d.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -emit-custom-ops -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -emit-custom-ops -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s // RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_translate --tflite-flatbuffer-to-mlir -o - | FileCheck --check-prefix=MLIR %s func @main(%arg0: tensor<1x8x8x128xf32>, %arg1: tensor<1x8x8x128xf32>) -> tensor<1x8x8x128xf32> { @@ -50,6 +50,12 @@ func @main(%arg0: tensor<1x8x8x128xf32>, %arg1: tensor<1x8x8x128xf32>) -> tensor // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 4 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/metadata.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/metadata.mlir index 560d849ece3..8d2f63a8f15 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/metadata.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/metadata.mlir @@ -20,6 +20,8 @@ module attributes { // CHECK-NEXT: data: [ 118, 97, 108, 117, 101, 49 ] // CHECK-NEXT: }, { // CHECK-NEXT: data: [ 118, 97, 108, 117, 101, 50 ] +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 54, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] // CHECK-NEXT: } ], // CHECK-NEXT: metadata: [ { // CHECK-NEXT: name: "key1", @@ -27,4 +29,8 @@ module attributes { // CHECK-NEXT: }, { // CHECK-NEXT: name: "key2", // CHECK-NEXT: buffer: 5 +// CHECK-NEXT: }, { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 6 // CHECK-NEXT: } ] +// CHECK-NEXT: } diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/mul_v2.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/mul_v2.mlir index 2f77163e7a9..3879fc3f1aa 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/mul_v2.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/mul_v2.mlir @@ -58,6 +58,12 @@ func @main(tensor<3x!quant.uniform<i8:f32, 0.1>>) -> tensor<3x!quant.uniform<i8: // CHECK-NEXT: data: [ 2, 2, 2 ] // CHECK-NEXT: }, { // CHECK-EMPTY: + // CHECK-NEXT: }, { + // CHECK-NEXT: data: [ 49, 46, 49, 52, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + // CHECK-NEXT: } ], + // CHECK-NEXT: metadata: [ { + // CHECK-NEXT: name: "min_runtime_version", + // CHECK-NEXT: buffer: 4 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/mul_v3.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/mul_v3.mlir index ea7dca7871e..f659395d4a1 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/mul_v3.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/mul_v3.mlir @@ -58,6 +58,12 @@ func @main(tensor<3x!quant.uniform<i8:f32, 1.0>>) -> tensor<3x!quant.uniform<i8: // CHECK-NEXT: data: [ 2, 2, 2 ] // CHECK-NEXT: }, { // CHECK-EMPTY: + // CHECK-NEXT: }, { + // CHECK-NEXT: data: [ 49, 46, 49, 53, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + // CHECK-NEXT: } ], + // CHECK-NEXT: metadata: [ { + // CHECK-NEXT: name: "min_runtime_version", + // CHECK-NEXT: buffer: 4 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/nn.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/nn.mlir index 6c63e69ab2f..402bbabf0c5 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/nn.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/nn.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s func @main(tensor<1x6x6x16xf32>) -> tensor<1x1x1x16xf32> { ^bb0(%arg0: tensor<1x6x6x16xf32>): @@ -47,6 +47,12 @@ func @main(tensor<1x6x6x16xf32>) -> tensor<1x1x1x16xf32> { // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: + // CHECK-NEXT: }, { + // CHECK-NEXT: data: [ 49, 46, 53, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + // CHECK-NEXT: } ], + // CHECK-NEXT: metadata: [ { + // CHECK-NEXT: name: "min_runtime_version", + // CHECK-NEXT: buffer: 3 // CHECK-NEXT: } ] // CHECK-NEXT: } diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/numeric_verify.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/numeric_verify.mlir index 8b2f6ea8b0e..f7830acabf7 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/numeric_verify.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/numeric_verify.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s // CHECK: { // CHECK-NEXT: version: 3, @@ -40,6 +40,12 @@ // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 3 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/quantization.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/quantization.mlir index 7d9b113de65..c50857fa2ea 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/quantization.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/quantization.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s func @main(%arg0: tensor<1x224x224x3xf32>) -> tensor<1x1001xf32> { // CHECK: { @@ -153,6 +153,12 @@ func @main(%arg0: tensor<1x224x224x3xf32>) -> tensor<1x1001xf32> { // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 49, 51, 46, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 10 // CHECK-NEXT: } ] // CHECK-NEXT:} diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/reshape.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/reshape.mlir index c019cf12f05..6ef628229a4 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/reshape.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/reshape.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s func @main(tensor<3x2xi32>) -> tensor<6xi32> { ^bb0(%arg0: tensor<3x2xi32>): @@ -51,6 +51,12 @@ func @main(tensor<3x2xi32>) -> tensor<6xi32> { // CHECK-NEXT: data: [ 6, 0, 0, 0 ] // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 53, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 4 // CHECK-NEXT: } ] // CHECK-NEXT: } diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/simple.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/simple.mlir index ee731c383f3..148039a1b41 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/simple.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/simple.mlir @@ -97,6 +97,12 @@ func @main(tensor<3x2xi32>) -> tensor<3x2xi32> // CHECK-NEXT: data: [ 10, 0, 0, 0 ] // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 54, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 6 // CHECK-NEXT: } ] // CHECK-NEXT: } diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/svdf.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/svdf.mlir index db9668b8e30..559f3745149 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/svdf.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/svdf.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s func @main(tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>) -> tensor<4 x f32> { // CHECK: { @@ -79,6 +79,12 @@ func @main(tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>) - // CHECK-NEXT: data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 53, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 7 // CHECK-NEXT: } ] // CHECK-NEXT: } // CHECK-EMPTY: diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/svdf_v2.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/svdf_v2.mlir index 8967822e234..ebfd1807280 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/svdf_v2.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/svdf_v2.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s func @main(tensor<4 x f32>, tensor<4 x i8>, tensor<4 x f32>, tensor<4 x f32>) -> tensor<4 x f32> { // CHECK: { @@ -80,6 +80,12 @@ func @main(tensor<4 x f32>, tensor<4 x i8>, tensor<4 x f32>, tensor<4 x f32>) -> // CHECK-NEXT: data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 49, 52, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 7 // CHECK-NEXT: } ] // CHECK-NEXT: } // CHECK-EMPTY: diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/tfl_while_op.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/tfl_while_op.mlir index 3ed6e43479e..bb9278c0d87 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/tfl_while_op.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/tfl_while_op.mlir @@ -189,6 +189,12 @@ // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 49, 52, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 14 // CHECK-NEXT: } ] // CHECK-NEXT: } diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/unidirectional_sequence_lstm.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/unidirectional_sequence_lstm.mlir index 019c96cab6c..8e579421b0b 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/unidirectional_sequence_lstm.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/unidirectional_sequence_lstm.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s func @main(tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>) -> tensor<4 x f32> { // CHECK: { @@ -249,6 +249,12 @@ func @main(tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, t // CHECK-NEXT: data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 49, 51, 46, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 26 // CHECK-NEXT: } ] // CHECK-NEXT: } // CHECK-EMPTY: diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/unidirectional_sequence_rnn.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/unidirectional_sequence_rnn.mlir index 88e31b2cf78..7ba24bd5c51 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/unidirectional_sequence_rnn.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/unidirectional_sequence_rnn.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s func @main(tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>) -> tensor<4 x f32> { // CHECK: { @@ -79,6 +79,12 @@ func @main(tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>, tensor<4 x f32>) - // CHECK-NEXT: data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 49, 52, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 7 // CHECK-NEXT: } ] // CHECK-NEXT: } // CHECK-EMPTY: diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/while_op.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/while_op.mlir index 58f19b66370..b40c9fb2044 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/while_op.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/while_op.mlir @@ -1,4 +1,4 @@ -// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck %s +// RUN: flatbuffer_translate -mlir-to-tflite-flatbuffer %s -o - | flatbuffer_to_string - | FileCheck --dump-input-on-failure %s // CHECK: { // CHECK-NEXT: version: 3, @@ -189,6 +189,12 @@ // CHECK-EMPTY: // CHECK-NEXT: }, { // CHECK-EMPTY: +// CHECK-NEXT: }, { +// CHECK-NEXT: data: [ 49, 46, 49, 52, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] +// CHECK-NEXT: } ], +// CHECK-NEXT: metadata: [ { +// CHECK-NEXT: name: "min_runtime_version", +// CHECK-NEXT: buffer: 14 // CHECK-NEXT: } ] // CHECK-NEXT: } diff --git a/tensorflow/lite/g3doc/guide/ops_version.md b/tensorflow/lite/g3doc/guide/ops_version.md index 1273ed306e6..46df25f7018 100644 --- a/tensorflow/lite/g3doc/guide/ops_version.md +++ b/tensorflow/lite/g3doc/guide/ops_version.md @@ -163,7 +163,7 @@ execute the op. In this example, it means: * Populate version=2 otherwise. To do this, you need to override `GetVersion` function for the operator class in -`lite/toco/tflite/operator.cc`. +`lite/tools/versioning/op_version.cc`. For ops with only one version, the `GetVersion` function is defined as: @@ -191,7 +191,8 @@ The last step is to add the new version info into the operator version map. This step is required because we need generate the model's minimum required runtime version based on this version map. -To do this, you need to add a new map entry in `lite/toco/tflite/op_version.cc`. +To do this, you need to add a new map entry in +`lite/tools/versioning/op_version.cc`. In this example, it means you need to add the following into `op_version_map`: ``` diff --git a/tensorflow/lite/kernels/BUILD b/tensorflow/lite/kernels/BUILD index 042a8511f8d..57e9b876ec1 100644 --- a/tensorflow/lite/kernels/BUILD +++ b/tensorflow/lite/kernels/BUILD @@ -182,7 +182,7 @@ cc_library( "//tensorflow/lite/testing:util", "//tensorflow/lite/tools/optimize:quantization_utils", "//tensorflow/lite/tools/optimize/sparsity:format_converter", - "//tensorflow/lite/tools/versioning:op_version", + "//tensorflow/lite/tools/versioning", "@com_google_googletest//:gtest", ], ) diff --git a/tensorflow/lite/model.cc b/tensorflow/lite/model.cc index ab1d3d7b66c..bb08976c73e 100644 --- a/tensorflow/lite/model.cc +++ b/tensorflow/lite/model.cc @@ -225,8 +225,20 @@ string FlatBufferModel::GetMinimumRuntime() const { auto buf = metadata->buffer(); auto* buffer = (*model_->buffers())[buf]; auto* array = buffer->data(); - return string(reinterpret_cast<const char*>(array->data()), - array->size()); + // Get the real length of the runtime string, since there might be + // trailing + // '\0's in the buffer. + for (int len = 0; len < array->size(); ++len) { + if (array->data()[len] == '\0') { + return string(reinterpret_cast<const char*>(array->data()), len); + } + } + // If there is no '\0' in the buffer, this indicates that the flatbuffer + // is malformed. + TF_LITE_REPORT_ERROR( + error_reporter_, + "Min_runtime_version in model metadata is malformed"); + break; } } return ""; diff --git a/tensorflow/lite/model_test.cc b/tensorflow/lite/model_test.cc index d843037e757..b9efdf676a8 100644 --- a/tensorflow/lite/model_test.cc +++ b/tensorflow/lite/model_test.cc @@ -366,7 +366,7 @@ TEST(BasicFlatBufferModel, TestReadRuntimeVersionFromModel) { "tensorflow/lite/testdata/test_min_runtime.bin"); ASSERT_TRUE(model2); // Check that we have read the runtime string correctly. - ASSERT_EQ(model2->GetMinimumRuntime(), "1.10.0"); + ASSERT_EQ(model2->GetMinimumRuntime(), "1.5.0"); } // The test model has the following tensor encoded in the TACO format: diff --git a/tensorflow/lite/testdata/test_min_runtime.bin b/tensorflow/lite/testdata/test_min_runtime.bin index c68174390dea75e6fbfbf67d7ee18cc82a3eadd8..567d7d1ff8860822ec75fc22177fd19c43a429d3 100644 GIT binary patch literal 536 zcmZ9JKTE@45Qk5Vw$xIKb;yvRqk{zNA8_cP2!c>Sq<ayP;T`f;YU=Fh;NYk5lQ@bv zIQU_N`26x#1z&h_m&@Jn?%pJ3Ha;8en{8TRku|MtUE3lW6ERzX1K5T~Xu=Mx!sn9N z2fV{8ToS|B!@|bA=)DcnmAdLh1U)F6pUmdIbVWY7%V)Q4>WQwA6Y&grUF;w|On0$A zX9MSAbbi%8oqFoZJWGjmnEG#r4v`^f-acq6^%cdnQ=@vmqlI0@3LVX@-Cy7y#vpxZ zXqN`JBz?|$%tJd$_qeJm)&AEqYt?%ztHpQaJd>+h_0gS3TmDIw)!%XLiJUh`@TI9d r`MMkDZ|3D*(2|~ROf!Tz<%PegIaQ+^)vM=k{UF2%*%y5x6jb>Q0v0r8 literal 580 zcmYk3%}T>i5QWDYn}DSj&7xozS-5Z^p+z4+2)GcTf?c>PVgd~`iS);<ui!(taOI=9 za^cE&zMED|ICt*My=Ugk+<}=*u5QlF4sBqb1=g{ig^KnSG20b_7M|(c>`d^49bvYy zud)ZiWSoqnq$;1Y#VSi<+f(d9I2GXc1h}7dT}QI_KXv^rn6*{c(`t69#7~N`AH}0# zJe05dfqb|}LXnr##kySOMK)EfWnPt19qPPM-_e~&pbL0k0(#Ykv+U{XP2fBgJ~o<M zzw%Fnec^Wg@R-f2d73T$a!`d@aJM~?)9fW_Ec>ogL<J_=RfHL!0Up|@b+<0G(p%g0 z2d}Ri{^lLv>1#22a>FGLv(>1VD_P>;T|F=(K78(lZbgIdv=X7VzGHHtpI-m-(72tI TwmRc)ax&ZIy?pmxa;|>?*oiu! diff --git a/tensorflow/lite/toco/tflite/BUILD b/tensorflow/lite/toco/tflite/BUILD index 43cb88de4f6..d34f38a6863 100644 --- a/tensorflow/lite/toco/tflite/BUILD +++ b/tensorflow/lite/toco/tflite/BUILD @@ -32,7 +32,7 @@ cc_library( "//tensorflow/lite/schema:schema_fbs", "//tensorflow/lite/toco:graph_transformations", "//tensorflow/lite/toco:model", - "//tensorflow/lite/tools/versioning:op_version", + "//tensorflow/lite/tools/versioning", "@com_google_absl//absl/memory", "@flatbuffers", ], @@ -147,6 +147,7 @@ cc_library( ":operator", "//tensorflow/lite/toco:model", "//tensorflow/lite/toco:tooling_util", + "//tensorflow/lite/tools/versioning", "@com_google_absl//absl/strings", ], ) diff --git a/tensorflow/lite/toco/tflite/op_version.cc b/tensorflow/lite/toco/tflite/op_version.cc index 09150d23f37..f217a4215e4 100644 --- a/tensorflow/lite/toco/tflite/op_version.cc +++ b/tensorflow/lite/toco/tflite/op_version.cc @@ -22,27 +22,13 @@ limitations under the License. #include "tensorflow/lite/toco/model.h" #include "tensorflow/lite/toco/tflite/operator.h" #include "tensorflow/lite/toco/tooling_util.h" +#include "tensorflow/lite/tools/versioning/runtime_version.h" namespace toco { namespace tflite { -bool CompareVersion(const string& v1, const string& v2) { - const std::vector<string>& vec1 = absl::StrSplit(v1, '.'); - const std::vector<string>& vec2 = absl::StrSplit(v2, '.'); - int i = 0; - while (i < vec1.size() && i < vec2.size()) { - int v1_val, v2_val; - if (absl::SimpleAtoi(vec1[i], &v1_val) && - absl::SimpleAtoi(vec2[i], &v2_val)) { - if (v1_val != v2_val) return v1_val < v2_val; - } - ++i; - } - // If there are remaining items in v2 not being compared, then v1 should - // precede v2. - return i < vec2.size(); -} - +// Deprecated and please register new ops/versions in +// tflite/tools/versioning/op_version.cc". string GetMinimumRuntimeVersionForModel(const Model& model) { // Use this as the placeholder string if a particular op is not yet included // in any Tensorflow's RC/Final release source package. Once that op is @@ -253,7 +239,7 @@ string GetMinimumRuntimeVersionForModel(const Model& model) { // doesn't have a minimum runtime version associated, continue. continue; } - if (CompareVersion(model_min_version, it->second)) { + if (::tflite::CompareRuntimeVersion(model_min_version, it->second)) { // Current min model runtime version should be bumped if we see a higher // op version. model_min_version = it->second; diff --git a/tensorflow/lite/toco/tflite/op_version.h b/tensorflow/lite/toco/tflite/op_version.h index 7b644c19db1..54a77501b14 100644 --- a/tensorflow/lite/toco/tflite/op_version.h +++ b/tensorflow/lite/toco/tflite/op_version.h @@ -20,11 +20,6 @@ limitations under the License. namespace toco { namespace tflite { -// Returns true if the first version string precedes the second. -// For example, '1.14' should precede '1.9', also '1.14.1' should precede -// '1.14'. If two version string is equal, then false will be returned. -bool CompareVersion(const string&, const string&); - // Get the minimum TF Lite runtime required to run a model. Each built-in // operator in the model will have its own minimum requirement of a runtime, and // the model's minimum requirement of runtime is defined as the maximum of all diff --git a/tensorflow/lite/toco/tflite/op_version_test.cc b/tensorflow/lite/toco/tflite/op_version_test.cc index 0d34b199735..14b086471b7 100644 --- a/tensorflow/lite/toco/tflite/op_version_test.cc +++ b/tensorflow/lite/toco/tflite/op_version_test.cc @@ -22,6 +22,7 @@ namespace toco { namespace tflite { namespace { +// TODO(b/150701120): port the tests to tools/versioning/op_version_test.cc. TEST(OpVersionTest, MinimumVersionForSameOpVersions) { Model model; // Float convolutional kernel is introduced since '1.5.0'. @@ -138,18 +139,6 @@ TEST(OpVersionTest, MinimumVersionForMixedOpVersions) { EXPECT_EQ(GetMinimumRuntimeVersionForModel(model), "1.10.0"); } -TEST(OpVersionTest, CompareVersionString) { - EXPECT_TRUE(CompareVersion("1.9", "1.13")); - EXPECT_FALSE(CompareVersion("1.13", "1.13")); - EXPECT_TRUE(CompareVersion("1.14", "1.14.1")); - EXPECT_FALSE(CompareVersion("1.14.1", "1.14")); - EXPECT_FALSE(CompareVersion("1.14.1", "1.9")); - EXPECT_FALSE(CompareVersion("1.0.9", "1.0.8")); - EXPECT_FALSE(CompareVersion("2.1.0", "1.2.0")); - EXPECT_TRUE(CompareVersion("", "1.13")); - EXPECT_FALSE(CompareVersion("", "")); -} - } // namespace } // namespace tflite } // namespace toco diff --git a/tensorflow/lite/tools/versioning/BUILD b/tensorflow/lite/tools/versioning/BUILD index 2958ccfd232..1ba221d3fa9 100644 --- a/tensorflow/lite/tools/versioning/BUILD +++ b/tensorflow/lite/tools/versioning/BUILD @@ -9,14 +9,20 @@ package( ) cc_library( - name = "op_version", - srcs = ["op_version.cc"], + name = "versioning", + srcs = [ + "op_version.cc", + "runtime_version.cc", + ], hdrs = [ "op_version.h", + "runtime_version.h", ], deps = [ "//tensorflow/core:tflite_portable_logging", + "//tensorflow/lite:minimal_logging", "//tensorflow/lite/kernels/internal:compatibility", + "//tensorflow/lite/schema:schema_fbs", "//tensorflow/lite/schema:schema_fbs_with_mutable", "@com_google_absl//absl/memory", "@com_google_absl//absl/strings", @@ -25,10 +31,13 @@ cc_library( ) tf_cc_test( - name = "op_version_test", - srcs = ["op_version_test.cc"], + name = "versioning_test", + srcs = [ + "op_version_test.cc", + "runtime_version_test.cc", + ], deps = [ - ":op_version", + ":versioning", "//tensorflow/lite/schema:schema_fbs_with_mutable", "@com_google_googletest//:gtest_main", ], diff --git a/tensorflow/lite/tools/versioning/runtime_version.cc b/tensorflow/lite/tools/versioning/runtime_version.cc new file mode 100644 index 00000000000..fda074fabdf --- /dev/null +++ b/tensorflow/lite/tools/versioning/runtime_version.cc @@ -0,0 +1,285 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/tools/versioning/runtime_version.h" + +#include <cstring> + +#include "absl/strings/numbers.h" +#include "absl/strings/str_split.h" +#include "tensorflow/lite/minimal_logging.h" +#include "tensorflow/lite/schema/mutable/schema_generated.h" + +namespace tflite { + +bool CompareRuntimeVersion(const std::string& v1, const std::string& v2) { + const std::vector<std::string> vec1 = absl::StrSplit(v1, '.'); + const std::vector<std::string> vec2 = absl::StrSplit(v2, '.'); + int i = 0; + while (i < vec1.size() && i < vec2.size()) { + int v1_val, v2_val; + if (absl::SimpleAtoi(vec1[i], &v1_val) && + absl::SimpleAtoi(vec2[i], &v2_val)) { + if (v1_val != v2_val) return v1_val < v2_val; + } + ++i; + } + // If there are remaining items in v2 not being compared, then v1 should + // precede v2. + return i < vec2.size(); +} + +void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) { + // Use this as the placeholder string if a particular op is not yet included + // in any Tensorflow's RC/Final release source package. Once that op is + // included in the release, please update this with the real version string. + static constexpr char kPendingReleaseOpVersion[] = "UNKNOWN"; + // A map from the version key of an op to its minimum runtime version. + // For example, {{kAveragePool, 1}, "1.5.0"}, means the 1st version of + // AveragePool requires a minimum TF Lite runtime version '1.5.0`. + static const std::map<std::pair<BuiltinOperator, int>, std::string>* + op_version_map = + new std::map<std::pair<BuiltinOperator, int>, std::string>({ + {{BuiltinOperator_AVERAGE_POOL_2D, 1}, "1.5.0"}, + {{BuiltinOperator_AVERAGE_POOL_2D, 2}, "1.14.0"}, + {{BuiltinOperator_CONV_2D, 1}, "1.5.0"}, + {{BuiltinOperator_CONV_2D, 2}, "1.14.0"}, + {{BuiltinOperator_CONV_2D, 3}, "1.14.0"}, + {{BuiltinOperator_DEPTHWISE_CONV_2D, 1}, "1.5.0"}, + {{BuiltinOperator_DEPTHWISE_CONV_2D, 2}, "1.12.0"}, + {{BuiltinOperator_DEPTHWISE_CONV_2D, 3}, "1.14.0"}, + {{BuiltinOperator_ADD, 1}, "1.5.0"}, + {{BuiltinOperator_ADD, 2}, "1.14.0"}, + {{BuiltinOperator_ADD_N, 1}, "1.14.0"}, + {{BuiltinOperator_SPACE_TO_BATCH_ND, 1}, "1.6.0"}, + {{BuiltinOperator_SPACE_TO_BATCH_ND, 2}, "1.14.0"}, + {{BuiltinOperator_SUB, 1}, "1.6.0"}, + {{BuiltinOperator_SUB, 2}, "1.14.0"}, + {{BuiltinOperator_DIV, 1}, "1.6.0"}, + {{BuiltinOperator_BATCH_TO_SPACE_ND, 1}, "1.6.0"}, + {{BuiltinOperator_BATCH_TO_SPACE_ND, 2}, "1.14.0"}, + {{BuiltinOperator_CAST, 1}, "1.5.0"}, + {{BuiltinOperator_CONCATENATION, 1}, "1.5.0"}, + {{BuiltinOperator_CONCATENATION, 2}, "1.14.0"}, + {{BuiltinOperator_DEPTH_TO_SPACE, 1}, "2.1.0"}, + {{BuiltinOperator_FAKE_QUANT, 1}, "1.5.0"}, + {{BuiltinOperator_FAKE_QUANT, 2}, "1.10.0"}, + {{BuiltinOperator_FULLY_CONNECTED, 1}, "1.5.0"}, + {{BuiltinOperator_FULLY_CONNECTED, 2}, "1.10.0"}, + {{BuiltinOperator_FULLY_CONNECTED, 3}, "1.14.0"}, + {{BuiltinOperator_FULLY_CONNECTED, 4}, "1.14.0"}, + {{BuiltinOperator_FULLY_CONNECTED, 5}, "2.0.0"}, + {{BuiltinOperator_FULLY_CONNECTED, 6}, "2.1.0"}, + {{BuiltinOperator_GATHER, 1}, "1.6.0"}, + {{BuiltinOperator_GATHER, 2}, "1.14.0"}, + {{BuiltinOperator_GATHER, 3}, "1.15.0"}, + {{BuiltinOperator_GATHER_ND, 1}, "1.14.0"}, + {{BuiltinOperator_SVDF, 1}, "1.5.0"}, + {{BuiltinOperator_SVDF, 2}, "1.14.0"}, + {{BuiltinOperator_SVDF, 3}, "2.2.0"}, + {{BuiltinOperator_L2_NORMALIZATION, 1}, "1.5.0"}, + {{BuiltinOperator_L2_NORMALIZATION, 2}, "1.14.0"}, + {{BuiltinOperator_L2_POOL_2D, 1}, "1.5.0"}, + {{BuiltinOperator_LOCAL_RESPONSE_NORMALIZATION, 1}, "1.5.0"}, + {{BuiltinOperator_MAX_POOL_2D, 1}, "1.5.0"}, + {{BuiltinOperator_MAX_POOL_2D, 2}, "1.14.0"}, + {{BuiltinOperator_MAXIMUM, 1}, "1.14.0"}, + {{BuiltinOperator_MAXIMUM, 2}, "1.14.0"}, + {{BuiltinOperator_MINIMUM, 1}, "1.14.0"}, + {{BuiltinOperator_MINIMUM, 2}, "1.14.0"}, + {{BuiltinOperator_MUL, 1}, "1.5.0"}, + {{BuiltinOperator_MUL, 2}, "1.14.0"}, + {{BuiltinOperator_MUL, 3}, "1.15.0"}, + {{BuiltinOperator_PAD, 1}, "1.5.0"}, + {{BuiltinOperator_PAD, 2}, "1.14.0"}, + {{BuiltinOperator_TILE, 1}, "1.10.1"}, + {{BuiltinOperator_TILE, 2}, "2.2.0"}, + {{BuiltinOperator_PADV2, 1}, "1.9.0"}, + {{BuiltinOperator_PADV2, 2}, "1.14.0"}, + {{BuiltinOperator_RESHAPE, 1}, "1.5.0"}, + {{BuiltinOperator_SOFTMAX, 1}, "1.5.0"}, + {{BuiltinOperator_SOFTMAX, 2}, "1.14.0"}, + {{BuiltinOperator_SPACE_TO_DEPTH, 1}, "1.5.0"}, + {{BuiltinOperator_SPACE_TO_DEPTH, 2}, "1.14.0"}, + {{BuiltinOperator_TRANSPOSE, 1}, "1.6.0"}, + {{BuiltinOperator_TRANSPOSE, 2}, "1.14.0"}, + {{BuiltinOperator_TRANSPOSE, 3}, "1.15.0"}, + {{BuiltinOperator_LSTM, 1}, "1.7.0"}, + {{BuiltinOperator_LSTM, 2}, "1.10.0"}, + {{BuiltinOperator_LSTM, 3}, "1.14.0"}, + {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_LSTM, 1}, "1.13.1"}, + {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_LSTM, 1}, "1.14.0"}, + {{BuiltinOperator_BIDIRECTIONAL_SEQUENCE_LSTM, 1}, "1.14.0"}, + {{BuiltinOperator_BIDIRECTIONAL_SEQUENCE_RNN, 1}, "1.14.0"}, + {{BuiltinOperator_MEAN, 1}, "1.6.0"}, + {{BuiltinOperator_MEAN, 2}, "1.14.0"}, + {{BuiltinOperator_SUM, 1}, "1.10.0"}, + {{BuiltinOperator_SUM, 2}, "1.15.0"}, + {{BuiltinOperator_REDUCE_MAX, 1}, "1.11.0"}, + {{BuiltinOperator_REDUCE_MAX, 2}, "1.14.0"}, + {{BuiltinOperator_REDUCE_MIN, 1}, "1.11.0"}, + {{BuiltinOperator_REDUCE_MIN, 2}, "1.14.0"}, + {{BuiltinOperator_REDUCE_PROD, 1}, "1.11.0"}, + {{BuiltinOperator_REDUCE_ANY, 1}, "1.11.0"}, + {{BuiltinOperator_RELU6, 1}, "1.5.0"}, + {{BuiltinOperator_RELU6, 2}, "1.14.0"}, + {{BuiltinOperator_RESIZE_BILINEAR, 1}, "1.7.0"}, + {{BuiltinOperator_RESIZE_BILINEAR, 2}, "1.14.0"}, + {{BuiltinOperator_RESIZE_BILINEAR, 3}, "2.2.0"}, + {{BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 1}, "1.13.1"}, + {{BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 2}, "1.14.0"}, + {{BuiltinOperator_SQUEEZE, 1}, "1.6.0"}, + {{BuiltinOperator_SPLIT, 1}, "1.5.0"}, + {{BuiltinOperator_SPLIT, 2}, "1.14.0"}, + {{BuiltinOperator_SPLIT, 3}, "1.14.0"}, + {{BuiltinOperator_SPLIT_V, 1}, "1.13.1"}, + {{BuiltinOperator_STRIDED_SLICE, 1}, "1.6.0"}, + {{BuiltinOperator_STRIDED_SLICE, 2}, "1.14.0"}, + {{BuiltinOperator_STRIDED_SLICE, 3}, "2.1.0"}, + {{BuiltinOperator_TOPK_V2, 1}, "1.7.0"}, + {{BuiltinOperator_TOPK_V2, 2}, "1.14.0"}, + {{BuiltinOperator_ARG_MAX, 1}, "1.9.0"}, + {{BuiltinOperator_ARG_MAX, 2}, "1.14.0"}, + {{BuiltinOperator_ARG_MIN, 1}, "1.9.0"}, + {{BuiltinOperator_ARG_MIN, 2}, "1.14.0"}, + {{BuiltinOperator_TRANSPOSE_CONV, 1}, "1.9.0"}, + {{BuiltinOperator_SPARSE_TO_DENSE, 1}, "1.9.0"}, + {{BuiltinOperator_SPARSE_TO_DENSE, 2}, "1.14.0"}, + {{BuiltinOperator_SPARSE_TO_DENSE, 3}, "1.15.0"}, + {{BuiltinOperator_EXPAND_DIMS, 1}, "1.10.0"}, + {{BuiltinOperator_PACK, 1}, "1.11.0"}, + {{BuiltinOperator_PACK, 2}, "1.14.0"}, + {{BuiltinOperator_SHAPE, 1}, "1.10.0"}, + {{BuiltinOperator_SLICE, 1}, "1.14.0"}, + {{BuiltinOperator_SLICE, 2}, "1.14.0"}, + {{BuiltinOperator_SLICE, 3}, "1.14.0"}, + {{BuiltinOperator_TANH, 1}, "1.14.0"}, + {{BuiltinOperator_TANH, 2}, "1.14.0"}, + {{BuiltinOperator_ONE_HOT, 1}, "1.11.0"}, + {{BuiltinOperator_UNPACK, 1}, "1.11.0"}, + {{BuiltinOperator_UNPACK, 2}, "1.14.0"}, + {{BuiltinOperator_UNPACK, 3}, "2.2.0"}, + {{BuiltinOperator_LEAKY_RELU, 1}, "1.13.1"}, + {{BuiltinOperator_LOGISTIC, 1}, "1.14.0"}, + {{BuiltinOperator_LOGISTIC, 2}, "1.14.0"}, + {{BuiltinOperator_LOG_SOFTMAX, 1}, "1.14.0"}, + {{BuiltinOperator_LOG_SOFTMAX, 2}, "1.14.0"}, + {{BuiltinOperator_SQUARED_DIFFERENCE, 1}, "1.13.1"}, + {{BuiltinOperator_MIRROR_PAD, 1}, "1.13.1"}, + {{BuiltinOperator_UNIQUE, 1}, "1.14.0"}, + {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_RNN, 1}, "1.14.0"}, + {{BuiltinOperator_WHERE, 1}, "1.14.0"}, + {{BuiltinOperator_DEQUANTIZE, 1}, "1.13.1"}, + {{BuiltinOperator_DEQUANTIZE, 2}, "1.14.0"}, + {{BuiltinOperator_DEQUANTIZE, 3}, "1.15.0"}, + {{BuiltinOperator_REVERSE_SEQUENCE, 1}, "1.14.0"}, + {{BuiltinOperator_EQUAL, 1}, "1.14.0"}, + {{BuiltinOperator_EQUAL, 2}, "1.14.0"}, + {{BuiltinOperator_NOT_EQUAL, 1}, "1.14.0"}, + {{BuiltinOperator_NOT_EQUAL, 2}, "1.14.0"}, + {{BuiltinOperator_GREATER, 1}, "1.14.0"}, + {{BuiltinOperator_GREATER, 2}, "1.14.0"}, + {{BuiltinOperator_GREATER_EQUAL, 1}, "1.14.0"}, + {{BuiltinOperator_GREATER_EQUAL, 2}, "1.14.0"}, + {{BuiltinOperator_LESS, 1}, "1.14.0"}, + {{BuiltinOperator_LESS, 2}, "1.14.0"}, + {{BuiltinOperator_LESS_EQUAL, 1}, "1.14.0"}, + {{BuiltinOperator_LESS_EQUAL, 2}, "1.14.0"}, + {{BuiltinOperator_SEGMENT_SUM, 1}, "2.2.0"}, + {{BuiltinOperator_SELECT, 1}, "1.14.0"}, + {{BuiltinOperator_SELECT, 2}, "1.14.0"}, + {{BuiltinOperator_SELECT_V2, 1}, "2.2.0"}, + {{BuiltinOperator_FLOOR_DIV, 1}, "1.14.0"}, + {{BuiltinOperator_FLOOR_DIV, 2}, "1.14.0"}, + {{BuiltinOperator_FLOOR, 1}, "1.9.0"}, + {{BuiltinOperator_CEIL, 1}, "1.14.0"}, + {{BuiltinOperator_MATRIX_DIAG, 1}, "1.14.0"}, + {{BuiltinOperator_MATRIX_SET_DIAG, 1}, "1.14.0"}, + {{BuiltinOperator_ELU, 1}, "1.14.0"}, + {{BuiltinOperator_ROUND, 1}, "1.14.0"}, + {{BuiltinOperator_RELU, 1}, "1.5.0"}, + {{BuiltinOperator_RELU, 2}, "2.1.0"}, + {{BuiltinOperator_RELU_N1_TO_1, 1}, "1.5.0"}, + {{BuiltinOperator_PRELU, 1}, "1.8.0"}, + {{BuiltinOperator_EXP, 1}, "1.7.0"}, + {{BuiltinOperator_COS, 1}, "1.14.0"}, + {{BuiltinOperator_NEG, 1}, "1.9.0"}, + {{BuiltinOperator_POW, 1}, "1.10.0"}, + {{BuiltinOperator_LOGICAL_OR, 1}, "1.11.0"}, + {{BuiltinOperator_LOGICAL_AND, 1}, "1.11.0"}, + {{BuiltinOperator_LOGICAL_NOT, 1}, "1.11.0"}, + {{BuiltinOperator_FLOOR_MOD, 1}, "1.13.0"}, + {{BuiltinOperator_RANGE, 1}, "1.13.0"}, + {{BuiltinOperator_SIN, 1}, "1.9.0"}, + {{BuiltinOperator_LOG, 1}, "1.14.0"}, + {{BuiltinOperator_RSQRT, 1}, "1.10.0"}, + {{BuiltinOperator_SQUARE, 1}, "1.12.0"}, + {{BuiltinOperator_ZEROS_LIKE, 1}, "1.12.0"}, + {{BuiltinOperator_ABS, 1}, "1.13.0"}, + {{BuiltinOperator_HARD_SWISH, 1}, "1.15.0"}, + {{BuiltinOperator_FILL, 1}, "1.13.0"}, + {{BuiltinOperator_REVERSE_V2, 1}, "1.14.0"}, + {{BuiltinOperator_REVERSE_V2, 2}, "2.2.0"}, + {{BuiltinOperator_RANK, 1}, "1.14.0"}, + }); + + auto model = GetMutableModel(model_buffer_pointer); + std::string model_min_version; + auto subgraphs = model->subgraphs(); + for (int i = 0; i < subgraphs->Length(); ++i) { + const SubGraph* subgraph = subgraphs->Get(i); + for (int j = 0; j < subgraph->operators()->Length(); ++j) { + const Operator* op = subgraph->operators()->Get(j); + const OperatorCode* op_code = + model->operator_codes()->Get(op->opcode_index()); + std::pair<BuiltinOperator, int> version_key = {op_code->builtin_code(), + op_code->version()}; + auto it = op_version_map->find(version_key); + if (it == op_version_map->end() || + it->second == kPendingReleaseOpVersion) { + // In case we didn't find the current op in the map, or the operator + // doesn't have a minimum runtime version associated, continue. + continue; + } + if (CompareRuntimeVersion(model_min_version, it->second)) { + // Current min model runtime version should be bumped if we see a higher + // op version. + model_min_version = it->second; + } + } + } + // The size of the `min_runtime_version` metadata buffer is 16 bytes. If the + // generated `model_min_version` is equal or longer than 16 bytes, print a + // warning message and return. + if (model_min_version.size() >= 16) { + TFLITE_LOG(TFLITE_LOG_WARNING, + "Skip writing minimum runtime version string since it's " + "longer than 16 bytes."); + return; + } + // Copy over the bytes from `model_min_version` into the buffer. + for (int i = 0; i < model->metadata()->size(); ++i) { + if (model->metadata()->Get(i)->name()->str() == "min_runtime_version") { + auto buffer = model->metadata()->Get(i)->buffer(); + auto buffer_data = + model->mutable_buffers()->GetMutableObject(buffer)->mutable_data(); + memset(buffer_data->data(), 0, buffer_data->size()); + memcpy(buffer_data->data(), model_min_version.data(), + model_min_version.size()); + break; + } + } +} + +} // namespace tflite diff --git a/tensorflow/lite/tools/versioning/runtime_version.h b/tensorflow/lite/tools/versioning/runtime_version.h new file mode 100644 index 00000000000..f4889172746 --- /dev/null +++ b/tensorflow/lite/tools/versioning/runtime_version.h @@ -0,0 +1,33 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_TOOLS_VERSIONING_RUNTIME_VERSION_H_ +#define TENSORFLOW_LITE_TOOLS_VERSIONING_RUNTIME_VERSION_H_ + +#include <string> + +#include "flatbuffers/flatbuffers.h" // TF:flatbuffers + +namespace tflite { +// Update minimum runtime version of the given TFL flatbuffer model. +void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer); + +// Returns true if the first version string precedes the second. +// For example, '1.14' should precede '1.9', also '1.14.1' should precede +// '1.14'. If two version string is equal, then false will be returned. +bool CompareRuntimeVersion(const std::string&, const std::string&); + +} // namespace tflite + +#endif // TENSORFLOW_LITE_TOOLS_VERSIONING_RUNTIME_VERSION_H_ diff --git a/tensorflow/lite/tools/versioning/runtime_version_test.cc b/tensorflow/lite/tools/versioning/runtime_version_test.cc new file mode 100644 index 00000000000..c7b70552340 --- /dev/null +++ b/tensorflow/lite/tools/versioning/runtime_version_test.cc @@ -0,0 +1,34 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/tools/versioning/runtime_version.h" + +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +namespace tflite { + +TEST(OpVersionTest, CompareRuntimeVersion) { + EXPECT_TRUE(CompareRuntimeVersion("1.9", "1.13")); + EXPECT_FALSE(CompareRuntimeVersion("1.13", "1.13")); + EXPECT_TRUE(CompareRuntimeVersion("1.14", "1.14.1")); + EXPECT_FALSE(CompareRuntimeVersion("1.14.1", "1.14")); + EXPECT_FALSE(CompareRuntimeVersion("1.14.1", "1.9")); + EXPECT_FALSE(CompareRuntimeVersion("1.0.9", "1.0.8")); + EXPECT_FALSE(CompareRuntimeVersion("2.1.0", "1.2.0")); + EXPECT_TRUE(CompareRuntimeVersion("", "1.13")); + EXPECT_FALSE(CompareRuntimeVersion("", "")); +} + +} // namespace tflite