• 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 namespace {
27 // Use this as the placeholder string if a particular op is not yet included
28 // in any Tensorflow's RC/Final release source package. Once that op is
29 // included in the release, please update this with the real version string.
30 static constexpr char kPendingReleaseVersion[] = "UNKNOWN";
31 }  // namespace
32 
CompareRuntimeVersion(const std::string & v1,const std::string & v2)33 bool CompareRuntimeVersion(const std::string& v1, const std::string& v2) {
34   const std::vector<std::string> vec1 = absl::StrSplit(v1, '.');
35   const std::vector<std::string> vec2 = absl::StrSplit(v2, '.');
36   int i = 0;
37   while (i < vec1.size() && i < vec2.size()) {
38     int v1_val, v2_val;
39     if (absl::SimpleAtoi(vec1[i], &v1_val) &&
40         absl::SimpleAtoi(vec2[i], &v2_val)) {
41       if (v1_val != v2_val) return v1_val < v2_val;
42     }
43     ++i;
44   }
45   // If there are remaining items in v2 not being compared, then v1 should
46   // precede v2.
47   return i < vec2.size();
48 }
49 
FindMinimumRuntimeVersionForOp(tflite::BuiltinOperator op_code,int op_version)50 std::string FindMinimumRuntimeVersionForOp(tflite::BuiltinOperator op_code,
51                                            int op_version) {
52   // A map from the version key of an op to its minimum runtime version.
53   // For example, {{kAveragePool, 1}, "1.5.0"},  means the 1st version of
54   // AveragePool requires a minimum TF Lite runtime version '1.5.0`.
55   static const std::map<std::pair<BuiltinOperator, int>, std::string>*
56       op_version_map =
57           new std::map<std::pair<BuiltinOperator, int>, std::string>({
58               {{BuiltinOperator_AVERAGE_POOL_2D, 1}, "1.5.0"},
59               {{BuiltinOperator_AVERAGE_POOL_2D, 2}, "1.14.0"},
60               {{BuiltinOperator_AVERAGE_POOL_2D, 3}, "2.3.0"},
61               {{BuiltinOperator_BATCH_MATMUL, 1}, "2.3.0"},
62               {{BuiltinOperator_BATCH_MATMUL, 2}, "2.3.0"},
63               {{BuiltinOperator_BATCH_MATMUL, 3}, "2.4.0"},
64               {{BuiltinOperator_BATCH_MATMUL, 4}, kPendingReleaseVersion},
65               // The version one of broadcast to op won't be not supported since
66               // the version one was rollbacked and the builtin op code number
67               // has been changed because of builtin op code shortage problem.
68               {{BuiltinOperator_BROADCAST_TO, 2}, kPendingReleaseVersion},
69               {{BuiltinOperator_BROADCAST_TO, 3}, kPendingReleaseVersion},
70               {{BuiltinOperator_CONV_2D, 1}, "1.5.0"},
71               {{BuiltinOperator_CONV_2D, 2}, "1.14.0"},
72               {{BuiltinOperator_CONV_2D, 3}, "1.14.0"},
73               {{BuiltinOperator_CONV_2D, 4}, "2.3.0"},
74               {{BuiltinOperator_CONV_2D, 5}, "2.4.0"},
75               {{BuiltinOperator_DEPTHWISE_CONV_2D, 1}, "1.5.0"},
76               {{BuiltinOperator_DEPTHWISE_CONV_2D, 2}, "1.12.0"},
77               {{BuiltinOperator_DEPTHWISE_CONV_2D, 3}, "1.14.0"},
78               {{BuiltinOperator_DEPTHWISE_CONV_2D, 4}, "2.2.0"},
79               {{BuiltinOperator_DEPTHWISE_CONV_2D, 5}, "2.3.0"},
80               {{BuiltinOperator_DEPTHWISE_CONV_2D, 6}, "2.3.0"},
81               {{BuiltinOperator_ADD, 1}, "1.5.0"},
82               {{BuiltinOperator_ADD, 2}, "1.14.0"},
83               {{BuiltinOperator_ADD, 3}, "2.4.0"},
84               {{BuiltinOperator_ADD, 4}, "2.4.0"},
85               {{BuiltinOperator_ADD_N, 1}, "1.14.0"},
86               {{BuiltinOperator_SPACE_TO_BATCH_ND, 1}, "1.6.0"},
87               {{BuiltinOperator_SPACE_TO_BATCH_ND, 2}, "1.14.0"},
88               {{BuiltinOperator_SPACE_TO_BATCH_ND, 3}, "2.3.0"},
89               {{BuiltinOperator_SUB, 1}, "1.6.0"},
90               {{BuiltinOperator_SUB, 2}, "1.14.0"},
91               {{BuiltinOperator_SUB, 3}, "2.3.0"},
92               {{BuiltinOperator_SUB, 4}, "2.4.0"},
93               {{BuiltinOperator_SUB, 5}, "2.4.0"},
94               {{BuiltinOperator_DENSIFY, 1}, "2.2.0"},
95               {{BuiltinOperator_DIV, 1}, "1.6.0"},
96               {{BuiltinOperator_DIV, 2}, "2.3.0"},
97               {{BuiltinOperator_BATCH_TO_SPACE_ND, 1}, "1.6.0"},
98               {{BuiltinOperator_BATCH_TO_SPACE_ND, 2}, "1.14.0"},
99               {{BuiltinOperator_BATCH_TO_SPACE_ND, 3}, "2.3.0"},
100               {{BuiltinOperator_CAST, 1}, "1.5.0"},
101               {{BuiltinOperator_CONCATENATION, 1}, "1.5.0"},
102               {{BuiltinOperator_CONCATENATION, 2}, "1.14.0"},
103               {{BuiltinOperator_CONCATENATION, 3}, "2.3.0"},
104               {{BuiltinOperator_DEPTH_TO_SPACE, 1}, "2.1.0"},
105               {{BuiltinOperator_DEPTH_TO_SPACE, 2}, kPendingReleaseVersion},
106               {{BuiltinOperator_EMBEDDING_LOOKUP, 1}, "1.13.0"},
107               {{BuiltinOperator_EMBEDDING_LOOKUP, 2}, "1.14.0"},
108               {{BuiltinOperator_EMBEDDING_LOOKUP, 3}, "1.14.0"},
109               {{BuiltinOperator_EMBEDDING_LOOKUP_SPARSE, 1}, "1.5.0"},
110               {{BuiltinOperator_FAKE_QUANT, 1}, "1.5.0"},
111               {{BuiltinOperator_FAKE_QUANT, 2}, "1.10.0"},
112               {{BuiltinOperator_FULLY_CONNECTED, 1}, "1.5.0"},
113               {{BuiltinOperator_FULLY_CONNECTED, 2}, "1.10.0"},
114               {{BuiltinOperator_FULLY_CONNECTED, 3}, "1.14.0"},
115               {{BuiltinOperator_FULLY_CONNECTED, 4}, "1.14.0"},
116               {{BuiltinOperator_FULLY_CONNECTED, 5}, "2.0.0"},
117               {{BuiltinOperator_FULLY_CONNECTED, 6}, "2.1.0"},
118               {{BuiltinOperator_FULLY_CONNECTED, 7}, "2.3.0"},
119               {{BuiltinOperator_FULLY_CONNECTED, 8}, "2.3.0"},
120               {{BuiltinOperator_FULLY_CONNECTED, 9}, "2.3.0"},
121               {{BuiltinOperator_GATHER, 1}, "1.6.0"},
122               {{BuiltinOperator_GATHER, 2}, "1.14.0"},
123               {{BuiltinOperator_GATHER, 3}, "1.15.0"},
124               {{BuiltinOperator_GATHER, 4}, "2.4.0"},
125               {{BuiltinOperator_GATHER_ND, 1}, "1.14.0"},
126               {{BuiltinOperator_GATHER_ND, 2}, "2.3.0"},
127               {{BuiltinOperator_GATHER_ND, 3}, kPendingReleaseVersion},
128               {{BuiltinOperator_HASHTABLE_LOOKUP, 1}, "1.5.0"},
129               {{BuiltinOperator_SVDF, 1}, "1.5.0"},
130               {{BuiltinOperator_SVDF, 2}, "1.14.0"},
131               {{BuiltinOperator_SVDF, 3}, "2.2.0"},
132               {{BuiltinOperator_SVDF, 4}, "2.3.0"},
133               {{BuiltinOperator_L2_NORMALIZATION, 1}, "1.5.0"},
134               {{BuiltinOperator_L2_NORMALIZATION, 2}, "1.14.0"},
135               {{BuiltinOperator_L2_POOL_2D, 1}, "1.5.0"},
136               {{BuiltinOperator_LOCAL_RESPONSE_NORMALIZATION, 1}, "1.5.0"},
137               {{BuiltinOperator_MAX_POOL_2D, 1}, "1.5.0"},
138               {{BuiltinOperator_MAX_POOL_2D, 2}, "1.14.0"},
139               {{BuiltinOperator_MAX_POOL_2D, 3}, "2.3.0"},
140               {{BuiltinOperator_MAXIMUM, 1}, "1.14.0"},
141               {{BuiltinOperator_MAXIMUM, 2}, "1.14.0"},
142               {{BuiltinOperator_MAXIMUM, 3}, "2.3.0"},
143               {{BuiltinOperator_MAXIMUM, 4}, "2.3.0"},
144               {{BuiltinOperator_MINIMUM, 1}, "1.14.0"},
145               {{BuiltinOperator_MINIMUM, 2}, "1.14.0"},
146               {{BuiltinOperator_MINIMUM, 3}, "2.3.0"},
147               {{BuiltinOperator_MINIMUM, 4}, "2.3.0"},
148               {{BuiltinOperator_MUL, 1}, "1.5.0"},
149               {{BuiltinOperator_MUL, 2}, "1.14.0"},
150               {{BuiltinOperator_MUL, 3}, "1.15.0"},
151               {{BuiltinOperator_MUL, 4}, "2.3.0"},
152               {{BuiltinOperator_NON_MAX_SUPPRESSION_V4, 1}, "2.1.0"},
153               {{BuiltinOperator_NON_MAX_SUPPRESSION_V5, 1}, "2.1.0"},
154               {{BuiltinOperator_PAD, 1}, "1.5.0"},
155               {{BuiltinOperator_PAD, 2}, "1.14.0"},
156               {{BuiltinOperator_PAD, 3}, "2.4.0"},
157               {{BuiltinOperator_TILE, 1}, "1.10.1"},
158               {{BuiltinOperator_TILE, 2}, "2.2.0"},
159               {{BuiltinOperator_PADV2, 1}, "1.9.0"},
160               {{BuiltinOperator_PADV2, 2}, "1.14.0"},
161               {{BuiltinOperator_PADV2, 3}, "2.4.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}, kPendingReleaseVersion},
194               {{BuiltinOperator_REDUCE_MIN, 1}, "1.11.0"},
195               {{BuiltinOperator_REDUCE_MIN, 2}, "1.14.0"},
196               {{BuiltinOperator_REDUCE_MIN, 3}, kPendingReleaseVersion},
197               {{BuiltinOperator_REDUCE_PROD, 1}, "1.11.0"},
198               {{BuiltinOperator_REDUCE_ANY, 1}, "1.11.0"},
199               {{BuiltinOperator_RELU6, 1}, "1.5.0"},
200               {{BuiltinOperator_RELU6, 2}, "1.14.0"},
201               {{BuiltinOperator_RELU6, 3}, kPendingReleaseVersion},
202               {{BuiltinOperator_RESIZE_BILINEAR, 1}, "1.7.0"},
203               {{BuiltinOperator_RESIZE_BILINEAR, 2}, "1.14.0"},
204               {{BuiltinOperator_RESIZE_BILINEAR, 3}, "2.2.0"},
205               {{BuiltinOperator_RESIZE_BILINEAR, 4}, kPendingReleaseVersion},
206               {{BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 1}, "1.13.1"},
207               {{BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 2}, "1.14.0"},
208               {{BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 3}, "2.3.0"},
209               {{BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 4}, "2.4.0"},
210               {{BuiltinOperator_RNN, 1}, "1.5.0"},
211               {{BuiltinOperator_RNN, 2}, "1.14.0"},
212               {{BuiltinOperator_RNN, 3}, "2.3.0"},
213               {{BuiltinOperator_SKIP_GRAM, 1}, "1.5.0"},
214               {{BuiltinOperator_SQUEEZE, 1}, "1.6.0"},
215               {{BuiltinOperator_SQUEEZE, 2}, kPendingReleaseVersion},
216               {{BuiltinOperator_SPLIT, 1}, "1.5.0"},
217               {{BuiltinOperator_SPLIT, 2}, "1.14.0"},
218               {{BuiltinOperator_SPLIT, 3}, "1.14.0"},
219               {{BuiltinOperator_SPLIT, 4}, "2.3.0"},
220               {{BuiltinOperator_SPLIT_V, 1}, "1.13.1"},
221               {{BuiltinOperator_SPLIT_V, 2}, "2.3.0"},
222               {{BuiltinOperator_STRIDED_SLICE, 1}, "1.6.0"},
223               {{BuiltinOperator_STRIDED_SLICE, 2}, "1.14.0"},
224               {{BuiltinOperator_STRIDED_SLICE, 3}, "2.1.0"},
225               {{BuiltinOperator_STRIDED_SLICE, 4}, "2.2.0"},
226               {{BuiltinOperator_STRIDED_SLICE, 5}, kPendingReleaseVersion},
227               {{BuiltinOperator_TOPK_V2, 1}, "1.7.0"},
228               {{BuiltinOperator_TOPK_V2, 2}, "1.14.0"},
229               {{BuiltinOperator_ARG_MAX, 1}, "1.9.0"},
230               {{BuiltinOperator_ARG_MAX, 2}, "1.14.0"},
231               {{BuiltinOperator_ARG_MIN, 1}, "1.9.0"},
232               {{BuiltinOperator_ARG_MIN, 2}, "1.14.0"},
233               {{BuiltinOperator_TRANSPOSE_CONV, 1}, "1.9.0"},
234               {{BuiltinOperator_TRANSPOSE_CONV, 2}, "2.2.0"},
235               {{BuiltinOperator_TRANSPOSE_CONV, 3}, "2.3.0"},
236               {{BuiltinOperator_SPARSE_TO_DENSE, 1}, "1.9.0"},
237               {{BuiltinOperator_SPARSE_TO_DENSE, 2}, "1.14.0"},
238               {{BuiltinOperator_SPARSE_TO_DENSE, 3}, "1.15.0"},
239               {{BuiltinOperator_EXPAND_DIMS, 1}, "1.10.0"},
240               {{BuiltinOperator_PACK, 1}, "1.11.0"},
241               {{BuiltinOperator_PACK, 2}, "1.14.0"},
242               {{BuiltinOperator_PACK, 3}, "2.3.0"},
243               {{BuiltinOperator_SHAPE, 1}, "1.10.0"},
244               {{BuiltinOperator_SLICE, 1}, "1.14.0"},
245               {{BuiltinOperator_SLICE, 2}, "1.14.0"},
246               {{BuiltinOperator_SLICE, 3}, "1.14.0"},
247               {{BuiltinOperator_SLICE, 4}, "2.4.0"},
248               {{BuiltinOperator_SLICE, 5}, kPendingReleaseVersion},
249               {{BuiltinOperator_TANH, 1}, "1.14.0"},
250               {{BuiltinOperator_TANH, 2}, "1.14.0"},
251               {{BuiltinOperator_TANH, 3}, "2.3.0"},
252               {{BuiltinOperator_ONE_HOT, 1}, "1.11.0"},
253               {{BuiltinOperator_UNPACK, 1}, "1.11.0"},
254               {{BuiltinOperator_UNPACK, 2}, "1.14.0"},
255               {{BuiltinOperator_UNPACK, 3}, "2.2.0"},
256               {{BuiltinOperator_UNPACK, 4}, "2.3.0"},
257               {{BuiltinOperator_LEAKY_RELU, 1}, "1.13.1"},
258               {{BuiltinOperator_LEAKY_RELU, 2}, "2.3.0"},
259               {{BuiltinOperator_LOGISTIC, 1}, "1.14.0"},
260               {{BuiltinOperator_LOGISTIC, 2}, "1.14.0"},
261               {{BuiltinOperator_LOGISTIC, 3}, "2.3.0"},
262               {{BuiltinOperator_LOG_SOFTMAX, 1}, "1.14.0"},
263               {{BuiltinOperator_LOG_SOFTMAX, 2}, "1.14.0"},
264               {{BuiltinOperator_LSH_PROJECTION, 1}, "1.5.0"},
265               {{BuiltinOperator_SQUARED_DIFFERENCE, 1}, "1.13.1"},
266               {{BuiltinOperator_SQUARED_DIFFERENCE, 2}, kPendingReleaseVersion},
267               {{BuiltinOperator_MIRROR_PAD, 1}, "1.13.1"},
268               {{BuiltinOperator_MIRROR_PAD, 2}, "2.3.0"},
269               {{BuiltinOperator_UNIQUE, 1}, "1.14.0"},
270               {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_RNN, 1}, "1.14.0"},
271               {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_RNN, 2}, "1.14.0"},
272               {{BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_RNN, 3}, "2.3.0"},
273               {{BuiltinOperator_WHERE, 1}, "1.14.0"},
274               {{BuiltinOperator_DEQUANTIZE, 1}, "1.13.1"},
275               {{BuiltinOperator_DEQUANTIZE, 2}, "1.14.0"},
276               {{BuiltinOperator_DEQUANTIZE, 3}, "1.15.0"},
277               {{BuiltinOperator_DEQUANTIZE, 4}, "2.2.0"},
278               {{BuiltinOperator_REVERSE_SEQUENCE, 1}, "1.14.0"},
279               {{BuiltinOperator_EQUAL, 1}, "1.14.0"},
280               {{BuiltinOperator_EQUAL, 2}, "1.14.0"},
281               {{BuiltinOperator_EQUAL, 3}, "2.3.0"},
282               {{BuiltinOperator_NOT_EQUAL, 1}, "1.14.0"},
283               {{BuiltinOperator_NOT_EQUAL, 2}, "1.14.0"},
284               {{BuiltinOperator_NOT_EQUAL, 3}, "2.3.0"},
285               {{BuiltinOperator_GREATER, 1}, "1.14.0"},
286               {{BuiltinOperator_GREATER, 2}, "1.14.0"},
287               {{BuiltinOperator_GREATER_EQUAL, 1}, "1.14.0"},
288               {{BuiltinOperator_GREATER_EQUAL, 2}, "1.14.0"},
289               {{BuiltinOperator_LESS, 1}, "1.14.0"},
290               {{BuiltinOperator_LESS, 2}, "1.14.0"},
291               {{BuiltinOperator_LESS_EQUAL, 1}, "1.14.0"},
292               {{BuiltinOperator_LESS_EQUAL, 2}, "1.14.0"},
293               {{BuiltinOperator_SCATTER_ND, 1}, "2.1.0"},
294               {{BuiltinOperator_SEGMENT_SUM, 1}, "2.2.0"},
295               {{BuiltinOperator_SELECT, 1}, "1.14.0"},
296               {{BuiltinOperator_SELECT, 2}, "1.14.0"},
297               {{BuiltinOperator_SELECT_V2, 1}, "2.2.0"},
298               {{BuiltinOperator_IF, 1}, "1.15.0"},
299               {{BuiltinOperator_FLOOR_DIV, 1}, "1.14.0"},
300               {{BuiltinOperator_FLOOR_DIV, 2}, "1.14.0"},
301               {{BuiltinOperator_FLOOR, 1}, "1.9.0"},
302               {{BuiltinOperator_CEIL, 1}, "1.14.0"},
303               {{BuiltinOperator_MATRIX_DIAG, 1}, "1.14.0"},
304               {{BuiltinOperator_MATRIX_SET_DIAG, 1}, "1.14.0"},
305               {{BuiltinOperator_ELU, 1}, "1.14.0"},
306               {{BuiltinOperator_QUANTIZE, 1}, "1.14.0"},
307               {{BuiltinOperator_QUANTIZE, 2}, "1.15.0"},
308               {{BuiltinOperator_ROUND, 1}, "1.14.0"},
309               {{BuiltinOperator_RELU, 1}, "1.5.0"},
310               {{BuiltinOperator_RELU, 2}, "2.1.0"},
311               {{BuiltinOperator_RELU, 3}, kPendingReleaseVersion},
312               {{BuiltinOperator_RELU_N1_TO_1, 1}, "1.5.0"},
313               {{BuiltinOperator_PRELU, 1}, "1.8.0"},
314               {{BuiltinOperator_EXP, 1}, "1.7.0"},
315               {{BuiltinOperator_COS, 1}, "1.14.0"},
316               {{BuiltinOperator_NEG, 1}, "1.9.0"},
317               {{BuiltinOperator_POW, 1}, "1.10.0"},
318               {{BuiltinOperator_LOGICAL_OR, 1}, "1.11.0"},
319               {{BuiltinOperator_LOGICAL_AND, 1}, "1.11.0"},
320               {{BuiltinOperator_LOGICAL_NOT, 1}, "1.11.0"},
321               {{BuiltinOperator_FLOOR_MOD, 1}, "1.13.0"},
322               {{BuiltinOperator_RANGE, 1}, "1.13.0"},
323               {{BuiltinOperator_SIN, 1}, "1.9.0"},
324               {{BuiltinOperator_LOG, 1}, "1.14.0"},
325               {{BuiltinOperator_SQRT, 1}, "1.10.0"},
326               {{BuiltinOperator_RSQRT, 1}, "1.10.0"},
327               {{BuiltinOperator_RSQRT, 2}, kPendingReleaseVersion},
328               {{BuiltinOperator_SQUARE, 1}, "1.12.0"},
329               {{BuiltinOperator_ZEROS_LIKE, 1}, "1.12.0"},
330               {{BuiltinOperator_ABS, 1}, "1.13.0"},
331               {{BuiltinOperator_ABS, 2}, "2.4.0"},
332               {{BuiltinOperator_ABS, 3}, kPendingReleaseVersion},
333               {{BuiltinOperator_HARD_SWISH, 1}, "1.15.0"},
334               {{BuiltinOperator_FILL, 1}, "1.13.0"},
335               {{BuiltinOperator_FILL, 2}, "2.3.0"},
336               {{BuiltinOperator_FILL, 3}, kPendingReleaseVersion},
337               {{BuiltinOperator_REVERSE_V2, 1}, "1.14.0"},
338               {{BuiltinOperator_REVERSE_V2, 2}, "2.2.0"},
339               {{BuiltinOperator_REVERSE_V2, 3}, kPendingReleaseVersion},
340               {{BuiltinOperator_RANK, 1}, "1.14.0"},
341               {{BuiltinOperator_WHILE, 1}, "1.15.0"},
342               {{BuiltinOperator_CUMSUM, 1}, "2.4.0"},
343               {{BuiltinOperator_CALL_ONCE, 1}, kPendingReleaseVersion},
344               {{BuiltinOperator_RFFT2D, 1}, kPendingReleaseVersion},
345               {{BuiltinOperator_CONV_3D, 1}, kPendingReleaseVersion},
346               {{BuiltinOperator_IMAG, 1}, kPendingReleaseVersion},
347               {{BuiltinOperator_REAL, 1}, kPendingReleaseVersion},
348               {{BuiltinOperator_COMPLEX_ABS, 1}, kPendingReleaseVersion},
349           });
350 
351   std::pair<BuiltinOperator, int> version_key = {op_code, op_version};
352   auto it = op_version_map->find(version_key);
353   if (it == op_version_map->end()) {
354     return std::string();
355   }
356   return it->second;
357 }
358 
UpdateMinimumRuntimeVersionForModel(uint8_t * model_buffer_pointer)359 void UpdateMinimumRuntimeVersionForModel(uint8_t* model_buffer_pointer) {
360   auto model = GetMutableModel(model_buffer_pointer);
361   std::string model_min_version;
362   auto subgraphs = model->subgraphs();
363   for (int i = 0; i < subgraphs->Length(); ++i) {
364     const SubGraph* subgraph = subgraphs->Get(i);
365     for (int j = 0; j < subgraph->operators()->Length(); ++j) {
366       const Operator* op = subgraph->operators()->Get(j);
367       const OperatorCode* op_code =
368           model->operator_codes()->Get(op->opcode_index());
369       std::string runtime_version = FindMinimumRuntimeVersionForOp(
370           GetBuiltinCode(op_code), op_code->version());
371       if (runtime_version.empty() ||
372           runtime_version == kPendingReleaseVersion) {
373         // In case we didn't find the current op in the map, or the operator
374         // doesn't have a minimum runtime version associated, continue.
375         continue;
376       }
377       if (CompareRuntimeVersion(model_min_version, runtime_version)) {
378         // Current min model runtime version should be bumped if we see a higher
379         // op version.
380         model_min_version = runtime_version;
381       }
382     }
383   }
384   // The size of the `min_runtime_version` metadata buffer is 16 bytes. If the
385   // generated `model_min_version` is equal or longer than 16 bytes, print a
386   // warning message and return.
387   if (model_min_version.size() >= 16) {
388     TFLITE_LOG(TFLITE_LOG_WARNING,
389                "Skip writing minimum runtime version string since it's "
390                "longer than 16 bytes.");
391     return;
392   }
393   // Copy over the bytes from `model_min_version` into the buffer.
394   for (int i = 0; i < model->metadata()->size(); ++i) {
395     if (model->metadata()->Get(i)->name()->str() == "min_runtime_version") {
396       auto buffer = model->metadata()->Get(i)->buffer();
397       auto buffer_data =
398           model->mutable_buffers()->GetMutableObject(buffer)->mutable_data();
399       memset(buffer_data->data(), 0, buffer_data->size());
400       memcpy(buffer_data->data(), model_min_version.data(),
401              model_min_version.size());
402       break;
403     }
404   }
405 }
406 
407 }  // namespace tflite
408