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