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