1// RUN: mlir-opt %s --sparse-compiler | \ 2// RUN: mlir-cpu-runner \ 3// RUN: -e entry -entry-point-result=void \ 4// RUN: -shared-libs=%mlir_integration_test_dir/libmlir_c_runner_utils%shlibext | \ 5// RUN: FileCheck %s 6 7#SparseMatrix = #sparse_tensor.encoding<{ 8 dimLevelType = [ "compressed", "compressed" ] 9}> 10 11#SparseTensor = #sparse_tensor.encoding<{ 12 dimLevelType = [ "compressed", "compressed", "compressed" ] 13}> 14 15#redsum = { 16 indexing_maps = [ 17 affine_map<(i,j,k) -> (i,j,k)>, // A 18 affine_map<(i,j,k) -> (i,j,k)>, // B 19 affine_map<(i,j,k) -> (i,j)> // X (out) 20 ], 21 iterator_types = ["parallel", "parallel", "reduction"], 22 doc = "X(i,j) = SUM_k A(i,j,k) * B(i,j,k)" 23} 24 25module { 26 func.func @redsum(%arga: tensor<?x?x?xi32, #SparseTensor>, 27 %argb: tensor<?x?x?xi32, #SparseTensor>) 28 -> tensor<?x?xi32, #SparseMatrix> { 29 %c0 = arith.constant 0 : index 30 %c1 = arith.constant 1 : index 31 %d0 = tensor.dim %arga, %c0 : tensor<?x?x?xi32, #SparseTensor> 32 %d1 = tensor.dim %arga, %c1 : tensor<?x?x?xi32, #SparseTensor> 33 %xinit = bufferization.alloc_tensor(%d0, %d1): tensor<?x?xi32, #SparseMatrix> 34 %0 = linalg.generic #redsum 35 ins(%arga, %argb: tensor<?x?x?xi32, #SparseTensor>, 36 tensor<?x?x?xi32, #SparseTensor>) 37 outs(%xinit: tensor<?x?xi32, #SparseMatrix>) { 38 ^bb(%a: i32, %b: i32, %x: i32): 39 %0 = arith.muli %a, %b : i32 40 %1 = arith.addi %x, %0 : i32 41 linalg.yield %1 : i32 42 } -> tensor<?x?xi32, #SparseMatrix> 43 return %0 : tensor<?x?xi32, #SparseMatrix> 44 } 45 46 // Driver method to call and verify tensor kernel. 47 func.func @entry() { 48 %c0 = arith.constant 0 : index 49 %i0 = arith.constant -1 : i32 50 51 // Setup very sparse 3-d tensors. 52 %t1 = arith.constant sparse< 53 [ [1,1,3], [2,0,0], [2,2,1], [2,2,2], [2,2,3] ], [ 1, 2, 3, 4, 5 ] 54 > : tensor<3x3x4xi32> 55 %t2 = arith.constant sparse< 56 [ [1,0,0], [1,1,3], [2,2,1], [2,2,3] ], [ 6, 7, 8, 9 ] 57 > : tensor<3x3x4xi32> 58 %st1 = sparse_tensor.convert %t1 59 : tensor<3x3x4xi32> to tensor<?x?x?xi32, #SparseTensor> 60 %st2 = sparse_tensor.convert %t2 61 : tensor<3x3x4xi32> to tensor<?x?x?xi32, #SparseTensor> 62 63 // Call kernel. 64 %0 = call @redsum(%st1, %st2) 65 : (tensor<?x?x?xi32, #SparseTensor>, 66 tensor<?x?x?xi32, #SparseTensor>) -> tensor<?x?xi32, #SparseMatrix> 67 68 // 69 // Verify results. Only two entries stored in result. Correct structure. 70 // 71 // CHECK: ( 7, 69, -1, -1 ) 72 // CHECK-NEXT: ( ( 0, 0, 0 ), ( 0, 7, 0 ), ( 0, 0, 69 ) ) 73 // 74 %val = sparse_tensor.values %0 75 : tensor<?x?xi32, #SparseMatrix> to memref<?xi32> 76 %vv = vector.transfer_read %val[%c0], %i0: memref<?xi32>, vector<4xi32> 77 vector.print %vv : vector<4xi32> 78 %dm = sparse_tensor.convert %0 79 : tensor<?x?xi32, #SparseMatrix> to tensor<?x?xi32> 80 %vm = vector.transfer_read %dm[%c0, %c0], %i0: tensor<?x?xi32>, vector<3x3xi32> 81 vector.print %vm : vector<3x3xi32> 82 83 // Release the resources. 84 bufferization.dealloc_tensor %st1 : tensor<?x?x?xi32, #SparseTensor> 85 bufferization.dealloc_tensor %st2 : tensor<?x?x?xi32, #SparseTensor> 86 bufferization.dealloc_tensor %0 : tensor<?x?xi32, #SparseMatrix> 87 return 88 } 89} 90