xref: /aosp_15_r20/external/tensorflow/tensorflow/lite/tools/versioning/op_version_test.cc (revision b6fb3261f9314811a0f4371741dbb8839866f948)
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