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#SparseVector = #sparse_tensor.encoding<{ dimLevelType = [ "compressed" ] }> 8 9#trait_op = { 10 indexing_maps = [ 11 affine_map<(i) -> (i)>, // a 12 affine_map<(i) -> (i)> // x (out) 13 ], 14 iterator_types = ["parallel"], 15 doc = "x(i) = OP a(i)" 16} 17 18module { 19 // Performs sign operation (using semi-ring unary op) 20 // with semantics that 21 // > 0 : +1.0 22 // < 0 : -1.0 23 // +Inf: +1.0 24 // -Inf: -1.0 25 // +NaN: +NaN 26 // -NaN: -NaN 27 // +0.0: +0.0 28 // -0.0: -0.0 29 func.func @sparse_sign(%arg0: tensor<?xf64, #SparseVector>) 30 -> tensor<?xf64, #SparseVector> { 31 %c0 = arith.constant 0 : index 32 %d = tensor.dim %arg0, %c0 : tensor<?xf64, #SparseVector> 33 %xin = bufferization.alloc_tensor(%d) : tensor<?xf64, #SparseVector> 34 %0 = linalg.generic #trait_op 35 ins(%arg0: tensor<?xf64, #SparseVector>) 36 outs(%xin: tensor<?xf64, #SparseVector>) { 37 ^bb0(%a: f64, %x: f64) : 38 %result = sparse_tensor.unary %a : f64 to f64 39 present={ 40 ^bb1(%s: f64): 41 %z = arith.constant 0.0 : f64 42 %1 = arith.cmpf one, %s, %z : f64 43 %2 = arith.uitofp %1 : i1 to f64 44 %3 = math.copysign %2, %s : f64 45 %4 = arith.cmpf uno, %s, %s : f64 46 %5 = arith.select %4, %s, %3 : f64 47 sparse_tensor.yield %5 : f64 48 } 49 absent={} 50 linalg.yield %result : f64 51 } -> tensor<?xf64, #SparseVector> 52 return %0 : tensor<?xf64, #SparseVector> 53 } 54 55 // Driver method to call and verify sign kernel. 56 func.func @entry() { 57 %c0 = arith.constant 0 : index 58 %du = arith.constant 99.99 : f64 59 60 %pnan = arith.constant 0x7FF0000001000000 : f64 61 %nnan = arith.constant 0xFFF0000001000000 : f64 62 %pinf = arith.constant 0x7FF0000000000000 : f64 63 %ninf = arith.constant 0xFFF0000000000000 : f64 64 65 // Setup sparse vector. 66 %v1 = arith.constant sparse< 67 [ [0], [3], [5], [11], [13], [17], [18], [20], [21], [28], [29], [31] ], 68 [ -1.5, 1.5, -10.2, 11.3, 1.0, -1.0, 69 0x7FF0000001000000, // +NaN 70 0xFFF0000001000000, // -NaN 71 0x7FF0000000000000, // +Inf 72 0xFFF0000000000000, // -Inf 73 -0.0, // -Zero 74 0.0 // +Zero 75 ] 76 > : tensor<32xf64> 77 %sv1 = sparse_tensor.convert %v1 78 : tensor<32xf64> to tensor<?xf64, #SparseVector> 79 80 // Call sign kernel. 81 %0 = call @sparse_sign(%sv1) : (tensor<?xf64, #SparseVector>) 82 -> tensor<?xf64, #SparseVector> 83 84 // 85 // Verify the results. 86 // 87 // CHECK: ( -1, 1, -1, 1, 1, -1, nan, -nan, 1, -1, -0, 0, 99.99 ) 88 // 89 %1 = sparse_tensor.values %0 : tensor<?xf64, #SparseVector> to memref<?xf64> 90 %2 = vector.transfer_read %1[%c0], %du: memref<?xf64>, vector<13xf64> 91 vector.print %2 : vector<13xf64> 92 93 // Release the resources. 94 bufferization.dealloc_tensor %sv1 : tensor<?xf64, #SparseVector> 95 bufferization.dealloc_tensor %0 : tensor<?xf64, #SparseVector> 96 return 97 } 98} 99 100 101