blob: 4d583435adeeee6cee00b07f2346f78e01249c24 [file] [log] [blame]
Mehdi Amini65b6ecb2019-12-24 02:47:41 +00001// RUN: mlir-opt %s -split-input-file -verify-diagnostics
2
3// Verify that ops with broadcastable trait verifies operand and result type
4// combinations and emits an error for invalid combinations.
5
River Riddle12bf5382022-04-20 16:20:54 -07006func.func @broadcast_scalar_scalar_scalar(tensor<i32>, tensor<i32>) -> tensor<i32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +00007^bb0(%arg0: tensor<i32>, %arg1: tensor<i32>):
8 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32>
9 return %0 : tensor<i32>
10}
11
12// -----
13
River Riddle12bf5382022-04-20 16:20:54 -070014func.func @broadcast_tensor_scalar_tensor(tensor<4xi32>, tensor<i32>) -> tensor<4xi32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +000015^bb0(%arg0: tensor<4xi32>, %arg1: tensor<i32>):
16 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<4xi32>, tensor<i32>) -> tensor<4xi32>
17 return %0 : tensor<4xi32>
18}
19
20// -----
21
22// Check only one dimension has size 1
River Riddle12bf5382022-04-20 16:20:54 -070023func.func @broadcast_tensor_tensor_tensor(tensor<4x3x2xi32>, tensor<3x1xi32>) -> tensor<4x3x2xi32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +000024^bb0(%arg0: tensor<4x3x2xi32>, %arg1: tensor<3x1xi32>):
25 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<4x3x2xi32>, tensor<3x1xi32>) -> tensor<4x3x2xi32>
26 return %0 : tensor<4x3x2xi32>
27}
28
29// -----
30
31// Check multiple dimensions have size 1
River Riddle12bf5382022-04-20 16:20:54 -070032func.func @broadcast_tensor_tensor_tensor(tensor<8x1x6x1xi32>, tensor<7x1x5xi32>) -> tensor<8x7x6x5xi32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +000033^bb0(%arg0: tensor<8x1x6x1xi32>, %arg1: tensor<7x1x5xi32>):
34 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<8x1x6x1xi32>, tensor<7x1x5xi32>) -> tensor<8x7x6x5xi32>
35 return %0 : tensor<8x7x6x5xi32>
36}
37
38// -----
39
40// Check leading unknown dimension
River Riddle12bf5382022-04-20 16:20:54 -070041func.func @broadcast_tensor_tensor_tensor(tensor<?x1x6x1xi32>, tensor<7x1x5xi32>) -> tensor<?x7x6x5xi32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +000042^bb0(%arg0: tensor<?x1x6x1xi32>, %arg1: tensor<7x1x5xi32>):
43 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<?x1x6x1xi32>, tensor<7x1x5xi32>) -> tensor<?x7x6x5xi32>
44 return %0 : tensor<?x7x6x5xi32>
45}
46
47// -----
48
49// Check unknown dimension in the middle
River Riddle12bf5382022-04-20 16:20:54 -070050func.func @broadcast_tensor_tensor_tensor(tensor<8x1x?x1xi32>, tensor<7x1x5xi32>) -> tensor<8x7x?x5xi32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +000051^bb0(%arg0: tensor<8x1x?x1xi32>, %arg1: tensor<7x1x5xi32>):
52 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<8x1x?x1xi32>, tensor<7x1x5xi32>) -> tensor<8x7x?x5xi32>
53 return %0 : tensor<8x7x?x5xi32>
54}
55
56// -----
57
58// Check incompatible vector and tensor result type
River Riddle12bf5382022-04-20 16:20:54 -070059func.func @broadcast_scalar_vector_vector(tensor<4xf32>, tensor<4xf32>) -> vector<4xf32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +000060^bb0(%arg0: tensor<4xf32>, %arg1: tensor<4xf32>):
Chia-hung Duan8cb51b42022-02-25 18:17:30 +000061 // expected-error @+1 {{op result #0 must be tensor of any type values, but got 'vector<4xf32>'}}
Mehdi Amini65b6ecb2019-12-24 02:47:41 +000062 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<4xf32>, tensor<4xf32>) -> vector<4xf32>
63 return %0 : vector<4xf32>
64}
65
66// -----
67
68// Check incompatible operand types with known dimension
River Riddle12bf5382022-04-20 16:20:54 -070069func.func @broadcast_tensor_tensor_tensor(tensor<4x3x2xi32>, tensor<3x3xi32>) -> tensor<4x3x2xi32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +000070^bb0(%arg0: tensor<4x3x2xi32>, %arg1: tensor<3x3xi32>):
71 // expected-error @+1 {{operands don't have broadcast-compatible shapes}}
72 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<4x3x2xi32>, tensor<3x3xi32>) -> tensor<4x3x2xi32>
73 return %0 : tensor<4x3x2xi32>
74}
75
76// -----
77
78// Check incompatible result type with known dimension
River Riddle12bf5382022-04-20 16:20:54 -070079func.func @broadcast_tensor_tensor_tensor(tensor<4x3x2xi32>, tensor<3x1xi32>) -> tensor<4x3x3xi32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +000080^bb0(%arg0: tensor<4x3x2xi32>, %arg1: tensor<3x1xi32>):
Jacques Pienaarc357d432020-01-11 09:42:18 -080081 // expected-error @+1 {{op result type '4x3x3' not broadcast compatible with broadcasted operands's shapes '4x3x2'}}
Mehdi Amini65b6ecb2019-12-24 02:47:41 +000082 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<4x3x2xi32>, tensor<3x1xi32>) -> tensor<4x3x3xi32>
83 return %0 : tensor<4x3x3xi32>
84}
85
86// -----
87
88// Check incompatible result type with known dimension
River Riddle12bf5382022-04-20 16:20:54 -070089func.func @broadcast_tensor_tensor_tensor(tensor<8x1x6x1xi32>, tensor<7x1x5xi32>) -> tensor<8x7x6x1xi32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +000090^bb0(%arg0: tensor<8x1x6x1xi32>, %arg1: tensor<7x1x5xi32>):
Jacques Pienaarc357d432020-01-11 09:42:18 -080091 // expected-error @+1 {{op result type '8x7x6x1' not broadcast compatible with broadcasted operands's shapes '8x7x6x5'}}
Mehdi Amini65b6ecb2019-12-24 02:47:41 +000092 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<8x1x6x1xi32>, tensor<7x1x5xi32>) -> tensor<8x7x6x1xi32>
93 return %0 : tensor<8x7x6x1xi32>
94}
95
96// -----
97
River Riddle12bf5382022-04-20 16:20:54 -070098func.func @broadcast_tensor_tensor_tensor(tensor<2xi32>, tensor<2xi32>) -> tensor<*xi32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +000099^bb0(%arg0: tensor<2xi32>, %arg1: tensor<2xi32>):
100 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<2xi32>, tensor<2xi32>) -> tensor<*xi32>
101 return %0 : tensor<*xi32>
102}
103
104// -----
105
River Riddle12bf5382022-04-20 16:20:54 -0700106func.func @broadcast_tensor_tensor_tensor(tensor<4x3x2xi32>, tensor<?xi32>) -> tensor<4x3x2xi32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +0000107^bb0(%arg0: tensor<4x3x2xi32>, %arg1: tensor<?xi32>):
108 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<4x3x2xi32>, tensor<?xi32>) -> tensor<4x3x2xi32>
109 return %0 : tensor<4x3x2xi32>
110}
111
112// -----
113
Rafael Ubal Tena814ba342023-08-01 08:44:05 -0700114// It is alright to have an implicit dynamic-to-static cast in a dimension size
115// as long as the runtime result size is consistent with the result tensor's
116// static dimension.
Rafael Ubal Tena4c010b02023-07-21 14:48:11 -0700117func.func @broadcast_tensor_tensor_tensor(%arg0: tensor<?xi32>, %arg1: tensor<?xi32>) -> tensor<2xi32> {
Rafael Ubal Tena4c010b02023-07-21 14:48:11 -0700118 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<?xi32>, tensor<?xi32>) -> tensor<2xi32>
119 return %0 : tensor<2xi32>
120}
121
122// -----
123
124func.func @broadcast_tensor_tensor_tensor(%arg0: tensor<?x6x1xi32>, %arg1: tensor<*xi32>) -> tensor<?x6x?xi32> {
125 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<?x6x1xi32>, tensor<*xi32>) -> tensor<?x6x?xi32>
126 return %0 : tensor<?x6x?xi32>
Jacques Pienaardce32ac2021-07-11 20:41:33 -0700127}
128
129// -----
130
Mehdi Amini65b6ecb2019-12-24 02:47:41 +0000131// Unranked operands but ranked result
River Riddle12bf5382022-04-20 16:20:54 -0700132func.func @broadcast_tensor_tensor_tensor(tensor<*xi32>, tensor<*xi32>) -> tensor<2xi32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +0000133^bb0(%arg0: tensor<*xi32>, %arg1: tensor<*xi32>):
134 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<*xi32>, tensor<*xi32>) -> tensor<2xi32>
135 return %0 : tensor<2xi32>
136}
137
138// -----
139
140// Unranked operand and compatible ranked result
River Riddle12bf5382022-04-20 16:20:54 -0700141func.func @broadcast_tensor_tensor_tensor(tensor<3x2xi32>, tensor<*xi32>) -> tensor<4x3x2xi32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +0000142^bb0(%arg0: tensor<3x2xi32>, %arg1: tensor<*xi32>):
Jacques Pienaarc357d432020-01-11 09:42:18 -0800143 %0 = "test.broadcastable"(%arg0, %arg0, %arg1) : (tensor<3x2xi32>, tensor<3x2xi32>, tensor<*xi32>) -> tensor<4x3x2xi32>
Mehdi Amini65b6ecb2019-12-24 02:47:41 +0000144 return %0 : tensor<4x3x2xi32>
145}
146
147// -----
148
River Riddle12bf5382022-04-20 16:20:54 -0700149func.func @broadcast_tensor_tensor_tensor(tensor<3x2xi32>, tensor<*xi32>) -> tensor<2xi32> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +0000150^bb0(%arg0: tensor<3x2xi32>, %arg1: tensor<*xi32>):
Jacques Pienaarc357d432020-01-11 09:42:18 -0800151 // expected-error @+1 {{op result type '2' not broadcast compatible with broadcasted operands's shapes '3x2'}}
Mehdi Amini65b6ecb2019-12-24 02:47:41 +0000152 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<3x2xi32>, tensor<*xi32>) -> tensor<2xi32>
153 return %0 : tensor<2xi32>
154}
155
156// -----
157
Rafael Ubal Tena4c010b02023-07-21 14:48:11 -0700158// Correct use of broadcast semantics for input dimensions
159func.func @broadcast_tensor_tensor_tensor(%arg0: tensor<?x1x6x1xi32>, %arg1: tensor<7x1x5xi32>) -> tensor<?x7x6x5xi32> {
160 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<?x1x6x1xi32>, tensor<7x1x5xi32>) -> tensor<?x7x6x5xi32>
161 return %0 : tensor<?x7x6x5xi32>
162}
163
164// -----
165
166// Incorrect attempt to use broadcast semantics for result
167func.func @broadcast_tensor_tensor_tensor(%arg0: tensor<1xi32>, %arg1: tensor<1xi32>) -> tensor<5xi32> {
168 // expected-error @+1 {{op result type '5' not broadcast compatible with broadcasted operands's shapes '1'}}
169 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<1xi32>, tensor<1xi32>) -> tensor<5xi32>
170 return %0 : tensor<5xi32>
Mehdi Amini65b6ecb2019-12-24 02:47:41 +0000171}
172
173// -----
174
River Riddle12bf5382022-04-20 16:20:54 -0700175func.func @broadcastDifferentResultType(tensor<4xi32>, tensor<4xi32>) -> tensor<4xi1> {
Mehdi Amini65b6ecb2019-12-24 02:47:41 +0000176^bb0(%arg0: tensor<4xi32>, %arg1: tensor<4xi32>):
177 %0 = "test.broadcastable"(%arg0, %arg1) : (tensor<4xi32>, tensor<4xi32>) -> tensor<4xi1>
178 return %0 : tensor<4xi1>
179}