• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 #include "tensorflow/lite/tools/versioning/runtime_version.h"
16 
17 #include <cstring>
18 
19 #include "absl/strings/numbers.h"
20 #include "absl/strings/str_split.h"
21 #include "tensorflow/lite/minimal_logging.h"
22 #include "tensorflow/lite/schema/mutable/schema_generated.h"
23 #include "tensorflow/lite/schema/schema_utils.h"
24 
25 namespace tflite {
26 
CompareRuntimeVersion(const std::string & v1,const std::string & v2)27 bool CompareRuntimeVersion(const std::string& v1, const std::string& v2) {
28   const std::vector<std::string> vec1 = absl::StrSplit(v1, '.');
29   const std::vector<std::string> vec2 = absl::StrSplit(v2, '.');
30   int i = 0;
31   while (i < vec1.size() && i < vec2.size()) {
32     int v1_val, v2_val;
33     if (absl::SimpleAtoi(vec1[i], &v1_val) &&
34         absl::SimpleAtoi(vec2[i], &v2_val)) {
35       if (v1_val != v2_val) return v1_val < v2_val;
36     }
37     ++i;
38   }
39   // If there are remaining items in v2 not being compared, then v1 should
40   // precede v2.
41   return i < vec2.size();
42 }
43 
FindMinimumRuntimeVersionForOp(tflite::BuiltinOperator op_code,int op_version)44 std::string FindMinimumRuntimeVersionForOp(tflite::BuiltinOperator op_code,
45                                            int op_version) {
46   // A map from the version key of an op to its minimum runtime version.
47   // For example, {{kAveragePool, 1}, "1.5.0"},  means the 1st version of
48   // AveragePool requires a minimum TF Lite runtime version '1.5.0`.
49   // NOTE: When adding a new op version pair, associate it with the current
50   // runtime version defined in tensorflow/core/public/version.h.
51   static const std::map<std::pair<BuiltinOperator, int>, std::string>*
52       op_version_map =
53           new std::map<std::pair<BuiltinOperator, int>, std::string>({
54               {{BuiltinOperator_AVERAGE_POOL_2D, 1}, "1.5.0"},
55               {{BuiltinOperator_AVERAGE_POOL_2D, 2}, "1.14.0"},
56               {{BuiltinOperator_AVERAGE_POOL_2D, 3}, "2.3.0"},
57               {{BuiltinOperator_BATCH_MATMUL, 1}, "2.3.0"},
58               {{BuiltinOperator_BATCH_MATMUL, 2}, "2.3.0"},
59               {{BuiltinOperator_BATCH_MATMUL, 3}, "2.4.0"},
60               {{BuiltinOperator_BATCH_MATMUL, 4}, "2.5.0"},
61               // The version one of broadcast to op won't be not supported since
62               // the version one was rollbacked and the builtin op code number
63               // has been changed because of builtin op code shortage problem.
64               {{BuiltinOperator_BROADCAST_TO, 2}, "2.5.0"},
65               {{BuiltinOperator_BROADCAST_TO, 3}, "2.5.0"},
66               {{BuiltinOperator_CONV_2D, 1}, "1.5.0"},
67               {{BuiltinOperator_CONV_2D, 2}, "1.14.0"},
68               {{BuiltinOperator_CONV_2D, 3}, "1.14.0"},
69               {{BuiltinOperator_CONV_2D, 4}, "2.3.0"},
70               {{BuiltinOperator_CONV_2D, 5}, "2.4.0"},
71               {{BuiltinOperator_DEPTHWISE_CONV_2D, 1}, "1.5.0"},
72               {{BuiltinOperator_DEPTHWISE_CONV_2D, 2}, "1.12.0"},
73               {{BuiltinOperator_DEPTHWISE_CONV_2D, 3}, "1.14.0"},
74               {{BuiltinOperator_DEPTHWISE_CONV_2D, 4}, "2.2.0"},
75               {{BuiltinOperator_DEPTHWISE_CONV_2D, 5}, "2.3.0"},
76               {{BuiltinOperator_DEPTHWISE_CONV_2D, 6}, "2.3.0"},
77               {{BuiltinOperator_ADD, 1}, "1.5.0"},
78               {{BuiltinOperator_ADD, 2}, "1.14.0"},
79               {{BuiltinOperator_ADD, 3}, "2.4.0"},
80               {{BuiltinOperator_ADD, 4}, "2.6.0"},
81               {{BuiltinOperator_ADD_N, 1}, "1.14.0"},
82               {{BuiltinOperator_SPACE_TO_BATCH_ND, 1}, "1.6.0"},
83               {{BuiltinOperator_SPACE_TO_BATCH_ND, 2}, "1.14.0"},
84               {{BuiltinOperator_SPACE_TO_BATCH_ND, 3}, "2.3.0"},
85               {{BuiltinOperator_SUB, 1}, "1.6.0"},
86               {{BuiltinOperator_SUB, 2}, "1.14.0"},
87               {{BuiltinOperator_SUB, 3}, "2.3.0"},
88               {{BuiltinOperator_SUB, 4}, "2.4.0"},
89               {{BuiltinOperator_SUB, 5}, "2.4.0"},
90               {{BuiltinOperator_DENSIFY, 1}, "2.2.0"},
91               {{BuiltinOperator_DIV, 1}, "1.6.0"},
92               {{BuiltinOperator_DIV, 2}, "2.3.0"},
93               {{BuiltinOperator_BATCH_TO_SPACE_ND, 1}, "1.6.0"},
94               {{BuiltinOperator_BATCH_TO_SPACE_ND, 2}, "1.14.0"},
95               {{BuiltinOperator_BATCH_TO_SPACE_ND, 3}, "2.3.0"},
96               {{BuiltinOperator_CAST, 1}, "1.5.0"},
97               {{BuiltinOperator_CONCATENATION, 1}, "1.5.0"},
98               {{BuiltinOperator_CONCATENATION, 2}, "1.14.0"},
99               {{BuiltinOperator_CONCATENATION, 3}, "2.3.0"},
100               {{BuiltinOperator_DEPTH_TO_SPACE, 1}, "2.1.0"},
101               {{BuiltinOperator_DEPTH_TO_SPACE, 2}, "2.5.0"},
102               {{BuiltinOperator_EMBEDDING_LOOKUP, 1}, "1.13.0"},
103               {{BuiltinOperator_EMBEDDING_LOOKUP, 2}, "1.14.0"},
104               {{BuiltinOperator_EMBEDDING_LOOKUP, 3}, "1.14.0"},
105               {{BuiltinOperator_EMBEDDING_LOOKUP_SPARSE, 1}, "1.5.0"},
106               {{BuiltinOperator_FAKE_QUANT, 1}, "1.5.0"},
107               {{BuiltinOperator_FAKE_QUANT, 2}, "1.10.0"},
108               {{BuiltinOperator_FULLY_CONNECTED, 1}, "1.5.0"},
109               {{BuiltinOperator_FULLY_CONNECTED, 2}, "1.10.0"},
110               {{BuiltinOperator_FULLY_CONNECTED, 3}, "1.14.0"},
111               {{BuiltinOperator_FULLY_CONNECTED, 4}, "1.14.0"},
112               {{BuiltinOperator_FULLY_CONNECTED, 5}, "2.0.0"},
113               {{BuiltinOperator_FULLY_CONNECTED, 6}, "2.1.0"},
114               {{BuiltinOperator_FULLY_CONNECTED, 7}, "2.3.0"},
115               {{BuiltinOperator_FULLY_CONNECTED, 8}, "2.3.0"},
116               {{BuiltinOperator_FULLY_CONNECTED, 9}, "2.3.0"},
117               {{BuiltinOperator_GATHER, 1}, "1.6.0"},
118               {{BuiltinOperator_GATHER, 2}, "1.14.0"},
119               {{BuiltinOperator_GATHER, 3}, "1.15.0"},
120               {{BuiltinOperator_GATHER, 4}, "2.4.0"},
121               {{BuiltinOperator_GATHER, 5}, "2.5.0"},
122               {{BuiltinOperator_GATHER_ND, 1}, "1.14.0"},
123               {{BuiltinOperator_GATHER_ND, 2}, "2.3.0"},
124               {{BuiltinOperator_GATHER_ND, 3}, "2.5.0"},
125               {{BuiltinOperator_HASHTABLE_LOOKUP, 1}, "1.5.0"},
126               {{BuiltinOperator_SVDF, 1}, "1.5.0"},
127               {{BuiltinOperator_SVDF, 2}, "1.14.0"},
128               {{BuiltinOperator_SVDF, 3}, "2.2.0"},
129               {{BuiltinOperator_SVDF, 4}, "2.3.0"},
130               {{BuiltinOperator_L2_NORMALIZATION, 1}, "1.5.0"},
131               {{BuiltinOperator_L2_NORMALIZATION, 2}, "1.14.0"},
132               {{BuiltinOperator_L2_POOL_2D, 1}, "1.5.0"},
133               {{BuiltinOperator_LOCAL_RESPONSE_NORMALIZATION, 1}, "1.5.0"},
134               {{BuiltinOperator_MAX_POOL_2D, 1}, "1.5.0"},
135               {{BuiltinOperator_MAX_POOL_2D, 2}, "1.14.0"},
136               {{BuiltinOperator_MAX_POOL_2D, 3}, "2.3.0"},
137               {{BuiltinOperator_MAXIMUM, 1}, "1.14.0"},
138               {{BuiltinOperator_MAXIMUM, 2}, "1.14.0"},
139               {{BuiltinOperator_MAXIMUM, 3}, "2.3.0"},
140               {{BuiltinOperator_MAXIMUM, 4}, "2.3.0"},
141               {{BuiltinOperator_MINIMUM, 1}, "1.14.0"},
142               {{BuiltinOperator_MINIMUM, 2}, "1.14.0"},
143               {{BuiltinOperator_MINIMUM, 3}, "2.3.0"},
144               {{BuiltinOperator_MINIMUM, 4}, "2.3.0"},
145               {{BuiltinOperator_MUL, 1}, "1.5.0"},
146               {{BuiltinOperator_MUL, 2}, "1.14.0"},
147               {{BuiltinOperator_MUL, 3}, "1.15.0"},
148               {{BuiltinOperator_MUL, 4}, "2.3.0"},
149               {{BuiltinOperator_MUL, 5}, "2.6.0"},
150               {{BuiltinOperator_NON_MAX_SUPPRESSION_V4, 1}, "2.1.0"},
151               {{BuiltinOperator_NON_MAX_SUPPRESSION_V5, 1}, "2.1.0"},
152               {{BuiltinOperator_PAD, 1}, "1.5.0"},
153               {{BuiltinOperator_PAD, 2}, "1.14.0"},
154               {{BuiltinOperator_PAD, 3}, "2.4.0"},
155               {{BuiltinOperator_PAD, 4}, "2.6.0"},
156               {{BuiltinOperator_TILE, 1}, "1.10.1"},
157               {{BuiltinOperator_TILE, 2}, "2.2.0"},
158               {{BuiltinOperator_PADV2, 1}, "1.9.0"},
159               {{BuiltinOperator_PADV2, 2}, "1.14.0"},
160               {{BuiltinOperator_PADV2, 3}, "2.4.0"},
161               {{BuiltinOperator_PADV2, 4}, "2.6.0"},
162               {{BuiltinOperator_RESHAPE, 1}, "1.5.0"},
163               {{BuiltinOperator_SOFTMAX, 1}, "1.5.0"},
164               {{BuiltinOperator_SOFTMAX, 2}, "1.14.0"},
165               {{BuiltinOperator_SOFTMAX, 3}, "2.3.0"},
166               {{BuiltinOperator_SPACE_TO_DEPTH, 1}, "1.5.0"},
167               {{BuiltinOperator_SPACE_TO_DEPTH, 2}, "1.14.0"},
168               {{BuiltinOperator_TRANSPOSE, 1}, "1.6.0"},
169               {{BuiltinOperator_TRANSPOSE, 2}, "1.14.0"},
170               {{BuiltinOperator_TRANSPOSE, 3}, "1.15.0"},
171               {{BuiltinOperator_TRANSPOSE, 4}, "2.3.0"},
172               {{BuiltinOperator_TRANSPOSE, 5}, "2.4.0"},
173               {{BuiltinOperator_LSTM, 1}, "1.7.0"},
174               {{BuiltinOperator_LSTM, 2}, "1.10.0"},
175               {{BuiltinOperator_LSTM, 3}, "1.14.0"},
176               {{BuiltinOperator_LSTM, 4}, "2.3.0"},
177               {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_LSTM, 1}, "1.13.1"},
178               {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_LSTM, 2}, "1.14.0"},
179               {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_LSTM, 3}, "2.3.0"},
180               {{BuiltinOperator_BIDIRECTIONAL_SEQUENCE_LSTM, 1}, "1.14.0"},
181               {{BuiltinOperator_BIDIRECTIONAL_SEQUENCE_LSTM, 2}, "1.14.0"},
182               {{BuiltinOperator_BIDIRECTIONAL_SEQUENCE_LSTM, 3}, "1.14.0"},
183               {{BuiltinOperator_BIDIRECTIONAL_SEQUENCE_RNN, 1}, "1.14.0"},
184               {{BuiltinOperator_BIDIRECTIONAL_SEQUENCE_RNN, 2}, "1.14.0"},
185               {{BuiltinOperator_BIDIRECTIONAL_SEQUENCE_RNN, 3}, "2.3.0"},
186               {{BuiltinOperator_MEAN, 1}, "1.6.0"},
187               {{BuiltinOperator_MEAN, 2}, "1.14.0"},
188               {{BuiltinOperator_MEAN, 3}, "2.4.0"},
189               {{BuiltinOperator_SUM, 1}, "1.10.0"},
190               {{BuiltinOperator_SUM, 2}, "1.15.0"},
191               {{BuiltinOperator_REDUCE_MAX, 1}, "1.11.0"},
192               {{BuiltinOperator_REDUCE_MAX, 2}, "1.14.0"},
193               {{BuiltinOperator_REDUCE_MAX, 3}, "2.5.0"},
194               {{BuiltinOperator_REDUCE_MIN, 1}, "1.11.0"},
195               {{BuiltinOperator_REDUCE_MIN, 2}, "1.14.0"},
196               {{BuiltinOperator_REDUCE_MIN, 3}, "2.5.0"},
197               {{BuiltinOperator_REDUCE_PROD, 1}, "1.11.0"},
198               {{BuiltinOperator_REDUCE_PROD, 2}, "2.6.0"},
199               {{BuiltinOperator_REDUCE_ANY, 1}, "1.11.0"},
200               {{BuiltinOperator_RELU6, 1}, "1.5.0"},
201               {{BuiltinOperator_RELU6, 2}, "1.14.0"},
202               {{BuiltinOperator_RELU6, 3}, "2.5.0"},
203               {{BuiltinOperator_RESIZE_BILINEAR, 1}, "1.7.0"},
204               {{BuiltinOperator_RESIZE_BILINEAR, 2}, "1.14.0"},
205               {{BuiltinOperator_RESIZE_BILINEAR, 3}, "2.2.0"},
206               {{BuiltinOperator_RESIZE_BILINEAR, 4}, "2.5.0"},
207               {{BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 1}, "1.13.1"},
208               {{BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 2}, "1.14.0"},
209               {{BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 3}, "2.3.0"},
210               {{BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 4}, "2.4.0"},
211               {{BuiltinOperator_RNN, 1}, "1.5.0"},
212               {{BuiltinOperator_RNN, 2}, "1.14.0"},
213               {{BuiltinOperator_RNN, 3}, "2.3.0"},
214               {{BuiltinOperator_SKIP_GRAM, 1}, "1.5.0"},
215               {{BuiltinOperator_SQUEEZE, 1}, "1.6.0"},
216               {{BuiltinOperator_SQUEEZE, 2}, "2.5.0"},
217               {{BuiltinOperator_SPLIT, 1}, "1.5.0"},
218               {{BuiltinOperator_SPLIT, 2}, "1.14.0"},
219               {{BuiltinOperator_SPLIT, 3}, "1.14.0"},
220               {{BuiltinOperator_SPLIT, 4}, "2.3.0"},
221               {{BuiltinOperator_SPLIT_V, 1}, "1.13.1"},
222               {{BuiltinOperator_SPLIT_V, 2}, "2.3.0"},
223               {{BuiltinOperator_STRIDED_SLICE, 1}, "1.6.0"},
224               {{BuiltinOperator_STRIDED_SLICE, 2}, "1.14.0"},
225               {{BuiltinOperator_STRIDED_SLICE, 3}, "2.1.0"},
226               {{BuiltinOperator_STRIDED_SLICE, 4}, "2.2.0"},
227               {{BuiltinOperator_STRIDED_SLICE, 5}, "2.5.0"},
228               {{BuiltinOperator_STRIDED_SLICE, 6}, "2.6.0"},
229               {{BuiltinOperator_TOPK_V2, 1}, "1.7.0"},
230               {{BuiltinOperator_TOPK_V2, 2}, "1.14.0"},
231               {{BuiltinOperator_ARG_MAX, 1}, "1.9.0"},
232               {{BuiltinOperator_ARG_MAX, 2}, "1.14.0"},
233               {{BuiltinOperator_ARG_MIN, 1}, "1.9.0"},
234               {{BuiltinOperator_ARG_MIN, 2}, "1.14.0"},
235               {{BuiltinOperator_TRANSPOSE_CONV, 1}, "1.9.0"},
236               {{BuiltinOperator_TRANSPOSE_CONV, 2}, "2.2.0"},
237               {{BuiltinOperator_TRANSPOSE_CONV, 3}, "2.3.0"},
238               {{BuiltinOperator_SPARSE_TO_DENSE, 1}, "1.9.0"},
239               {{BuiltinOperator_SPARSE_TO_DENSE, 2}, "1.14.0"},
240               {{BuiltinOperator_SPARSE_TO_DENSE, 3}, "1.15.0"},
241               {{BuiltinOperator_EXPAND_DIMS, 1}, "1.10.0"},
242               {{BuiltinOperator_PACK, 1}, "1.11.0"},
243               {{BuiltinOperator_PACK, 2}, "1.14.0"},
244               {{BuiltinOperator_PACK, 3}, "2.3.0"},
245               {{BuiltinOperator_SHAPE, 1}, "1.10.0"},
246               {{BuiltinOperator_SLICE, 1}, "1.14.0"},
247               {{BuiltinOperator_SLICE, 2}, "1.14.0"},
248               {{BuiltinOperator_SLICE, 3}, "1.14.0"},
249               {{BuiltinOperator_SLICE, 4}, "2.4.0"},
250               {{BuiltinOperator_SLICE, 5}, "2.5.0"},
251               {{BuiltinOperator_TANH, 1}, "1.14.0"},
252               {{BuiltinOperator_TANH, 2}, "1.14.0"},
253               {{BuiltinOperator_TANH, 3}, "2.3.0"},
254               {{BuiltinOperator_ONE_HOT, 1}, "1.11.0"},
255               {{BuiltinOperator_UNPACK, 1}, "1.11.0"},
256               {{BuiltinOperator_UNPACK, 2}, "1.14.0"},
257               {{BuiltinOperator_UNPACK, 3}, "2.2.0"},
258               {{BuiltinOperator_UNPACK, 4}, "2.3.0"},
259               {{BuiltinOperator_LEAKY_RELU, 1}, "1.13.1"},
260               {{BuiltinOperator_LEAKY_RELU, 2}, "2.3.0"},
261               {{BuiltinOperator_LOGISTIC, 1}, "1.14.0"},
262               {{BuiltinOperator_LOGISTIC, 2}, "1.14.0"},
263               {{BuiltinOperator_LOGISTIC, 3}, "2.3.0"},
264               {{BuiltinOperator_LOG_SOFTMAX, 1}, "1.14.0"},
265               {{BuiltinOperator_LOG_SOFTMAX, 2}, "1.14.0"},
266               {{BuiltinOperator_LSH_PROJECTION, 1}, "1.5.0"},
267               {{BuiltinOperator_SQUARED_DIFFERENCE, 1}, "1.13.1"},
268               {{BuiltinOperator_SQUARED_DIFFERENCE, 2}, "2.5.0"},
269               {{BuiltinOperator_MIRROR_PAD, 1}, "1.13.1"},
270               {{BuiltinOperator_MIRROR_PAD, 2}, "2.3.0"},
271               {{BuiltinOperator_UNIQUE, 1}, "1.14.0"},
272               {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_RNN, 1}, "1.14.0"},
273               {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_RNN, 2}, "1.14.0"},
274               {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_RNN, 3}, "2.3.0"},
275               {{BuiltinOperator_WHERE, 1}, "1.14.0"},
276               {{BuiltinOperator_DEQUANTIZE, 1}, "1.13.1"},
277               {{BuiltinOperator_DEQUANTIZE, 2}, "1.14.0"},
278               {{BuiltinOperator_DEQUANTIZE, 3}, "1.15.0"},
279               {{BuiltinOperator_DEQUANTIZE, 4}, "2.2.0"},
280               {{BuiltinOperator_DEQUANTIZE, 5}, "2.7.0"},
281               {{BuiltinOperator_REVERSE_SEQUENCE, 1}, "1.14.0"},
282               {{BuiltinOperator_EQUAL, 1}, "1.14.0"},
283               {{BuiltinOperator_EQUAL, 2}, "1.14.0"},
284               {{BuiltinOperator_EQUAL, 3}, "2.3.0"},
285               {{BuiltinOperator_NOT_EQUAL, 1}, "1.14.0"},
286               {{BuiltinOperator_NOT_EQUAL, 2}, "1.14.0"},
287               {{BuiltinOperator_NOT_EQUAL, 3}, "2.3.0"},
288               {{BuiltinOperator_GREATER, 1}, "1.14.0"},
289               {{BuiltinOperator_GREATER, 2}, "1.14.0"},
290               {{BuiltinOperator_GREATER_EQUAL, 1}, "1.14.0"},
291               {{BuiltinOperator_GREATER_EQUAL, 2}, "1.14.0"},
292               {{BuiltinOperator_LESS, 1}, "1.14.0"},
293               {{BuiltinOperator_LESS, 2}, "1.14.0"},
294               {{BuiltinOperator_LESS_EQUAL, 1}, "1.14.0"},
295               {{BuiltinOperator_LESS_EQUAL, 2}, "1.14.0"},
296               {{BuiltinOperator_SCATTER_ND, 1}, "2.1.0"},
297               {{BuiltinOperator_SEGMENT_SUM, 1}, "2.2.0"},
298               {{BuiltinOperator_SELECT, 1}, "1.14.0"},
299               {{BuiltinOperator_SELECT, 2}, "1.14.0"},
300               {{BuiltinOperator_SELECT_V2, 1}, "2.2.0"},
301               {{BuiltinOperator_IF, 1}, "1.15.0"},
302               {{BuiltinOperator_FLOOR_DIV, 1}, "1.14.0"},
303               {{BuiltinOperator_FLOOR_DIV, 2}, "1.14.0"},
304               {{BuiltinOperator_FLOOR, 1}, "1.9.0"},
305               {{BuiltinOperator_CEIL, 1}, "1.14.0"},
306               {{BuiltinOperator_MATRIX_DIAG, 1}, "1.14.0"},
307               {{BuiltinOperator_MATRIX_SET_DIAG, 1}, "1.14.0"},
308               {{BuiltinOperator_ELU, 1}, "1.14.0"},
309               {{BuiltinOperator_QUANTIZE, 1}, "1.14.0"},
310               {{BuiltinOperator_QUANTIZE, 2}, "1.15.0"},
311               {{BuiltinOperator_ROUND, 1}, "1.14.0"},
312               {{BuiltinOperator_RELU, 1}, "1.5.0"},
313               {{BuiltinOperator_RELU, 2}, "2.1.0"},
314               {{BuiltinOperator_RELU, 3}, "2.5.0"},
315               {{BuiltinOperator_RELU_N1_TO_1, 1}, "1.5.0"},
316               {{BuiltinOperator_PRELU, 1}, "1.8.0"},
317               {{BuiltinOperator_EXP, 1}, "1.7.0"},
318               {{BuiltinOperator_COS, 1}, "1.14.0"},
319               {{BuiltinOperator_NEG, 1}, "1.9.0"},
320               {{BuiltinOperator_POW, 1}, "1.10.0"},
321               {{BuiltinOperator_LOGICAL_OR, 1}, "1.11.0"},
322               {{BuiltinOperator_LOGICAL_AND, 1}, "1.11.0"},
323               {{BuiltinOperator_LOGICAL_NOT, 1}, "1.11.0"},
324               {{BuiltinOperator_FLOOR_MOD, 1}, "1.13.0"},
325               {{BuiltinOperator_RANGE, 1}, "1.13.0"},
326               {{BuiltinOperator_SIN, 1}, "1.9.0"},
327               {{BuiltinOperator_LOG, 1}, "1.14.0"},
328               {{BuiltinOperator_SQRT, 1}, "1.10.0"},
329               {{BuiltinOperator_RSQRT, 1}, "1.10.0"},
330               {{BuiltinOperator_RSQRT, 2}, "2.5.0"},
331               {{BuiltinOperator_SQUARE, 1}, "1.12.0"},
332               {{BuiltinOperator_ZEROS_LIKE, 1}, "1.12.0"},
333               {{BuiltinOperator_ABS, 1}, "1.13.0"},
334               {{BuiltinOperator_ABS, 2}, "2.4.0"},
335               {{BuiltinOperator_ABS, 3}, "2.5.0"},
336               {{BuiltinOperator_ABS, 4}, "2.6.0"},
337               {{BuiltinOperator_HARD_SWISH, 1}, "1.15.0"},
338               {{BuiltinOperator_FILL, 1}, "1.13.0"},
339               {{BuiltinOperator_FILL, 2}, "2.3.0"},
340               {{BuiltinOperator_FILL, 3}, "2.5.0"},
341               {{BuiltinOperator_REVERSE_V2, 1}, "1.14.0"},
342               {{BuiltinOperator_REVERSE_V2, 2}, "2.2.0"},
343               {{BuiltinOperator_REVERSE_V2, 3}, "2.5.0"},
344               {{BuiltinOperator_RANK, 1}, "1.14.0"},
345               {{BuiltinOperator_WHILE, 1}, "1.15.0"},
346               {{BuiltinOperator_CUMSUM, 1}, "2.4.0"},
347               {{BuiltinOperator_CALL_ONCE, 1}, "2.5.0"},
348               {{BuiltinOperator_RFFT2D, 1}, "2.5.0"},
349               {{BuiltinOperator_CONV_3D, 1}, "2.5.0"},
350               {{BuiltinOperator_IMAG, 1}, "2.5.0"},
351               {{BuiltinOperator_REAL, 1}, "2.5.0"},
352               {{BuiltinOperator_COMPLEX_ABS, 1}, "2.5.0"},
353               {{BuiltinOperator_HASHTABLE, 1}, "2.5.0"},
354               {{BuiltinOperator_HASHTABLE_FIND, 1}, "2.5.0"},
355               {{BuiltinOperator_HASHTABLE_IMPORT, 1}, "2.5.0"},
356               {{BuiltinOperator_HASHTABLE_SIZE, 1}, "2.5.0"},
357               {{BuiltinOperator_REDUCE_ALL, 1}, "2.6.0"},
358               {{BuiltinOperator_CONV_3D_TRANSPOSE, 1}, "2.6.0"},
359               {{BuiltinOperator_VAR_HANDLE, 1}, "2.6.0"},
360               {{BuiltinOperator_READ_VARIABLE, 1}, "2.6.0"},
361               {{BuiltinOperator_ASSIGN_VARIABLE, 1}, "2.6.0"},
362               {{BuiltinOperator_BROADCAST_ARGS, 1}, "2.6.0"},
363           });
364 
365   std::pair<BuiltinOperator, int> version_key = {op_code, op_version};
366   auto it = op_version_map->find(version_key);
367   if (it == op_version_map->end()) {
368     return std::string();
369   }
370   return it->second;
371 }
372 
UpdateMinimumRuntimeVersionForModel(uint8_t * model_buffer_pointer)373 void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) {
374   auto model = GetMutableModel(model_buffer_pointer);
375   std::string model_min_version;
376   auto subgraphs = model->subgraphs();
377   for (int i = 0; i < subgraphs->Length(); ++i) {
378     const SubGraph* subgraph = subgraphs->Get(i);
379     for (int j = 0; j < subgraph->operators()->Length(); ++j) {
380       const Operator* op = subgraph->operators()->Get(j);
381       const OperatorCode* op_code =
382           model->operator_codes()->Get(op->opcode_index());
383       std::string runtime_version = FindMinimumRuntimeVersionForOp(
384           GetBuiltinCode(op_code), op_code->version());
385       // If we didn't find the current op version in the map, skip comparison.
386       if (runtime_version.empty()) {
387         continue;
388       }
389       if (CompareRuntimeVersion(model_min_version, runtime_version)) {
390         // Current min model runtime version should be bumped if we see a higher
391         // op version.
392         model_min_version = runtime_version;
393       }
394     }
395   }
396   // The size of the `min_runtime_version` metadata buffer is 16 bytes. If the
397   // generated `model_min_version` is equal or longer than 16 bytes, print a
398   // warning message and return.
399   if (model_min_version.size() >= 16) {
400     TFLITE_LOG(TFLITE_LOG_WARNING,
401                "Skip writing minimum runtime version string since it's "
402                "longer than 16 bytes.");
403     return;
404   }
405   // Copy over the bytes from `model_min_version` into the buffer.
406   for (int i = 0; i < model->metadata()->size(); ++i) {
407     if (model->metadata()->Get(i)->name()->str() == "min_runtime_version") {
408       auto buffer = model->metadata()->Get(i)->buffer();
409       auto buffer_data =
410           model->mutable_buffers()->GetMutableObject(buffer)->mutable_data();
411       memset(buffer_data->data(), 0, buffer_data->size());
412       memcpy(buffer_data->data(), model_min_version.data(),
413              model_min_version.size());
414       break;
415     }
416   }
417 }
418 
419 }  // namespace tflite
420