quantizeLinear.https.any.js (35970B)
1 // META: title=test WebNN API quantizeLinear operation 2 // META: global=window 3 // META: variant=?cpu 4 // META: variant=?gpu 5 // META: variant=?npu 6 // META: script=../resources/utils.js 7 // META: timeout=long 8 9 'use strict'; 10 11 // Calculate a floating-point input down to a low-precision integer 12 // (typically uint8 with a zero-point bias) following the expression: 13 // output = clamp(roundToNearestEvens(input / scale) + zeroPoint, 0, 255). 14 // 15 // MLOperand quantizeLinear( 16 // MLOperand input, MLOperand scale, MLOperand zeroPoint, 17 // optional MLOperatorOptions options = {}); 18 19 20 const getQuantizeLinearPrecisionTolerance = (graphResources) => { 21 const toleranceValueDict = {int32: 1, int8: 1, uint8: 1, int4: 1, uint4: 1}; 22 const expectedDataType = 23 getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs); 24 return {metricType: 'ULP', value: toleranceValueDict[expectedDataType]}; 25 }; 26 27 const quantizeLinearTests = [ 28 // float32 tests 29 { 30 'name': 31 'quantizeLinear float32 0D constant tensor with int8 0D zeroPoint', 32 'graph': { 33 'inputs': { 34 'quantizeLinearInput': { 35 'data': [10.794857501983643], 36 'descriptor': {shape: [], dataType: 'float32'}, 37 'constant': true 38 }, 39 'quantizeLinearScale': { 40 'data': [1.1202747821807861], 41 'descriptor': {shape: [], dataType: 'float32'}, 42 'constant': true 43 }, 44 'quantizeLinearZeroPoint': { 45 'data': [1], 46 'descriptor': {shape: [], dataType: 'int8'}, 47 'constant': true 48 } 49 }, 50 'operators': [{ 51 'name': 'quantizeLinear', 52 'arguments': [ 53 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 54 {'zeroPoint': 'quantizeLinearZeroPoint'} 55 ], 56 'outputs': 'quantizeLinearOutput' 57 }], 58 'expectedOutputs': { 59 'quantizeLinearOutput': 60 {'data': [11], 'descriptor': {shape: [], dataType: 'int8'}} 61 } 62 } 63 }, 64 { 65 'name': 66 'quantizeLinear float32 0D tensor with int8 0D zeroPoint', 67 'graph': { 68 'inputs': { 69 'quantizeLinearInput': { 70 'data': [10.794857501983643], 71 'descriptor': {shape: [], dataType: 'float32'}, 72 'constant': false 73 }, 74 'quantizeLinearScale': { 75 'data': [1.1202747821807861], 76 'descriptor': {shape: [], dataType: 'float32'}, 77 'constant': true 78 }, 79 'quantizeLinearZeroPoint': { 80 'data': [1], 81 'descriptor': {shape: [], dataType: 'int8'}, 82 'constant': true 83 } 84 }, 85 'operators': [{ 86 'name': 'quantizeLinear', 87 'arguments': [ 88 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 89 {'zeroPoint': 'quantizeLinearZeroPoint'} 90 ], 91 'outputs': 'quantizeLinearOutput' 92 }], 93 'expectedOutputs': { 94 'quantizeLinearOutput': 95 {'data': [11], 'descriptor': {shape: [], dataType: 'int8'}} 96 } 97 } 98 }, 99 { 100 'name': 'quantizeLinear float32 1D constant tensor with uint8 1D zeroPoint', 101 'graph': { 102 'inputs': { 103 'quantizeLinearInput': { 104 'data': [ 105 -2.549168109893799, -4.794857501983643, 8.413617134094238, 106 6.108623504638672 107 ], 108 'descriptor': {shape: [4], dataType: 'float32'}, 109 'constant': true 110 }, 111 'quantizeLinearScale': { 112 'data': [ 113 9.343092918395996, 114 0.2800687253475189, 115 4.617084980010986, 116 1.1202747821807861, 117 ], 118 'descriptor': {shape: [4], dataType: 'float32'}, 119 'constant': true 120 }, 121 'quantizeLinearZeroPoint': { 122 'data': [128, 128, 128, 128], 123 'descriptor': {shape: [4], dataType: 'uint8'}, 124 'constant': true 125 } 126 }, 127 'operators': [{ 128 'name': 'quantizeLinear', 129 'arguments': [ 130 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 131 {'zeroPoint': 'quantizeLinearZeroPoint'} 132 ], 133 'outputs': 'quantizeLinearOutput' 134 }], 135 'expectedOutputs': { 136 'quantizeLinearOutput': { 137 'data': [128, 111, 130, 133], 138 'descriptor': {shape: [4], dataType: 'uint8'} 139 } 140 } 141 } 142 }, 143 { 144 'name': 145 'quantizeLinear float32 2D tensor broadcasting zeroPoint and scale', 146 'graph': { 147 'inputs': { 148 'quantizeLinearInput': { 149 'data': [ 150 -2.549168109893799, -4.794857501983643, 8.413617134094238, 151 6.108623504638672 152 ], 153 'descriptor': {shape: [2, 2], dataType: 'float32'}, 154 'constant': false 155 }, 156 'quantizeLinearScale': { 157 'data': [9.343092918395996], 158 'descriptor': {shape: [1, 1], dataType: 'float32'}, 159 'constant': true 160 }, 161 'quantizeLinearZeroPoint': { 162 'data': [128], 163 'descriptor': {shape: [1, 1], dataType: 'uint8'}, 164 'constant': true 165 } 166 }, 167 'operators': [{ 168 'name': 'quantizeLinear', 169 'arguments': [ 170 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 171 {'zeroPoint': 'quantizeLinearZeroPoint'} 172 ], 173 'outputs': 'quantizeLinearOutput' 174 }], 175 'expectedOutputs': { 176 'quantizeLinearOutput': { 177 'data': [128, 127, 129, 129], 178 'descriptor': {shape: [2, 2], dataType: 'uint8'} 179 } 180 } 181 } 182 }, 183 { 184 'name': 185 'quantizeLinear float32 4D tensor broadcasting scale and zeroPoint', 186 'graph': { 187 'inputs': { 188 'quantizeLinearInput': { 189 'data': [ 190 -2.549168109893799, -4.794857501983643, 8.413617134094238, 191 6.108623504638672 192 ], 193 'descriptor': {shape: [1, 1, 2, 2], dataType: 'float32'}, 194 'constant': false 195 }, 196 'quantizeLinearScale': { 197 'data': [0.2800687253475189, 4.617084980010986], 198 'descriptor': {shape: [1, 1, 2, 1], dataType: 'float32'}, 199 'constant': true 200 }, 201 'quantizeLinearZeroPoint': { 202 'data': [128, 128], 203 'descriptor': {shape: [1, 1, 2, 1], dataType: 'uint8'}, 204 'constant': true 205 } 206 }, 207 'operators': [{ 208 'name': 'quantizeLinear', 209 'arguments': [ 210 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 211 {'zeroPoint': 'quantizeLinearZeroPoint'} 212 ], 213 'outputs': 'quantizeLinearOutput' 214 }], 215 'expectedOutputs': { 216 'quantizeLinearOutput': { 217 'data': [119, 111, 130, 129], 218 'descriptor': {shape: [1, 1, 2, 2], dataType: 'uint8'} 219 } 220 } 221 } 222 }, 223 { 224 'name': 'per-tensor quantizeLinear for float32 4D tensor', 225 'graph': { 226 'inputs': { 227 'quantizeLinearInput': { 228 'data': [ 229 -2.549168109893799, -4.794857501983643, 8.413617134094238, 230 6.108623504638672 231 ], 232 'descriptor': {shape: [1, 1, 2, 2], dataType: 'float32'}, 233 'constant': false 234 }, 235 'quantizeLinearScale': { 236 'data': [ 237 0.2800687253475189, 4.617084980010986, 0.2800687253475189, 238 4.617084980010986 239 ], 240 'descriptor': {shape: [1, 1, 2, 2], dataType: 'float32'}, 241 'constant': true 242 }, 243 'quantizeLinearZeroPoint': { 244 'data': [128, 128, 128, 128], 245 'descriptor': {shape: [1, 1, 2, 2], dataType: 'uint8'}, 246 'constant': true 247 } 248 }, 249 'operators': [{ 250 'name': 'quantizeLinear', 251 'arguments': [ 252 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 253 {'zeroPoint': 'quantizeLinearZeroPoint'} 254 ], 255 'outputs': 'quantizeLinearOutput' 256 }], 257 'expectedOutputs': { 258 'quantizeLinearOutput': { 259 'data': [119, 127, 158, 129], 260 'descriptor': {shape: [1, 1, 2, 2], dataType: 'uint8'} 261 } 262 } 263 } 264 }, 265 { 266 'name': 267 'quantizeLinear float32 3D tensor with implicit block_size = [1, 2, 1].', 268 'graph': { 269 'inputs': { 270 'quantizeLinearInput': { 271 'data': [ 272 -2.549168109893799, -4.794857501983643, 8.413617134094238, 273 6.108623504638672 274 ], 275 'descriptor': {shape: [1, 4, 1], dataType: 'float32'}, 276 'constant': false 277 }, 278 'quantizeLinearScale': { 279 'data': [0.2800687253475189, 4.617084980010986], 280 'descriptor': {shape: [1, 2, 1], dataType: 'float32'}, 281 'constant': true 282 }, 283 'quantizeLinearZeroPoint': { 284 'data': [128, 189], 285 'descriptor': {shape: [1, 2, 1], dataType: 'uint8'}, 286 'constant': true 287 } 288 }, 289 'operators': [{ 290 'name': 'quantizeLinear', 291 'arguments': [ 292 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 293 {'zeroPoint': 'quantizeLinearZeroPoint'} 294 ], 295 'outputs': 'quantizeLinearOutput' 296 }], 297 'expectedOutputs': { 298 'quantizeLinearOutput': { 299 'data': [119, 111, 191, 190], 300 'descriptor': {shape: [1, 4, 1], dataType: 'uint8'} 301 } 302 } 303 } 304 }, 305 { 306 'name': 307 'quantizeLinear float32 tensor with int4 zeroPoint which has odd size', 308 'graph': { 309 'inputs': { 310 'quantizeLinearInput': { 311 'data': [4.794857501983643], 312 'descriptor': {shape: [], dataType: 'float32'}, 313 'constant': false 314 }, 315 'quantizeLinearScale': { 316 'data': [1.1202747821807861], 317 'descriptor': {shape: [], dataType: 'float32'}, 318 'constant': true 319 }, 320 'quantizeLinearZeroPoint': { 321 'data': [-4], 322 'descriptor': {shape: [], dataType: 'int4'}, 323 'constant': true 324 } 325 }, 326 'operators': [{ 327 'name': 'quantizeLinear', 328 'arguments': [ 329 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 330 {'zeroPoint': 'quantizeLinearZeroPoint'} 331 ], 332 'outputs': 'quantizeLinearOutput' 333 }], 334 'expectedOutputs': { 335 'quantizeLinearOutput': 336 {'data': [0], 'descriptor': {shape: [], dataType: 'int4'}} 337 } 338 } 339 }, 340 { 341 'name': 342 'quantizeLinear float32 tensor with int4 zeroPoint which has even size', 343 'graph': { 344 'inputs': { 345 'quantizeLinearInput': { 346 'data': [4.794857501983643, 3.23434354545], 347 'descriptor': {shape: [2], dataType: 'float32'}, 348 'constant': false 349 }, 350 'quantizeLinearScale': { 351 'data': [1.1202747821807861, 1.1202747821807861], 352 'descriptor': {shape: [2], dataType: 'float32'}, 353 'constant': true 354 }, 355 'quantizeLinearZeroPoint': { 356 'data': [-6, -5], 357 'descriptor': {shape: [2], dataType: 'int4'}, 358 'constant': true 359 } 360 }, 361 'operators': [{ 362 'name': 'quantizeLinear', 363 'arguments': [ 364 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 365 {'zeroPoint': 'quantizeLinearZeroPoint'} 366 ], 367 'outputs': 'quantizeLinearOutput' 368 }], 369 'expectedOutputs': { 370 'quantizeLinearOutput': 371 {'data': [-2, -2], 'descriptor': {shape: [2], dataType: 'int4'}} 372 } 373 } 374 }, 375 { 376 'name': 377 'quantizeLinear float32 2D tensor with int4 zeroPoint which has even size', 378 'graph': { 379 'inputs': { 380 'quantizeLinearInput': { 381 'data': [ 382 4.794857501983643, 3.23434354545, 2.794857501983643, 383 5.794857501983643, 0, 7.23434354545 384 ], 385 'descriptor': {shape: [3, 2], dataType: 'float32'}, 386 'constant': false 387 }, 388 'quantizeLinearScale': { 389 'data': [1.1202747821807861, 2.1202747821807861], 390 'descriptor': {shape: [1, 2], dataType: 'float32'}, 391 'constant': true 392 }, 393 'quantizeLinearZeroPoint': { 394 'data': [-6, -5], 395 'descriptor': {shape: [1, 2], dataType: 'int4'}, 396 'constant': true 397 } 398 }, 399 'operators': [{ 400 'name': 'quantizeLinear', 401 'arguments': [ 402 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 403 {'zeroPoint': 'quantizeLinearZeroPoint'} 404 ], 405 'outputs': 'quantizeLinearOutput' 406 }], 407 'expectedOutputs': { 408 'quantizeLinearOutput': { 409 'data': [-2, -3, -4, -2, -6, -2], 410 'descriptor': {shape: [3, 2], dataType: 'int4'} 411 } 412 } 413 } 414 }, 415 { 416 'name': 417 'quantizeLinear float32 2D tensor with int4 zeroPoint with block_size = [3, 2]', 418 'graph': { 419 'inputs': { 420 'quantizeLinearInput': { 421 'data': [ 422 4.794857501983643, 3.23434354545, 2.794857501983643, 423 5.794857501983643, 0, 7.23434354545, 4.794857501983643, 424 3.23434354545, 2.794857501983643, 5.794857501983643, 0, 425 7.23434354545 426 ], 427 'descriptor': {shape: [3, 4], dataType: 'float32'}, 428 'constant': false 429 }, 430 'quantizeLinearScale': { 431 'data': [1.1202747821807861, 2.1202747821807861], 432 'descriptor': {shape: [1, 2], dataType: 'float32'}, 433 'constant': true 434 }, 435 'quantizeLinearZeroPoint': { 436 'data': [-6, -5], 437 'descriptor': {shape: [1, 2], dataType: 'int4'}, 438 'constant': true 439 } 440 }, 441 'operators': [{ 442 'name': 'quantizeLinear', 443 'arguments': [ 444 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 445 {'zeroPoint': 'quantizeLinearZeroPoint'} 446 ], 447 'outputs': 'quantizeLinearOutput' 448 }], 449 'expectedOutputs': { 450 'quantizeLinearOutput': { 451 'data': [-2, -3, -4, -2, -6, 0, -3, -3, -4, -1, -5, -2], 452 'descriptor': {shape: [3, 4], dataType: 'int4'} 453 } 454 } 455 } 456 }, 457 { 458 'name': 459 'quantizeLinear float32 tensor with uint4 zeroPoint which has odd size', 460 'graph': { 461 'inputs': { 462 'quantizeLinearInput': { 463 'data': [ 464 4.794857501983643, 2.794857501983643, 1.794857501983643, 0, 465 3.794857501983643 466 ], 467 'descriptor': {shape: [5], dataType: 'float32'}, 468 'constant': false 469 }, 470 'quantizeLinearScale': { 471 'data': [1.1202747821807861], 472 'descriptor': {shape: [1], dataType: 'float32'}, 473 'constant': true 474 }, 475 'quantizeLinearZeroPoint': { 476 'data': [10], 477 'descriptor': {shape: [1], dataType: 'uint4'}, 478 'constant': true 479 } 480 }, 481 'operators': [{ 482 'name': 'quantizeLinear', 483 'arguments': [ 484 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 485 {'zeroPoint': 'quantizeLinearZeroPoint'} 486 ], 487 'outputs': 'quantizeLinearOutput' 488 }], 489 'expectedOutputs': { 490 'quantizeLinearOutput': { 491 'data': [14, 12, 12, 10, 13], 492 'descriptor': {shape: [5], dataType: 'uint4'} 493 } 494 } 495 } 496 }, 497 { 498 'name': 499 'quantizeLinear float32 tensor with uint4 zeroPoint which has even size', 500 'graph': { 501 'inputs': { 502 'quantizeLinearInput': { 503 'data': [4.794857501983643, 3.23434354545], 504 'descriptor': {shape: [2], dataType: 'float32'}, 505 'constant': false 506 }, 507 'quantizeLinearScale': { 508 'data': [1.1202747821807861, 1.1202747821807861], 509 'descriptor': {shape: [2], dataType: 'float32'}, 510 'constant': true 511 }, 512 'quantizeLinearZeroPoint': { 513 'data': [1, 5], 514 'descriptor': {shape: [2], dataType: 'uint4'}, 515 'constant': true 516 } 517 }, 518 'operators': [{ 519 'name': 'quantizeLinear', 520 'arguments': [ 521 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 522 {'zeroPoint': 'quantizeLinearZeroPoint'} 523 ], 524 'outputs': 'quantizeLinearOutput' 525 }], 526 'expectedOutputs': { 527 'quantizeLinearOutput': 528 {'data': [5, 8], 'descriptor': {shape: [2], dataType: 'uint4'}} 529 } 530 } 531 }, 532 { 533 'name': 534 'quantizeLinear float32 1D tensor with uint4 zeroPoint with block_size = 3', 535 'graph': { 536 'inputs': { 537 'quantizeLinearInput': { 538 'data': [ 539 4.794857501983643, 3.23434354545, 1.794857501983643, 2.23434354545, 540 4.794857501983643, 3.23434354545 541 ], 542 'descriptor': {shape: [6], dataType: 'float32'}, 543 'constant': false 544 }, 545 'quantizeLinearScale': { 546 'data': [1.1202747821807861, 1.1202747821807861], 547 'descriptor': {shape: [2], dataType: 'float32'}, 548 'constant': true 549 }, 550 'quantizeLinearZeroPoint': { 551 'data': [1, 5], 552 'descriptor': {shape: [2], dataType: 'uint4'}, 553 'constant': true 554 } 555 }, 556 'operators': [{ 557 'name': 'quantizeLinear', 558 'arguments': [ 559 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 560 {'zeroPoint': 'quantizeLinearZeroPoint'} 561 ], 562 'outputs': 'quantizeLinearOutput' 563 }], 564 'expectedOutputs': { 565 'quantizeLinearOutput': { 566 'data': [5, 4, 3, 7, 9, 8], 567 'descriptor': {shape: [6], dataType: 'uint4'} 568 } 569 } 570 } 571 }, 572 { 573 'name': 'quantizeLinear float32 tensor with int32 zeroPoint', 574 'graph': { 575 'inputs': { 576 'quantizeLinearInput': { 577 'data': [-22405.495643615723, 7391418.921366602], 578 'descriptor': {shape: [2], dataType: 'float32'}, 579 'constant': false 580 }, 581 'quantizeLinearScale': { 582 'data': [1.1202747821807861, 0.2800687253475189], 583 'descriptor': {shape: [2], dataType: 'float32'}, 584 'constant': true 585 }, 586 'quantizeLinearZeroPoint': { 587 'data': [32345, -2445234], 588 'descriptor': {shape: [2], dataType: 'int32'}, 589 'constant': true 590 } 591 }, 592 'operators': [{ 593 'name': 'quantizeLinear', 594 'arguments': [ 595 {'input': 'quantizeLinearInput'}, 596 {'scale': 'quantizeLinearScale'}, 597 {'zeroPoint': 'quantizeLinearZeroPoint'} 598 ], 599 'outputs': 'quantizeLinearOutput' 600 }], 601 'expectedOutputs': { 602 'quantizeLinearOutput': { 603 'data': [12345, 23946213], 604 'descriptor': {shape: [2], dataType: 'int32'} 605 } 606 } 607 } 608 }, 609 610 // float16 tests 611 { 612 'name': 613 'quantizeLinear float16 0D constant tensor with int8 0D zeroPoint', 614 'graph': { 615 'inputs': { 616 'quantizeLinearInput': { 617 'data': [10.796875], 618 'descriptor': {'shape': [], 'dataType': 'float16'}, 619 'constant': true 620 }, 621 'quantizeLinearScale': { 622 'data': [1.1201171875], 623 'descriptor': {'shape': [], 'dataType': 'float16'}, 624 'constant': true 625 }, 626 'quantizeLinearZeroPoint': { 627 'data': [1], 628 'descriptor': {'shape': [], 'dataType': 'int8'}, 629 'constant': true 630 } 631 }, 632 'operators': [{ 633 'name': 'quantizeLinear', 634 'arguments': [ 635 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 636 {'zeroPoint': 'quantizeLinearZeroPoint'} 637 ], 638 'outputs': 'quantizeLinearOutput' 639 }], 640 'expectedOutputs': { 641 'quantizeLinearOutput': 642 {'data': [11], 'descriptor': {'shape': [], 'dataType': 'int8'}} 643 } 644 } 645 }, 646 { 647 'name': 648 'quantizeLinear float16 0D tensor with int8 0D zeroPoint', 649 'graph': { 650 'inputs': { 651 'quantizeLinearInput': { 652 'data': [10.796875], 653 'descriptor': {'shape': [], 'dataType': 'float16'}, 654 'constant': false 655 }, 656 'quantizeLinearScale': { 657 'data': [1.1201171875], 658 'descriptor': {'shape': [], 'dataType': 'float16'}, 659 'constant': true 660 }, 661 'quantizeLinearZeroPoint': { 662 'data': [1], 663 'descriptor': {'shape': [], 'dataType': 'int8'}, 664 'constant': true 665 } 666 }, 667 'operators': [{ 668 'name': 'quantizeLinear', 669 'arguments': [ 670 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 671 {'zeroPoint': 'quantizeLinearZeroPoint'} 672 ], 673 'outputs': 'quantizeLinearOutput' 674 }], 675 'expectedOutputs': { 676 'quantizeLinearOutput': 677 {'data': [11], 'descriptor': {'shape': [], 'dataType': 'int8'}} 678 } 679 } 680 }, 681 { 682 'name': 'quantizeLinear float16 1D tensor with uint8 1D zeroPoint', 683 'graph': { 684 'inputs': { 685 'quantizeLinearInput': { 686 'data': [-2.548828125, -4.79296875, 8.4140625, 6.109375], 687 'descriptor': {'shape': [4], 'dataType': 'float16'}, 688 'constant': false 689 }, 690 'quantizeLinearScale': { 691 'data': [9.34375, 0.280029296875, 4.6171875, 1.1201171875], 692 'descriptor': {'shape': [4], 'dataType': 'float16'}, 693 'constant': true 694 }, 695 'quantizeLinearZeroPoint': { 696 'data': [128, 128, 128, 128], 697 'descriptor': {'shape': [4], 'dataType': 'uint8'}, 698 'constant': true 699 } 700 }, 701 'operators': [{ 702 'name': 'quantizeLinear', 703 'arguments': [ 704 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 705 {'zeroPoint': 'quantizeLinearZeroPoint'} 706 ], 707 'outputs': 'quantizeLinearOutput' 708 }], 709 'expectedOutputs': { 710 'quantizeLinearOutput': { 711 'data': [128, 111, 130, 133], 712 'descriptor': {'shape': [4], 'dataType': 'uint8'} 713 } 714 } 715 } 716 }, 717 { 718 'name': 719 'quantizeLinear float16 2D tensor broadcasting zeroPoint and scale', 720 'graph': { 721 'inputs': { 722 'quantizeLinearInput': { 723 'data': [-2.548828125, -4.79296875, 8.4140625, 6.109375], 724 'descriptor': {'shape': [2, 2], 'dataType': 'float16'}, 725 'constant': false 726 }, 727 'quantizeLinearScale': { 728 'data': [9.34375], 729 'descriptor': {'shape': [1, 1], 'dataType': 'float16'}, 730 'constant': true 731 }, 732 'quantizeLinearZeroPoint': { 733 'data': [128], 734 'descriptor': {'shape': [1, 1], 'dataType': 'uint8'}, 735 'constant': true 736 } 737 }, 738 'operators': [{ 739 'name': 'quantizeLinear', 740 'arguments': [ 741 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 742 {'zeroPoint': 'quantizeLinearZeroPoint'} 743 ], 744 'outputs': 'quantizeLinearOutput' 745 }], 746 'expectedOutputs': { 747 'quantizeLinearOutput': { 748 'data': [128, 127, 129, 129], 749 'descriptor': {'shape': [2, 2], 'dataType': 'uint8'} 750 } 751 } 752 } 753 }, 754 { 755 'name': 756 'quantizeLinear float16 4D tensor broadcasting scale and zeroPoint', 757 'graph': { 758 'inputs': { 759 'quantizeLinearInput': { 760 'data': [-2.548828125, -4.79296875, 8.4140625, 6.109375], 761 'descriptor': {'shape': [1, 1, 2, 2], 'dataType': 'float16'}, 762 'constant': false 763 }, 764 'quantizeLinearScale': { 765 'data': [0.280029296875, 4.6171875], 766 'descriptor': {'shape': [1, 1, 2, 1], 'dataType': 'float16'}, 767 'constant': true 768 }, 769 'quantizeLinearZeroPoint': { 770 'data': [128, 128], 771 'descriptor': {'shape': [1, 1, 2, 1], 'dataType': 'uint8'}, 772 'constant': true 773 } 774 }, 775 'operators': [{ 776 'name': 'quantizeLinear', 777 'arguments': [ 778 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 779 {'zeroPoint': 'quantizeLinearZeroPoint'} 780 ], 781 'outputs': 'quantizeLinearOutput' 782 }], 783 'expectedOutputs': { 784 'quantizeLinearOutput': { 785 'data': [119, 111, 130, 129], 786 'descriptor': {'shape': [1, 1, 2, 2], 'dataType': 'uint8'} 787 } 788 } 789 } 790 }, 791 { 792 'name': 'per-tensor quantizeLinear for float16 4D tensor', 793 'graph': { 794 'inputs': { 795 'quantizeLinearInput': { 796 'data': [-2.548828125, -4.79296875, 8.4140625, 6.109375], 797 'descriptor': {'shape': [1, 1, 2, 2], 'dataType': 'float16'}, 798 'constant': false 799 }, 800 'quantizeLinearScale': { 801 'data': [0.280029296875, 4.6171875, 0.280029296875, 4.6171875], 802 'descriptor': {'shape': [1, 1, 2, 2], 'dataType': 'float16'}, 803 'constant': true 804 }, 805 'quantizeLinearZeroPoint': { 806 'data': [128, 128, 128, 128], 807 'descriptor': {'shape': [1, 1, 2, 2], 'dataType': 'uint8'}, 808 'constant': true 809 } 810 }, 811 'operators': [{ 812 'name': 'quantizeLinear', 813 'arguments': [ 814 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 815 {'zeroPoint': 'quantizeLinearZeroPoint'} 816 ], 817 'outputs': 'quantizeLinearOutput' 818 }], 819 'expectedOutputs': { 820 'quantizeLinearOutput': { 821 'data': [119, 127, 158, 129], 822 'descriptor': {'shape': [1, 1, 2, 2], 'dataType': 'uint8'} 823 } 824 } 825 } 826 }, 827 { 828 'name': 829 'quantizeLinear float16 3D tensor with implicit block_size = [1, 2, 1].', 830 'graph': { 831 'inputs': { 832 'quantizeLinearInput': { 833 'data': [-2.548828125, -4.79296875, 8.4140625, 6.109375], 834 'descriptor': {'shape': [1, 4, 1], 'dataType': 'float16'}, 835 'constant': false 836 }, 837 'quantizeLinearScale': { 838 'data': [0.280029296875, 4.6171875], 839 'descriptor': {'shape': [1, 2, 1], 'dataType': 'float16'}, 840 'constant': true 841 }, 842 'quantizeLinearZeroPoint': { 843 'data': [128, 189], 844 'descriptor': {'shape': [1, 2, 1], 'dataType': 'uint8'}, 845 'constant': true 846 } 847 }, 848 'operators': [{ 849 'name': 'quantizeLinear', 850 'arguments': [ 851 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 852 {'zeroPoint': 'quantizeLinearZeroPoint'} 853 ], 854 'outputs': 'quantizeLinearOutput' 855 }], 856 'expectedOutputs': { 857 'quantizeLinearOutput': { 858 'data': [119, 111, 191, 190], 859 'descriptor': {'shape': [1, 4, 1], 'dataType': 'uint8'} 860 } 861 } 862 } 863 }, 864 { 865 'name': 866 'quantizeLinear float16 tensor with int4 zeroPoint which has odd size', 867 'graph': { 868 'inputs': { 869 'quantizeLinearInput': { 870 'data': [4.79296875], 871 'descriptor': {'shape': [], 'dataType': 'float16'}, 872 'constant': false 873 }, 874 'quantizeLinearScale': { 875 'data': [1.1201171875], 876 'descriptor': {'shape': [], 'dataType': 'float16'}, 877 'constant': true 878 }, 879 'quantizeLinearZeroPoint': { 880 'data': [-4], 881 'descriptor': {'shape': [], 'dataType': 'int4'}, 882 'constant': true 883 } 884 }, 885 'operators': [{ 886 'name': 'quantizeLinear', 887 'arguments': [ 888 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 889 {'zeroPoint': 'quantizeLinearZeroPoint'} 890 ], 891 'outputs': 'quantizeLinearOutput' 892 }], 893 'expectedOutputs': { 894 'quantizeLinearOutput': 895 {'data': [0], 'descriptor': {'shape': [], 'dataType': 'int4'}} 896 } 897 } 898 }, 899 { 900 'name': 901 'quantizeLinear float16 tensor with int4 zeroPoint which has even size', 902 'graph': { 903 'inputs': { 904 'quantizeLinearInput': { 905 'data': [4.79296875, 3.234375], 906 'descriptor': {'shape': [2], 'dataType': 'float16'}, 907 'constant': false 908 }, 909 'quantizeLinearScale': { 910 'data': [1.1201171875, 1.1201171875], 911 'descriptor': {'shape': [2], 'dataType': 'float16'}, 912 'constant': true 913 }, 914 'quantizeLinearZeroPoint': { 915 'data': [-6, -5], 916 'descriptor': {'shape': [2], 'dataType': 'int4'}, 917 'constant': true 918 } 919 }, 920 'operators': [{ 921 'name': 'quantizeLinear', 922 'arguments': [ 923 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 924 {'zeroPoint': 'quantizeLinearZeroPoint'} 925 ], 926 'outputs': 'quantizeLinearOutput' 927 }], 928 'expectedOutputs': { 929 'quantizeLinearOutput': 930 {'data': [-2, -2], 'descriptor': {'shape': [2], 'dataType': 'int4'}} 931 } 932 } 933 }, 934 { 935 'name': 936 'quantizeLinear float16 2D tensor with int4 zeroPoint which has even size', 937 'graph': { 938 'inputs': { 939 'quantizeLinearInput': { 940 'data': [4.79296875, 3.234375, 2.794921875, 5.79296875, 0, 7.234375], 941 'descriptor': {'shape': [3, 2], 'dataType': 'float16'}, 942 'constant': false 943 }, 944 'quantizeLinearScale': { 945 'data': [1.1201171875, 2.12109375], 946 'descriptor': {'shape': [1, 2], 'dataType': 'float16'}, 947 'constant': true 948 }, 949 'quantizeLinearZeroPoint': { 950 'data': [-6, -5], 951 'descriptor': {'shape': [1, 2], 'dataType': 'int4'}, 952 'constant': true 953 } 954 }, 955 'operators': [{ 956 'name': 'quantizeLinear', 957 'arguments': [ 958 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 959 {'zeroPoint': 'quantizeLinearZeroPoint'} 960 ], 961 'outputs': 'quantizeLinearOutput' 962 }], 963 'expectedOutputs': { 964 'quantizeLinearOutput': { 965 'data': [-2, -3, -4, -2, -6, -2], 966 'descriptor': {'shape': [3, 2], 'dataType': 'int4'} 967 } 968 } 969 } 970 }, 971 { 972 'name': 973 'quantizeLinear float16 2D tensor with int4 zeroPoint with block_size = [3, 2]', 974 'graph': { 975 'inputs': { 976 'quantizeLinearInput': { 977 'data': [ 978 4.79296875, 3.234375, 2.794921875, 5.79296875, 0, 7.234375, 979 4.79296875, 3.234375, 2.794921875, 5.79296875, 0, 7.234375 980 ], 981 'descriptor': {'shape': [3, 4], 'dataType': 'float16'}, 982 'constant': false 983 }, 984 'quantizeLinearScale': { 985 'data': [1.1201171875, 2.12109375], 986 'descriptor': {'shape': [1, 2], 'dataType': 'float16'}, 987 'constant': true 988 }, 989 'quantizeLinearZeroPoint': { 990 'data': [-6, -5], 991 'descriptor': {'shape': [1, 2], 'dataType': 'int4'}, 992 'constant': true 993 } 994 }, 995 'operators': [{ 996 'name': 'quantizeLinear', 997 'arguments': [ 998 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 999 {'zeroPoint': 'quantizeLinearZeroPoint'} 1000 ], 1001 'outputs': 'quantizeLinearOutput' 1002 }], 1003 'expectedOutputs': { 1004 'quantizeLinearOutput': { 1005 'data': [-2, -3, -4, -2, -6, 0, -3, -3, -4, -1, -5, -2], 1006 'descriptor': {'shape': [3, 4], 'dataType': 'int4'} 1007 } 1008 } 1009 } 1010 }, 1011 { 1012 'name': 1013 'quantizeLinear float16 tensor with uint4 zeroPoint which has odd size', 1014 'graph': { 1015 'inputs': { 1016 'quantizeLinearInput': { 1017 'data': [4.79296875, 2.794921875, 1.794921875, 0, 3.794921875], 1018 'descriptor': {'shape': [5], 'dataType': 'float16'}, 1019 'constant': false 1020 }, 1021 'quantizeLinearScale': { 1022 'data': [1.1201171875], 1023 'descriptor': {'shape': [1], 'dataType': 'float16'}, 1024 'constant': true 1025 }, 1026 'quantizeLinearZeroPoint': { 1027 'data': [10], 1028 'descriptor': {'shape': [1], 'dataType': 'uint4'}, 1029 'constant': true 1030 } 1031 }, 1032 'operators': [{ 1033 'name': 'quantizeLinear', 1034 'arguments': [ 1035 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 1036 {'zeroPoint': 'quantizeLinearZeroPoint'} 1037 ], 1038 'outputs': 'quantizeLinearOutput' 1039 }], 1040 'expectedOutputs': { 1041 'quantizeLinearOutput': { 1042 'data': [14, 12, 12, 10, 13], 1043 'descriptor': {'shape': [5], 'dataType': 'uint4'} 1044 } 1045 } 1046 } 1047 }, 1048 { 1049 'name': 1050 'quantizeLinear float16 tensor with uint4 zeroPoint which has even size', 1051 'graph': { 1052 'inputs': { 1053 'quantizeLinearInput': { 1054 'data': [4.79296875, 3.234375], 1055 'descriptor': {'shape': [2], 'dataType': 'float16'}, 1056 'constant': false 1057 }, 1058 'quantizeLinearScale': { 1059 'data': [1.1201171875, 1.1201171875], 1060 'descriptor': {'shape': [2], 'dataType': 'float16'}, 1061 'constant': true 1062 }, 1063 'quantizeLinearZeroPoint': { 1064 'data': [1, 5], 1065 'descriptor': {'shape': [2], 'dataType': 'uint4'}, 1066 'constant': true 1067 } 1068 }, 1069 'operators': [{ 1070 'name': 'quantizeLinear', 1071 'arguments': [ 1072 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 1073 {'zeroPoint': 'quantizeLinearZeroPoint'} 1074 ], 1075 'outputs': 'quantizeLinearOutput' 1076 }], 1077 'expectedOutputs': { 1078 'quantizeLinearOutput': 1079 {'data': [5, 8], 'descriptor': {'shape': [2], 'dataType': 'uint4'}} 1080 } 1081 } 1082 }, 1083 { 1084 'name': 1085 'quantizeLinear float16 1D tensor with uint4 zeroPoint with block_size = 3', 1086 'graph': { 1087 'inputs': { 1088 'quantizeLinearInput': { 1089 'data': [ 1090 4.794857501983643, 3.23434354545, 1.794857501983643, 2.23434354545, 1091 4.794857501983643, 3.23434354545 1092 ], 1093 'descriptor': {'shape': [6], 'dataType': 'float16'}, 1094 'constant': false 1095 }, 1096 'quantizeLinearScale': { 1097 'data': [1.1201171875, 1.1201171875], 1098 'descriptor': {'shape': [2], 'dataType': 'float16'}, 1099 'constant': true 1100 }, 1101 'quantizeLinearZeroPoint': { 1102 'data': [1, 5], 1103 'descriptor': {'shape': [2], 'dataType': 'uint4'}, 1104 'constant': true 1105 } 1106 }, 1107 'operators': [{ 1108 'name': 'quantizeLinear', 1109 'arguments': [ 1110 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 1111 {'zeroPoint': 'quantizeLinearZeroPoint'} 1112 ], 1113 'outputs': 'quantizeLinearOutput' 1114 }], 1115 'expectedOutputs': { 1116 'quantizeLinearOutput': { 1117 'data': [5, 4, 3, 7, 9, 8], 1118 'descriptor': {'shape': [6], 'dataType': 'uint4'} 1119 } 1120 } 1121 } 1122 }, 1123 { 1124 'name': 'quantizeLinear float16 tensor with int32 zeroPoint', 1125 'graph': { 1126 'inputs': { 1127 'quantizeLinearInput': { 1128 'data': [-22400, 8.4140625], 1129 'descriptor': {'shape': [2], 'dataType': 'float16'}, 1130 'constant': false 1131 }, 1132 'quantizeLinearScale': { 1133 'data': [1.1201171875, 0.280029296875], 1134 'descriptor': {'shape': [2], 'dataType': 'float16'}, 1135 'constant': true 1136 }, 1137 'quantizeLinearZeroPoint': { 1138 'data': [32345, -2445234], 1139 'descriptor': {'shape': [2], 'dataType': 'int32'}, 1140 'constant': true 1141 } 1142 }, 1143 'operators': [{ 1144 'name': 'quantizeLinear', 1145 'arguments': [ 1146 {'input': 'quantizeLinearInput'}, {'scale': 'quantizeLinearScale'}, 1147 {'zeroPoint': 'quantizeLinearZeroPoint'} 1148 ], 1149 'outputs': 'quantizeLinearOutput' 1150 }], 1151 'expectedOutputs': { 1152 'quantizeLinearOutput': { 1153 'data': [12347, -2445204], 1154 'descriptor': {'shape': [2], 'dataType': 'int32'} 1155 } 1156 } 1157 } 1158 } 1159 ]; 1160 1161 webnn_conformance_test( 1162 quantizeLinearTests, buildAndExecuteGraph, 1163 getQuantizeLinearPrecisionTolerance);