diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/if_op.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/if_op.mlir index b89ba0fe400..7290209cc4a 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/if_op.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/if_op.mlir @@ -157,7 +157,7 @@ // 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: 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", diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/quantization.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/quantization.mlir index 9bbbdca1c97..dbe10a3f90c 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/quantization.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/quantization.mlir @@ -154,7 +154,7 @@ func @main(%arg0: tensor<1x224x224x3xf32>) -> tensor<1x1001xf32> { // 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: 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", 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 1d3a70f0996..996543cc9c7 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/tfl_while_op.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/tfl_while_op.mlir @@ -190,7 +190,7 @@ // 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: 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", diff --git a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/while_op.mlir b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/while_op.mlir index a76fbbeb871..d69e8f40311 100644 --- a/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/while_op.mlir +++ b/tensorflow/compiler/mlir/lite/tests/mlir2flatbuffer/while_op.mlir @@ -190,7 +190,7 @@ // 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: 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", diff --git a/tensorflow/lite/tools/versioning/BUILD b/tensorflow/lite/tools/versioning/BUILD index 1ba221d3fa9..34d63bd9645 100644 --- a/tensorflow/lite/tools/versioning/BUILD +++ b/tensorflow/lite/tools/versioning/BUILD @@ -38,6 +38,8 @@ tf_cc_test( ], deps = [ ":versioning", + "//tensorflow/lite/kernels:builtin_ops", + "//tensorflow/lite/schema:schema_fbs", "//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 index 702f9fc7f85..92a7001606f 100644 --- a/tensorflow/lite/tools/versioning/runtime_version.cc +++ b/tensorflow/lite/tools/versioning/runtime_version.cc @@ -22,6 +22,12 @@ limitations under the License. #include "tensorflow/lite/schema/mutable/schema_generated.h" namespace tflite { +namespace { +// 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 kPendingReleaseVersion[] = "UNKNOWN"; +} // namespace bool CompareRuntimeVersion(const std::string& v1, const std::string& v2) { const std::vector vec1 = absl::StrSplit(v1, '.'); @@ -40,11 +46,8 @@ bool CompareRuntimeVersion(const std::string& v1, const std::string& 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"; +std::string FindMinimumRuntimeVersionForOp(tflite::BuiltinOperator op_code, + int op_version) { // 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`. @@ -53,27 +56,41 @@ void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) { new std::map, std::string>({ {{BuiltinOperator_AVERAGE_POOL_2D, 1}, "1.5.0"}, {{BuiltinOperator_AVERAGE_POOL_2D, 2}, "1.14.0"}, + {{BuiltinOperator_AVERAGE_POOL_2D, 3}, kPendingReleaseVersion}, + {{BuiltinOperator_BATCH_MATMUL, 1}, kPendingReleaseVersion}, {{BuiltinOperator_CONV_2D, 1}, "1.5.0"}, {{BuiltinOperator_CONV_2D, 2}, "1.14.0"}, {{BuiltinOperator_CONV_2D, 3}, "1.14.0"}, + {{BuiltinOperator_CONV_2D, 4}, kPendingReleaseVersion}, {{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_DEPTHWISE_CONV_2D, 4}, "2.2.0"}, + {{BuiltinOperator_DEPTHWISE_CONV_2D, 5}, kPendingReleaseVersion}, {{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_SPACE_TO_BATCH_ND, 3}, kPendingReleaseVersion}, {{BuiltinOperator_SUB, 1}, "1.6.0"}, {{BuiltinOperator_SUB, 2}, "1.14.0"}, + {{BuiltinOperator_SUB, 3}, kPendingReleaseVersion}, + {{BuiltinOperator_DENSIFY, 1}, "2.2.0"}, {{BuiltinOperator_DIV, 1}, "1.6.0"}, - {{BuiltinOperator_DIV, 2}, kPendingReleaseOpVersion}, + {{BuiltinOperator_DIV, 2}, kPendingReleaseVersion}, {{BuiltinOperator_BATCH_TO_SPACE_ND, 1}, "1.6.0"}, {{BuiltinOperator_BATCH_TO_SPACE_ND, 2}, "1.14.0"}, + {{BuiltinOperator_BATCH_TO_SPACE_ND, 3}, kPendingReleaseVersion}, {{BuiltinOperator_CAST, 1}, "1.5.0"}, {{BuiltinOperator_CONCATENATION, 1}, "1.5.0"}, {{BuiltinOperator_CONCATENATION, 2}, "1.14.0"}, + {{BuiltinOperator_CONCATENATION, 3}, kPendingReleaseVersion}, {{BuiltinOperator_DEPTH_TO_SPACE, 1}, "2.1.0"}, + {{BuiltinOperator_EMBEDDING_LOOKUP, 1}, "1.13.0"}, + {{BuiltinOperator_EMBEDDING_LOOKUP, 2}, "1.14.0"}, + {{BuiltinOperator_EMBEDDING_LOOKUP, 3}, "1.14.0"}, + {{BuiltinOperator_EMBEDDING_LOOKUP_SPARSE, 1}, "1.5.0"}, {{BuiltinOperator_FAKE_QUANT, 1}, "1.5.0"}, {{BuiltinOperator_FAKE_QUANT, 2}, "1.10.0"}, {{BuiltinOperator_FULLY_CONNECTED, 1}, "1.5.0"}, @@ -82,10 +99,14 @@ void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) { {{BuiltinOperator_FULLY_CONNECTED, 4}, "1.14.0"}, {{BuiltinOperator_FULLY_CONNECTED, 5}, "2.0.0"}, {{BuiltinOperator_FULLY_CONNECTED, 6}, "2.1.0"}, + {{BuiltinOperator_FULLY_CONNECTED, 7}, kPendingReleaseVersion}, + {{BuiltinOperator_FULLY_CONNECTED, 8}, kPendingReleaseVersion}, {{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_GATHER_ND, 2}, kPendingReleaseVersion}, + {{BuiltinOperator_HASHTABLE_LOOKUP, 1}, "1.5.0"}, {{BuiltinOperator_SVDF, 1}, "1.5.0"}, {{BuiltinOperator_SVDF, 2}, "1.14.0"}, {{BuiltinOperator_SVDF, 3}, "2.2.0"}, @@ -95,13 +116,21 @@ void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) { {{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_MAX_POOL_2D, 3}, kPendingReleaseVersion}, {{BuiltinOperator_MAXIMUM, 1}, "1.14.0"}, {{BuiltinOperator_MAXIMUM, 2}, "1.14.0"}, + {{BuiltinOperator_MAXIMUM, 3}, kPendingReleaseVersion}, + {{BuiltinOperator_MAXIMUM, 4}, kPendingReleaseVersion}, {{BuiltinOperator_MINIMUM, 1}, "1.14.0"}, {{BuiltinOperator_MINIMUM, 2}, "1.14.0"}, + {{BuiltinOperator_MINIMUM, 3}, kPendingReleaseVersion}, + {{BuiltinOperator_MINIMUM, 4}, kPendingReleaseVersion}, {{BuiltinOperator_MUL, 1}, "1.5.0"}, {{BuiltinOperator_MUL, 2}, "1.14.0"}, {{BuiltinOperator_MUL, 3}, "1.15.0"}, + {{BuiltinOperator_MUL, 4}, kPendingReleaseVersion}, + {{BuiltinOperator_NON_MAX_SUPPRESSION_V4, 1}, "2.1.0"}, + {{BuiltinOperator_NON_MAX_SUPPRESSION_V5, 1}, "2.1.0"}, {{BuiltinOperator_PAD, 1}, "1.5.0"}, {{BuiltinOperator_PAD, 2}, "1.14.0"}, {{BuiltinOperator_TILE, 1}, "1.10.1"}, @@ -111,18 +140,23 @@ void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) { {{BuiltinOperator_RESHAPE, 1}, "1.5.0"}, {{BuiltinOperator_SOFTMAX, 1}, "1.5.0"}, {{BuiltinOperator_SOFTMAX, 2}, "1.14.0"}, + {{BuiltinOperator_SOFTMAX, 3}, kPendingReleaseVersion}, {{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_TRANSPOSE, 4}, kPendingReleaseVersion}, {{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_UNIDIRECTIONAL_SEQUENCE_LSTM, 2}, "1.14.0"}, {{BuiltinOperator_BIDIRECTIONAL_SEQUENCE_LSTM, 1}, "1.14.0"}, + {{BuiltinOperator_BIDIRECTIONAL_SEQUENCE_LSTM, 2}, "1.14.0"}, + {{BuiltinOperator_BIDIRECTIONAL_SEQUENCE_LSTM, 3}, "1.14.0"}, {{BuiltinOperator_BIDIRECTIONAL_SEQUENCE_RNN, 1}, "1.14.0"}, + {{BuiltinOperator_BIDIRECTIONAL_SEQUENCE_RNN, 2}, "1.14.0"}, {{BuiltinOperator_MEAN, 1}, "1.6.0"}, {{BuiltinOperator_MEAN, 2}, "1.14.0"}, {{BuiltinOperator_SUM, 1}, "1.10.0"}, @@ -140,14 +174,22 @@ void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) { {{BuiltinOperator_RESIZE_BILINEAR, 3}, "2.2.0"}, {{BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 1}, "1.13.1"}, {{BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 2}, "1.14.0"}, + {{BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 3}, + kPendingReleaseVersion}, + {{BuiltinOperator_RNN, 1}, "1.5.0"}, + {{BuiltinOperator_RNN, 2}, "1.14.0"}, + {{BuiltinOperator_SKIP_GRAM, 1}, "1.5.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, 4}, kPendingReleaseVersion}, {{BuiltinOperator_SPLIT_V, 1}, "1.13.1"}, + {{BuiltinOperator_SPLIT_V, 2}, kPendingReleaseVersion}, {{BuiltinOperator_STRIDED_SLICE, 1}, "1.6.0"}, {{BuiltinOperator_STRIDED_SLICE, 2}, "1.14.0"}, {{BuiltinOperator_STRIDED_SLICE, 3}, "2.1.0"}, + {{BuiltinOperator_STRIDED_SLICE, 4}, "2.2.0"}, {{BuiltinOperator_TOPK_V2, 1}, "1.7.0"}, {{BuiltinOperator_TOPK_V2, 2}, "1.14.0"}, {{BuiltinOperator_ARG_MAX, 1}, "1.9.0"}, @@ -155,40 +197,53 @@ void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) { {{BuiltinOperator_ARG_MIN, 1}, "1.9.0"}, {{BuiltinOperator_ARG_MIN, 2}, "1.14.0"}, {{BuiltinOperator_TRANSPOSE_CONV, 1}, "1.9.0"}, + {{BuiltinOperator_TRANSPOSE_CONV, 2}, "2.2.0"}, + {{BuiltinOperator_TRANSPOSE_CONV, 3}, kPendingReleaseVersion}, {{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_PACK, 3}, kPendingReleaseVersion}, {{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_TANH, 3}, kPendingReleaseVersion}, {{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_UNPACK, 4}, kPendingReleaseVersion}, {{BuiltinOperator_LEAKY_RELU, 1}, "1.13.1"}, + {{BuiltinOperator_LEAKY_RELU, 2}, kPendingReleaseVersion}, {{BuiltinOperator_LOGISTIC, 1}, "1.14.0"}, {{BuiltinOperator_LOGISTIC, 2}, "1.14.0"}, + {{BuiltinOperator_LOGISTIC, 3}, kPendingReleaseVersion}, {{BuiltinOperator_LOG_SOFTMAX, 1}, "1.14.0"}, {{BuiltinOperator_LOG_SOFTMAX, 2}, "1.14.0"}, + {{BuiltinOperator_LSH_PROJECTION, 1}, "1.5.0"}, {{BuiltinOperator_SQUARED_DIFFERENCE, 1}, "1.13.1"}, {{BuiltinOperator_MIRROR_PAD, 1}, "1.13.1"}, + {{BuiltinOperator_MIRROR_PAD, 2}, kPendingReleaseVersion}, {{BuiltinOperator_UNIQUE, 1}, "1.14.0"}, {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_RNN, 1}, "1.14.0"}, + {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_RNN, 2}, "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_DEQUANTIZE, 4}, "2.2.0"}, {{BuiltinOperator_REVERSE_SEQUENCE, 1}, "1.14.0"}, {{BuiltinOperator_EQUAL, 1}, "1.14.0"}, {{BuiltinOperator_EQUAL, 2}, "1.14.0"}, + {{BuiltinOperator_EQUAL, 3}, kPendingReleaseVersion}, {{BuiltinOperator_NOT_EQUAL, 1}, "1.14.0"}, {{BuiltinOperator_NOT_EQUAL, 2}, "1.14.0"}, + {{BuiltinOperator_NOT_EQUAL, 3}, kPendingReleaseVersion}, {{BuiltinOperator_GREATER, 1}, "1.14.0"}, {{BuiltinOperator_GREATER, 2}, "1.14.0"}, {{BuiltinOperator_GREATER_EQUAL, 1}, "1.14.0"}, @@ -197,10 +252,12 @@ void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) { {{BuiltinOperator_LESS, 2}, "1.14.0"}, {{BuiltinOperator_LESS_EQUAL, 1}, "1.14.0"}, {{BuiltinOperator_LESS_EQUAL, 2}, "1.14.0"}, + {{BuiltinOperator_SCATTER_ND, 1}, "2.1.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_IF, 1}, "1.15.0"}, {{BuiltinOperator_FLOOR_DIV, 1}, "1.14.0"}, {{BuiltinOperator_FLOOR_DIV, 2}, "1.14.0"}, {{BuiltinOperator_FLOOR, 1}, "1.9.0"}, @@ -208,6 +265,8 @@ void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) { {{BuiltinOperator_MATRIX_DIAG, 1}, "1.14.0"}, {{BuiltinOperator_MATRIX_SET_DIAG, 1}, "1.14.0"}, {{BuiltinOperator_ELU, 1}, "1.14.0"}, + {{BuiltinOperator_QUANTIZE, 1}, "1.14.0"}, + {{BuiltinOperator_QUANTIZE, 2}, "1.15.0"}, {{BuiltinOperator_ROUND, 1}, "1.14.0"}, {{BuiltinOperator_RELU, 1}, "1.5.0"}, {{BuiltinOperator_RELU, 2}, "2.1.0"}, @@ -224,17 +283,29 @@ void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) { {{BuiltinOperator_RANGE, 1}, "1.13.0"}, {{BuiltinOperator_SIN, 1}, "1.9.0"}, {{BuiltinOperator_LOG, 1}, "1.14.0"}, + {{BuiltinOperator_SQRT, 1}, "1.10.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_FILL, 2}, kPendingReleaseVersion}, {{BuiltinOperator_REVERSE_V2, 1}, "1.14.0"}, {{BuiltinOperator_REVERSE_V2, 2}, "2.2.0"}, {{BuiltinOperator_RANK, 1}, "1.14.0"}, + {{BuiltinOperator_WHILE, 1}, "1.15.0"}, }); + std::pair version_key = {op_code, op_version}; + auto it = op_version_map->find(version_key); + if (it == op_version_map->end()) { + return std::string(); + } + return it->second; +} + +void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) { auto model = GetMutableModel(model_buffer_pointer); std::string model_min_version; auto subgraphs = model->subgraphs(); @@ -244,19 +315,18 @@ void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) { const Operator* op = subgraph->operators()->Get(j); const OperatorCode* op_code = model->operator_codes()->Get(op->opcode_index()); - std::pair 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) { + std::string runtime_version = FindMinimumRuntimeVersionForOp( + op_code->builtin_code(), op_code->version()); + if (runtime_version.empty() || + runtime_version == kPendingReleaseVersion) { // 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)) { + if (CompareRuntimeVersion(model_min_version, runtime_version)) { // Current min model runtime version should be bumped if we see a higher // op version. - model_min_version = it->second; + model_min_version = runtime_version; } } } diff --git a/tensorflow/lite/tools/versioning/runtime_version.h b/tensorflow/lite/tools/versioning/runtime_version.h index ad88bd2ab89..64329eb1118 100644 --- a/tensorflow/lite/tools/versioning/runtime_version.h +++ b/tensorflow/lite/tools/versioning/runtime_version.h @@ -18,11 +18,17 @@ limitations under the License. #include #include "flatbuffers/flatbuffers.h" // from @flatbuffers +#include "tensorflow/lite/schema/mutable/schema_generated.h" namespace tflite { // Update minimum runtime version of the given TFL flatbuffer model. void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer); +// Find the minimum runtime version of a given op version. Return an empty +// string the version is not registered. +std::string FindMinimumRuntimeVersionForOp(tflite::BuiltinOperator op_code, + int op_version); + // Returns true if the first version string precedes the second. // For example, '1.9' should precede '1.14', also '1.14' should precede // '1.14.1'. If two version string is equal, then false will be returned. diff --git a/tensorflow/lite/tools/versioning/runtime_version_test.cc b/tensorflow/lite/tools/versioning/runtime_version_test.cc index c7b70552340..c32de228cc3 100644 --- a/tensorflow/lite/tools/versioning/runtime_version_test.cc +++ b/tensorflow/lite/tools/versioning/runtime_version_test.cc @@ -16,7 +16,8 @@ limitations under the License. #include #include - +#include "tensorflow/lite/kernels/register.h" +#include "tensorflow/lite/schema/schema_generated.h" namespace tflite { TEST(OpVersionTest, CompareRuntimeVersion) { @@ -31,4 +32,24 @@ TEST(OpVersionTest, CompareRuntimeVersion) { EXPECT_FALSE(CompareRuntimeVersion("", "")); } +// This test will fail if an op version is added to a builtin op, but not +// registered to runtime version. +TEST(OpVersionTest, OpversionMissing) { + tflite::ops::builtin::BuiltinOpResolver resolver; + + for (int id = BuiltinOperator_MIN; id <= BuiltinOperator_MAX; ++id) { + for (int version = 1;; ++version) { + auto op_code = static_cast(id); + if (resolver.FindOp(op_code, version) == nullptr) break; + // Throw error if the version is not registered in runtime version. + std::string runtime_version = + FindMinimumRuntimeVersionForOp(op_code, version); + EXPECT_NE(runtime_version, "") + << "Please add the version " << version << " of " + << tflite::EnumNamesBuiltinOperator()[op_code] + << " runtime_version.cc"; + } + } +} + } // namespace tflite