// First use with `kViaCOO` for sparse2sparse conversion (the old way). // RUN: mlir-opt %s --sparse-tensor-conversion="s2s-strategy=1" \ // RUN: --canonicalize --cse | FileCheck %s -check-prefix=CHECK-COO // // Now again with `kAuto` (the new default). // RUN: mlir-opt %s --sparse-tensor-conversion="s2s-strategy=0" \ // RUN: --canonicalize --cse | FileCheck %s -check-prefixes=CHECK-AUTO,CHECK #SparseVector64 = #sparse_tensor.encoding<{ dimLevelType = ["compressed"], pointerBitWidth = 64, indexBitWidth = 64 }> #SparseVector32 = #sparse_tensor.encoding<{ dimLevelType = ["compressed"], pointerBitWidth = 32, indexBitWidth = 32 }> #SparseVector = #sparse_tensor.encoding<{ dimLevelType = ["compressed"] }> // CHECK-LABEL: func @sparse_nop_convert( // CHECK-SAME: %[[A:.*]]: !llvm.ptr) -> !llvm.ptr // CHECK: return %[[A]] : !llvm.ptr func.func @sparse_nop_convert(%arg0: tensor<64xf32, #SparseVector>) -> tensor<64xf32, #SparseVector> { %0 = sparse_tensor.convert %arg0 : tensor<64xf32, #SparseVector> to tensor<64xf32, #SparseVector> return %0 : tensor<64xf32, #SparseVector> } // CHECK-LABEL: func @sparse_hidden_nop_cast( // CHECK-SAME: %[[A:.*]]: !llvm.ptr) -> !llvm.ptr // CHECK: return %[[A]] : !llvm.ptr func.func @sparse_hidden_nop_cast(%arg0: tensor<32xf32, #SparseVector>) -> tensor { %0 = sparse_tensor.convert %arg0 : tensor<32xf32, #SparseVector> to tensor return %0 : tensor } // CHECK-LABEL: func @sparse_convert_1d_ss( // CHECK-SAME: %[[A:.*]]: !llvm.ptr) // CHECK-DAG: %[[SparseToSparse:.*]] = arith.constant 3 : i32 // CHECK-DAG: %[[P:.*]] = memref.alloca() : memref<1xi8> // CHECK-DAG: %[[Q:.*]] = memref.alloca() : memref<1xindex> // CHECK-DAG: %[[R:.*]] = memref.alloca() : memref<1xindex> // CHECK-DAG: %[[X:.*]] = memref.cast %[[P]] : memref<1xi8> to memref // CHECK-DAG: %[[Y:.*]] = memref.cast %[[Q]] : memref<1xindex> to memref // CHECK-DAG: %[[Z:.*]] = memref.cast %[[R]] : memref<1xindex> to memref // CHECK: %[[T:.*]] = call @newSparseTensor(%[[X]], %[[Y]], %[[Z]], %{{.*}}, %{{.*}}, %{{.*}}, %[[SparseToSparse]], %[[A]]) // CHECK: return %[[T]] : !llvm.ptr func.func @sparse_convert_1d_ss(%arg0: tensor) -> tensor { %0 = sparse_tensor.convert %arg0 : tensor to tensor return %0 : tensor } // CHECK-COO-LABEL: func @sparse_convert( // CHECK-COO-SAME: %[[A:.*]]: !llvm.ptr) // CHECK-COO-DAG: %[[ToCOO:.*]] = arith.constant 5 : i32 // CHECK-COO-DAG: %[[FromCOO:.*]] = arith.constant 2 : i32 // CHECK-COO-DAG: %[[P:.*]] = memref.alloca() : memref<1xi8> // CHECK-COO-DAG: %[[Q:.*]] = memref.alloca() : memref<1xindex> // CHECK-COO-DAG: %[[R:.*]] = memref.alloca() : memref<1xindex> // CHECK-COO-DAG: %[[X:.*]] = memref.cast %[[P]] : memref<1xi8> to memref // CHECK-COO-DAG: %[[Y:.*]] = memref.cast %[[Q]] : memref<1xindex> to memref // CHECK-COO-DAG: %[[Z:.*]] = memref.cast %[[R]] : memref<1xindex> to memref // CHECK-COO: %[[C:.*]] = call @newSparseTensor(%[[X]], %[[Y]], %[[Z]], %{{.*}}, %{{.*}}, %{{.*}}, %[[ToCOO]], %[[A]]) // CHECK-COO: %[[T:.*]] = call @newSparseTensor(%[[X]], %[[Y]], %[[Z]], %{{.*}}, %{{.*}}, %{{.*}}, %[[FromCOO]], %[[C]]) // CHECK-COO: call @delSparseTensorCOOF32(%[[C]]) // CHECK-COO: return %[[T]] : !llvm.ptr // CHECK-AUTO-LABEL: func @sparse_convert( // CHECK-AUTO-SAME: %[[A:.*]]: !llvm.ptr) // CHECK-AUTO-DAG: %[[SparseToSparse:.*]] = arith.constant 3 : i32 // CHECK-AUTO-DAG: %[[P:.*]] = memref.alloca() : memref<1xi8> // CHECK-AUTO-DAG: %[[Q:.*]] = memref.alloca() : memref<1xindex> // CHECK-AUTO-DAG: %[[R:.*]] = memref.alloca() : memref<1xindex> // CHECK-AUTO-DAG: %[[X:.*]] = memref.cast %[[P]] : memref<1xi8> to memref // CHECK-AUTO-DAG: %[[Y:.*]] = memref.cast %[[Q]] : memref<1xindex> to memref // CHECK-AUTO-DAG: %[[Z:.*]] = memref.cast %[[R]] : memref<1xindex> to memref // CHECK-AUTO: %[[T:.*]] = call @newSparseTensor(%[[X]], %[[Y]], %[[Z]], %{{.*}}, %{{.*}}, %{{.*}}, %[[SparseToSparse]], %[[A]]) // CHECK-AUTO: return %[[T]] : !llvm.ptr func.func @sparse_convert(%arg0: tensor) -> tensor { %0 = sparse_tensor.convert %arg0 : tensor to tensor return %0 : tensor } #SparseSingleton64 = #sparse_tensor.encoding<{ dimLevelType = ["singleton"], pointerBitWidth = 64, indexBitWidth = 64 }> #SparseSingleton32 = #sparse_tensor.encoding<{ dimLevelType = ["singleton"], pointerBitWidth = 32, indexBitWidth = 32 }> // CHECK-COO-LABEL: func @sparse_convert_singleton( // CHECK-COO-SAME: %[[A:.*]]: !llvm.ptr) // CHECK-COO-DAG: %[[ToCOO:.*]] = arith.constant 5 : i32 // CHECK-COO-DAG: %[[FromCOO:.*]] = arith.constant 2 : i32 // CHECK-COO-DAG: %[[P:.*]] = memref.alloca() : memref<1xi8> // CHECK-COO-DAG: %[[Q:.*]] = memref.alloca() : memref<1xindex> // CHECK-COO-DAG: %[[R:.*]] = memref.alloca() : memref<1xindex> // CHECK-COO-DAG: %[[X:.*]] = memref.cast %[[P]] : memref<1xi8> to memref // CHECK-COO-DAG: %[[Y:.*]] = memref.cast %[[Q]] : memref<1xindex> to memref // CHECK-COO-DAG: %[[Z:.*]] = memref.cast %[[R]] : memref<1xindex> to memref // CHECK-COO: %[[C:.*]] = call @newSparseTensor(%[[X]], %[[Y]], %[[Z]], %{{.*}}, %{{.*}}, %{{.*}}, %[[ToCOO]], %[[A]]) // CHECK-COO: %[[T:.*]] = call @newSparseTensor(%[[X]], %[[Y]], %[[Z]], %{{.*}}, %{{.*}}, %{{.*}}, %[[FromCOO]], %[[C]]) // CHECK-COO: call @delSparseTensorCOOF32(%[[C]]) // CHECK-COO: return %[[T]] : !llvm.ptr // CHECK-AUTO-LABEL: func @sparse_convert_singleton( // CHECK-AUTO-SAME: %[[A:.*]]: !llvm.ptr) // CHECK-AUTO-DAG: %[[SparseToSparse:.*]] = arith.constant 3 : i32 // CHECK-AUTO-DAG: %[[P:.*]] = memref.alloca() : memref<1xi8> // CHECK-AUTO-DAG: %[[Q:.*]] = memref.alloca() : memref<1xindex> // CHECK-AUTO-DAG: %[[R:.*]] = memref.alloca() : memref<1xindex> // CHECK-AUTO-DAG: %[[X:.*]] = memref.cast %[[P]] : memref<1xi8> to memref // CHECK-AUTO-DAG: %[[Y:.*]] = memref.cast %[[Q]] : memref<1xindex> to memref // CHECK-AUTO-DAG: %[[Z:.*]] = memref.cast %[[R]] : memref<1xindex> to memref // CHECK-AUTO: %[[T:.*]] = call @newSparseTensor(%[[X]], %[[Y]], %[[Z]], %{{.*}}, %{{.*}}, %{{.*}}, %[[SparseToSparse]], %[[A]]) // CHECK-AUTO: return %[[T]] : !llvm.ptr func.func @sparse_convert_singleton(%arg0: tensor) -> tensor { %0 = sparse_tensor.convert %arg0 : tensor to tensor return %0 : tensor }