let hasVerifier = 1;
}
-def SparseTensor_PushBackOp : SparseTensor_Op<"push_back", []>,
+def SparseTensor_PushBackOp : SparseTensor_Op<"push_back",
+ [TypesMatchWith<"value type matches element type of inBuffer",
+ "inBuffer", "value",
+ "$_self.cast<ShapedType>().getElementType()">,
+ AllTypesMatch<["inBuffer", "outBuffer"]>]>,
Arguments<(ins StridedMemRefRankOf<[Index], [1]>:$bufferSizes,
StridedMemRefRankOf<[AnyType], [1]>:$inBuffer,
AnyType:$value, IndexAttr:$idx, UnitAttr:$inbounds)>,
Example:
```mlir
- %r = sparse_tensor.push_back %bufferSizes, %buffer, %val {idx = 0 : index}
- : memref<?xindex>, memref<?xf64>, f64 -> memref<?xf64>
+ %r = sparse_tensor.push_back %bufferSizes, %buffer, %val
+ {idx = 0 : index} : memref<?xindex>, memref<?xf64>, f64
```
```mlir
%r = sparse_tensor.push_back inbounds %bufferSizes, %buffer, %val
- {idx = 0 : index} : memref<?xindex>, memref<?xf64>, f64 -> memref<?xf64>
+ {idx = 0 : index} : memref<?xindex>, memref<?xf64>, f64
```
}];
let assemblyFormat = "(`inbounds` $inbounds^)? $bufferSizes `,` $inBuffer"
" `,` $value attr-dict `:` type($bufferSizes) `,`"
- " type($inBuffer) `,` type($value) `to`"
- " type($outBuffer)";
+ " type($inBuffer) `,` type($value)";
}
def SparseTensor_ExpandOp : SparseTensor_Op<"expand", []>,
// CHECK: memref.store %[[P2]], %[[A]]{{\[}}%[[C2]]]
// CHECK: return %[[M]] : memref<?xf64>
func.func @sparse_push_back(%arg0: memref<?xindex>, %arg1: memref<?xf64>, %arg2: f64) -> memref<?xf64> {
- %0 = sparse_tensor.push_back %arg0, %arg1, %arg2 {idx = 2 : index} : memref<?xindex>, memref<?xf64>, f64 to memref<?xf64>
+ %0 = sparse_tensor.push_back %arg0, %arg1, %arg2 {idx = 2 : index} : memref<?xindex>, memref<?xf64>, f64
return %0 : memref<?xf64>
}
// CHECK: memref.store %[[P2]], %[[A]]{{\[}}%[[C2]]]
// CHECK: return %[[B]] : memref<?xf64>
func.func @sparse_push_back_inbound(%arg0: memref<?xindex>, %arg1: memref<?xf64>, %arg2: f64) -> memref<?xf64> {
- %0 = sparse_tensor.push_back inbounds %arg0, %arg1, %arg2 {idx = 2 : index} : memref<?xindex>, memref<?xf64>, f64 to memref<?xf64>
+ %0 = sparse_tensor.push_back inbounds %arg0, %arg1, %arg2 {idx = 2 : index} : memref<?xindex>, memref<?xf64>, f64
return %0 : memref<?xf64>
}
// -----
+func.func @sparse_push_back(%arg0: memref<?xindex>, %arg1: memref<?xf64>, %arg2: f32) -> memref<?xf64> {
+ // expected-error@+1 {{'sparse_tensor.push_back' op failed to verify that value type matches element type of inBuffer}}
+ %0 = sparse_tensor.push_back %arg0, %arg1, %arg2 {idx = 2 : index} : memref<?xindex>, memref<?xf64>, f32
+ return %0 : memref<?xf64>
+}
+
+// -----
+
func.func @sparse_unannotated_expansion(%arg0: tensor<128xf64>) {
// expected-error@+1 {{'sparse_tensor.expand' op operand #0 must be sparse tensor of any type values, but got 'tensor<128xf64>'}}
%values, %filled, %added, %count = sparse_tensor.expand %arg0
// CHECK-SAME: %[[A:.*]]: memref<?xindex>,
// CHECK-SAME: %[[B:.*]]: memref<?xf64>,
// CHECK-SAME: %[[C:.*]]: f64) -> memref<?xf64> {
-// CHECK: %[[D:.*]] = sparse_tensor.push_back %[[A]], %[[B]], %[[C]] {idx = 2 : index} : memref<?xindex>, memref<?xf64>, f64 to memref<?xf64>
+// CHECK: %[[D:.*]] = sparse_tensor.push_back %[[A]], %[[B]], %[[C]] {idx = 2 : index} : memref<?xindex>, memref<?xf64>, f64
// CHECK: return %[[D]]
func.func @sparse_push_back(%arg0: memref<?xindex>, %arg1: memref<?xf64>, %arg2: f64) -> memref<?xf64> {
- %0 = sparse_tensor.push_back %arg0, %arg1, %arg2 {idx = 2 : index} : memref<?xindex>, memref<?xf64>, f64 to memref<?xf64>
+ %0 = sparse_tensor.push_back %arg0, %arg1, %arg2 {idx = 2 : index} : memref<?xindex>, memref<?xf64>, f64
return %0 : memref<?xf64>
}
// CHECK-SAME: %[[A:.*]]: memref<?xindex>,
// CHECK-SAME: %[[B:.*]]: memref<?xf64>,
// CHECK-SAME: %[[C:.*]]: f64) -> memref<?xf64> {
-// CHECK: %[[D:.*]] = sparse_tensor.push_back inbounds %[[A]], %[[B]], %[[C]] {idx = 2 : index} : memref<?xindex>, memref<?xf64>, f64 to memref<?xf64>
+// CHECK: %[[D:.*]] = sparse_tensor.push_back inbounds %[[A]], %[[B]], %[[C]] {idx = 2 : index} : memref<?xindex>, memref<?xf64>, f64
// CHECK: return %[[D]]
func.func @sparse_push_back_inbound(%arg0: memref<?xindex>, %arg1: memref<?xf64>, %arg2: f64) -> memref<?xf64> {
- %0 = sparse_tensor.push_back inbounds %arg0, %arg1, %arg2 {idx = 2 : index} : memref<?xindex>, memref<?xf64>, f64 to memref<?xf64>
+ %0 = sparse_tensor.push_back inbounds %arg0, %arg1, %arg2 {idx = 2 : index} : memref<?xindex>, memref<?xf64>, f64
return %0 : memref<?xf64>
}
%buffer = memref.alloc(%c1) : memref<?xf32>
memref.store %c0, %bufferSizes[%c0] : memref<?xindex>
- %buffer2 = sparse_tensor.push_back %bufferSizes, %buffer, %d2 {idx=0 : index} : memref<?xindex>, memref<?xf32>, f32 to memref<?xf32>
- %buffer3 = sparse_tensor.push_back %bufferSizes, %buffer2, %d1 {idx=0 : index} : memref<?xindex>, memref<?xf32>, f32 to memref<?xf32>
+ %buffer2 = sparse_tensor.push_back %bufferSizes, %buffer, %d2 {idx=0 : index} : memref<?xindex>, memref<?xf32>, f32
+ %buffer3 = sparse_tensor.push_back %bufferSizes, %buffer2, %d1 {idx=0 : index} : memref<?xindex>, memref<?xf32>, f32
// CHECK: ( 2 )
%sizeValue = vector.transfer_read %bufferSizes[%c0], %c0: memref<?xindex>, vector<1xindex>