1 /* Copyright 2019 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/op_version.h"
16
17 #include <vector>
18
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 #include "tensorflow/lite/builtin_op_data.h"
22 #include "tensorflow/lite/schema/schema_generated.h"
23
24 namespace tflite {
25 namespace {
26
27 // Creates vector of OpSignatureTensorSpec with the given TfLiteType vector.
CreateOpSignatureTensorSpecs(const std::vector<TfLiteType> & types)28 std::vector<OpSignatureTensorSpec> CreateOpSignatureTensorSpecs(
29 const std::vector<TfLiteType>& types) {
30 std::vector<OpSignatureTensorSpec> tensor_specs;
31 for (auto type : types) {
32 OpSignatureTensorSpec tensor_spec = {};
33 tensor_spec.type = type;
34 tensor_specs.push_back(tensor_spec);
35 }
36 return tensor_specs;
37 }
38
39 // Creates vector of OpSignatureTensorSpec with the given TfLiteType vector,
40 // each with rank 'rank'
CreateOpSignatureTensorSpecs(const std::vector<TfLiteType> & types,int rank)41 std::vector<OpSignatureTensorSpec> CreateOpSignatureTensorSpecs(
42 const std::vector<TfLiteType>& types, int rank) {
43 std::vector<OpSignatureTensorSpec> tensor_specs;
44 for (auto type : types) {
45 OpSignatureTensorSpec tensor_spec = {};
46 tensor_spec.type = type;
47 for (int i = 0; i < rank; i++) {
48 tensor_spec.dims.push_back(4);
49 }
50 tensor_specs.push_back(tensor_spec);
51 }
52 return tensor_specs;
53 }
54
55 // Creates vector of OpSignatureTensorSpec of single tensor spec of TfLiteType.
CreateOpSignatureTensorSpecs(const TfLiteType type)56 std::vector<OpSignatureTensorSpec> CreateOpSignatureTensorSpecs(
57 const TfLiteType type) {
58 std::vector<OpSignatureTensorSpec> tensor_specs;
59 OpSignatureTensorSpec tensor_spec = {};
60 tensor_spec.type = type;
61 tensor_specs.push_back(tensor_spec);
62 return tensor_specs;
63 }
64
65 // Creates vector of OpSignatureTensorSpec of single tensor spec of TfLiteType
66 // with shapes.
CreateOpSignatureTensorSpecs(const TfLiteType type,const int dim)67 std::vector<OpSignatureTensorSpec> CreateOpSignatureTensorSpecs(
68 const TfLiteType type, const int dim) {
69 std::vector<OpSignatureTensorSpec> tensor_specs;
70 OpSignatureTensorSpec tensor_spec = {};
71 tensor_spec.type = type;
72 for (int i = 0; i < dim; i++) {
73 tensor_spec.dims.push_back(4);
74 }
75 tensor_specs.push_back(tensor_spec);
76 return tensor_specs;
77 }
78
79 // Creates vector of OpSignatureTensorSpec of two tensor specs of TfLiteType
80 // with shapes.
CreateOpSignatureTensorSpecs(const TfLiteType type,const int dim1,const int dim2)81 std::vector<OpSignatureTensorSpec> CreateOpSignatureTensorSpecs(
82 const TfLiteType type, const int dim1, const int dim2) {
83 std::vector<OpSignatureTensorSpec> tensor_specs;
84 OpSignatureTensorSpec tensor_spec1 = {};
85 tensor_spec1.type = type;
86 for (int i = 0; i < dim1; i++) {
87 tensor_spec1.dims.push_back(4);
88 }
89 tensor_specs.push_back(tensor_spec1);
90
91 OpSignatureTensorSpec tensor_spec2 = {};
92 tensor_spec2.type = type;
93 for (int i = 0; i < dim2; i++) {
94 tensor_spec2.dims.push_back(4);
95 }
96 tensor_specs.push_back(tensor_spec2);
97 return tensor_specs;
98 }
99
100 } // namespace
101
TEST(OpVersionTest,VersioningSpareToDense)102 TEST(OpVersionTest, VersioningSpareToDense) {
103 OpSignature fake_op_sig = {
104 .op = BuiltinOperator_SPARSE_TO_DENSE,
105 .inputs = CreateOpSignatureTensorSpecs(
106 std::vector<TfLiteType>{kTfLiteInt8, kTfLiteInt8, kTfLiteInt8}),
107 };
108 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
109
110 fake_op_sig = {
111 .op = BuiltinOperator_SPARSE_TO_DENSE,
112 .inputs = CreateOpSignatureTensorSpecs(
113 std::vector<TfLiteType>{kTfLiteUInt8, kTfLiteUInt8, kTfLiteUInt8}),
114 };
115 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
116
117 fake_op_sig = {
118 .op = BuiltinOperator_SPARSE_TO_DENSE,
119 .inputs = CreateOpSignatureTensorSpecs(
120 std::vector<TfLiteType>{kTfLiteInt64, kTfLiteInt64, kTfLiteInt64}),
121 };
122 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
123
124 fake_op_sig = {
125 .op = BuiltinOperator_SPARSE_TO_DENSE,
126 .inputs = CreateOpSignatureTensorSpecs(
127 std::vector<TfLiteType>{kTfLiteInt32, kTfLiteInt32, kTfLiteInt32}),
128 };
129 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
130 }
131
132 // Test version for a simple Op with 2 versions and the input type controls the
133 // version.
SimpleVersioningTest(BuiltinOperator op)134 void SimpleVersioningTest(BuiltinOperator op) {
135 OpSignature fake_op_sig = {
136 .op = op,
137 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
138 };
139 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
140
141 fake_op_sig = {
142 .op = op,
143 .inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8),
144 };
145 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
146 }
147
148 // Similar to SimpleVersioningTest function, but
149 // op has 3 versions and the input type includes kTfLiteInt16.
SimpleVersioningTestExtended(BuiltinOperator op)150 void SimpleVersioningTestExtended(BuiltinOperator op) {
151 OpSignature fake_op_sig = {
152 .op = op,
153 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
154 };
155 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
156
157 SimpleVersioningTest(op);
158 }
159
160 // Test version for a simple Op with 2 versions and the output type controls the
SimpleOutputVersioningTest(BuiltinOperator op)161 void SimpleOutputVersioningTest(BuiltinOperator op) {
162 OpSignature fake_op_sig = {
163 .op = op,
164 .inputs = std::vector<OpSignatureTensorSpec>{},
165 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
166 };
167 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
168
169 fake_op_sig = {
170 .op = op,
171 .inputs = std::vector<OpSignatureTensorSpec>{},
172 .outputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8),
173 };
174 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
175 }
176
TEST(OpVersionTest,VersioningEqualTest)177 TEST(OpVersionTest, VersioningEqualTest) {
178 SimpleVersioningTest(BuiltinOperator_EQUAL);
179 OpSignature fake_op_sig = {
180 .op = BuiltinOperator_EQUAL,
181 .inputs = CreateOpSignatureTensorSpecs(kTfLiteString),
182 };
183 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
184 }
185
TEST(OpVersionTest,VersioningNotEqualTest)186 TEST(OpVersionTest, VersioningNotEqualTest) {
187 SimpleVersioningTest(BuiltinOperator_NOT_EQUAL);
188 OpSignature fake_op_sig = {
189 .op = BuiltinOperator_NOT_EQUAL,
190 .inputs = CreateOpSignatureTensorSpecs(kTfLiteString),
191 };
192 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
193 }
194
TEST(OpVersionTest,VersioningLessTest)195 TEST(OpVersionTest, VersioningLessTest) {
196 SimpleVersioningTest(BuiltinOperator_LESS);
197 }
198
TEST(OpVersionTest,VersioningLessEqualTest)199 TEST(OpVersionTest, VersioningLessEqualTest) {
200 SimpleVersioningTest(BuiltinOperator_LESS_EQUAL);
201 }
202
TEST(OpVersionTest,VersioningGreaterTest)203 TEST(OpVersionTest, VersioningGreaterTest) {
204 SimpleVersioningTest(BuiltinOperator_GREATER);
205 }
206
TEST(OpVersionTest,VersioningGreaterEqualTest)207 TEST(OpVersionTest, VersioningGreaterEqualTest) {
208 SimpleVersioningTest(BuiltinOperator_GREATER_EQUAL);
209 }
210
TEST(OpVersionTest,VersioningSpaceToBatchNDTest)211 TEST(OpVersionTest, VersioningSpaceToBatchNDTest) {
212 SimpleVersioningTest(BuiltinOperator_NOT_EQUAL);
213 }
214
TEST(OpVersionTest,VersioningLogSoftmaxTest)215 TEST(OpVersionTest, VersioningLogSoftmaxTest) {
216 SimpleVersioningTest(BuiltinOperator_LOG_SOFTMAX);
217 }
218
TEST(OpVersionTest,VersioningPackTest)219 TEST(OpVersionTest, VersioningPackTest) {
220 SimpleVersioningTest(BuiltinOperator_PACK);
221 }
222
TEST(OpVersionTest,VersioningUnpackTest)223 TEST(OpVersionTest, VersioningUnpackTest) {
224 OpSignature fake_op_sig = {
225 .op = BuiltinOperator_UNPACK,
226 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
227 };
228 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
229
230 fake_op_sig = {
231 .op = BuiltinOperator_UNPACK,
232 .inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8),
233 };
234 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
235
236 fake_op_sig = {
237 .op = BuiltinOperator_UNPACK,
238 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt32),
239 };
240 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
241 }
242
TEST(OpVersionTest,VersioningReluTest)243 TEST(OpVersionTest, VersioningReluTest) {
244 OpSignature fake_op_sig = {
245 .op = BuiltinOperator_RELU,
246 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
247 };
248 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
249
250 fake_op_sig = {
251 .op = BuiltinOperator_RELU,
252 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
253 };
254 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
255
256 fake_op_sig = {
257 .op = BuiltinOperator_RELU,
258 .inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8),
259 };
260 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
261
262 fake_op_sig = {
263 .op = BuiltinOperator_RELU,
264 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt32),
265 };
266 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
267 }
268
TEST(OpVersionTest,VersioningBatchToSpaceNDTest)269 TEST(OpVersionTest, VersioningBatchToSpaceNDTest) {
270 OpSignature fake_op_sig = {
271 .op = BuiltinOperator_BATCH_TO_SPACE_ND,
272 };
273 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8, 3);
274 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
275 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8, 4);
276 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
277
278 fake_op_sig = {
279 .op = BuiltinOperator_BATCH_TO_SPACE_ND,
280 };
281 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8, 3);
282 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
283 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8, 4);
284 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
285 }
286
TEST(OpVersionTest,VersioningTanhTest)287 TEST(OpVersionTest, VersioningTanhTest) {
288 SimpleVersioningTest(BuiltinOperator_TANH);
289 }
290
TEST(OpVersionTest,VersioningStridedSliceTest)291 TEST(OpVersionTest, VersioningStridedSliceTest) {
292 TfLiteStridedSliceParams strided_slice_params = {};
293 OpSignature fake_op_sig = {
294 .op = BuiltinOperator_STRIDED_SLICE,
295 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
296 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
297 .builtin_data = reinterpret_cast<void*>(&strided_slice_params),
298 };
299 strided_slice_params.ellipsis_mask = 0;
300 strided_slice_params.new_axis_mask = 2;
301 fake_op_sig.ext_options.strided_slice.num_dims = 5;
302 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 6);
303
304 strided_slice_params.new_axis_mask = 0;
305 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 4);
306
307 fake_op_sig.ext_options.strided_slice.num_dims = 4;
308 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
309
310 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8);
311 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
312 }
313
TEST(OpVersionTest,VersioningSpaceToDepthTest)314 TEST(OpVersionTest, VersioningSpaceToDepthTest) {
315 SimpleVersioningTest(BuiltinOperator_SPACE_TO_DEPTH);
316 }
317
TEST(OpVersionTest,VersioningSliceTest)318 TEST(OpVersionTest, VersioningSliceTest) {
319 OpSignature fake_op_sig = {
320 .op = BuiltinOperator_SLICE,
321 };
322 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt16, 5);
323 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 5);
324
325 fake_op_sig = {
326 .op = BuiltinOperator_SLICE,
327 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
328 };
329 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt16, 4);
330 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 4);
331
332 fake_op_sig = {
333 .op = BuiltinOperator_SLICE,
334 };
335 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteString, 4);
336 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
337
338 fake_op_sig = {
339 .op = BuiltinOperator_SLICE,
340 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
341 };
342 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8, 4);
343 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
344
345 fake_op_sig = {
346 .op = BuiltinOperator_SLICE,
347 };
348 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8, 4);
349 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
350 }
351
TEST(OpVersionTest,VersioningLogisticTest)352 TEST(OpVersionTest, VersioningLogisticTest) {
353 SimpleVersioningTest(BuiltinOperator_SPACE_TO_DEPTH);
354 }
355
TEST(OpVersionTest,VersioningL2NormTest)356 TEST(OpVersionTest, VersioningL2NormTest) {
357 SimpleOutputVersioningTest(BuiltinOperator_L2_NORMALIZATION);
358 }
359
TEST(OpVersionTest,VersioningMaxTest)360 TEST(OpVersionTest, VersioningMaxTest) {
361 OpSignature fake_op_sig = {
362 .op = BuiltinOperator_MAXIMUM,
363 };
364
365 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8, 4, 5);
366 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
367 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8, 5, 5);
368 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
369 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8, 4, 4);
370 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
371
372 fake_op_sig = {
373 .op = BuiltinOperator_MAXIMUM,
374 };
375 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8, 4, 5);
376 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
377 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8, 4, 4);
378 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
379 }
380
TEST(OpVersionTest,VersioningMinTest)381 TEST(OpVersionTest, VersioningMinTest) {
382 OpSignature fake_op_sig = {
383 .op = BuiltinOperator_MINIMUM,
384 };
385
386 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8, 4, 5);
387 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
388 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8, 5, 5);
389 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
390 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8, 4, 4);
391 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
392
393 fake_op_sig = {
394 .op = BuiltinOperator_MINIMUM,
395 };
396 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8, 4, 5);
397 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
398 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8, 4, 4);
399 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
400 }
401
TEST(OpVersionTest,VersioningMeanTest)402 TEST(OpVersionTest, VersioningMeanTest) {
403 SimpleVersioningTestExtended(BuiltinOperator_MEAN);
404 }
405
TEST(OpVersionTest,VersioningSumTest)406 TEST(OpVersionTest, VersioningSumTest) {
407 SimpleVersioningTest(BuiltinOperator_SUM);
408 }
409
TEST(OpVersionTest,VersioningReduceMinTest)410 TEST(OpVersionTest, VersioningReduceMinTest) {
411 SimpleVersioningTestExtended(BuiltinOperator_REDUCE_MIN);
412 }
413
TEST(OpVersionTest,VersioningReduceMaxTest)414 TEST(OpVersionTest, VersioningReduceMaxTest) {
415 SimpleVersioningTestExtended(BuiltinOperator_REDUCE_MAX);
416 }
417
TEST(OpVersionTest,VersioningReduceProdTest)418 TEST(OpVersionTest, VersioningReduceProdTest) {
419 OpSignature fake_op_sig;
420 fake_op_sig.op = BuiltinOperator_REDUCE_PROD;
421 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt16);
422 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
423
424 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8);
425 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
426
427 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32);
428 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
429 }
430
TEST(OpVersionTest,VersioningAddTest)431 TEST(OpVersionTest, VersioningAddTest) {
432 TfLiteAddParams add_params = {};
433 OpSignature fake_op_sig = {
434 .op = BuiltinOperator_ADD,
435 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
436 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
437 .builtin_data = reinterpret_cast<void*>(&add_params)};
438 add_params.pot_scale_int16 = false;
439 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
440
441 SimpleVersioningTest(BuiltinOperator_ADD);
442 }
443
TEST(OpVersionTest,VersioningSubTest)444 TEST(OpVersionTest, VersioningSubTest) {
445 TfLiteSubParams sub_params = {};
446 OpSignature fake_op_sig = {
447 .op = BuiltinOperator_SUB,
448 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
449 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
450 .builtin_data = reinterpret_cast<void*>(&sub_params)};
451 sub_params.pot_scale_int16 = false;
452 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 5);
453
454 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt64);
455 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 4);
456
457 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8, 4, 5);
458 fake_op_sig.outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8);
459 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
460
461 SimpleVersioningTest(BuiltinOperator_SUB);
462 }
463
TEST(OpVersionTest,VersioningMUL6Test)464 TEST(OpVersionTest, VersioningMUL6Test) {
465 OpSignature fake_op_sig;
466 fake_op_sig.op = BuiltinOperator_MUL;
467 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteComplex64);
468 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 6);
469 }
470
TEST(OpVersionTest,VersioningMUL5Test)471 TEST(OpVersionTest, VersioningMUL5Test) {
472 OpSignature fake_op_sig;
473 fake_op_sig.op = BuiltinOperator_MUL;
474 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt64);
475 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 5);
476 }
477
TEST(OpVersionTest,VersioningSub4Test)478 TEST(OpVersionTest, VersioningSub4Test) {
479 OpSignature fake_op_sig = {
480 .op = BuiltinOperator_SUB,
481 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt64),
482 };
483 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 4);
484 }
485
SimpleMulVersioningTest(TfLiteType data_type,float multiplier,int version)486 void SimpleMulVersioningTest(TfLiteType data_type, float multiplier,
487 int version) {
488 OpSignature fake_op_sig = {
489 .op = BuiltinOperator_MUL,
490 .inputs = CreateOpSignatureTensorSpecs(
491 std::vector<TfLiteType>{data_type, data_type}),
492 .outputs = CreateOpSignatureTensorSpecs(data_type),
493 };
494 fake_op_sig.ext_options.mul = {1.0f, 1.0f, 1.0f / multiplier};
495 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), version);
496 }
497
TEST(OpVersionTest,VersioningMulTest)498 TEST(OpVersionTest, VersioningMulTest) {
499 SimpleMulVersioningTest(kTfLiteUInt8, 0.5f, 1);
500 SimpleMulVersioningTest(kTfLiteInt8, 0.5f, 2);
501 SimpleMulVersioningTest(kTfLiteInt8, 2.0f, 3);
502 }
503
TEST(OpVersionTest,VersioningPadTest)504 TEST(OpVersionTest, VersioningPadTest) {
505 SimpleVersioningTest(BuiltinOperator_PAD);
506 }
507
TEST(OpVersionTest,VersioningPadV2Test)508 TEST(OpVersionTest, VersioningPadV2Test) {
509 SimpleVersioningTest(BuiltinOperator_PADV2);
510 }
511
TEST(OpVersionTest,VersioningConcatenationTest)512 TEST(OpVersionTest, VersioningConcatenationTest) {
513 SimpleVersioningTest(BuiltinOperator_CONCATENATION);
514 }
515
TEST(OpVersionTest,VersioningSelectTest)516 TEST(OpVersionTest, VersioningSelectTest) {
517 OpSignature fake_op_sig = {
518 .op = BuiltinOperator_SELECT,
519 .inputs = CreateOpSignatureTensorSpecs(
520 std::vector<TfLiteType>{kTfLiteUInt8, kTfLiteUInt8, kTfLiteUInt8}, 5),
521 .outputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8),
522 };
523 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
524 fake_op_sig = {
525 .op = BuiltinOperator_SELECT,
526 .inputs = CreateOpSignatureTensorSpecs(
527 std::vector<TfLiteType>{kTfLiteInt8, kTfLiteInt8, kTfLiteInt8}, 4),
528 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
529 };
530 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
531 fake_op_sig = {
532 .op = BuiltinOperator_SELECT,
533 .inputs = CreateOpSignatureTensorSpecs(
534 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteFloat32,
535 kTfLiteFloat32},
536 4),
537 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
538 };
539 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
540 }
541
TEST(OpVersionTest,VersioningRelu6Test)542 TEST(OpVersionTest, VersioningRelu6Test) {
543 SimpleVersioningTestExtended(BuiltinOperator_RELU6);
544 }
545
TEST(OpVersionTest,VersioningFullyConnectedTest)546 TEST(OpVersionTest, VersioningFullyConnectedTest) {
547 TfLiteFullyConnectedParams fully_connected_params = {};
548 OpSignature fake_op_sig = {
549 .op = BuiltinOperator_FULLY_CONNECTED,
550 .inputs = CreateOpSignatureTensorSpecs(
551 std::vector<TfLiteType>{kTfLiteUInt8, kTfLiteUInt8}),
552 .outputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8),
553 .builtin_data = reinterpret_cast<void*>(&fully_connected_params),
554 };
555 fully_connected_params.weights_format =
556 kTfLiteFullyConnectedWeightsFormatShuffled4x16Int8;
557 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 6);
558
559 fake_op_sig = {
560 .op = BuiltinOperator_FULLY_CONNECTED,
561 .inputs = CreateOpSignatureTensorSpecs(
562 std::vector<TfLiteType>{kTfLiteInt8, kTfLiteInt8}),
563 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
564 .builtin_data = reinterpret_cast<void*>(&fully_connected_params),
565 };
566 fully_connected_params.weights_format =
567 kTfLiteFullyConnectedWeightsFormatShuffled4x16Int8;
568 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 6);
569
570 fake_op_sig = {
571 .op = BuiltinOperator_FULLY_CONNECTED,
572 .inputs = CreateOpSignatureTensorSpecs(
573 std::vector<TfLiteType>{kTfLiteInt8, kTfLiteInt8}),
574 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
575 .builtin_data = reinterpret_cast<void*>(&fully_connected_params),
576 };
577 fully_connected_params.weights_format =
578 kTfLiteFullyConnectedWeightsFormatDefault;
579 fake_op_sig.ext_options.fully_connected.sparse_weight = true;
580 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 8);
581
582 fake_op_sig = {
583 .op = BuiltinOperator_FULLY_CONNECTED,
584 .inputs = CreateOpSignatureTensorSpecs(
585 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteInt8, kTfLiteFloat32}),
586 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
587 .builtin_data = reinterpret_cast<void*>(&fully_connected_params),
588 };
589 fully_connected_params.asymmetric_quantize_inputs = false;
590 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
591 fully_connected_params.asymmetric_quantize_inputs = true;
592 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 9);
593 }
594
TEST(OpVersionTest,VersioningDequantizeTest)595 TEST(OpVersionTest, VersioningDequantizeTest) {
596 OpSignature fake_op_sig = {
597 .op = BuiltinOperator_DEQUANTIZE,
598 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
599 };
600 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
601
602 fake_op_sig = {
603 .op = BuiltinOperator_DEQUANTIZE,
604 .inputs = CreateOpSignatureTensorSpecs(kTfLiteFloat16),
605 };
606 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
607
608 fake_op_sig = {
609 .op = BuiltinOperator_DEQUANTIZE,
610 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
611 };
612 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
613
614 fake_op_sig.ext_options.dequantize.is_per_channel_quantized = true;
615 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 5);
616
617 fake_op_sig = {
618 .op = BuiltinOperator_DEQUANTIZE,
619 .inputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
620 };
621 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
622 }
623
TEST(OpVersionTest,VersioningQuantizeTest)624 TEST(OpVersionTest, VersioningQuantizeTest) {
625 OpSignature fake_op_sig;
626 fake_op_sig.op = BuiltinOperator_QUANTIZE;
627 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32);
628 fake_op_sig.ext_options.quantize.is_per_channel_quantized = false;
629
630 fake_op_sig.outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8);
631 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
632
633 fake_op_sig.outputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8);
634 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
635
636 fake_op_sig.outputs = CreateOpSignatureTensorSpecs(kTfLiteInt16);
637 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
638
639 fake_op_sig.ext_options.quantize.is_per_channel_quantized = true;
640 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
641 }
642
TEST(OpVersionTest,VersioningConv2DTest)643 TEST(OpVersionTest, VersioningConv2DTest) {
644 OpSignature fake_op_sig = {
645 .op = BuiltinOperator_CONV_2D,
646 .inputs = CreateOpSignatureTensorSpecs(
647 std::vector<TfLiteType>{kTfLiteUInt8, kTfLiteUInt8}),
648 .outputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8),
649 };
650 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
651
652 fake_op_sig = {
653 .op = BuiltinOperator_CONV_2D,
654 .inputs = CreateOpSignatureTensorSpecs(
655 std::vector<TfLiteType>{kTfLiteInt8, kTfLiteInt8}),
656 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
657 };
658 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
659
660 fake_op_sig = {
661 .op = BuiltinOperator_CONV_2D,
662 .inputs = CreateOpSignatureTensorSpecs(
663 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteInt8}),
664 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
665 };
666 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
667
668 fake_op_sig = {
669 .op = BuiltinOperator_CONV_2D,
670 .inputs = CreateOpSignatureTensorSpecs(
671 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteInt8}),
672 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
673 };
674 fake_op_sig.ext_options.conv_2d.is_per_channel_quantized = true;
675 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 5);
676
677 fake_op_sig.op = BuiltinOperator_CONV_2D;
678 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(
679 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteInt8});
680 fake_op_sig.outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32);
681 fake_op_sig.ext_options.conv_2d.is_grouped_convolution = true;
682
683 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 6);
684 }
685
TEST(OpVersionTest,VersioningFloorDivOperatorTest)686 TEST(OpVersionTest, VersioningFloorDivOperatorTest) {
687 OpSignature fake_op_sig = {
688 .op = BuiltinOperator_FLOOR_DIV,
689 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt32),
690 };
691 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
692
693 fake_op_sig = {
694 .op = BuiltinOperator_FLOOR_DIV,
695 .inputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
696 };
697 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
698 }
699
TEST(OpVersionTest,VersioningTransposeConvOperatorTest)700 TEST(OpVersionTest, VersioningTransposeConvOperatorTest) {
701 OpSignature fake_op_sig = {
702 .op = BuiltinOperator_TRANSPOSE_CONV,
703 .inputs = CreateOpSignatureTensorSpecs(
704 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteUInt8}),
705 };
706 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
707
708 fake_op_sig = {
709 .op = BuiltinOperator_TRANSPOSE_CONV,
710 .inputs = CreateOpSignatureTensorSpecs(
711 std::vector<TfLiteType>{kTfLiteInt32, kTfLiteInt8, kTfLiteInt8}),
712 };
713 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
714
715 fake_op_sig = {
716 .op = BuiltinOperator_TRANSPOSE_CONV,
717 .inputs = CreateOpSignatureTensorSpecs(std::vector<TfLiteType>{
718 kTfLiteInt32, kTfLiteInt8, kTfLiteInt8, kTfLiteInt32}),
719 };
720 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
721
722 const auto none_type = kTfLiteNoType;
723 fake_op_sig = {
724 .op = BuiltinOperator_TRANSPOSE_CONV,
725 .inputs = CreateOpSignatureTensorSpecs(std::vector<TfLiteType>{
726 kTfLiteInt32, kTfLiteInt8, kTfLiteInt8, none_type}),
727 };
728 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
729 }
730
TEST(OpVersionTest,VersioningSVDFOperatorTest)731 TEST(OpVersionTest, VersioningSVDFOperatorTest) {
732 TfLiteSVDFParams svdf_params = {};
733 OpSignature fake_op_sig = {
734 .op = BuiltinOperator_SVDF,
735 .inputs = CreateOpSignatureTensorSpecs(std::vector<TfLiteType>{
736 kTfLiteFloat32, kTfLiteFloat32, kTfLiteFloat32, kTfLiteFloat32,
737 kTfLiteFloat32}),
738 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
739 .builtin_data = reinterpret_cast<void*>(&svdf_params),
740 };
741 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
742
743 fake_op_sig = {
744 .op = BuiltinOperator_SVDF,
745 .inputs = CreateOpSignatureTensorSpecs(
746 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteInt8, kTfLiteFloat32,
747 kTfLiteFloat32, kTfLiteFloat32}),
748 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
749 .builtin_data = reinterpret_cast<void*>(&svdf_params),
750 };
751 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
752 svdf_params.asymmetric_quantize_inputs = true;
753 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 4);
754
755 svdf_params = {};
756 fake_op_sig = {
757 .op = BuiltinOperator_SVDF,
758 .inputs = CreateOpSignatureTensorSpecs(std::vector<TfLiteType>{
759 kTfLiteInt8, kTfLiteInt8, kTfLiteInt32, kTfLiteInt32, kTfLiteInt16}),
760 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
761 .builtin_data = reinterpret_cast<void*>(&svdf_params),
762 };
763 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
764 }
765
TEST(OpVersionTest,VersioningDepthwiseConv2DTest)766 TEST(OpVersionTest, VersioningDepthwiseConv2DTest) {
767 TfLiteDepthwiseConvParams depthwise_conv_params = {};
768 OpSignature fake_op_sig = {
769 .op = BuiltinOperator_DEPTHWISE_CONV_2D,
770 .inputs = CreateOpSignatureTensorSpecs(
771 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteInt8}),
772 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
773 .builtin_data = reinterpret_cast<void*>(&depthwise_conv_params),
774 };
775 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 4);
776 fake_op_sig.ext_options.depthwise_conv_2d.is_per_channel_quantized = true;
777 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 6);
778
779 depthwise_conv_params = {};
780 fake_op_sig = {
781 .op = BuiltinOperator_DEPTHWISE_CONV_2D,
782 .inputs = CreateOpSignatureTensorSpecs(
783 std::vector<TfLiteType>{kTfLiteInt8, kTfLiteInt8}),
784 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
785 .builtin_data = reinterpret_cast<void*>(&depthwise_conv_params),
786 };
787 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
788
789 fake_op_sig = {
790 .op = BuiltinOperator_DEPTHWISE_CONV_2D,
791 .inputs = CreateOpSignatureTensorSpecs(
792 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteFloat32}),
793 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
794 .builtin_data = reinterpret_cast<void*>(&depthwise_conv_params),
795 };
796 depthwise_conv_params.dilation_width_factor = 2;
797 depthwise_conv_params.dilation_height_factor = 2;
798 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
799
800 fake_op_sig = {
801 .op = BuiltinOperator_DEPTHWISE_CONV_2D,
802 .inputs = CreateOpSignatureTensorSpecs(
803 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteFloat32}),
804 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
805 .builtin_data = reinterpret_cast<void*>(&depthwise_conv_params),
806 };
807 depthwise_conv_params.dilation_width_factor = 1;
808 depthwise_conv_params.dilation_height_factor = 1;
809 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
810 }
TEST(OpVersionTest,VersioningTileOperatorTest)811 TEST(OpVersionTest, VersioningTileOperatorTest) {
812 OpSignature fake_op_sig = {
813 .op = BuiltinOperator_TILE,
814 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt32),
815 };
816 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
817
818 fake_op_sig = {
819 .op = BuiltinOperator_TILE,
820 .inputs = CreateOpSignatureTensorSpecs(kTfLiteString),
821 };
822 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
823 }
TEST(OpVersionTest,VersioningTransposeTest)824 TEST(OpVersionTest, VersioningTransposeTest) {
825 OpSignature fake_op_sig = {
826 .op = BuiltinOperator_TRANSPOSE,
827 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
828 };
829 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 5);
830
831 fake_op_sig = {
832 .op = BuiltinOperator_TRANSPOSE,
833 };
834 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteBool, 5);
835 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 4);
836 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteBool, 4);
837 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
838
839 fake_op_sig = {
840 .op = BuiltinOperator_TRANSPOSE,
841 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
842 };
843 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
844
845 fake_op_sig = {
846 .op = BuiltinOperator_TRANSPOSE,
847 .inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8),
848 };
849 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
850 }
TEST(OpVersionTest,VersioningGatherNdOperatorTest)851 TEST(OpVersionTest, VersioningGatherNdOperatorTest) {
852 OpSignature fake_op_sig = {
853 .op = BuiltinOperator_GATHER_ND,
854 .inputs = CreateOpSignatureTensorSpecs(
855 std::vector<TfLiteType>{kTfLiteInt32, kTfLiteInt32}),
856 };
857 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
858
859 fake_op_sig = {
860 .op = BuiltinOperator_GATHER_ND,
861 .inputs = CreateOpSignatureTensorSpecs(
862 std::vector<TfLiteType>{kTfLiteString, kTfLiteInt32}),
863 };
864 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
865
866 fake_op_sig = {
867 .op = BuiltinOperator_GATHER_ND,
868 .inputs = CreateOpSignatureTensorSpecs(
869 std::vector<TfLiteType>{kTfLiteInt16, kTfLiteInt32}),
870 };
871 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
872 }
TEST(OpVersionTest,VersioningDivTest)873 TEST(OpVersionTest, VersioningDivTest) {
874 OpSignature fake_op_sig = {
875 .op = BuiltinOperator_DIV,
876 };
877 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8, 5, 4);
878 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
879 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8, 5, 5);
880 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
881 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8, 4, 4);
882 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
883 }
TEST(OpVersionTEst,VersioningFillTest)884 TEST(OpVersionTEst, VersioningFillTest) {
885 OpSignature fake_op_sig = {BuiltinOperator_FILL};
886 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(
887 std::vector<TfLiteType>{kTfLiteInt32, kTfLiteInt8});
888 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
889 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(
890 std::vector<TfLiteType>{kTfLiteInt64, kTfLiteInt16});
891 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
892 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(
893 std::vector<TfLiteType>{kTfLiteInt32, kTfLiteBool});
894 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
895 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(
896 std::vector<TfLiteType>{kTfLiteInt32, kTfLiteString});
897 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
898 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(
899 std::vector<TfLiteType>{kTfLiteInt32, kTfLiteInt32});
900 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
901 }
TEST(OpVersionTest,VersioningResizeBilinearTest)902 TEST(OpVersionTest, VersioningResizeBilinearTest) {
903 // Default.
904 TfLiteResizeBilinearParams resize_bilinear_params = {};
905 OpSignature fake_op_sig = {
906 .op = BuiltinOperator_RESIZE_BILINEAR,
907 .inputs = CreateOpSignatureTensorSpecs(
908 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteInt32}),
909 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
910 .builtin_data = reinterpret_cast<void*>(&resize_bilinear_params),
911 };
912 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
913
914 // align_corners=true is still version 1.
915 resize_bilinear_params.align_corners = true;
916 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
917
918 // half_pixel_centers=true must be version 3.
919 resize_bilinear_params.align_corners = false;
920 resize_bilinear_params.half_pixel_centers = true;
921 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
922
923 // int8 input is version 2.
924 resize_bilinear_params = {};
925 fake_op_sig = {
926 .op = BuiltinOperator_RESIZE_BILINEAR,
927 .inputs = CreateOpSignatureTensorSpecs(
928 std::vector<TfLiteType>{kTfLiteInt8, kTfLiteInt32}),
929 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
930 .builtin_data = reinterpret_cast<void*>(&resize_bilinear_params),
931 };
932 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
933
934 resize_bilinear_params.half_pixel_centers = true;
935 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
936
937 // int16 input is version 4.
938 resize_bilinear_params = {};
939 fake_op_sig = {
940 .op = BuiltinOperator_RESIZE_BILINEAR,
941 .inputs = CreateOpSignatureTensorSpecs(
942 std::vector<TfLiteType>{kTfLiteInt16, kTfLiteInt32}),
943 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
944 .builtin_data = reinterpret_cast<void*>(&resize_bilinear_params),
945 };
946 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 4);
947 }
TEST(OpVersionTest,VersioningResizeNearestNeighborTest)948 TEST(OpVersionTest, VersioningResizeNearestNeighborTest) {
949 // Default.
950 TfLiteResizeNearestNeighborParams resize_nearest_neighbor_params = {};
951 OpSignature fake_op_sig = {
952 .op = BuiltinOperator_RESIZE_NEAREST_NEIGHBOR,
953 .inputs = CreateOpSignatureTensorSpecs(
954 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteInt32}),
955 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
956 .builtin_data = reinterpret_cast<void*>(&resize_nearest_neighbor_params),
957 };
958 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
959
960 // align_corners=true is version 3.
961 resize_nearest_neighbor_params.align_corners = true;
962 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
963
964 // half_pixel_centers=true must be version 3.
965 resize_nearest_neighbor_params.align_corners = false;
966 resize_nearest_neighbor_params.half_pixel_centers = true;
967 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
968
969 // int8 input is version 2.
970 resize_nearest_neighbor_params = {};
971 fake_op_sig = {
972 .op = BuiltinOperator_RESIZE_NEAREST_NEIGHBOR,
973 .inputs = CreateOpSignatureTensorSpecs(
974 std::vector<TfLiteType>{kTfLiteInt8, kTfLiteInt32}),
975 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
976 .builtin_data = reinterpret_cast<void*>(&resize_nearest_neighbor_params),
977 };
978 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
979
980 resize_nearest_neighbor_params.align_corners = true;
981 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
982
983 // int16 input is version 4.
984 resize_nearest_neighbor_params = {};
985 fake_op_sig = {
986 .op = BuiltinOperator_RESIZE_NEAREST_NEIGHBOR,
987 .inputs = CreateOpSignatureTensorSpecs(
988 std::vector<TfLiteType>{kTfLiteInt16, kTfLiteInt32}),
989 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
990 .builtin_data = reinterpret_cast<void*>(&resize_nearest_neighbor_params),
991 };
992 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 4);
993 }
TEST(OpVersionTest,VersioningAbsTest)994 TEST(OpVersionTest, VersioningAbsTest) {
995 // Default.
996 OpSignature fake_op_sig = {
997 .op = BuiltinOperator_ABS,
998 .inputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
999 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
1000 };
1001 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
1002
1003 // int8 input is version 2.
1004 fake_op_sig = {
1005 .op = BuiltinOperator_ABS,
1006 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
1007 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
1008 };
1009 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
1010
1011 // int16 quantized input is version 3.
1012 fake_op_sig = {
1013 .op = BuiltinOperator_ABS,
1014 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
1015 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
1016 };
1017 fake_op_sig.ext_options.abs.input_quantized = true;
1018 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
1019 // int16 non-quantized input is version 4.
1020 fake_op_sig = {
1021 .op = BuiltinOperator_ABS,
1022 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
1023 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
1024 };
1025 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 4);
1026 }
TEST(OpVersionTest,VersioningBatchMatMulTest)1027 TEST(OpVersionTest, VersioningBatchMatMulTest) {
1028 // Default.
1029 TfLiteBatchMatMulParams batch_mat_mul_params = {};
1030 OpSignature fake_op_sig = {
1031 .op = BuiltinOperator_BATCH_MATMUL,
1032 .inputs = CreateOpSignatureTensorSpecs(
1033 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteFloat32}),
1034 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
1035 .builtin_data = reinterpret_cast<void*>(&batch_mat_mul_params),
1036 };
1037 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
1038
1039 // int8 input is version 2.
1040 batch_mat_mul_params = {};
1041 fake_op_sig = {
1042 .op = BuiltinOperator_BATCH_MATMUL,
1043 .inputs = CreateOpSignatureTensorSpecs(
1044 std::vector<TfLiteType>{kTfLiteInt8, kTfLiteInt8}),
1045 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
1046 .builtin_data = reinterpret_cast<void*>(&batch_mat_mul_params),
1047 };
1048 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
1049
1050 // int16 input is version 3.
1051 fake_op_sig = {
1052 .op = BuiltinOperator_BATCH_MATMUL,
1053 .inputs = CreateOpSignatureTensorSpecs(
1054 std::vector<TfLiteType>{kTfLiteInt16, kTfLiteInt8}),
1055 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
1056 .builtin_data = reinterpret_cast<void*>(&batch_mat_mul_params),
1057 };
1058 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
1059
1060 // Symmetric hybrid quantized input is version 1.
1061 fake_op_sig = {
1062 .op = BuiltinOperator_BATCH_MATMUL,
1063 .inputs = CreateOpSignatureTensorSpecs(
1064 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteInt8}),
1065 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
1066 .builtin_data = reinterpret_cast<void*>(&batch_mat_mul_params),
1067 };
1068 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
1069
1070 // Asymmetric hybrid quantized input is version 4.
1071 fake_op_sig = {
1072 .op = BuiltinOperator_BATCH_MATMUL,
1073 .inputs = CreateOpSignatureTensorSpecs(
1074 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteInt8}),
1075 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
1076 .builtin_data = reinterpret_cast<void*>(&batch_mat_mul_params),
1077 };
1078 batch_mat_mul_params.asymmetric_quantize_inputs = true;
1079 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 4);
1080 }
TEST(OpVersionTest,VersioningSquaredDifferenceTest)1081 TEST(OpVersionTest, VersioningSquaredDifferenceTest) {
1082 // Default.
1083 OpSignature fake_op_sig = {
1084 .op = BuiltinOperator_SQUARED_DIFFERENCE,
1085 .inputs = CreateOpSignatureTensorSpecs(
1086 std::vector<TfLiteType>{kTfLiteFloat32, kTfLiteFloat32}),
1087 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
1088 };
1089 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
1090
1091 // int8 input is version 2.
1092 fake_op_sig = {
1093 .op = BuiltinOperator_SQUARED_DIFFERENCE,
1094 .inputs = CreateOpSignatureTensorSpecs(
1095 std::vector<TfLiteType>{kTfLiteInt8, kTfLiteInt8}),
1096 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
1097 };
1098 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
1099 }
TEST(OpVersionTest,VersioningRsqrtTest)1100 TEST(OpVersionTest, VersioningRsqrtTest) {
1101 // Default.
1102 OpSignature fake_op_sig = {
1103 .op = BuiltinOperator_RSQRT,
1104 .inputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
1105 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
1106 };
1107 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
1108
1109 // int8 input is version 2.
1110 fake_op_sig = {
1111 .op = BuiltinOperator_RSQRT,
1112 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
1113 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
1114 };
1115 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
1116 }
TEST(OpVersionTest,VersioningBroadcastToTest)1117 TEST(OpVersionTest, VersioningBroadcastToTest) {
1118 OpSignature fake_op_sig = {
1119 .op = BuiltinOperator_BROADCAST_TO,
1120 .inputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
1121 .outputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32),
1122 };
1123 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
1124
1125 // Quantized broadcast_to op is version 3.
1126 fake_op_sig = {
1127 .op = BuiltinOperator_BROADCAST_TO,
1128 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
1129 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt8),
1130 };
1131 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
1132
1133 fake_op_sig = {
1134 .op = BuiltinOperator_BROADCAST_TO,
1135 .inputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
1136 .outputs = CreateOpSignatureTensorSpecs(kTfLiteInt16),
1137 };
1138 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 3);
1139 }
1140
TEST(OpVersionTest,VersioningGeluTest)1141 TEST(OpVersionTest, VersioningGeluTest) {
1142 OpSignature fake_op_sig;
1143 fake_op_sig.op = BuiltinOperator_GELU;
1144 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteFloat32);
1145 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 1);
1146
1147 fake_op_sig.op = BuiltinOperator_GELU;
1148 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteInt8);
1149 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
1150
1151 fake_op_sig.op = BuiltinOperator_GELU;
1152 fake_op_sig.inputs = CreateOpSignatureTensorSpecs(kTfLiteUInt8);
1153 EXPECT_EQ(GetBuiltinOperatorVersion(fake_op_sig), 2);
1154 }
1155 } // namespace tflite
1156