xref: /llvm-project/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td (revision 956c0707d9098499a2682297b71f46b0a562eed9)
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