1 //*****************************************************************************
2 // Copyright 2017-2020 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //*****************************************************************************
17 #include "gtest/gtest.h"
18 #include "ngraph/ngraph.hpp"
19 #include "util/type_prop.hpp"
21 NGRAPH_SUPPRESS_DEPRECATED_START
24 using namespace ngraph;
26 TEST(type_prop, quantized_dot_8_bit_output)
28 element::Type f32 = element::f32;
29 element::Type i8 = element::i8;
30 element::Type u8 = element::u8;
31 element::Type input0_type = u8;
32 element::Type input1_type = i8;
33 element::Type output_type = i8;
34 element::Type scale_type = f32;
35 element::Type input0_zero_point_type = u8;
36 element::Type input1_zero_point_type = i8;
37 element::Type output_zero_point_type = i8;
38 Shape output_shape{64, 72};
41 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
42 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
43 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
44 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{});
45 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{});
46 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
47 auto quant_dot = make_shared<op::QuantizedDot>(input0,
61 ASSERT_EQ(quant_dot->get_element_type(), output_type);
62 ASSERT_EQ(quant_dot->get_shape(), output_shape);
65 TEST(type_prop, quantized_dot_32_bit_output)
67 element::Type f32 = element::f32;
68 element::Type i8 = element::i8;
69 element::Type u8 = element::u8;
70 element::Type i32 = element::i32;
71 element::Type input0_type = u8;
72 element::Type input1_type = i8;
73 element::Type output_type = i32;
74 element::Type scale_type = f32;
75 element::Type input0_zero_point_type = u8;
76 element::Type input1_zero_point_type = i8;
77 element::Type output_zero_point_type = i32;
78 Shape output_shape{64, 72};
81 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
82 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
83 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
84 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{});
85 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{});
86 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
87 auto quant_dot = make_shared<op::QuantizedDot>(input0,
101 ASSERT_EQ(quant_dot->get_element_type(), output_type);
102 ASSERT_EQ(quant_dot->get_shape(), output_shape);
105 TEST(type_prop, quantized_dot_non_quantized_input0_fails)
107 element::Type f32 = element::f32;
108 element::Type i8 = element::i8;
109 element::Type u8 = element::u8;
110 element::Type input0_type = f32;
111 element::Type input1_type = i8;
112 element::Type output_type = i8;
113 element::Type scale_type = f32;
114 element::Type input0_zero_point_type = u8;
115 element::Type input1_zero_point_type = i8;
116 element::Type output_zero_point_type = i8;
117 Shape output_shape{64, 72};
120 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
121 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
122 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
123 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{});
124 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{});
125 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
128 auto quant_dot = make_shared<op::QuantizedDot>(input0,
142 FAIL() << "Attempt to use non-quantized input0 not detected";
144 catch (const NodeValidationFailure& error)
146 EXPECT_HAS_SUBSTRING(error.what(), "Input0 element type (f32) must be a quantized type");
150 FAIL() << "Deduced type check failed for unexpected reason";
154 TEST(type_prop, quantized_dot_non_quantized_input1_fails)
156 element::Type f32 = element::f32;
157 element::Type i8 = element::i8;
158 element::Type u8 = element::u8;
159 element::Type input0_type = u8;
160 element::Type input1_type = f32;
161 element::Type output_type = i8;
162 element::Type scale_type = f32;
163 element::Type input0_zero_point_type = u8;
164 element::Type input1_zero_point_type = i8;
165 element::Type output_zero_point_type = i8;
166 Shape output_shape{64, 72};
169 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
170 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
171 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
172 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{});
173 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{});
174 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
177 auto quant_dot = make_shared<op::QuantizedDot>(input0,
191 FAIL() << "Attempt to use non-quantized input1 not detected";
193 catch (const NodeValidationFailure& error)
195 EXPECT_HAS_SUBSTRING(error.what(), "Input1 element type (f32) must be a quantized type");
199 FAIL() << "Deduced type check failed for unexpected reason";
203 TEST(type_prop, quantized_dot_dyn_output_fails)
205 element::Type f32 = element::f32;
206 element::Type i8 = element::i8;
207 element::Type u8 = element::u8;
208 element::Type input0_type = u8;
209 element::Type input1_type = i8;
210 element::Type output_type = element::dynamic;
211 element::Type scale_type = f32;
212 element::Type input0_zero_point_type = u8;
213 element::Type input1_zero_point_type = i8;
214 element::Type output_zero_point_type = i8;
215 Shape output_shape{64, 72};
218 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
219 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
220 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
221 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{});
222 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{});
223 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
226 auto quant_dot = make_shared<op::QuantizedDot>(input0,
240 FAIL() << "Attempt to use dynamic output type not detected";
242 catch (const NodeValidationFailure& error)
244 EXPECT_HAS_SUBSTRING(error.what(), "Output element type must not be dynamic");
248 FAIL() << "Deduced type check failed for unexpected reason";
252 TEST(type_prop, quantized_dot_non_floating_point_scale_fails)
254 element::Type f32 = element::f32;
255 element::Type i8 = element::i8;
256 element::Type u8 = element::u8;
257 element::Type input0_type = u8;
258 element::Type input1_type = i8;
259 element::Type output_type = i8;
260 element::Type scale_type = i8;
261 element::Type input0_zero_point_type = u8;
262 element::Type input1_zero_point_type = i8;
263 element::Type output_zero_point_type = i8;
264 Shape output_shape{64, 72};
267 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
268 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
269 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
270 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{});
271 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{});
272 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
275 auto quant_dot = make_shared<op::QuantizedDot>(input0,
289 FAIL() << "Attempt to non floating point scale not detected";
291 catch (const NodeValidationFailure& error)
293 EXPECT_HAS_SUBSTRING(error.what(), "Scale must be a floating point number");
297 FAIL() << "Deduced type check failed for unexpected reason";
301 TEST(type_prop, quantized_dot_input0_zero_point_type_mismatch_fails)
303 element::Type f32 = element::f32;
304 element::Type i8 = element::i8;
305 element::Type u8 = element::u8;
306 element::Type input0_type = u8;
307 element::Type input1_type = i8;
308 element::Type output_type = i8;
309 element::Type scale_type = f32;
310 element::Type input0_zero_point_type = i8;
311 element::Type input1_zero_point_type = i8;
312 element::Type output_zero_point_type = i8;
313 Shape output_shape{64, 72};
316 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
317 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
318 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
319 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{});
320 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{});
321 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
324 auto quant_dot = make_shared<op::QuantizedDot>(input0,
338 FAIL() << "Attempt to use zero point type different from input0 type not detected";
340 catch (const NodeValidationFailure& error)
342 EXPECT_HAS_SUBSTRING(
344 "Input0 Zero point element type (i8) must match input0 element type (u8)");
348 FAIL() << "Deduced type check failed for unexpected reason";
352 TEST(type_prop, quantized_dot_input1_zero_point_type_mismatch_fails)
354 element::Type f32 = element::f32;
355 element::Type i8 = element::i8;
356 element::Type u8 = element::u8;
357 element::Type input0_type = u8;
358 element::Type input1_type = i8;
359 element::Type output_type = i8;
360 element::Type scale_type = f32;
361 element::Type input0_zero_point_type = u8;
362 element::Type input1_zero_point_type = u8;
363 element::Type output_zero_point_type = i8;
364 Shape output_shape{64, 72};
367 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
368 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
369 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
370 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{});
371 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{});
372 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
375 auto quant_dot = make_shared<op::QuantizedDot>(input0,
389 FAIL() << "Attempt to use zero point type different from input1 type not detected";
391 catch (const NodeValidationFailure& error)
393 EXPECT_HAS_SUBSTRING(
395 "Input1 Zero point element type (u8) must match input1 element type (i8)");
399 FAIL() << "Deduced type check failed for unexpected reason";
403 TEST(type_prop, quantized_dot_non_scalar_input0_zero_point_fails)
405 element::Type f32 = element::f32;
406 element::Type i8 = element::i8;
407 element::Type u8 = element::u8;
408 element::Type input0_type = u8;
409 element::Type input1_type = i8;
410 element::Type output_type = i8;
411 element::Type scale_type = f32;
412 element::Type input0_zero_point_type = u8;
413 element::Type input1_zero_point_type = i8;
414 element::Type output_zero_point_type = i8;
415 Shape output_shape{64, 72};
418 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
419 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
420 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
421 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{1, 2});
422 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{});
423 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
426 auto quant_dot = make_shared<op::QuantizedDot>(input0,
440 FAIL() << "Attempt to use non scalar input0 zero point not detected";
442 catch (const NodeValidationFailure& error)
444 EXPECT_HAS_SUBSTRING(error.what(),
445 "Input0 scale and input0 zero point shape must be same and 1");
449 FAIL() << "Deduced type check failed for unexpected reason";
453 TEST(type_prop, quantized_dot_non_scalar_input1_zero_point_fails)
455 element::Type f32 = element::f32;
456 element::Type i8 = element::i8;
457 element::Type u8 = element::u8;
458 element::Type input0_type = u8;
459 element::Type input1_type = i8;
460 element::Type output_type = i8;
461 element::Type scale_type = f32;
462 element::Type input0_zero_point_type = u8;
463 element::Type input1_zero_point_type = i8;
464 element::Type output_zero_point_type = i8;
465 Shape output_shape{64, 72};
468 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
469 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
470 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
471 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{});
472 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{1, 2});
473 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
476 auto quant_dot = make_shared<op::QuantizedDot>(input0,
490 FAIL() << "Attempt to use non scalar input1 zero point not detected";
492 catch (const NodeValidationFailure& error)
494 EXPECT_HAS_SUBSTRING(error.what(),
495 "Input1 scale and input1 zero point shape must be same and 1");
499 FAIL() << "Deduced type check failed for unexpected reason";
503 TEST(type_prop, quantized_dot_non_scalar_output_zero_point_fails)
505 element::Type f32 = element::f32;
506 element::Type i8 = element::i8;
507 element::Type u8 = element::u8;
508 element::Type input0_type = u8;
509 element::Type input1_type = i8;
510 element::Type output_type = i8;
511 element::Type scale_type = f32;
512 element::Type input0_zero_point_type = u8;
513 element::Type input1_zero_point_type = i8;
514 element::Type output_zero_point_type = i8;
515 Shape output_shape{64, 72};
518 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
519 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
520 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
521 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{});
522 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{});
523 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{1, 2});
526 auto quant_dot = make_shared<op::QuantizedDot>(input0,
540 FAIL() << "Attempt to use non scalar output zero point not detected";
542 catch (const NodeValidationFailure& error)
544 EXPECT_HAS_SUBSTRING(error.what(),
545 "Output scale and output zero point shape must be same and 1");
549 FAIL() << "Deduced type check failed for unexpected reason";
553 TEST(type_prop, quantized_dot_non_empty_input0_axes)
555 element::Type f32 = element::f32;
556 element::Type i8 = element::i8;
557 element::Type u8 = element::u8;
558 element::Type input0_type = u8;
559 element::Type input1_type = i8;
560 element::Type output_type = i8;
561 element::Type scale_type = f32;
562 element::Type input0_zero_point_type = u8;
563 element::Type input1_zero_point_type = i8;
564 element::Type output_zero_point_type = i8;
565 Shape output_shape{64, 72};
568 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
569 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
570 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
571 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{});
572 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{});
573 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
576 auto quant_dot = make_shared<op::QuantizedDot>(input0,
590 FAIL() << "Attempt to use non empty input0 axes not detected";
592 catch (const NodeValidationFailure& error)
594 EXPECT_HAS_SUBSTRING(error.what(), "Input0, input1 and output AxisSet should be empty");
598 FAIL() << "Deduced type check failed for unexpected reason";
602 TEST(type_prop, quantized_dot_non_empty_input1_axes)
604 element::Type f32 = element::f32;
605 element::Type i8 = element::i8;
606 element::Type u8 = element::u8;
607 element::Type input0_type = u8;
608 element::Type input1_type = i8;
609 element::Type output_type = i8;
610 element::Type scale_type = f32;
611 element::Type input0_zero_point_type = u8;
612 element::Type input1_zero_point_type = i8;
613 element::Type output_zero_point_type = i8;
614 Shape output_shape{64, 72};
617 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
618 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
619 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
620 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{});
621 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{});
622 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
625 auto quant_dot = make_shared<op::QuantizedDot>(input0,
639 FAIL() << "Attempt to use non empty input1 axes not detected";
641 catch (const NodeValidationFailure& error)
643 EXPECT_HAS_SUBSTRING(error.what(), "Input0, input1 and output AxisSet should be empty");
647 FAIL() << "Deduced type check failed for unexpected reason";
651 TEST(type_prop, quantized_dot_non_empty_output_axes)
653 element::Type f32 = element::f32;
654 element::Type i8 = element::i8;
655 element::Type u8 = element::u8;
656 element::Type input0_type = u8;
657 element::Type input1_type = i8;
658 element::Type output_type = i8;
659 element::Type scale_type = f32;
660 element::Type input0_zero_point_type = u8;
661 element::Type input1_zero_point_type = i8;
662 element::Type output_zero_point_type = i8;
663 Shape output_shape{64, 72};
666 auto input0 = make_shared<op::Parameter>(input0_type, Shape{64, 3});
667 auto input1 = make_shared<op::Parameter>(input1_type, Shape{3, 72});
668 auto scale = make_shared<op::Parameter>(scale_type, Shape{});
669 auto input0_zero_point = make_shared<op::Parameter>(input0_zero_point_type, Shape{});
670 auto input1_zero_point = make_shared<op::Parameter>(input1_zero_point_type, Shape{});
671 auto output_zero_point = make_shared<op::Parameter>(output_zero_point_type, Shape{});
674 auto quant_dot = make_shared<op::QuantizedDot>(input0,
688 FAIL() << "Attempt to use non empty output axes not detected";
690 catch (const NodeValidationFailure& error)
692 EXPECT_HAS_SUBSTRING(error.what(), "Input0, input1 and output AxisSet should be empty");
696 FAIL() << "Deduced type check failed for unexpected reason";