1//===-- TosaOps.td - TOSA dialect operation definitions ----*- tablegen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file defines the operation set for the TOSA dialect as defined in 10// the TOSA specfication (https://developer.mlplatform.org/w/tosa/). 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef TOSA_OPS 15#define TOSA_OPS 16 17include "mlir/IR/OpBase.td" 18 19include "mlir/Interfaces/SideEffectInterfaces.td" 20include "mlir/Interfaces/InferTypeOpInterface.td" 21include "mlir/Interfaces/LoopLikeInterface.td" 22include "mlir/Dialect/Tosa/IR/TosaInterfaces.td" 23 24include "mlir/Dialect/Tosa/IR/TosaTypesBase.td" 25include "mlir/Dialect/Tosa/IR/TosaOpBase.td" 26 27//===----------------------------------------------------------------------===// 28// TOSA Spec Section 2.2 29// Operator Class: Tensor Data Engine Operators. 30//===----------------------------------------------------------------------===// 31 32//===----------------------------------------------------------------------===// 33// Operator: argmax 34//===----------------------------------------------------------------------===// 35def Tosa_ArgMaxOp : Tosa_InferShapedTypeOp<"argmax"> { 36 let summary = "Perform argmax on the input."; 37 38 let description = [{ 39 This returns the index with the largest value across the given axis of the 40 input tensor. 41 }]; 42 43 let arguments = (ins 44 Tosa_Tensor: $input, 45 I32Attr: $axis, 46 DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode 47 ); 48 49 let results = (outs 50 Tosa_Tensor: $output 51 ); 52 53 let hasFolder = 1; 54 let hasVerifier = 1; 55} 56 57//===----------------------------------------------------------------------===// 58// Accumulator types. 59//===----------------------------------------------------------------------===// 60 61def Tosa_AccType : AnyTypeOf<[I<32>, I<48>, F16, F32]>; 62 63//===----------------------------------------------------------------------===// 64// Operator: avg_pool2d 65//===----------------------------------------------------------------------===// 66def Tosa_AvgPool2dOp : Tosa_InferShapedTypeOp<"avg_pool2d"> { 67 let summary = "Performs average pooling on the input."; 68 69 let description = [{ 70 This performs an average pooling over the given input tensor. A sliding 71 window of size given by <kernel size> is passed over the input tensor, with 72 the mean value being placed in the output tensor. 73 }]; 74 75 let arguments = (ins 76 Tosa_Tensor4D:$input, 77 Tosa_IntArrayAttr2:$kernel, 78 Tosa_IntArrayAttr2:$stride, 79 Tosa_IntArrayAttr4:$pad, 80 TypeAttrOf<Tosa_AccType>:$acc_type, 81 OptionalAttr<Tosa_UnaryOpQuantizationAttr>:$quantization_info 82 ); 83 84 let results = (outs 85 Tosa_Tensor4D:$output 86 ); 87 88 let builders = [Tosa_AvgPool2dOpQuantInfoBuilder]; 89 let hasVerifier = 1; 90} 91 92//===----------------------------------------------------------------------===// 93// Operator: conv2d 94//===----------------------------------------------------------------------===// 95def Tosa_Conv2DOp : Tosa_InferShapedTypeOp<"conv2d"> { 96 let summary = "2D Convolution Operator"; 97 98 let description = [{ 99 Performs a 2D convolution over the given tensor input, using the weight 100 tensor. 101 }]; 102 103 let arguments = (ins 104 Tosa_Tensor4D:$input, 105 TosaTensorRankOf<[Tosa_Weight], [4]>:$weight, 106 Tosa_Tensor1D:$bias, 107 Tosa_IntArrayAttr4:$pad, 108 Tosa_IntArrayAttr2:$stride, 109 Tosa_IntArrayAttr2:$dilation, 110 TypeAttrOf<Tosa_AccType>:$acc_type, 111 OptionalAttr<Tosa_ConvOpQuantizationAttr>:$quantization_info, 112 DefaultValuedOptionalAttr<BoolAttr, "false">:$local_bound 113 ); 114 115 let results = (outs 116 Tosa_Tensor4D:$output 117 ); 118 119 let builders = [Tosa_ConvOpQuantInfoBuilder]; 120 let hasVerifier = 1; 121} 122 123//===----------------------------------------------------------------------===// 124// Operator: conv3d 125//===----------------------------------------------------------------------===// 126def Tosa_Conv3DOp : Tosa_InferShapedTypeOp<"conv3d"> { 127 let summary = "3D Convolution operator"; 128 129 let description = [{ 130 Performs a 3D convolution over the given input tensor. 131 }]; 132 133 let arguments = (ins 134 Tosa_Tensor5D:$input, 135 TosaTensorRankOf<[Tosa_Weight], [5]>:$weight, 136 Tosa_Tensor1D:$bias, 137 Tosa_IntArrayAttr6:$pad, 138 Tosa_IntArrayAttr3:$stride, 139 Tosa_IntArrayAttr3:$dilation, 140 TypeAttrOf<Tosa_AccType>:$acc_type, 141 OptionalAttr<Tosa_ConvOpQuantizationAttr>:$quantization_info, 142 DefaultValuedOptionalAttr<BoolAttr, "false">:$local_bound 143 ); 144 145 let results = (outs 146 Tosa_Tensor5D:$output 147 ); 148 149 let builders = [Tosa_ConvOpQuantInfoBuilder]; 150 let hasVerifier = 1; 151} 152 153//===----------------------------------------------------------------------===// 154// Operator: depthwise_conv2d 155//===----------------------------------------------------------------------===// 156def Tosa_DepthwiseConv2DOp : Tosa_InferShapedTypeOp<"depthwise_conv2d"> { 157 let summary = "Depthwise 2D Convolution operator"; 158 159 let description = [{ 160 Performs 2D convolutions separately over each channel of the given tensor 161 input, using the weight tensor. 162 }]; 163 164 let arguments = (ins 165 Tosa_Tensor4D:$input, 166 TosaTensorRankOf<[Tosa_Weight], [4]>:$weight, 167 Tosa_Tensor1D:$bias, 168 Tosa_IntArrayAttr4:$pad, 169 Tosa_IntArrayAttr2:$stride, 170 Tosa_IntArrayAttr2:$dilation, 171 TypeAttrOf<Tosa_AccType>:$acc_type, 172 OptionalAttr<Tosa_ConvOpQuantizationAttr>:$quantization_info, 173 DefaultValuedOptionalAttr<BoolAttr, "false">:$local_bound 174 ); 175 176 let results = (outs 177 Tosa_Tensor4D:$output 178 ); 179 180 let builders = [Tosa_ConvOpQuantInfoBuilder]; 181 let hasVerifier = 1; 182} 183 184//===----------------------------------------------------------------------===// 185// Operator: fft2d 186//===----------------------------------------------------------------------===// 187def Tosa_FFT2dOp : Tosa_InferShapedTypeOp<"fft2d"> { 188 let summary = "Performs FFT2D operation on the input."; 189 190 let description = [{ 191 Performs a batched complex 2D Fast Fourier Transform over the input. The 192 complex input values are constructed from the corresponding values in the 193 input_real and input_imag tensors. The resulting values in the output are 194 split into the output_real and output_imag tensors. No normalization is 195 applied on either the forward or inverse versions of the operation. 196 197 Example: 198 199 ```mlir 200 %out_real, %out_imag = tosa.fft2d %in_real, %in_imag : (tensor<8x9xf32>, tensor<8x9xf32>) -> (tensor<8x9xf32>, tensor<8x9xf32>) 201 ``` 202 }]; 203 204 let arguments = (ins 205 Tosa_Tensor3D:$input_real, 206 Tosa_Tensor3D:$input_imag, 207 208 BoolAttr:$inverse, 209 DefaultValuedOptionalAttr<BoolAttr, "false">:$local_bound 210 ); 211 212 let results = (outs 213 Tosa_Tensor3D:$output_real, 214 Tosa_Tensor3D:$output_imag 215 ); 216 217 let assemblyFormat = [{ 218 $input_real `,` $input_imag attr-dict `:` `(` type($input_real) `,` 219 type($input_imag) `)` `->` `(` type($output_real) `,` type($output_imag) `)` 220 }]; 221} 222 223//===----------------------------------------------------------------------===// 224// Operator: fully_connected 225//===----------------------------------------------------------------------===// 226def Tosa_FullyConnectedOp : Tosa_InferShapedTypeOp<"fully_connected"> { 227 let summary = "Fully Connected operator"; 228 229 let description = [{ 230 Performs a fully connected network. 231 }]; 232 233 let arguments = (ins 234 Tosa_Tensor2D:$input, 235 TosaTensorRankOf<[Tosa_Weight], [2]>:$weight, 236 Tosa_Tensor1D:$bias, 237 OptionalAttr<Tosa_ConvOpQuantizationAttr>:$quantization_info 238 ); 239 240 let results = (outs 241 Tosa_Tensor2D:$output 242 ); 243 244 let builders = [Tosa_FCOpQuantInfoBuilder]; 245 let hasVerifier = 1; 246} 247 248//===----------------------------------------------------------------------===// 249// Operator: matmul 250//===----------------------------------------------------------------------===// 251def Tosa_MatMulOp : Tosa_InferShapedTypeOp<"matmul"> { 252 let summary = "Matrix multiplication with bias"; 253 254 let description = [{ 255 Performs a two dimensional matrix multiplication. This allows both inputs to 256 be activations, rather than reserving weights as an attribute in the 257 FULLY_CONNECTED operator. 258 }]; 259 260 let arguments = (ins 261 Tosa_Tensor3D:$a, 262 Tosa_Tensor3D:$b, 263 OptionalAttr<Tosa_MatMulOpQuantizationAttr>:$quantization_info 264 ); 265 266 let results = (outs 267 Tosa_Tensor3D:$c 268 ); 269 270 let builders = [Tosa_MatMulOpQuantInfoBuilder]; 271} 272 273//===----------------------------------------------------------------------===// 274// Operator: max_pool2d 275//===----------------------------------------------------------------------===// 276def Tosa_MaxPool2dOp : Tosa_InferShapedTypeOp<"max_pool2d"> { 277 let summary = "Performs max pooling on the input."; 278 279 let description = [{ 280 This performs a max pooling over the given input tensor. A sliding window of 281 size given by <kernel size> is passed over the input tensor, with the 282 maximum value being placed in the 283 output tensor. 284 }]; 285 286 let arguments = (ins 287 Tosa_Tensor4D:$input, 288 289 Tosa_IntArrayAttr2:$kernel, 290 Tosa_IntArrayAttr2:$stride, 291 Tosa_IntArrayAttr4:$pad, 292 DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode 293 ); 294 295 let results = (outs 296 Tosa_Tensor4D:$output 297 ); 298 299 let hasCanonicalizer = 1; 300} 301 302//===----------------------------------------------------------------------===// 303// Operator: rfft2d 304//===----------------------------------------------------------------------===// 305def Tosa_RFFT2dOp : Tosa_InferShapedTypeOp<"rfft2d"> { 306 let summary = "Performs RFFT2D operation on the input."; 307 308 let description = [{ 309 Performs a batched 2D real-valued Fast Fourier Transform over the input where 310 the input tensor consists of real values producing complex valued output. The 311 complex output values will be split into the output_real and output_imag 312 tensor arguments. RFFT2D takes advantage of Hermitian symmetry to only 313 calculate the first half of the final output axis. Imaginary values with 314 locations (0,0), (0,W/2), (H/2,0) and (H/2,W/2) are zero. 315 316 Example: 317 318 ```mlir 319 %real, %imag = tosa.rfft2d %in : (tensor<8x16xf32>) -> (tensor<8x9xf32>, tensor<8x9xf32>) 320 ``` 321 }]; 322 323 let arguments = (ins 324 Tosa_Tensor3D:$input, 325 DefaultValuedOptionalAttr<BoolAttr, "false">:$local_bound 326 ); 327 328 let results = (outs 329 Tosa_Tensor3D:$output_real, 330 Tosa_Tensor3D:$output_imag 331 ); 332 333 let assemblyFormat = [{ 334 $input attr-dict `:` `(` type($input) `)` `->` `(` type($output_real) `,` type($output_imag) `)` 335 }]; 336} 337 338//===----------------------------------------------------------------------===// 339// Operator: transpose_conv2d 340//===----------------------------------------------------------------------===// 341def Tosa_TransposeConv2DOp : Tosa_InferShapedTypeOp<"transpose_conv2d"> { 342 let summary = "Transpose 2D Convolution operator."; 343 344 let description = [{ 345 Performs a 2D transposed convolution over the given tensor input, using the 346 weights tensor. 347 }]; 348 349 let arguments = (ins 350 Tosa_Tensor4D:$input, 351 TosaTensorRankOf<[Tosa_Weight], [4]>:$filter, 352 Tosa_Tensor1D:$bias, 353 Tosa_IntArrayAttr4:$out_pad, 354 Tosa_IntArrayAttr2:$stride, 355 Tosa_IntArrayAttr4:$out_shape, 356 TypeAttrOf<Tosa_AccType>:$acc_type, 357 OptionalAttr<Tosa_ConvOpQuantizationAttr>:$quantization_info, 358 DefaultValuedOptionalAttr<BoolAttr, "false">:$local_bound 359 ); 360 361 let results = (outs 362 Tosa_Tensor4D:$output 363 ); 364 365 let builders = [Tosa_TransConvOpQuantInfoBuilder]; 366 let hasVerifier = 1; 367} 368 369//===----------------------------------------------------------------------===// 370// TOSA Spec Section 2.3 371// Operator Class: Activation Functions. 372//===----------------------------------------------------------------------===// 373 374//===----------------------------------------------------------------------===// 375// Operator: clamp 376//===----------------------------------------------------------------------===// 377def Tosa_ClampOp : Tosa_ElementwiseUnaryOp<"clamp"> { 378 let summary = "Computes clamp(features, min, max)."; 379 380 let description = [{ 381 Clamp to an arbitrary minimum and maximum value. 382 Maximum and minimum values are specified as values in the range of the 383 input type. 384 No zero point subtraction is done to the values, thus to clamp to the zero 385 point value, the zero point itself should be supplied as the minimum value. 386 }]; 387 388 let arguments = (ins 389 Tosa_Tensor:$input, 390 I64Attr:$min_int, 391 I64Attr:$max_int, 392 Tosa_FloatAttr:$min_fp, 393 Tosa_FloatAttr:$max_fp, 394 DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode 395 ); 396 397 let results = (outs 398 Tosa_Tensor:$output 399 ); 400 401 let hasCanonicalizer = 1; 402 let hasVerifier = 1; 403} 404 405//===----------------------------------------------------------------------===// 406// Operator: sigmoid 407//===----------------------------------------------------------------------===// 408def Tosa_SigmoidOp : Tosa_ElementwiseUnaryOp<"sigmoid"> { 409 let summary = "Computes elementwise sigmoid of input."; 410 411 let description = [{ 412 Sigmoid function: output = 1 / (1 + exp(-input)) 413 For quantized integer data types, the TABLE operator should be used instead 414 with the following definition. The sigmoid table has 513 entries each of 415 16-bit precision and covering the input range -16.0 to +16.0 416 in steps of 1/16. 417 }]; 418 419 let arguments = (ins 420 Tosa_Tensor:$input 421 ); 422 423 let results = (outs 424 Tosa_Tensor:$output 425 ); 426} 427 428//===----------------------------------------------------------------------===// 429// Operator: tanh 430//===----------------------------------------------------------------------===// 431def Tosa_TanhOp : Tosa_ElementwiseUnaryOp<"tanh"> { 432 let summary = "Computes elementwise hyperbolic tangent of input"; 433 434 let description = [{ 435 Parameterized hyperbolic tangent. 436 For quantized integer data types, the TABLE operator should be used instead 437 with the following definition. The tanh_table has 513 entries each of 438 16-bit precision and covering the input range -8.0 to +8.0 in steps of 1/32. 439 }]; 440 441 let arguments = (ins 442 Tosa_Tensor:$input 443 ); 444 445 let results = (outs 446 Tosa_Tensor:$output 447 ); 448} 449 450//===----------------------------------------------------------------------===// 451// Operator: erf 452//===----------------------------------------------------------------------===// 453def Tosa_ErfOp : Tosa_ElementwiseUnaryOp<"erf"> { 454 let summary = "Computes gauss error function of input"; 455 456 let description = [{ 457 Gauss error function: $ erf(x) = \frac{2}{\sqrt(\pi)} \int_{0}^{x} e^{-t^2} \ dt $ 458 For quantized integer data types, the TABLE operator should be used instead 459 with the following definition. The erf_table has 513 entries each of 460 16-bit/8-bit precision and covering the input range -4.0 to +4.0 in steps of 1/64. 461 }]; 462 463 let arguments = (ins 464 Tosa_Tensor:$input 465 ); 466 467 let results = (outs 468 Tosa_Tensor:$output 469 ); 470 471 let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)"; 472} 473 474//===----------------------------------------------------------------------===// 475// TOSA Spec Section 2.4 476// Operator Class: Elementwise unary/binary/ternary operators. 477// Operator Subclass: Elementwise binary ops. 478//===----------------------------------------------------------------------===// 479 480//===----------------------------------------------------------------------===// 481// Operator: add 482//===----------------------------------------------------------------------===// 483def Tosa_AddOp : Tosa_ElementwiseOp<"add", [ 484 Commutative, 485 ResultsBroadcastableShape, 486 SameOperandsAndResultElementType, 487 SameOperandsAndResultRank]> { 488 let summary = "Elementwise addition operator"; 489 490 let description = [{ 491 Elementwise addition of input1 and input2. Axis of size 1 will be broadcast, 492 as necessary. 493 494 Example: 495 496 ```mlir 497 // Elementwise addition. 498 %out = tosa.add %in1, %in2 : tensor<12x6xf32>, tensor<12x6xf32> -> tensor<12x6xf32> 499 500 // Elementwise addition with broadcasting. 501 %out = tosa.add %in1, %in2 : tensor<12x6xsi32>, tensor<1x1xsi32> -> tensor<12x6xsi32> 502 ``` 503 }]; 504 505 let arguments = (ins 506 Tosa_Tensor:$input1, 507 Tosa_Tensor:$input2 508 ); 509 510 let results = (outs 511 Tosa_Tensor:$output 512 ); 513 514 let hasFolder = 1; 515} 516 517//===----------------------------------------------------------------------===// 518// Operator: arithmetic_right_shift 519//===----------------------------------------------------------------------===// 520def Tosa_ArithmeticRightShiftOp : Tosa_ElementwiseOp<"arithmetic_right_shift", [ 521 ResultsBroadcastableShape, 522 SameOperandsAndResultElementType, 523 SameOperandsAndResultRank]> { 524 let summary = "Elementwise Arithmetic Right Shift"; 525 526 let description = [{ 527 Elementwise arithmetic right shift of input1 by the amount specified in 528 input2. Axis of size 1 will be broadcast, as necessary. 529 }]; 530 531 let arguments = (ins 532 Tosa_Tensor:$input1, 533 Tosa_Tensor:$input2, 534 BoolAttr:$round 535 ); 536 537 let results = (outs 538 Tosa_Tensor:$output 539 ); 540} 541 542//===----------------------------------------------------------------------===// 543// Operator: bitwise_and 544//===----------------------------------------------------------------------===// 545def Tosa_BitwiseAndOp : Tosa_ElementwiseOp<"bitwise_and", [ 546 Commutative, 547 ResultsBroadcastableShape, 548 SameOperandsAndResultElementType, 549 SameOperandsAndResultRank]> { 550 let summary = "Bitwise AND operator"; 551 552 let description = [{ 553 Elementwise bitwise AND of input1 and input2. Axis of size 1 554 will be broadcast as necessary. 555 }]; 556 557 let arguments = (ins 558 Tosa_Tensor:$input1, 559 Tosa_Tensor:$input2 560 ); 561 562 let results = (outs 563 Tosa_Tensor:$output 564 ); 565} 566 567//===----------------------------------------------------------------------===// 568// Operator: bitwise_or 569//===----------------------------------------------------------------------===// 570def Tosa_BitwiseOrOp : Tosa_ElementwiseOp<"bitwise_or", [ 571 Commutative, 572 ResultsBroadcastableShape, 573 SameOperandsAndResultElementType, 574 SameOperandsAndResultRank]> { 575 let summary = "Bitwise OR operator"; 576 577 let description = [{ 578 Elementwise bitwise OR of input1 and input2. Axis of size 1 will be 579 broadcast as necessary. 580 }]; 581 582 let arguments = (ins 583 Tosa_Tensor:$input1, 584 Tosa_Tensor:$input2 585 ); 586 587 let results = (outs 588 Tosa_Tensor:$output 589 ); 590} 591 592//===----------------------------------------------------------------------===// 593// Operator: bitwise_xor 594//===----------------------------------------------------------------------===// 595def Tosa_BitwiseXorOp : Tosa_ElementwiseOp<"bitwise_xor", [ 596 Commutative, 597 ResultsBroadcastableShape, 598 SameOperandsAndResultElementType, 599 SameOperandsAndResultRank]> { 600 let summary = "Bitwise XOR operator"; 601 602 let description = [{ 603 Elementwise bitwise XOR of input1 and input2. Axis of size 1 will be 604 broadcast as necessary. 605 }]; 606 607 let arguments = (ins 608 Tosa_Tensor:$input1, 609 Tosa_Tensor:$input2 610 ); 611 612 let results = (outs 613 Tosa_Tensor:$output 614 ); 615} 616 617//===----------------------------------------------------------------------===// 618// Operator: int_div 619//===----------------------------------------------------------------------===// 620def Tosa_IntDivOp : Tosa_ElementwiseOp<"int_div", [ 621 ResultsBroadcastableShape, 622 SameOperandsAndResultRank, 623 SameOperandsAndResultElementType]> { 624 let summary = "Integer divide operator"; 625 626 let description = [{ 627 Elementwise integer divide operator of input1 by input2. Axis of size 1 628 will be broadcast, as necessary. 629 }]; 630 631 let arguments = (ins 632 Tosa_Int32Tensor:$input1, 633 Tosa_Int32Tensor:$input2 634 ); 635 636 let results = (outs 637 Tosa_Int32Tensor:$output 638 ); 639 640 let hasFolder = 1; 641} 642 643//===----------------------------------------------------------------------===// 644// Operator: logical_and 645//===----------------------------------------------------------------------===// 646def Tosa_LogicalAndOp : Tosa_ElementwiseOp<"logical_and", [ 647 Commutative, 648 ResultsBroadcastableShape, 649 SameOperandsAndResultElementType, 650 SameOperandsAndResultRank]> { 651 let summary = "Returns the truth value of x AND y element-wise."; 652 653 let description = [{ 654 Elementwise logical AND of input1 and input2. Axis of size 1 will be 655 broadcast, as necessary. 656 }]; 657 658 let arguments = (ins 659 Tosa_I1Tensor:$input1, 660 Tosa_I1Tensor:$input2 661 ); 662 663 let results = (outs 664 Tosa_I1Tensor:$z 665 ); 666} 667 668//===----------------------------------------------------------------------===// 669// Operator: logical_left_shift 670//===----------------------------------------------------------------------===// 671def Tosa_LogicalLeftShiftOp : Tosa_ElementwiseOp<"logical_left_shift", [ 672 ResultsBroadcastableShape, 673 SameOperandsAndResultElementType, 674 SameOperandsAndResultRank]> { 675 let summary = "Elementwise Logical Left Shift"; 676 677 let description = [{ 678 Elementwise left shift of input1 and input2. Axis of size 1 will be 679 broadcast, as necessary. 680 }]; 681 682 let arguments = (ins 683 Tosa_Tensor:$input1, 684 Tosa_Tensor:$input2 685 ); 686 687 let results = (outs 688 Tosa_Tensor:$output 689 ); 690} 691 692//===----------------------------------------------------------------------===// 693// Operator: logical_right_shift 694//===----------------------------------------------------------------------===// 695def Tosa_LogicalRightShiftOp : Tosa_ElementwiseOp<"logical_right_shift", [ 696 ResultsBroadcastableShape, 697 SameOperandsAndResultElementType, 698 SameOperandsAndResultRank]> { 699 let summary = "Elementwise Logical Right Shift"; 700 701 let description = [{ 702 Elementwise logical right shift of input1 by the amount specified in input2. 703 Axis of size 1 will be broadcast, as necessary. 704 }]; 705 706 let arguments = (ins 707 Tosa_Tensor:$input1, 708 Tosa_Tensor:$input2 709 ); 710 711 let results = (outs 712 Tosa_Tensor:$output 713 ); 714} 715 716//===----------------------------------------------------------------------===// 717// Operator: logical_or 718//===----------------------------------------------------------------------===// 719def Tosa_LogicalOrOp : Tosa_ElementwiseOp<"logical_or", [ 720 Commutative, 721 ResultsBroadcastableShape, 722 SameOperandsAndResultElementType, 723 SameOperandsAndResultRank]> { 724 let summary = "Returns the truth value of x OR y element-wise."; 725 726 let description = [{ 727 Elementwise logical OR of input1 and input2. Axis of size 1 will be 728 broadcast as necessary. 729 }]; 730 731 let arguments = (ins 732 Tosa_I1Tensor:$input1, 733 Tosa_I1Tensor:$input2 734 ); 735 736 let results = (outs 737 Tosa_I1Tensor:$z 738 ); 739} 740 741//===----------------------------------------------------------------------===// 742// Operator: logical_xor 743//===----------------------------------------------------------------------===// 744def Tosa_LogicalXorOp : Tosa_ElementwiseOp<"logical_xor", [ 745 Commutative, 746 ResultsBroadcastableShape, 747 SameOperandsAndResultElementType, 748 SameOperandsAndResultRank]> { 749 let summary = "Returns the truth value of x XOR y element-wise."; 750 751 let description = [{ 752 Elementwise logical XOR of input1 and input2. Axis of size 1 will be 753 broadcast as necessary. 754 }]; 755 756 let arguments = (ins 757 Tosa_I1Tensor:$input1, 758 Tosa_I1Tensor:$input2 759 ); 760 761 let results = (outs 762 Tosa_I1Tensor:$z 763 ); 764} 765 766//===----------------------------------------------------------------------===// 767// Operator: maximum 768//===----------------------------------------------------------------------===// 769def Tosa_MaximumOp : Tosa_ElementwiseOp<"maximum", [ 770 Commutative, 771 ResultsBroadcastableShape, 772 SameOperandsAndResultElementType, 773 SameOperandsAndResultRank]> { 774 let summary = "Elementwise Maximum"; 775 776 let description = [{ 777 Elementwise max of input1 and input2. Axis of size 1 will be broadcast, as 778 necessary. 779 }]; 780 781 let arguments = (ins 782 Tosa_Tensor:$input1, 783 Tosa_Tensor:$input2, 784 DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode 785 ); 786 787 let results = (outs 788 Tosa_Tensor:$output 789 ); 790} 791 792//===----------------------------------------------------------------------===// 793// Operator: minimum 794//===----------------------------------------------------------------------===// 795def Tosa_MinimumOp : Tosa_ElementwiseOp<"minimum", [ 796 Commutative, 797 ResultsBroadcastableShape, 798 SameOperandsAndResultElementType, 799 SameOperandsAndResultRank]> { 800 let summary = "Elementwise Minimum"; 801 802 let description = [{ 803 Elementwise minimum of input1 and input2. Axis of size 1 804 will be broadcast, as necessary. 805 }]; 806 807 let arguments = (ins 808 Tosa_Tensor:$input1, 809 Tosa_Tensor:$input2, 810 DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode 811 ); 812 813 let results = (outs 814 Tosa_Tensor:$output 815 ); 816} 817 818def MulOperandsAndResultElementType : 819 NativeOpTrait<"MulOperandsAndResultElementType"> { 820 let cppNamespace = "mlir::OpTrait::tosa"; 821} 822 823//===----------------------------------------------------------------------===// 824// Operator: mul 825//===----------------------------------------------------------------------===// 826def Tosa_MulOp : Tosa_ElementwiseOp<"mul", [ 827 Commutative, 828 MulOperandsAndResultElementType]> { 829 let summary = "Multiplication operator"; 830 831 let description = [{ 832 Elementwise multiplication (Hadamard product) of input1 and input2. 833 Axis of size 1 will be broadcast, as necessary. 834 i8/i16 input type can be promoted to i32 result type. 835 }]; 836 837 let arguments = (ins 838 Tosa_Tensor:$input1, 839 Tosa_Tensor:$input2, 840 Optional<TosaTensorRankOf<[Tosa_Int8], [1]>>:$shift 841 ); 842 843 let results = (outs 844 Tosa_Tensor:$output 845 ); 846 847 let hasFolder = 1; 848 let hasVerifier = 1; 849} 850 851//===----------------------------------------------------------------------===// 852// Operator: pow 853//===----------------------------------------------------------------------===// 854def Tosa_PowOp : Tosa_ElementwiseOp<"pow", [ 855 ResultsBroadcastableShape, 856 SameOperandsAndResultElementType, 857 SameOperandsAndResultRank]> { 858 let summary = "Computes the power of one value to another."; 859 860 let description = [{ 861 Elementwise input1 raised to the power of input2. 862 Axis of size 1 will be broadcast, as necessary. 863 }]; 864 865 let arguments = (ins 866 Tosa_Tensor:$input1, 867 Tosa_Tensor:$input2 868 ); 869 870 let results = (outs 871 Tosa_Tensor:$output 872 ); 873} 874 875//===----------------------------------------------------------------------===// 876// Operator: sub 877//===----------------------------------------------------------------------===// 878def Tosa_SubOp : Tosa_ElementwiseOp<"sub", [ 879 ResultsBroadcastableShape, 880 SameOperandsAndResultElementType, 881 SameOperandsAndResultRank]> { 882 let summary = "Elementwise subtraction operator"; 883 884 let description = [{ 885 Elementwise subtraction of input1 and input2. Axis of size 1 will be 886 broadcast as necessary. 887 }]; 888 889 let arguments = (ins 890 Tosa_Tensor:$input1, 891 Tosa_Tensor:$input2 892 ); 893 894 let results = (outs 895 Tosa_Tensor:$output 896 ); 897 898 let hasFolder = 1; 899} 900 901//===----------------------------------------------------------------------===// 902// Operator: table 903//===----------------------------------------------------------------------===// 904def Tosa_TableOp : Tosa_InferShapedTypeOp<"table"> { 905 let summary = "Table lookup op"; 906 907 let description = [{ 908 Interpolated table lookup operation. Input values are scaled to create a 909 fixed-point 9.7 value. The high 9 bits are used to index into the table. 910 The fractional bits are used to interpolate based on the looked up value and 911 the index+1 value in the table. The TABLE operator then returns a 16.7 912 interpolated value. Note that there must be 513 values to handle the full 913 range of inputs. 914 915 The TABLE operator is expected to be used as follows: 916 * A RESCALE node is expected before the TABLE operator to scale the input 917 to a full int16_t range for the table lookup 918 * If an int16_t result is required then follow the TABLE operator with a 919 RESCALE with a right shift of 7 920 * If an int8_t result is required then follow the TABLE operator with a 921 RESCALE with a right shift of 15 922 }]; 923 924 let arguments = (ins 925 Tosa_Tensor: $input1, 926 Tosa_Tensor1D: $table 927 ); 928 929 let results = (outs 930 Tosa_Tensor:$output 931 ); 932 933 let assemblyFormat = [{ 934 $input1 `,` $table attr-dict `:` `(` type($input1) `,` type($table) `)` `->` type($output) 935 }]; 936 937 let hasVerifier = 1; 938} 939 940//===----------------------------------------------------------------------===// 941// TOSA Spec Section 2.5 942// Operator Class: Elementwise unary/binary/ternary operators. 943// Operator Subclass: Elementwise unary ops. 944//===----------------------------------------------------------------------===// 945 946//===----------------------------------------------------------------------===// 947// Operator: abs 948//===----------------------------------------------------------------------===// 949def Tosa_AbsOp : Tosa_ElementwiseUnaryOp<"abs"> { 950 let summary = "Elementwise abs op"; 951 952 let description = [{ 953 Elementwise absolute value operation 954 955 Example: 956 957 ```mlir 958 %out = tosa.abs(%in) : (tensor<21x3xf32>) -> tensor<21x3xf32> 959 ``` 960 }]; 961 962 let arguments = (ins 963 Tosa_Tensor:$input1 964 ); 965 966 let results = (outs 967 Tosa_Tensor:$output 968 ); 969 970 let hasFolder = 1; 971} 972 973//===----------------------------------------------------------------------===// 974// Operator: bitwise_not 975//===----------------------------------------------------------------------===// 976def Tosa_BitwiseNotOp : Tosa_ElementwiseUnaryOp<"bitwise_not"> { 977 let summary = "Bitwise NOT operator"; 978 979 let description = [{ 980 Elementwise bitwise NOT of input tensor. 981 }]; 982 983 let arguments = (ins 984 Tosa_Tensor:$input1 985 ); 986 987 let results = (outs 988 Tosa_Tensor:$output 989 ); 990} 991 992//===----------------------------------------------------------------------===// 993// Operator: ceil 994//===----------------------------------------------------------------------===// 995def Tosa_CeilOp : Tosa_ElementwiseUnaryOp<"ceil"> { 996 let summary = "Elementwise ceil op"; 997 998 let description = [{ 999 Elementwise ceiling operation 1000 }]; 1001 1002 let arguments = (ins 1003 Tosa_Tensor:$input1 1004 ); 1005 1006 let results = (outs 1007 Tosa_Tensor:$output 1008 ); 1009} 1010 1011//===----------------------------------------------------------------------===// 1012// Operator: clz 1013//===----------------------------------------------------------------------===// 1014def Tosa_ClzOp : Tosa_ElementwiseUnaryOp<"clz"> { 1015 let summary = "Elementwise count leading zero op"; 1016 1017 let description = [{ 1018 Elementwise count leading zeros operation 1019 }]; 1020 1021 let arguments = (ins 1022 Tosa_Tensor:$input1 1023 ); 1024 1025 let results = (outs 1026 Tosa_Tensor:$output 1027 ); 1028} 1029 1030//===----------------------------------------------------------------------===// 1031// Operator: cos 1032//===----------------------------------------------------------------------===// 1033def Tosa_CosOp : Tosa_ElementwiseUnaryOp<"cos"> { 1034 let summary = "Elementwise cos op"; 1035 1036 let description = [{ 1037 Elementwise cosine operation for values given in radians. 1038 }]; 1039 1040 let arguments = (ins 1041 Tosa_FloatTensor:$input1 1042 ); 1043 1044 let results = (outs 1045 Tosa_FloatTensor:$output 1046 ); 1047} 1048 1049//===----------------------------------------------------------------------===// 1050// Operator: exp 1051//===----------------------------------------------------------------------===// 1052def Tosa_ExpOp : Tosa_ElementwiseUnaryOp<"exp"> { 1053 let summary = "Elementwise exp op"; 1054 1055 let description = [{ 1056 Elementwise e to the x operation 1057 }]; 1058 1059 let arguments = (ins 1060 Tosa_Tensor:$input1 1061 ); 1062 1063 let results = (outs 1064 Tosa_Tensor:$output 1065 ); 1066 1067 let hasFolder = 1; 1068} 1069 1070//===----------------------------------------------------------------------===// 1071// Operator: floor 1072//===----------------------------------------------------------------------===// 1073def Tosa_FloorOp : Tosa_ElementwiseUnaryOp<"floor"> { 1074 let summary = "Elementwise floor op"; 1075 1076 let description = [{ 1077 Elementwise floor operation 1078 }]; 1079 1080 let arguments = (ins 1081 Tosa_Tensor:$input1 1082 ); 1083 1084 let results = (outs 1085 Tosa_Tensor:$output 1086 ); 1087} 1088 1089//===----------------------------------------------------------------------===// 1090// Operator: log 1091//===----------------------------------------------------------------------===// 1092def Tosa_LogOp : Tosa_ElementwiseUnaryOp<"log"> { 1093 let summary = "Elementwise log op"; 1094 1095 let description = [{ 1096 Elementwise natural logarithm operation 1097 }]; 1098 1099 let arguments = (ins 1100 Tosa_Tensor:$input1 1101 ); 1102 1103 let results = (outs 1104 Tosa_Tensor:$output 1105 ); 1106 1107 let hasFolder = 1; 1108} 1109 1110//===----------------------------------------------------------------------===// 1111// Operator: logical_not 1112//===----------------------------------------------------------------------===// 1113def Tosa_LogicalNotOp : Tosa_ElementwiseUnaryOp<"logical_not"> { 1114 let summary = "Returns the truth value of NOT x element-wise."; 1115 1116 let description = [{ 1117 Elementwise logical NOT of input. 1118 }]; 1119 1120 let arguments = (ins 1121 Tosa_I1Tensor:$input1 1122 ); 1123 1124 let results = (outs 1125 Tosa_I1Tensor:$output 1126 ); 1127} 1128 1129//===----------------------------------------------------------------------===// 1130// Operator: negate 1131//===----------------------------------------------------------------------===// 1132def Tosa_NegateOp : Tosa_ElementwiseUnaryOp<"negate"> { 1133 let summary = "Elementwise negate op"; 1134 1135 let description = [{ 1136 Elementwise negation operation 1137 }]; 1138 1139 let arguments = (ins 1140 Tosa_Tensor:$input1, 1141 OptionalAttr<Tosa_UnaryOpQuantizationAttr>:$quantization_info 1142 ); 1143 1144 let results = (outs 1145 Tosa_Tensor:$output 1146 ); 1147 1148 let builders = [Tosa_UnaryOpQuantInfoBuilder]; 1149 1150 let hasFolder = 1; 1151} 1152 1153//===----------------------------------------------------------------------===// 1154// Operator: reciprocal 1155//===----------------------------------------------------------------------===// 1156def Tosa_ReciprocalOp : Tosa_ElementwiseUnaryOp<"reciprocal"> { 1157 let summary = "Elementwise reciprocal op"; 1158 1159 let description = [{ 1160 Elementwise reciprocal operation. For integer operation, a TABLE should be 1161 used with the appropriate ranges. 1162 }]; 1163 1164 let arguments = (ins 1165 Tosa_Tensor:$input1 1166 ); 1167 1168 let results = (outs 1169 Tosa_Tensor:$output 1170 ); 1171 1172 let extraClassDeclaration = [{ 1173 /// Return the reciprocal result on the operand. 1174 static inline APFloat calcOneElement(const APFloat &operand) { 1175 APFloat recip = APFloat(operand.getSemantics(), 1); 1176 recip.divide(operand, APFloat::rmNearestTiesToEven); 1177 return recip; 1178 } 1179 }]; 1180 1181 let hasFolder = 1; 1182} 1183 1184//===----------------------------------------------------------------------===// 1185// Operator: rsqrt 1186//===----------------------------------------------------------------------===// 1187def Tosa_RsqrtOp : Tosa_ElementwiseUnaryOp<"rsqrt"> { 1188 let summary = "Elementwise 1/sqrt op"; 1189 1190 let description = [{ 1191 Elementwise reciprocal square root operation. For integer operation, a TABLE 1192 should be used with the appropriate ranges. 1193 }]; 1194 1195 let arguments = (ins 1196 Tosa_Tensor:$input1 1197 ); 1198 1199 let results = (outs 1200 Tosa_Tensor:$output 1201 ); 1202} 1203 1204//===----------------------------------------------------------------------===// 1205// Operator: sin 1206//===----------------------------------------------------------------------===// 1207def Tosa_SinOp : Tosa_ElementwiseUnaryOp<"sin"> { 1208 let summary = "Elementwise sin op"; 1209 1210 let description = [{ 1211 Elementwise sine operation for values given in radians. 1212 }]; 1213 1214 let arguments = (ins 1215 Tosa_FloatTensor:$input1 1216 ); 1217 1218 let results = (outs 1219 Tosa_FloatTensor:$output 1220 ); 1221} 1222 1223//===----------------------------------------------------------------------===// 1224// TOSA Spec Section 2.6 1225// Operator Class: Elementwise unary/binary/ternary operators. 1226// Operator Subclass: Elementwise ternary ops. 1227//===----------------------------------------------------------------------===// 1228 1229//===----------------------------------------------------------------------===// 1230// Operator: select 1231//===----------------------------------------------------------------------===// 1232def Tosa_SelectOp : Tosa_ElementwiseOp<"select", [ 1233 ResultsBroadcastableShape, 1234 SameOperandsAndResultRank]> { 1235 let summary = "Elementwise select operator"; 1236 1237 let description = [{ 1238 Elementwise select of the output based on a condition. 1239 }]; 1240 1241 let arguments = (ins 1242 Tosa_I1Tensor:$pred, 1243 Tosa_Tensor:$on_true, 1244 Tosa_Tensor:$on_false 1245 ); 1246 1247 let results = (outs 1248 Tosa_Tensor:$output 1249 ); 1250 let hasCanonicalizeMethod = 1; 1251 let hasFolder = 1; 1252 1253 let assemblyFormat = [{ 1254 operands attr-dict `:` `(` type($pred) `,` type($on_true) `,` type($on_false) 1255 `)` `->` type($output) 1256 }]; 1257} 1258 1259//===----------------------------------------------------------------------===// 1260// TOSA Spec Section 2.7 1261// Operator Class: Logical Operations. 1262//===----------------------------------------------------------------------===// 1263 1264//===----------------------------------------------------------------------===// 1265// Operator: equal 1266//===----------------------------------------------------------------------===// 1267def Tosa_EqualOp : Tosa_ElementwiseOp<"equal", [ 1268 InferTensorType, 1269 Commutative, 1270 ResultsBroadcastableShape, 1271 SameOperandsElementType, 1272 SameOperandsAndResultRank]> { 1273 let summary = "Returns the truth value of (x == y) element-wise."; 1274 1275 let description = [{ 1276 Elementwise comparison operation 1277 }]; 1278 1279 let arguments = (ins 1280 Tosa_Tensor:$input1, 1281 Tosa_Tensor:$input2 1282 ); 1283 1284 let results = (outs 1285 Tosa_I1Tensor:$output 1286 ); 1287 1288 let extraClassDeclaration = [{ 1289 /// Returns when two result types are compatible for this op; method used by 1290 /// InferTypeOpInterface. 1291 static bool isCompatibleReturnTypes(TypeRange l, TypeRange r); 1292 }]; 1293 1294 let hasFolder = 1; 1295} 1296 1297//===----------------------------------------------------------------------===// 1298// Operator: greater 1299//===----------------------------------------------------------------------===// 1300def Tosa_GreaterOp : Tosa_ElementwiseOp<"greater", [ 1301 ResultsBroadcastableShape, 1302 SameOperandsElementType, 1303 SameOperandsAndResultRank]> { 1304 let summary = "Returns the truth value of (x > y) element-wise."; 1305 1306 let description = [{ 1307 Elementwise greater than comparison operation 1308 }]; 1309 1310 let arguments = (ins 1311 Tosa_Tensor:$input1, 1312 Tosa_Tensor:$input2 1313 ); 1314 1315 let results = (outs 1316 Tosa_I1Tensor:$output 1317 ); 1318 1319 let hasFolder = 1; 1320} 1321 1322//===----------------------------------------------------------------------===// 1323// Operator: greater_equal 1324//===----------------------------------------------------------------------===// 1325def Tosa_GreaterEqualOp : Tosa_ElementwiseOp<"greater_equal", [ 1326 ResultsBroadcastableShape, 1327 SameOperandsElementType, 1328 SameOperandsAndResultRank 1329 ]> { 1330 let summary = "Returns the truth value of (x >= y) element-wise."; 1331 1332 let description = [{ 1333 Elementwise comparison operation 1334 }]; 1335 1336 let arguments = (ins 1337 Tosa_Tensor:$input1, 1338 Tosa_Tensor:$input2 1339 ); 1340 1341 let results = (outs 1342 Tosa_I1Tensor:$output 1343 ); 1344 1345 let hasFolder = 1; 1346} 1347 1348//===----------------------------------------------------------------------===// 1349// TOSA Spec Section 2.8 1350// Operator Class: Reduction Ops. 1351//===----------------------------------------------------------------------===// 1352 1353//===----------------------------------------------------------------------===// 1354// Operator: reduce_all 1355//===----------------------------------------------------------------------===// 1356def Tosa_ReduceAllOp : Tosa_InferTensorTypeOp<"reduce_all"> { 1357 let summary = "Reduce All operator"; 1358 1359 let description = [{ 1360 Reduce a tensor along the given axis with a logical AND operation 1361 }]; 1362 1363 let arguments = (ins 1364 Tosa_Tensor:$input, 1365 I32Attr:$axis 1366 ); 1367 1368 let results = (outs 1369 Tosa_Tensor:$output 1370 ); 1371 1372 let hasFolder = 1; 1373 let hasVerifier = 1; 1374 1375 let extraClassDeclaration = [{ 1376 /// Returns true when two result types are compatible for this op; 1377 /// Method used by InferTypeOpInterface. 1378 static bool isCompatibleReturnTypes(TypeRange l, TypeRange r); 1379 1380 /// Return the AND result between two integer operands 1381 static inline APInt calcOneElement(APInt leftOperand, APInt rightOperand) { 1382 return leftOperand & rightOperand; 1383 } 1384 }]; 1385} 1386 1387//===----------------------------------------------------------------------===// 1388// Operator: reduce_any 1389//===----------------------------------------------------------------------===// 1390def Tosa_ReduceAnyOp : Tosa_InferTensorTypeOp<"reduce_any"> { 1391 let summary = "Reduce Any operator"; 1392 1393 let description = [{ 1394 Reduce a tensor along the given axis with a logical OR operation 1395 }]; 1396 1397 let arguments = (ins 1398 Tosa_Tensor:$input, 1399 I32Attr:$axis 1400 ); 1401 1402 let results = (outs 1403 Tosa_Tensor:$output 1404 ); 1405 1406 let hasFolder = 1; 1407 let hasVerifier = 1; 1408 1409 let extraClassDeclaration = [{ 1410 /// Returns true when two result types are compatible for this op; 1411 /// Method used by InferTypeOpInterface. 1412 static bool isCompatibleReturnTypes(TypeRange l, TypeRange r); 1413 1414 /// Return the OR result between two integer operands 1415 static inline APInt calcOneElement(APInt leftOperand, APInt rightOperand) { 1416 return leftOperand | rightOperand; 1417 } 1418 }]; 1419} 1420 1421//===----------------------------------------------------------------------===// 1422// Operator: reduce_max 1423//===----------------------------------------------------------------------===// 1424def Tosa_ReduceMaxOp : Tosa_InferTensorTypeOp<"reduce_max"> { 1425 let summary = "Reduce Max operator"; 1426 1427 let description = [{ 1428 Reduce a tensor along the given axis with a maximum operation 1429 }]; 1430 1431 let arguments = (ins 1432 Tosa_Tensor:$input, 1433 I32Attr:$axis, 1434 DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode 1435 ); 1436 1437 let results = (outs 1438 Tosa_Tensor:$output 1439 ); 1440 1441 let hasFolder = 1; 1442 let hasVerifier = 1; 1443 1444 let extraClassDeclaration = [{ 1445 /// Returns true when two result types are compatible for this op; 1446 /// Method used by InferTypeOpInterface. 1447 static bool isCompatibleReturnTypes(TypeRange l, TypeRange r); 1448 1449 /// Return the max of the two integer operands 1450 static inline APInt calcOneElement(APInt leftOperand, APInt rightOperand) { 1451 const llvm::APInt subtractRes = leftOperand - rightOperand; 1452 return (!subtractRes.isNegative()) ? leftOperand : rightOperand; 1453 } 1454 }]; 1455} 1456 1457//===----------------------------------------------------------------------===// 1458// Operator: reduce_min 1459//===----------------------------------------------------------------------===// 1460def Tosa_ReduceMinOp : Tosa_InferTensorTypeOp<"reduce_min"> { 1461 let summary = "Reduce Min operator"; 1462 1463 let description = [{ 1464 Reduce a tensor along the given axis with a minimum operation 1465 }]; 1466 1467 let arguments = (ins 1468 Tosa_Tensor:$input, 1469 I32Attr:$axis, 1470 DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode 1471 ); 1472 1473 let results = (outs 1474 Tosa_Tensor:$output 1475 ); 1476 1477 let hasFolder = 1; 1478 let hasVerifier = 1; 1479 1480 let extraClassDeclaration = [{ 1481 /// Returns true when two result types are compatible for this op; 1482 /// Method used by InferTypeOpInterface. 1483 static bool isCompatibleReturnTypes(TypeRange l, TypeRange r); 1484 1485 /// Return the min of the two integer operands 1486 static inline APInt calcOneElement(APInt leftOperand, APInt rightOperand) { 1487 const llvm::APInt subtractRes = leftOperand - rightOperand; 1488 return (!subtractRes.isNegative()) ? rightOperand : leftOperand; 1489 } 1490 }]; 1491} 1492 1493//===----------------------------------------------------------------------===// 1494// Operator: reduce_prod 1495//===----------------------------------------------------------------------===// 1496def Tosa_ReduceProdOp : Tosa_InferTensorTypeOp<"reduce_prod"> { 1497 let summary = "Reduce Prod operator"; 1498 1499 let description = [{ 1500 Reduce a tensor along the given axis by computing the product of the axis. 1501 }]; 1502 1503 let arguments = (ins 1504 Tosa_Tensor:$input, 1505 I32Attr:$axis 1506 ); 1507 1508 let results = (outs 1509 Tosa_Tensor:$output 1510 ); 1511 1512 let hasFolder = 1; 1513 let hasVerifier = 1; 1514 1515 let extraClassDeclaration = [{ 1516 /// Returns true when two result types are compatible for this op; 1517 /// Method used by InferTypeOpInterface. 1518 static bool isCompatibleReturnTypes(TypeRange l, TypeRange r); 1519 1520 /// Return the prod of the two integer operands 1521 static inline APInt calcOneElement(APInt leftOperand, APInt rightOperand) { 1522 return leftOperand * rightOperand; 1523 } 1524 }]; 1525} 1526 1527//===----------------------------------------------------------------------===// 1528// Operator: reduce_sum 1529//===----------------------------------------------------------------------===// 1530def Tosa_ReduceSumOp : Tosa_InferTensorTypeOp<"reduce_sum"> { 1531 let summary = "Reduce Sum operator"; 1532 1533 let description = [{ 1534 Reduce a tensor along the given axis by computing the sum of the axis. 1535 }]; 1536 1537 let arguments = (ins 1538 Tosa_Tensor:$input, 1539 I32Attr:$axis 1540 ); 1541 1542 let results = (outs 1543 Tosa_Tensor:$output 1544 ); 1545 1546 let hasFolder = 1; 1547 let hasVerifier = 1; 1548 1549 let extraClassDeclaration = [{ 1550 /// Returns true when two result types are compatible for this op; 1551 /// Method used by InferTypeOpInterface. 1552 static bool isCompatibleReturnTypes(TypeRange l, TypeRange r); 1553 1554 /// Return the sum of the two integer operands 1555 static inline APInt calcOneElement(APInt leftOperand, APInt rightOperand) { 1556 return leftOperand + rightOperand; 1557 } 1558 }]; 1559} 1560 1561//===----------------------------------------------------------------------===// 1562// TOSA Spec Section 2.9 1563// Operator Class: Data Layout / Memory Reinterpretation. 1564//===----------------------------------------------------------------------===// 1565 1566//===----------------------------------------------------------------------===// 1567// Operator: concat 1568//===----------------------------------------------------------------------===// 1569def Tosa_ConcatOp : Tosa_InferTensorTypeOp<"concat"> { 1570 let summary = "Concatenates tensors along one dimension."; 1571 1572 let description = [{ 1573 Concatenate a variadic amount of tensors along a given axis. No data 1574 conversion happens during a concat operation. 1575 }]; 1576 1577 let arguments = (ins 1578 Variadic<Tosa_Tensor>:$input1, 1579 I32Attr:$axis 1580 ); 1581 1582 let results = (outs 1583 Tosa_Tensor:$output 1584 ); 1585 1586 let hasCanonicalizer = 1; 1587 let hasFolder = 1; 1588 1589 let extraClassDeclaration = [{ 1590 /// Returns true when two result types are compatible for this op; 1591 /// Method used by InferTypeOpInterface. 1592 static bool isCompatibleReturnTypes(TypeRange l, TypeRange r); 1593 }]; 1594} 1595 1596//===----------------------------------------------------------------------===// 1597// Operator: pad 1598//===----------------------------------------------------------------------===// 1599def Tosa_PadOp : Tosa_InferShapedTypeOp<"pad"> { 1600 let summary = "Pads a tensor with value specified."; 1601 1602 let description = [{ 1603 The `tosa.pad` operation pads a tensor along borders of each dimension with 1604 `pad_const` (defaults to zero), given a padding configuration `padding` 1605 specifying low and high values along the dimensions. 1606 1607 Example: 1608 1609 ```mlir 1610 %0 = tosa.const_shape { value = dense<[1, 2, 3, 4]> : tensor<4xindex> } : () -> !tosa.shape<4> 1611 tosa.pad %arg0, %0 : (tensor<1x2xf32>, !tosa.shape<4>) -> (tensor<4x9xf32>) 1612 ``` 1613 1614 Example 2: 1615 1616 ```mlir 1617 %0 = tosa.const_shape { value = dense<[-1, 2, 3, 4]> : tensor<4xindex> } : () -> !tosa.shape<4> 1618 tosa.pad %arg0, %0 : (tensor<1x2xf32>, !tosa.shape<4>) -> (tensor<?x9xf32>) 1619 ``` 1620 }]; 1621 1622 let arguments = (ins 1623 Tosa_RankedTensor:$input1, 1624 Tosa_Shape:$padding, 1625 Optional<Tosa_ScalarTensor>:$pad_const, 1626 OptionalAttr<Tosa_PadOpQuantizationAttr>:$quantization_info 1627 ); 1628 1629 let results = (outs 1630 Tosa_RankedTensor:$output 1631 ); 1632 1633 let builders = [Tosa_PadOpQuantInfoBuilder, 1634 Tosa_ExplicitValuePadOpQuantInfoBuilder]; 1635 1636 let hasCanonicalizer = 1; 1637 let hasFolder = 1; 1638 let hasVerifier = 1; 1639} 1640 1641//===----------------------------------------------------------------------===// 1642// Operator: reshape 1643//===----------------------------------------------------------------------===// 1644def Tosa_ReshapeOp : Tosa_InferTensorTypeOp<"reshape"> { 1645 let summary = "Reshape operator"; 1646 1647 let description = [{ 1648 Returns a tensor with the same type/values as the input, with a new shape 1649 specified by the shape argument. Reshape may operate on tensors of any rank. 1650 No data conversion happens during a reshape operation. 1651 }]; 1652 1653 let hasFolder = 1; 1654 let hasVerifier = 1; 1655 1656 let arguments = (ins 1657 Tosa_Tensor:$input1, 1658 DenseI64ArrayAttr:$new_shape 1659 ); 1660 1661 let results = (outs 1662 Tosa_RankedTensor:$output 1663 ); 1664 1665 let extraClassDeclaration = [{ 1666 /// Returns true when two result types are compatible for this op; 1667 /// Method used by InferTypeOpInterface. 1668 static bool isCompatibleReturnTypes(TypeRange l, TypeRange r); 1669 }]; 1670 1671 let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)"; 1672} 1673 1674//===----------------------------------------------------------------------===// 1675// Operator: reverse 1676//===----------------------------------------------------------------------===// 1677def Tosa_ReverseOp: Tosa_Op<"reverse", [ 1678 DeclareOpInterfaceMethods<InferShapedTypeOpInterface, 1679 ["inferReturnTypeComponents"]>, Pure]> { 1680 let summary = "Reverse operator"; 1681 1682 let description = [{ 1683 Returns a tensor with the same type/values as the input, with the data 1684 reversed along the given axis. No data conversion happens during a reverse 1685 operation. 1686 }]; 1687 1688 let arguments = (ins 1689 Tosa_Tensor:$input1, 1690 I32Attr:$axis 1691 ); 1692 1693 let results = (outs 1694 Tosa_Tensor:$output 1695 ); 1696 1697 let hasFolder = 1; 1698 let hasVerifier = 1; 1699 1700 let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)"; 1701} 1702 1703//===----------------------------------------------------------------------===// 1704// Operator: slice 1705//===----------------------------------------------------------------------===// 1706def Tosa_SliceOp : Tosa_InferShapedTypeOp<"slice"> { 1707 let summary = "Slice operator"; 1708 1709 let description = [{ 1710 Extracts a slice of the input1 on the given axis, beginning at the 1711 start coordinates, and extending for size elements in each direction. No 1712 data conversion happens during a slice operation. 1713 }]; 1714 1715 let arguments = (ins 1716 Tosa_Tensor:$input1, 1717 Tosa_Shape:$start, 1718 Tosa_Shape:$size 1719 ); 1720 1721 let results = (outs 1722 Tosa_Tensor:$output 1723 ); 1724 1725 let hasCanonicalizer = 1; 1726 let hasFolder = 1; 1727 let hasVerifier = 1; 1728} 1729 1730//===----------------------------------------------------------------------===// 1731// Operator: tile 1732//===----------------------------------------------------------------------===// 1733def Tosa_TileOp : Tosa_InferShapedTypeOp<"tile"> { 1734 let summary = "Tile operator"; 1735 1736 let description = [{ 1737 Replicates input 0 multiplies times along each dimension. 1738 }]; 1739 1740 let arguments = (ins 1741 Tosa_Tensor:$input1, 1742 Tosa_Shape:$multiples); 1743 1744 let results = (outs 1745 Tosa_Tensor:$output 1746 ); 1747 1748 let extraClassDeclaration = [{ 1749 LogicalResult getConstantMultiples(llvm::SmallVector<int64_t> &multiples); 1750 }]; 1751 1752 let hasFolder = 1; 1753 let hasVerifier = 1; 1754} 1755 1756//===----------------------------------------------------------------------===// 1757// Operator: transpose 1758//===----------------------------------------------------------------------===// 1759def Tosa_TransposeOp : Tosa_InferShapedTypeOp<"transpose", 1760 [DeclareOpInterfaceMethods<ReifyRankedShapedTypeOpInterface>, 1761 AllElementTypesMatch<["input1", "output"]>]> { 1762 let summary = "Transpose operator"; 1763 1764 let description = [{ 1765 Permutes the dimensions based on perm. 1766 }]; 1767 1768 let arguments = (ins 1769 Tosa_Tensor:$input1, 1770 Tosa_Int32Tensor:$perms 1771 ); 1772 1773 let results = ( 1774 outs Tosa_Tensor:$output 1775 ); 1776 1777 let extraClassDeclaration = [{ 1778 LogicalResult getConstantPerms(llvm::SmallVector<int32_t> &perms); 1779 }]; 1780 1781 let hasCanonicalizer = 1; 1782 let hasFolder = 1; 1783 let hasVerifier = 1; 1784} 1785 1786//===----------------------------------------------------------------------===// 1787// TOSA Spec Section 2.10 1788// Operator Class: Scatter/gather Operations. 1789//===----------------------------------------------------------------------===// 1790 1791//===----------------------------------------------------------------------===// 1792// Operator: gather 1793//===----------------------------------------------------------------------===// 1794def Tosa_GatherOp : Tosa_InferShapedTypeOp<"gather"> { 1795 let summary = "Gather operation,"; 1796 1797 let description = [{ 1798 Generate a tensor for which each element in the output is a slice of the 1799 values tensor based on the value of indices. 1800 }]; 1801 1802 let arguments = (ins 1803 Tosa_Tensor3D:$values, 1804 TosaTensorRankOf<[Tosa_Int32], [2]>:$indices 1805 ); 1806 1807 let results = (outs 1808 Tosa_Tensor3D:$output 1809 ); 1810} 1811 1812//===----------------------------------------------------------------------===// 1813// Operator: scatter 1814//===----------------------------------------------------------------------===// 1815def Tosa_ScatterOp : Tosa_InferShapedTypeOp<"scatter"> { 1816 let summary = "Scatter operation,"; 1817 1818 let description = [{ 1819 The values_out tensor is set to the values_in tensor with data modified as follows: 1820 data from the input tensor is inserted at the positions specified by the indices tensor. 1821 }]; 1822 1823 let arguments = (ins 1824 Tosa_Tensor3D:$values_in, 1825 TosaTensorRankOf<[Tosa_Int32], [2]>:$indices, 1826 Tosa_Tensor3D:$input 1827 ); 1828 1829 let results = (outs 1830 Tosa_Tensor3D:$values_out 1831 ); 1832} 1833 1834//===----------------------------------------------------------------------===// 1835// TOSA Spec Section 2.11 1836// Operator Class: Image Frontend Functions. 1837//===----------------------------------------------------------------------===// 1838 1839//===----------------------------------------------------------------------===// 1840// Operator: resize 1841//===----------------------------------------------------------------------===// 1842def Tosa_ResizeOp : Tosa_InferShapedTypeOp<"resize"> { 1843 let summary = "Resize operation, supports various resize/upsample modes"; 1844 1845 let description = [{ 1846 Resizes a tensor. Resize is only allowed in the H and W dimensions. In 1847 expected use, The height dimension is scaled by factor (scale_y_n/scale_y_d). 1848 And the width dimension is scaled by factor (scale_x_n/scale_x_d). Thus the 1849 output dimensions can be derived from the input dimensions by inverting the 1850 scale. And the [order_y, border_x] values adjust the output size to allow 1851 fractional sampling beyond integer input position (IH-1,IW-1). 1852 }]; 1853 1854 let arguments = (ins 1855 Tosa_Tensor4D:$input, 1856 Tosa_IntArrayAttr4:$scale, 1857 Tosa_IntArrayAttr2:$offset, 1858 Tosa_IntArrayAttr2:$border, 1859 Tosa_ResizeTypeAttr:$mode 1860 ); 1861 1862 let results = (outs 1863 Tosa_Tensor4D:$output 1864 ); 1865 1866 let hasFolder = 1; 1867} 1868 1869//===----------------------------------------------------------------------===// 1870// TOSA Spec Section 2.12 1871// Operator Class: Type Conversion. 1872//===----------------------------------------------------------------------===// 1873 1874//===----------------------------------------------------------------------===// 1875// Operator: cast 1876//===----------------------------------------------------------------------===// 1877def Tosa_CastOp: Tosa_Op<"cast", [Pure, 1878 DeclareOpInterfaceMethods<InferShapedTypeOpInterface, 1879 ["inferReturnTypeComponents"]>]> { 1880 1881 let summary = "Cast operation"; 1882 1883 let description = [{ 1884 Performs a set of permissible cast operations 1885 1886 | Mode | Input | Output | 1887 |--------------------------|---------|---------| 1888 | signed 8 to bool | int8 | Boolean | 1889 | signed 16 to bool | int16 | Boolean | 1890 | signed 32 to bool | int32 | Boolean | 1891 | bool to 8 | Boolean | int8 | 1892 | bool to 16 | Boolean | int16 | 1893 | bool to 32 | Boolean | int32 | 1894 | signed 8 to signed 16 | int8 | int16 | 1895 | signed 8 to signed 32 | int8 | int32 | 1896 | signed 16 to signed 8 | int16 | int8 | 1897 | signed 16 to signed 32 | int16 | int32 | 1898 | signed 32 to signed 8 | int32 | int8 | 1899 | signed 32 to signed 16 | int32 | int16 | 1900 | float to signed 8 | float | int8 | 1901 | float to signed 16 | float | int16 | 1902 | signed 8 to float | int8 | float | 1903 | signed 16 to float | int16 | float | 1904 | float 32 to float 64 | float32 | float64 | 1905 | float 64 to float 32 | float64 | float32 | 1906 }]; 1907 1908 let arguments = (ins 1909 Tosa_Tensor:$input 1910 ); 1911 1912 let results = (outs 1913 Tosa_Tensor:$output 1914 ); 1915 1916 let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)"; 1917 1918 let hasFolder = 1; 1919} 1920 1921//===----------------------------------------------------------------------===// 1922// Operator: rescale 1923//===----------------------------------------------------------------------===// 1924def Tosa_RescaleOp: Tosa_Op<"rescale", [Pure, 1925 DeclareOpInterfaceMethods<InferShapedTypeOpInterface, 1926 ["inferReturnTypeComponents"]>]> { 1927 let summary = "Tosa rescale operator"; 1928 1929 let description = [{ 1930 Rescale quantized values into a new domain. Supported rescalings are: 1931 1932 | Mode | Input | Output | Unsigned input | Unsigned output | 1933 |------------------------|-------|--------|----------------|-----------------| 1934 | signed 8 to 8 | int8 | int8 | false | false | 1935 | signed 8 to 16 | int8 | int16 | false | false | 1936 | signed 8 to 32 | int8 | int32 | false | false | 1937 | signed 16 to 8 | int16 | int8 | false | false | 1938 | signed 16 to 16 | int16 | int16 | false | false | 1939 | signed 16 to 32 | int16 | int32 | false | false | 1940 | signed 32 to 8 | int32 | int8 | false | false | 1941 | signed 32 to 16 | int32 | int16 | false | false | 1942 | signed 32 to 32 | int32 | int32 | false | false | 1943 | signed 48 to 8 | int48 | int8 | false | false | 1944 | signed 48 to 16 | int48 | int16 | false | false | 1945 | signed 48 to 32 | int48 | int32 | false | false | 1946 | unsigned 8 to signed 8 | uint8 | int8 | true | false | 1947 | signed 8 to unsigned 8 | int8 | uint8 | false | true | 1948 }]; 1949 1950 let arguments = (ins 1951 Tosa_Tensor:$input, 1952 I32Attr:$input_zp, 1953 I32Attr:$output_zp, 1954 DenseI32ArrayAttr:$multiplier, 1955 DenseI8ArrayAttr:$shift, 1956 BoolAttr:$scale32, 1957 BoolAttr:$double_round, 1958 BoolAttr:$per_channel, 1959 DefaultValuedOptionalAttr<BoolAttr, "false">:$input_unsigned, 1960 DefaultValuedOptionalAttr<BoolAttr, "false">:$output_unsigned 1961 ); 1962 1963 let results = (outs 1964 Tosa_Tensor:$output 1965 ); 1966 1967 let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)"; 1968} 1969 1970//===----------------------------------------------------------------------===// 1971// TOSA Spec Section 2.13 1972// Operator Class: Data Node Ops. 1973//===----------------------------------------------------------------------===// 1974 1975//===----------------------------------------------------------------------===// 1976// Operator: const 1977//===----------------------------------------------------------------------===// 1978def Tosa_ConstOp : Tosa_Op<"const", [ConstantLike, Pure, 1979 AllShapesMatch<["value", "output"]>, 1980 FirstAttrDerivedResultType]> { 1981 let summary = "Constant op."; 1982 1983 let description = [{ 1984 A node containing constant data for use as the input to an operation. May 1985 hold data in any of the supported data formats. 1986 1987 Example: 1988 1989 ```mlir 1990 // Generic form 1991 %out = "tosa.const"() {value = dense<0> : tensor<2x3xi32>} : () -> tensor<2x3xi32> 1992 ``` 1993 }]; 1994 1995 let arguments = (ins 1996 ElementsAttr:$value 1997 ); 1998 1999 let results = (outs 2000 TosaTensorOf<[AnyTypeOf<[Tosa_AnyNumber]>]>:$output 2001 ); 2002 2003 let hasFolder = 1; 2004 let hasVerifier = 1; 2005} 2006 2007//===----------------------------------------------------------------------===// 2008// Operator: identity 2009//===----------------------------------------------------------------------===// 2010def Tosa_IdentityOp: Tosa_Op<"identity", [Pure, 2011 DeclareOpInterfaceMethods<InferShapedTypeOpInterface, 2012 ["inferReturnTypeComponents"]>]> { 2013 let summary = "Identity operator"; 2014 let description = [{ 2015 Returns a tensor with the same shape, size, type 2016 and content as the input. 2017 }]; 2018 2019 let arguments = (ins 2020 Tosa_Tensor:$input1 2021 ); 2022 2023 let results = (outs 2024 Tosa_Tensor:$output 2025 ); 2026 2027 let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)"; 2028} 2029 2030//===----------------------------------------------------------------------===// 2031// TOSA Spec Section 2.14 2032// Operator Class: Custom Operators. 2033//===----------------------------------------------------------------------===// 2034 2035//===----------------------------------------------------------------------===// 2036// Operator: custom 2037//===----------------------------------------------------------------------===// 2038def Tosa_CustomOp : Tosa_Op<"custom"> { 2039 2040 let summary = "Custom operator wrapper for Tosa"; 2041 2042 let description = [{ 2043 Hardware implementing TOSA may choose to add additional custom operators 2044 that are not expressed in the existing TOSA operations. These operators are 2045 not expected to be portable across TOSA implementations. The input and 2046 output signatures must be expressed in the corresponding TOSA node. 2047 2048 `operator_name` is a string that tells the backend which custom operator is 2049 being called. 2050 2051 `domain_name` is a string identifier which can help avoid name collisions on 2052 the identifier field. 2053 2054 `implementation_attrs` is a string which is a backend and identifier specific 2055 set of attributes to the custom operator. 2056 2057 `input_list` is the set of tensor inputs to the custom operator. 2058 2059 `output_list` is the list of tensors returned by the operator. The number of operators 2060 is backend specific. 2061 2062 Example: 2063 2064 ```mlir 2065 %out = tosa.custom %in {domain_name = "tosa_mlir_test", operator_name = 2066 "custom_test", implementation_attrs = ""}: (tensor<10xi32>) -> 2067 (tensor<10xi32>) 2068 ``` 2069 }]; 2070 2071 let arguments = (ins 2072 StrAttr:$operator_name, 2073 StrAttr:$domain_name, 2074 StrAttr:$implementation_attrs, 2075 Variadic<Tosa_Tensor>:$input_list 2076 ); 2077 2078 let results = (outs 2079 Variadic<Tosa_Tensor>:$output_list 2080 ); 2081 2082 let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)"; 2083} 2084 2085//===----------------------------------------------------------------------===// 2086// TOSA Spec Section 2.15 2087// Operator Class: Control Flow Operators. 2088//===----------------------------------------------------------------------===// 2089 2090//===----------------------------------------------------------------------===// 2091// Operator: cond_if 2092//===----------------------------------------------------------------------===// 2093//===----------------------------------------------------------------------===// 2094// Further described in docs/Rationale/RationaleTOSADialect.md . 2095//===----------------------------------------------------------------------===// 2096def Tosa_IfOp : Tosa_Op<"cond_if", 2097 [InferShapedTypeOpAdaptor, 2098 SingleBlockImplicitTerminator<"YieldOp">, 2099 RecursiveMemoryEffects]> { 2100 let summary = "Conditional if operator"; 2101 2102 let description = [{ 2103 Evaluates a Boolean condition and then takes one of two distinct execution 2104 paths. This implements the semantic If-then-else structure. 2105 }]; 2106 2107 let arguments = (ins 2108 Tosa_I1Tensor:$cond, 2109 Variadic<Tosa_Tensor>:$inputs 2110 ); 2111 2112 let results = (outs 2113 Variadic<Tosa_Tensor>:$output 2114 ); 2115 2116 let regions = (region 2117 SizedRegion<1>:$then_branch, 2118 SizedRegion<1>:$else_branch 2119 ); 2120 2121 let hasCustomAssemblyFormat = 1; 2122} 2123 2124//===----------------------------------------------------------------------===// 2125// Operator: while_loop 2126//===----------------------------------------------------------------------===// 2127//===----------------------------------------------------------------------===// 2128// Further described in docs/Rationale/RationaleTOSADialect.md . 2129//===----------------------------------------------------------------------===// 2130def Tosa_WhileOp : Tosa_Op<"while_loop", [ 2131 DeclareOpInterfaceMethods<LoopLikeOpInterface>, 2132 InferShapedTypeOpAdaptor, 2133 SingleBlockImplicitTerminator<"YieldOp">, 2134 RecursiveMemoryEffects]> { 2135 let summary = "output = input; While (Cond(output)) {output = Body(output)}"; 2136 2137 let description = [{ 2138 Generates and evaluates a Bool condition and either executes a loop body or 2139 exits to another control point. This action is performed repeatedly after 2140 updating and re-evaluating the Boolean condition every iteration. This 2141 implements the semantic foreach or while iterative loop structure. 2142 }]; 2143 2144 let arguments = (ins 2145 Variadic<Tosa_Tensor>:$inputs 2146 ); 2147 2148 let results = (outs 2149 Variadic<Tosa_Tensor>:$output 2150 ); 2151 2152 let regions = (region 2153 SizedRegion<1>:$cond, 2154 SizedRegion<1>:$body 2155 ); 2156 2157 let hasCustomAssemblyFormat = 1; 2158} 2159 2160include "mlir/Dialect/Tosa/IR/TosaUtilOps.td" 2161 2162include "mlir/Dialect/Tosa/IR/TosaShapeOps.td" 2163 2164#endif // TOSA_OPS 2165