1// RUN: mlir-opt %s -split-input-file -verify-diagnostics
2
3func.func @invalid_new_dense(%arg0: !llvm.ptr<i8>) -> tensor<32xf32> {
4  // expected-error@+1 {{expected a sparse tensor result}}
5  %0 = sparse_tensor.new %arg0 : !llvm.ptr<i8> to tensor<32xf32>
6  return %0 : tensor<32xf32>
7}
8
9// -----
10
11func.func @invalid_release_dense(%arg0: tensor<4xi32>) {
12  // expected-error@+1 {{expected a sparse tensor to release}}
13  sparse_tensor.release %arg0 : tensor<4xi32>
14  return
15}
16
17// -----
18
19func.func @invalid_init_dense(%arg0: index, %arg1: index) -> tensor<?x?xf32> {
20  // expected-error@+1 {{expected a sparse tensor result}}
21  %0 = sparse_tensor.init [%arg0, %arg1] : tensor<?x?xf32>
22  return %0 : tensor<?x?xf32>
23}
24
25// -----
26
27#SparseVector = #sparse_tensor.encoding<{dimLevelType = ["compressed"]}>
28
29func.func @invalid_init_rank(%arg0: index) -> tensor<?xf32, #SparseVector> {
30  // expected-error@+1 {{unexpected mismatch between tensor rank and sizes: 1 vs. 2}}
31  %0 = sparse_tensor.init [%arg0, %arg0] : tensor<?xf32, #SparseVector>
32  return %0 : tensor<?xf32, #SparseVector>
33}
34
35// -----
36
37#SparseMatrix = #sparse_tensor.encoding<{dimLevelType = ["compressed", "compressed"]}>
38
39func.func @invalid_init_size() -> tensor<?x10xf32, #SparseMatrix> {
40  %c10 = arith.constant 10 : index
41  %c20 = arith.constant 20 : index
42  // expected-error@+1 {{unexpected mismatch with static dimension size 10}}
43  %0 = sparse_tensor.init [%c10, %c20] : tensor<?x10xf32, #SparseMatrix>
44  return %0 : tensor<?x10xf32, #SparseMatrix>
45}
46
47// -----
48
49func.func @invalid_pointers_dense(%arg0: tensor<128xf64>) -> memref<?xindex> {
50  %c = arith.constant 0 : index
51  // expected-error@+1 {{expected a sparse tensor to get pointers}}
52  %0 = sparse_tensor.pointers %arg0, %c : tensor<128xf64> to memref<?xindex>
53  return %0 : memref<?xindex>
54}
55
56// -----
57
58func.func @invalid_pointers_unranked(%arg0: tensor<*xf64>) -> memref<?xindex> {
59  %c = arith.constant 0 : index
60  // expected-error@+1 {{expected a sparse tensor to get pointers}}
61  %0 = sparse_tensor.pointers %arg0, %c : tensor<*xf64> to memref<?xindex>
62  return %0 : memref<?xindex>
63}
64
65// -----
66
67#SparseVector = #sparse_tensor.encoding<{dimLevelType = ["compressed"], pointerBitWidth=32}>
68
69func.func @mismatch_pointers_types(%arg0: tensor<128xf64, #SparseVector>) -> memref<?xindex> {
70  %c = arith.constant 0 : index
71  // expected-error@+1 {{unexpected type for pointers}}
72  %0 = sparse_tensor.pointers %arg0, %c : tensor<128xf64, #SparseVector> to memref<?xindex>
73  return %0 : memref<?xindex>
74}
75
76// -----
77
78#SparseVector = #sparse_tensor.encoding<{dimLevelType = ["compressed"]}>
79
80func.func @pointers_oob(%arg0: tensor<128xf64, #SparseVector>) -> memref<?xindex> {
81  %c = arith.constant 1 : index
82  // expected-error@+1 {{requested pointers dimension out of bounds}}
83  %0 = sparse_tensor.pointers %arg0, %c : tensor<128xf64, #SparseVector> to memref<?xindex>
84  return %0 : memref<?xindex>
85}
86
87// -----
88
89func.func @invalid_indices_dense(%arg0: tensor<10x10xi32>) -> memref<?xindex> {
90  %c = arith.constant 1 : index
91  // expected-error@+1 {{expected a sparse tensor to get indices}}
92  %0 = sparse_tensor.indices %arg0, %c : tensor<10x10xi32> to memref<?xindex>
93  return %0 : memref<?xindex>
94}
95
96// -----
97
98func.func @invalid_indices_unranked(%arg0: tensor<*xf64>) -> memref<?xindex> {
99  %c = arith.constant 0 : index
100  // expected-error@+1 {{expected a sparse tensor to get indices}}
101  %0 = sparse_tensor.indices %arg0, %c : tensor<*xf64> to memref<?xindex>
102  return %0 : memref<?xindex>
103}
104
105// -----
106
107#SparseVector = #sparse_tensor.encoding<{dimLevelType = ["compressed"]}>
108
109func.func @mismatch_indices_types(%arg0: tensor<?xf64, #SparseVector>) -> memref<?xi32> {
110  %c = arith.constant 0 : index
111  // expected-error@+1 {{unexpected type for indices}}
112  %0 = sparse_tensor.indices %arg0, %c : tensor<?xf64, #SparseVector> to memref<?xi32>
113  return %0 : memref<?xi32>
114}
115
116// -----
117
118#SparseVector = #sparse_tensor.encoding<{dimLevelType = ["compressed"]}>
119
120func.func @indices_oob(%arg0: tensor<128xf64, #SparseVector>) -> memref<?xindex> {
121  %c = arith.constant 1 : index
122  // expected-error@+1 {{requested indices dimension out of bounds}}
123  %0 = sparse_tensor.indices %arg0, %c : tensor<128xf64, #SparseVector> to memref<?xindex>
124  return %0 : memref<?xindex>
125}
126
127// -----
128
129func.func @invalid_values_dense(%arg0: tensor<1024xf32>) -> memref<?xf32> {
130  // expected-error@+1 {{expected a sparse tensor to get values}}
131  %0 = sparse_tensor.values %arg0 : tensor<1024xf32> to memref<?xf32>
132  return %0 : memref<?xf32>
133}
134
135// -----
136
137#SparseVector = #sparse_tensor.encoding<{dimLevelType = ["compressed"]}>
138
139func.func @mismatch_values_types(%arg0: tensor<?xf64, #SparseVector>) -> memref<?xf32> {
140  // expected-error@+1 {{unexpected mismatch in element types}}
141  %0 = sparse_tensor.values %arg0 : tensor<?xf64, #SparseVector> to memref<?xf32>
142  return %0 : memref<?xf32>
143}
144
145// -----
146
147func.func @sparse_unannotated_load(%arg0: tensor<16x32xf64>) -> tensor<16x32xf64> {
148  // expected-error@+1 {{expected a sparse tensor to materialize}}
149  %0 = sparse_tensor.load %arg0 : tensor<16x32xf64>
150  return %0 : tensor<16x32xf64>
151}
152
153// -----
154
155func.func @sparse_unannotated_insert(%arg0: tensor<128xf64>, %arg1: memref<?xindex>, %arg2: f64) {
156  // expected-error@+1 {{expected a sparse tensor for insertion}}
157  sparse_tensor.lex_insert %arg0, %arg1, %arg2 : tensor<128xf64>, memref<?xindex>, f64
158  return
159}
160
161// -----
162
163func.func @sparse_unannotated_expansion(%arg0: tensor<128xf64>) {
164  // expected-error@+1 {{expected a sparse tensor for expansion}}
165  %values, %filled, %added, %count = sparse_tensor.expand %arg0
166    : tensor<128xf64> to memref<?xf64>, memref<?xi1>, memref<?xindex>, index
167  return
168}
169
170// -----
171
172func.func @sparse_unannotated_compression(%arg0: tensor<128xf64>, %arg1: memref<?xindex>,
173                                     %arg2: memref<?xf64>, %arg3: memref<?xi1>,
174				     %arg4: memref<?xindex>, %arg5: index) {
175  // expected-error@+1 {{expected a sparse tensor for compression}}
176  sparse_tensor.compress %arg0, %arg1, %arg2, %arg3, %arg4, %arg5
177    : tensor<128xf64>, memref<?xindex>, memref<?xf64>, memref<?xi1>, memref<?xindex>, index
178}
179
180// -----
181
182func.func @sparse_convert_unranked(%arg0: tensor<*xf32>) -> tensor<10xf32> {
183  // expected-error@+1 {{unexpected type in convert}}
184  %0 = sparse_tensor.convert %arg0 : tensor<*xf32> to tensor<10xf32>
185  return %0 : tensor<10xf32>
186}
187
188// -----
189
190#DCSR = #sparse_tensor.encoding<{dimLevelType = ["compressed", "compressed"]}>
191
192func.func @sparse_convert_rank_mismatch(%arg0: tensor<10x10xf64, #DCSR>) -> tensor<?xf64> {
193  // expected-error@+1 {{unexpected conversion mismatch in rank}}
194  %0 = sparse_tensor.convert %arg0 : tensor<10x10xf64, #DCSR> to tensor<?xf64>
195  return %0 : tensor<?xf64>
196}
197
198// -----
199
200#CSR = #sparse_tensor.encoding<{dimLevelType = ["dense", "compressed"]}>
201
202func.func @sparse_convert_dim_mismatch(%arg0: tensor<10x?xf32>) -> tensor<10x10xf32, #CSR> {
203  // expected-error@+1 {{unexpected conversion mismatch in dimension 1}}
204  %0 = sparse_tensor.convert %arg0 : tensor<10x?xf32> to tensor<10x10xf32, #CSR>
205  return %0 : tensor<10x10xf32, #CSR>
206}
207
208// -----
209
210func.func @invalid_out_dense(%arg0: tensor<10xf64>, %arg1: !llvm.ptr<i8>) {
211  // expected-error@+1 {{expected a sparse tensor for output}}
212  sparse_tensor.out %arg0, %arg1 : tensor<10xf64>, !llvm.ptr<i8>
213  return
214}
215
216// -----
217
218func.func @invalid_binary_num_args_mismatch_overlap(%arg0: f64, %arg1: f64) -> f64 {
219  // expected-error@+1 {{overlap region must have exactly 2 arguments}}
220  %r = sparse_tensor.binary %arg0, %arg1 : f64, f64 to f64
221    overlap={
222      ^bb0(%x: f64):
223        sparse_tensor.yield %x : f64
224    }
225    left={}
226    right={}
227  return %r : f64
228}
229
230// -----
231
232func.func @invalid_binary_num_args_mismatch_right(%arg0: f64, %arg1: f64) -> f64 {
233  // expected-error@+1 {{right region must have exactly 1 arguments}}
234  %r = sparse_tensor.binary %arg0, %arg1 : f64, f64 to f64
235    overlap={}
236    left={}
237    right={
238      ^bb0(%x: f64, %y: f64):
239        sparse_tensor.yield %y : f64
240    }
241  return %r : f64
242}
243
244// -----
245
246func.func @invalid_binary_argtype_mismatch(%arg0: f64, %arg1: f64) -> f64 {
247  // expected-error@+1 {{overlap region argument 2 type mismatch}}
248  %r = sparse_tensor.binary %arg0, %arg1 : f64, f64 to f64
249    overlap={
250      ^bb0(%x: f64, %y: f32):
251        sparse_tensor.yield %x : f64
252    }
253    left=identity
254    right=identity
255  return %r : f64
256}
257
258// -----
259
260func.func @invalid_binary_wrong_return_type(%arg0: f64, %arg1: f64) -> f64 {
261  // expected-error@+1 {{left region yield type mismatch}}
262  %0 = sparse_tensor.binary %arg0, %arg1 : f64, f64 to f64
263    overlap={}
264    left={
265      ^bb0(%x: f64):
266        %1 = arith.constant 0.0 : f32
267        sparse_tensor.yield %1 : f32
268    }
269    right=identity
270  return %0 : f64
271}
272
273// -----
274
275func.func @invalid_binary_wrong_identity_type(%arg0: i64, %arg1: f64) -> f64 {
276  // expected-error@+1 {{left=identity requires first argument to have the same type as the output}}
277  %0 = sparse_tensor.binary %arg0, %arg1 : i64, f64 to f64
278    overlap={}
279    left=identity
280    right=identity
281  return %0 : f64
282}
283
284// -----
285
286func.func @invalid_unary_argtype_mismatch(%arg0: f64) -> f64 {
287  // expected-error@+1 {{present region argument 1 type mismatch}}
288  %r = sparse_tensor.unary %arg0 : f64 to f64
289    present={
290      ^bb0(%x: index):
291        sparse_tensor.yield %x : index
292    }
293    absent={}
294  return %r : f64
295}
296
297// -----
298
299func.func @invalid_unary_num_args_mismatch(%arg0: f64) -> f64 {
300  // expected-error@+1 {{absent region must have exactly 0 arguments}}
301  %r = sparse_tensor.unary %arg0 : f64 to f64
302    present={}
303    absent={
304      ^bb0(%x: f64):
305        sparse_tensor.yield %x : f64
306    }
307  return %r : f64
308}
309
310// -----
311
312func.func @invalid_unary_wrong_return_type(%arg0: f64) -> f64 {
313  // expected-error@+1 {{present region yield type mismatch}}
314  %0 = sparse_tensor.unary %arg0 : f64 to f64
315    present={
316      ^bb0(%x: f64):
317        %1 = arith.constant 0.0 : f32
318        sparse_tensor.yield %1 : f32
319    }
320    absent={}
321  return %0 : f64
322}
323