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