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