416 lines · plain
1// RUN: mlir-opt %s --sparse-reinterpret-map -sparsification | FileCheck %s2 3#CSR = #sparse_tensor.encoding<{4 map = (d0, d1) -> (d0 : dense, d1 : compressed),5}>6 7#DCSR = #sparse_tensor.encoding<{8 map = (d0, d1) -> (d0 : compressed, d1 : compressed)9}>10 11#SparseTensor = #sparse_tensor.encoding<{12 map = (d0, d1, d2) -> (d0 : compressed, d1 : compressed, d2 : compressed)13}>14 15#trait_scale_inpl = {16 indexing_maps = [17 affine_map<(i,j) -> (i,j)> // X (out)18 ],19 iterator_types = ["parallel", "parallel"],20 doc = "X(i,j) *= 2 or X(i,j) += X(i,j)"21}22 23// CHECK-LABEL: func.func @sparse_simply_dynamic1(24// CHECK-SAME: %[[VAL_0:.*]]: tensor<32x16xf32, #sparse{{[0-9]*}}>) -> tensor<32x16xf32, #sparse{{[0-9]*}}> {25// CHECK-DAG: %[[VAL_1:.*]] = arith.constant 0 : index26// CHECK-DAG: %[[VAL_2:.*]] = arith.constant 1 : index27// CHECK-DAG: %[[VAL_3:.*]] = arith.constant 2.000000e+00 : f3228// CHECK-DAG: %[[VAL_4:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 0 : index} : tensor<32x16xf32, #sparse{{[0-9]*}}> to memref<?xindex>29// CHECK-DAG: %[[VAL_5:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 1 : index} : tensor<32x16xf32, #sparse{{[0-9]*}}> to memref<?xindex>30// CHECK-DAG: %[[VAL_6:.*]] = sparse_tensor.values %[[VAL_0]] : tensor<32x16xf32, #sparse{{[0-9]*}}> to memref<?xf32>31// CHECK: %[[VAL_7:.*]] = memref.load %[[VAL_4]]{{\[}}%[[VAL_1]]] : memref<?xindex>32// CHECK: %[[VAL_8:.*]] = memref.load %[[VAL_4]]{{\[}}%[[VAL_2]]] : memref<?xindex>33// CHECK: scf.for %[[VAL_9:.*]] = %[[VAL_7]] to %[[VAL_8]] step %[[VAL_2]] {34// CHECK: %[[VAL_10:.*]] = memref.load %[[VAL_5]]{{\[}}%[[VAL_9]]] : memref<?xindex>35// CHECK: %[[VAL_11:.*]] = arith.addi %[[VAL_9]], %[[VAL_2]] : index36// CHECK: %[[VAL_12:.*]] = memref.load %[[VAL_5]]{{\[}}%[[VAL_11]]] : memref<?xindex>37// CHECK: scf.for %[[VAL_13:.*]] = %[[VAL_10]] to %[[VAL_12]] step %[[VAL_2]] {38// CHECK: %[[VAL_14:.*]] = memref.load %[[VAL_6]]{{\[}}%[[VAL_13]]] : memref<?xf32>39// CHECK: %[[VAL_15:.*]] = arith.mulf %[[VAL_14]], %[[VAL_3]] : f3240// CHECK: memref.store %[[VAL_15]], %[[VAL_6]]{{\[}}%[[VAL_13]]] : memref<?xf32>41// CHECK: }42// CHECK: }43// CHECK: %[[VAL_16:.*]] = sparse_tensor.load %[[VAL_0]] : tensor<32x16xf32, #sparse{{[0-9]*}}>44// CHECK: return %[[VAL_16]] : tensor<32x16xf32, #sparse{{[0-9]*}}>45// CHECK: }46func.func @sparse_simply_dynamic1(%argx: tensor<32x16xf32, #DCSR>) -> tensor<32x16xf32, #DCSR> {47 %c = arith.constant 2.0 : f3248 %0 = linalg.generic #trait_scale_inpl49 outs(%argx: tensor<32x16xf32, #DCSR>) {50 ^bb(%x: f32):51 %1 = arith.mulf %x, %c : f3252 linalg.yield %1 : f3253 } -> tensor<32x16xf32, #DCSR>54 return %0 : tensor<32x16xf32, #DCSR>55}56 57// CHECK-LABEL: func.func @sparse_simply_dynamic2(58// CHECK-SAME: %[[VAL_0:.*]]: tensor<32x16xf32, #sparse{{[0-9]*}}>) -> tensor<32x16xf32, #sparse{{[0-9]*}}> {59// CHECK-DAG: %[[VAL_1:.*]] = arith.constant 0 : index60// CHECK-DAG: %[[VAL_2:.*]] = arith.constant 1 : index61// CHECK-DAG: %[[VAL_3:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 0 : index} : tensor<32x16xf32, #sparse{{[0-9]*}}> to memref<?xindex>62// CHECK-DAG: %[[VAL_4:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 1 : index} : tensor<32x16xf32, #sparse{{[0-9]*}}> to memref<?xindex>63// CHECK-DAG: %[[VAL_5:.*]] = sparse_tensor.values %[[VAL_0]] : tensor<32x16xf32, #sparse{{[0-9]*}}> to memref<?xf32>64// CHECK: %[[VAL_6:.*]] = memref.load %[[VAL_3]]{{\[}}%[[VAL_1]]] : memref<?xindex>65// CHECK: %[[VAL_7:.*]] = memref.load %[[VAL_3]]{{\[}}%[[VAL_2]]] : memref<?xindex>66// CHECK: scf.for %[[VAL_8:.*]] = %[[VAL_6]] to %[[VAL_7]] step %[[VAL_2]] {67// CHECK: %[[VAL_9:.*]] = memref.load %[[VAL_4]]{{\[}}%[[VAL_8]]] : memref<?xindex>68// CHECK: %[[VAL_10:.*]] = arith.addi %[[VAL_8]], %[[VAL_2]] : index69// CHECK: %[[VAL_11:.*]] = memref.load %[[VAL_4]]{{\[}}%[[VAL_10]]] : memref<?xindex>70// CHECK: scf.for %[[VAL_12:.*]] = %[[VAL_9]] to %[[VAL_11]] step %[[VAL_2]] {71// CHECK: %[[VAL_13:.*]] = memref.load %[[VAL_5]]{{\[}}%[[VAL_12]]] : memref<?xf32>72// CHECK: %[[VAL_14:.*]] = memref.load %[[VAL_5]]{{\[}}%[[VAL_12]]] : memref<?xf32>73// CHECK: %[[VAL_15:.*]] = arith.addf %[[VAL_13]], %[[VAL_14]] : f3274// CHECK: memref.store %[[VAL_15]], %[[VAL_5]]{{\[}}%[[VAL_12]]] : memref<?xf32>75// CHECK: }76// CHECK: }77// CHECK: %[[VAL_16:.*]] = sparse_tensor.load %[[VAL_0]] : tensor<32x16xf32, #sparse{{[0-9]*}}>78// CHECK: return %[[VAL_16]] : tensor<32x16xf32, #sparse{{[0-9]*}}>79// CHECK: }80func.func @sparse_simply_dynamic2(%argx: tensor<32x16xf32, #DCSR>) -> tensor<32x16xf32, #DCSR> {81 %0 = linalg.generic #trait_scale_inpl82 outs(%argx: tensor<32x16xf32, #DCSR>) {83 ^bb(%x: f32):84 %1 = arith.addf %x, %x : f3285 linalg.yield %1 : f3286 } -> tensor<32x16xf32, #DCSR>87 return %0 : tensor<32x16xf32, #DCSR>88}89 90#trait_scale = {91 indexing_maps = [92 affine_map<(i,j) -> (i,j)>, // A93 affine_map<(i,j) -> (i,j)> // X (out)94 ],95 iterator_types = ["parallel", "parallel"],96 doc = "X(i,j) = A(i,j) * 2.0"97}98 99// CHECK-LABEL: func.func @sparse_truly_dynamic(100// CHECK-SAME: %[[VAL_0:.*]]: tensor<10x20xf32, #sparse{{[0-9]*}}>) -> tensor<10x20xf32, #sparse{{[0-9]*}}> {101// CHECK-DAG: %[[VAL_1:.*]] = arith.constant 10 : index102// CHECK-DAG: %[[VAL_2:.*]] = arith.constant 0 : index103// CHECK-DAG: %[[VAL_3:.*]] = arith.constant 1 : index104// CHECK-DAG: %[[VAL_4:.*]] = arith.constant 2.000000e+00 : f32105// CHECK-DAG: %[[VAL_5:.*]] = tensor.empty() : tensor<10x20xf32, #sparse{{[0-9]*}}>106// CHECK-DAG: %[[VAL_6:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 1 : index} : tensor<10x20xf32, #sparse{{[0-9]*}}> to memref<?xindex>107// CHECK-DAG: %[[VAL_7:.*]] = sparse_tensor.coordinates %[[VAL_0]] {level = 1 : index} : tensor<10x20xf32, #sparse{{[0-9]*}}> to memref<?xindex>108// CHECK-DAG: %[[VAL_8:.*]] = sparse_tensor.values %[[VAL_0]] : tensor<10x20xf32, #sparse{{[0-9]*}}> to memref<?xf32>109// CHECK: %[[VAL_9:.*]] = scf.for %[[VAL_10:.*]] = %[[VAL_2]] to %[[VAL_1]] step %[[VAL_3]] iter_args(%[[VAL_11:.*]] = %[[VAL_5]]) -> (tensor<10x20xf32, #sparse{{[0-9]*}}>) {110// CHECK: %[[VAL_12:.*]] = memref.load %[[VAL_6]]{{\[}}%[[VAL_10]]] : memref<?xindex>111// CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_10]], %[[VAL_3]] : index112// CHECK: %[[VAL_14:.*]] = memref.load %[[VAL_6]]{{\[}}%[[VAL_13]]] : memref<?xindex>113// CHECK: %[[VAL_15:.*]] = scf.for %[[VAL_16:.*]] = %[[VAL_12]] to %[[VAL_14]] step %[[VAL_3]] iter_args(%[[VAL_17:.*]] = %[[VAL_11]]) -> (tensor<10x20xf32, #sparse{{[0-9]*}}>) {114// CHECK: %[[VAL_18:.*]] = memref.load %[[VAL_7]]{{\[}}%[[VAL_16]]] : memref<?xindex>115// CHECK: %[[VAL_19:.*]] = memref.load %[[VAL_8]]{{\[}}%[[VAL_16]]] : memref<?xf32>116// CHECK: %[[VAL_20:.*]] = arith.mulf %[[VAL_19]], %[[VAL_4]] : f32117// CHECK: %[[VAL_21:.*]] = tensor.insert %[[VAL_20]] into %[[VAL_17]]{{\[}}%[[VAL_10]], %[[VAL_18]]] : tensor<10x20xf32, #sparse{{[0-9]*}}>118// CHECK: scf.yield %[[VAL_21]] : tensor<10x20xf32, #sparse{{[0-9]*}}>119// CHECK: }120// CHECK: scf.yield %[[VAL_22:.*]] : tensor<10x20xf32, #sparse{{[0-9]*}}>121// CHECK: }122// CHECK: %[[VAL_23:.*]] = sparse_tensor.load %[[VAL_24:.*]] hasInserts : tensor<10x20xf32, #sparse{{[0-9]*}}>123// CHECK: return %[[VAL_23]] : tensor<10x20xf32, #sparse{{[0-9]*}}>124// CHECK: }125func.func @sparse_truly_dynamic(%arga: tensor<10x20xf32, #CSR>) -> tensor<10x20xf32, #DCSR> {126 %s = arith.constant 2.0 : f32127 %xm = tensor.empty() : tensor<10x20xf32, #DCSR>128 %0 = linalg.generic #trait_scale129 ins(%arga: tensor<10x20xf32, #CSR>)130 outs(%xm: tensor<10x20xf32, #DCSR>) {131 ^bb(%a: f32, %x: f32):132 %1 = arith.mulf %a, %s : f32133 linalg.yield %1 : f32134 } -> tensor<10x20xf32, #DCSR>135 return %0 : tensor<10x20xf32, #DCSR>136}137 138#trait_sumred = {139 indexing_maps = [140 affine_map<(i,j,k) -> (i,j,k)>, // A141 affine_map<(i,j,k) -> (i,j,k)>, // B142 affine_map<(i,j,k) -> (i,j)> // X (out)143 ],144 iterator_types = ["parallel", "parallel", "reduction"],145 doc = "X(i,j) = SUM_k A(i,j,k) * B(i,j,k)"146}147 148// CHECK-LABEL: func.func @sumred(149// CHECK-SAME: %[[VAL_0:.*]]: tensor<?x?x?xi32, #sparse{{[0-9]*}}>,150// CHECK-SAME: %[[VAL_1:.*]]: tensor<?x?x?xi32, #sparse{{[0-9]*}}>) -> tensor<?x?xi32, #sparse{{[0-9]*}}> {151// CHECK-DAG: %[[VAL_2:.*]] = arith.constant 0 : index152// CHECK-DAG: %[[VAL_3:.*]] = arith.constant 1 : index153// CHECK-DAG: %[[VAL_4:.*]] = arith.constant 0 : i32154// CHECK-DAG: %[[VAL_FALSE:.*]] = arith.constant false155// CHECK-DAG: %[[VAL_TRUE:.*]] = arith.constant true156// CHECK-DAG: %[[VAL_5:.*]] = tensor.dim %[[VAL_0]], %[[VAL_2]] : tensor<?x?x?xi32, #sparse{{[0-9]*}}>157// CHECK-DAG: %[[VAL_6:.*]] = tensor.dim %[[VAL_0]], %[[VAL_3]] : tensor<?x?x?xi32, #sparse{{[0-9]*}}>158// CHECK-DAG: %[[VAL_7:.*]] = tensor.empty(%[[VAL_5]], %[[VAL_6]]) : tensor<?x?xi32, #sparse{{[0-9]*}}>159// CHECK-DAG: %[[VAL_8:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 0 : index} : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xindex>160// CHECK-DAG: %[[VAL_9:.*]] = sparse_tensor.coordinates %[[VAL_0]] {level = 0 : index} : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xindex>161// CHECK-DAG: %[[VAL_10:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 1 : index} : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xindex>162// CHECK-DAG: %[[VAL_11:.*]] = sparse_tensor.coordinates %[[VAL_0]] {level = 1 : index} : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xindex>163// CHECK-DAG: %[[VAL_12:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 2 : index} : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xindex>164// CHECK-DAG: %[[VAL_13:.*]] = sparse_tensor.coordinates %[[VAL_0]] {level = 2 : index} : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xindex>165// CHECK-DAG: %[[VAL_14:.*]] = sparse_tensor.values %[[VAL_0]] : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xi32>166// CHECK-DAG: %[[VAL_15:.*]] = sparse_tensor.positions %[[VAL_1]] {level = 0 : index} : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xindex>167// CHECK-DAG: %[[VAL_16:.*]] = sparse_tensor.coordinates %[[VAL_1]] {level = 0 : index} : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xindex>168// CHECK-DAG: %[[VAL_17:.*]] = sparse_tensor.positions %[[VAL_1]] {level = 1 : index} : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xindex>169// CHECK-DAG: %[[VAL_18:.*]] = sparse_tensor.coordinates %[[VAL_1]] {level = 1 : index} : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xindex>170// CHECK-DAG: %[[VAL_19:.*]] = sparse_tensor.positions %[[VAL_1]] {level = 2 : index} : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xindex>171// CHECK-DAG: %[[VAL_20:.*]] = sparse_tensor.coordinates %[[VAL_1]] {level = 2 : index} : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xindex>172// CHECK-DAG: %[[VAL_21:.*]] = sparse_tensor.values %[[VAL_1]] : tensor<?x?x?xi32, #sparse{{[0-9]*}}> to memref<?xi32>173// CHECK: %[[VAL_22:.*]] = memref.load %[[VAL_8]]{{\[}}%[[VAL_2]]] : memref<?xindex>174// CHECK: %[[VAL_23:.*]] = memref.load %[[VAL_8]]{{\[}}%[[VAL_3]]] : memref<?xindex>175// CHECK: %[[VAL_24:.*]] = memref.load %[[VAL_15]]{{\[}}%[[VAL_2]]] : memref<?xindex>176// CHECK: %[[VAL_25:.*]] = memref.load %[[VAL_15]]{{\[}}%[[VAL_3]]] : memref<?xindex>177// CHECK: %[[VAL_26:.*]]:3 = scf.while (%[[VAL_27:.*]] = %[[VAL_22]], %[[VAL_28:.*]] = %[[VAL_24]], %[[VAL_29:.*]] = %[[VAL_7]]) : (index, index, tensor<?x?xi32, #sparse{{[0-9]*}}>) -> (index, index, tensor<?x?xi32, #sparse{{[0-9]*}}>) {178// CHECK: %[[VAL_30:.*]] = arith.cmpi ult, %[[VAL_27]], %[[VAL_23]] : index179// CHECK: %[[VAL_31:.*]] = arith.cmpi ult, %[[VAL_28]], %[[VAL_25]] : index180// CHECK: %[[VAL_32:.*]] = arith.andi %[[VAL_30]], %[[VAL_31]] : i1181// CHECK: scf.condition(%[[VAL_32]]) %[[VAL_27]], %[[VAL_28]], %[[VAL_29]] : index, index, tensor<?x?xi32, #sparse{{[0-9]*}}>182// CHECK: } do {183// CHECK: ^bb0(%[[VAL_33:.*]]: index, %[[VAL_34:.*]]: index, %[[VAL_35:.*]]: tensor<?x?xi32, #sparse{{[0-9]*}}>):184// CHECK: %[[VAL_36:.*]] = memref.load %[[VAL_9]]{{\[}}%[[VAL_33]]] : memref<?xindex>185// CHECK: %[[VAL_37:.*]] = memref.load %[[VAL_16]]{{\[}}%[[VAL_34]]] : memref<?xindex>186// CHECK: %[[VAL_38:.*]] = arith.cmpi ult, %[[VAL_37]], %[[VAL_36]] : index187// CHECK: %[[VAL_39:.*]] = arith.select %[[VAL_38]], %[[VAL_37]], %[[VAL_36]] : index188// CHECK: %[[VAL_40:.*]] = arith.cmpi eq, %[[VAL_36]], %[[VAL_39]] : index189// CHECK: %[[VAL_41:.*]] = arith.cmpi eq, %[[VAL_37]], %[[VAL_39]] : index190// CHECK: %[[VAL_42:.*]] = arith.andi %[[VAL_40]], %[[VAL_41]] : i1191// CHECK: %[[VAL_43:.*]] = scf.if %[[VAL_42]] -> (tensor<?x?xi32, #sparse{{[0-9]*}}>) {192// CHECK: %[[VAL_44:.*]] = memref.load %[[VAL_10]]{{\[}}%[[VAL_33]]] : memref<?xindex>193// CHECK: %[[VAL_45:.*]] = arith.addi %[[VAL_33]], %[[VAL_3]] : index194// CHECK: %[[VAL_46:.*]] = memref.load %[[VAL_10]]{{\[}}%[[VAL_45]]] : memref<?xindex>195// CHECK: %[[VAL_47:.*]] = memref.load %[[VAL_17]]{{\[}}%[[VAL_34]]] : memref<?xindex>196// CHECK: %[[VAL_48:.*]] = arith.addi %[[VAL_34]], %[[VAL_3]] : index197// CHECK: %[[VAL_49:.*]] = memref.load %[[VAL_17]]{{\[}}%[[VAL_48]]] : memref<?xindex>198// CHECK: %[[VAL_50:.*]]:3 = scf.while (%[[VAL_51:.*]] = %[[VAL_44]], %[[VAL_52:.*]] = %[[VAL_47]], %[[VAL_53:.*]] = %[[VAL_35]]) : (index, index, tensor<?x?xi32, #sparse{{[0-9]*}}>) -> (index, index, tensor<?x?xi32, #sparse{{[0-9]*}}>) {199// CHECK: %[[VAL_54:.*]] = arith.cmpi ult, %[[VAL_51]], %[[VAL_46]] : index200// CHECK: %[[VAL_55:.*]] = arith.cmpi ult, %[[VAL_52]], %[[VAL_49]] : index201// CHECK: %[[VAL_56:.*]] = arith.andi %[[VAL_54]], %[[VAL_55]] : i1202// CHECK: scf.condition(%[[VAL_56]]) %[[VAL_51]], %[[VAL_52]], %[[VAL_53]] : index, index, tensor<?x?xi32, #sparse{{[0-9]*}}>203// CHECK: } do {204// CHECK: ^bb0(%[[VAL_57:.*]]: index, %[[VAL_58:.*]]: index, %[[VAL_59:.*]]: tensor<?x?xi32, #sparse{{[0-9]*}}>):205// CHECK: %[[VAL_60:.*]] = memref.load %[[VAL_11]]{{\[}}%[[VAL_57]]] : memref<?xindex>206// CHECK: %[[VAL_61:.*]] = memref.load %[[VAL_18]]{{\[}}%[[VAL_58]]] : memref<?xindex>207// CHECK: %[[VAL_62:.*]] = arith.cmpi ult, %[[VAL_61]], %[[VAL_60]] : index208// CHECK: %[[VAL_63:.*]] = arith.select %[[VAL_62]], %[[VAL_61]], %[[VAL_60]] : index209// CHECK: %[[VAL_64:.*]] = arith.cmpi eq, %[[VAL_60]], %[[VAL_63]] : index210// CHECK: %[[VAL_65:.*]] = arith.cmpi eq, %[[VAL_61]], %[[VAL_63]] : index211// CHECK: %[[VAL_66:.*]] = arith.andi %[[VAL_64]], %[[VAL_65]] : i1212// CHECK: %[[VAL_67:.*]] = scf.if %[[VAL_66]] -> (tensor<?x?xi32, #sparse{{[0-9]*}}>) {213// CHECK: %[[VAL_68:.*]] = memref.load %[[VAL_12]]{{\[}}%[[VAL_57]]] : memref<?xindex>214// CHECK: %[[VAL_69:.*]] = arith.addi %[[VAL_57]], %[[VAL_3]] : index215// CHECK: %[[VAL_70:.*]] = memref.load %[[VAL_12]]{{\[}}%[[VAL_69]]] : memref<?xindex>216// CHECK: %[[VAL_71:.*]] = memref.load %[[VAL_19]]{{\[}}%[[VAL_58]]] : memref<?xindex>217// CHECK: %[[VAL_72:.*]] = arith.addi %[[VAL_58]], %[[VAL_3]] : index218// CHECK: %[[VAL_73:.*]] = memref.load %[[VAL_19]]{{\[}}%[[VAL_72]]] : memref<?xindex>219// CHECK: %[[VAL_74:.*]]:5 = scf.while (%[[VAL_75:.*]] = %[[VAL_68]], %[[VAL_76:.*]] = %[[VAL_71]], %[[VAL_77:.*]] = %[[VAL_4]], %[[VAL_200:.*]] = %[[VAL_FALSE]], %[[VAL_78:.*]] = %[[VAL_59]]) : (index, index, i32, i1, tensor<?x?xi32, #sparse{{[0-9]*}}>) -> (index, index, i32, i1, tensor<?x?xi32, #sparse{{[0-9]*}}>) {220// CHECK: %[[VAL_79:.*]] = arith.cmpi ult, %[[VAL_75]], %[[VAL_70]] : index221// CHECK: %[[VAL_80:.*]] = arith.cmpi ult, %[[VAL_76]], %[[VAL_73]] : index222// CHECK: %[[VAL_81:.*]] = arith.andi %[[VAL_79]], %[[VAL_80]] : i1223// CHECK: scf.condition(%[[VAL_81]]) %[[VAL_75]], %[[VAL_76]], %[[VAL_77]], %[[VAL_200]], %[[VAL_78]] : index, index, i32, i1, tensor<?x?xi32, #sparse{{[0-9]*}}>224// CHECK: } do {225// CHECK: ^bb0(%[[VAL_82:.*]]: index, %[[VAL_83:.*]]: index, %[[VAL_84:.*]]: i32, %[[VAL_201:.*]]: i1, %[[VAL_85:.*]]: tensor<?x?xi32, #sparse{{[0-9]*}}>):226// CHECK: %[[VAL_86:.*]] = memref.load %[[VAL_13]]{{\[}}%[[VAL_82]]] : memref<?xindex>227// CHECK: %[[VAL_87:.*]] = memref.load %[[VAL_20]]{{\[}}%[[VAL_83]]] : memref<?xindex>228// CHECK: %[[VAL_88:.*]] = arith.cmpi ult, %[[VAL_87]], %[[VAL_86]] : index229// CHECK: %[[VAL_89:.*]] = arith.select %[[VAL_88]], %[[VAL_87]], %[[VAL_86]] : index230// CHECK: %[[VAL_90:.*]] = arith.cmpi eq, %[[VAL_86]], %[[VAL_89]] : index231// CHECK: %[[VAL_91:.*]] = arith.cmpi eq, %[[VAL_87]], %[[VAL_89]] : index232// CHECK: %[[VAL_92:.*]] = arith.andi %[[VAL_90]], %[[VAL_91]] : i1233// CHECK: %[[VAL_93:.*]]:3 = scf.if %[[VAL_92]] -> (i32, i1, tensor<?x?xi32, #sparse{{[0-9]*}}>) {234// CHECK: %[[VAL_94:.*]] = memref.load %[[VAL_14]]{{\[}}%[[VAL_82]]] : memref<?xi32>235// CHECK: %[[VAL_95:.*]] = memref.load %[[VAL_21]]{{\[}}%[[VAL_83]]] : memref<?xi32>236// CHECK: %[[VAL_96:.*]] = arith.muli %[[VAL_94]], %[[VAL_95]] : i32237// CHECK: %[[VAL_97:.*]] = arith.addi %[[VAL_84]], %[[VAL_96]] : i32238// CHECK: scf.yield %[[VAL_97]], %[[VAL_TRUE]], %[[VAL_85]] : i32, i1, tensor<?x?xi32, #sparse{{[0-9]*}}>239// CHECK: } else {240// CHECK: scf.yield %[[VAL_84]], %[[VAL_201]], %[[VAL_85]] : i32, i1, tensor<?x?xi32, #sparse{{[0-9]*}}>241// CHECK: }242// CHECK: %[[VAL_98:.*]] = arith.cmpi eq, %[[VAL_86]], %[[VAL_89]] : index243// CHECK: %[[VAL_99:.*]] = arith.addi %[[VAL_82]], %[[VAL_3]] : index244// CHECK: %[[VAL_100:.*]] = arith.select %[[VAL_98]], %[[VAL_99]], %[[VAL_82]] : index245// CHECK: %[[VAL_101:.*]] = arith.cmpi eq, %[[VAL_87]], %[[VAL_89]] : index246// CHECK: %[[VAL_102:.*]] = arith.addi %[[VAL_83]], %[[VAL_3]] : index247// CHECK: %[[VAL_103:.*]] = arith.select %[[VAL_101]], %[[VAL_102]], %[[VAL_83]] : index248// CHECK: scf.yield %[[VAL_100]], %[[VAL_103]], %[[VAL_104:.*]]#0, %[[VAL_104]]#1, %[[VAL_104]]#2 : index, index, i32, i1, tensor<?x?xi32, #sparse{{[0-9]*}}>249// CHECK: }250// CHECK: %[[VAL_202:.*]] = scf.if %[[VAL_74]]#3 -> (tensor<?x?xi32, #sparse{{[0-9]*}}>) {251// CHECK: %[[VAL_105:.*]] = tensor.insert %[[VAL_74]]#2 into %[[VAL_74]]#4{{\[}}%[[VAL_39]], %[[VAL_63]]] : tensor<?x?xi32, #sparse{{[0-9]*}}>252// CHECK: scf.yield %[[VAL_105]] : tensor<?x?xi32, #sparse{{[0-9]*}}>253// CHECK: } else {254// CHECK: scf.yield %[[VAL_74]]#4 : tensor<?x?xi32, #sparse{{[0-9]*}}>255// CHECK: }256// CHECK: scf.yield %[[VAL_202]] : tensor<?x?xi32, #sparse{{[0-9]*}}>257// CHECK: } else {258// CHECK: scf.yield %[[VAL_59]] : tensor<?x?xi32, #sparse{{[0-9]*}}>259// CHECK: }260// CHECK: %[[VAL_107:.*]] = arith.cmpi eq, %[[VAL_60]], %[[VAL_63]] : index261// CHECK: %[[VAL_108:.*]] = arith.addi %[[VAL_57]], %[[VAL_3]] : index262// CHECK: %[[VAL_109:.*]] = arith.select %[[VAL_107]], %[[VAL_108]], %[[VAL_57]] : index263// CHECK: %[[VAL_110:.*]] = arith.cmpi eq, %[[VAL_61]], %[[VAL_63]] : index264// CHECK: %[[VAL_111:.*]] = arith.addi %[[VAL_58]], %[[VAL_3]] : index265// CHECK: %[[VAL_112:.*]] = arith.select %[[VAL_110]], %[[VAL_111]], %[[VAL_58]] : index266// CHECK: scf.yield %[[VAL_109]], %[[VAL_112]], %[[VAL_113:.*]] : index, index, tensor<?x?xi32, #sparse{{[0-9]*}}>267// CHECK: }268// CHECK: scf.yield %[[VAL_114:.*]]#2 : tensor<?x?xi32, #sparse{{[0-9]*}}>269// CHECK: } else {270// CHECK: scf.yield %[[VAL_35]] : tensor<?x?xi32, #sparse{{[0-9]*}}>271// CHECK: }272// CHECK: %[[VAL_115:.*]] = arith.cmpi eq, %[[VAL_36]], %[[VAL_39]] : index273// CHECK: %[[VAL_116:.*]] = arith.addi %[[VAL_33]], %[[VAL_3]] : index274// CHECK: %[[VAL_117:.*]] = arith.select %[[VAL_115]], %[[VAL_116]], %[[VAL_33]] : index275// CHECK: %[[VAL_118:.*]] = arith.cmpi eq, %[[VAL_37]], %[[VAL_39]] : index276// CHECK: %[[VAL_119:.*]] = arith.addi %[[VAL_34]], %[[VAL_3]] : index277// CHECK: %[[VAL_120:.*]] = arith.select %[[VAL_118]], %[[VAL_119]], %[[VAL_34]] : index278// CHECK: scf.yield %[[VAL_117]], %[[VAL_120]], %[[VAL_121:.*]] : index, index, tensor<?x?xi32, #sparse{{[0-9]*}}>279// CHECK: }280// CHECK: %[[VAL_122:.*]] = sparse_tensor.load %[[VAL_123:.*]]#2 hasInserts : tensor<?x?xi32, #sparse{{[0-9]*}}>281// CHECK: return %[[VAL_122]] : tensor<?x?xi32, #sparse{{[0-9]*}}>282// CHECK: }283func.func @sumred(%arga: tensor<?x?x?xi32, #SparseTensor>,284 %argb: tensor<?x?x?xi32, #SparseTensor>) -> tensor<?x?xi32, #DCSR> {285 %c0 = arith.constant 0 : index286 %c1 = arith.constant 1 : index287 %d0 = tensor.dim %arga, %c0 : tensor<?x?x?xi32, #SparseTensor>288 %d1 = tensor.dim %arga, %c1 : tensor<?x?x?xi32, #SparseTensor>289 %xinit = tensor.empty(%d0, %d1) : tensor<?x?xi32, #DCSR>290 %0 = linalg.generic #trait_sumred291 ins(%arga, %argb: tensor<?x?x?xi32, #SparseTensor>,292 tensor<?x?x?xi32, #SparseTensor>)293 outs(%xinit: tensor<?x?xi32, #DCSR>) {294 ^bb(%a: i32, %b: i32, %x: i32):295 %0 = arith.muli %a, %b : i32296 %1 = arith.addi %x, %0 : i32297 linalg.yield %1 : i32298 } -> tensor<?x?xi32, #DCSR>299 return %0 : tensor<?x?xi32, #DCSR>300}301 302#trait_matmat = {303 indexing_maps = [304 affine_map<(i,j,k) -> (i,k)>, // A305 affine_map<(i,j,k) -> (k,j)>, // B306 affine_map<(i,j,k) -> (i,j)> // C (out)307 ],308 iterator_types = ["parallel", "parallel", "reduction"],309 doc = "C(i,j) = SUM_k A(i,k) * B(k,j)"310}311 312// CHECK-LABEL: func.func @matmat(313// CHECK-SAME: %[[VAL_0:.*]]: tensor<?x?xf32, #sparse{{[0-9]*}}>,314// CHECK-SAME: %[[VAL_1:.*]]: tensor<?x?xf32, #sparse{{[0-9]*}}>) -> tensor<?x?xf32, #sparse{{[0-9]*}}> {315// CHECK-DAG: %[[VAL_2:.*]] = arith.constant 0 : index316// CHECK-DAG: %[[VAL_3:.*]] = arith.constant 1 : index317// CHECK-DAG: %[[VAL_4:.*]] = arith.constant false318// CHECK-DAG: %[[VAL_5:.*]] = arith.constant true319// CHECK-DAG: %[[VAL_6:.*]] = tensor.dim %[[VAL_0]], %[[VAL_2]] : tensor<?x?xf32, #sparse{{[0-9]*}}>320// CHECK-DAG: %[[VAL_7:.*]] = tensor.dim %[[VAL_1]], %[[VAL_3]] : tensor<?x?xf32, #sparse{{[0-9]*}}>321// CHECK-DAG: %[[VAL_8:.*]] = tensor.empty(%[[VAL_6]], %[[VAL_7]]) : tensor<?x?xf32, #sparse{{[0-9]*}}>322// CHECK-DAG: %[[VAL_9:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 0 : index} : tensor<?x?xf32, #sparse{{[0-9]*}}> to memref<?xindex>323// CHECK-DAG: %[[VAL_10:.*]] = sparse_tensor.coordinates %[[VAL_0]] {level = 0 : index} : tensor<?x?xf32, #sparse{{[0-9]*}}> to memref<?xindex>324// CHECK-DAG: %[[VAL_11:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 1 : index} : tensor<?x?xf32, #sparse{{[0-9]*}}> to memref<?xindex>325// CHECK-DAG: %[[VAL_12:.*]] = sparse_tensor.coordinates %[[VAL_0]] {level = 1 : index} : tensor<?x?xf32, #sparse{{[0-9]*}}> to memref<?xindex>326// CHECK-DAG: %[[VAL_13:.*]] = sparse_tensor.values %[[VAL_0]] : tensor<?x?xf32, #sparse{{[0-9]*}}> to memref<?xf32>327// CHECK-DAG: %[[VAL_14:.*]] = sparse_tensor.positions %[[VAL_1]] {level = 0 : index} : tensor<?x?xf32, #sparse{{[0-9]*}}> to memref<?xindex>328// CHECK-DAG: %[[VAL_15:.*]] = sparse_tensor.coordinates %[[VAL_1]] {level = 0 : index} : tensor<?x?xf32, #sparse{{[0-9]*}}> to memref<?xindex>329// CHECK-DAG: %[[VAL_16:.*]] = sparse_tensor.positions %[[VAL_1]] {level = 1 : index} : tensor<?x?xf32, #sparse{{[0-9]*}}> to memref<?xindex>330// CHECK-DAG: %[[VAL_17:.*]] = sparse_tensor.coordinates %[[VAL_1]] {level = 1 : index} : tensor<?x?xf32, #sparse{{[0-9]*}}> to memref<?xindex>331// CHECK-DAG: %[[VAL_18:.*]] = sparse_tensor.values %[[VAL_1]] : tensor<?x?xf32, #sparse{{[0-9]*}}> to memref<?xf32>332// CHECK: %[[VAL_19:.*]] = memref.load %[[VAL_9]]{{\[}}%[[VAL_2]]] : memref<?xindex>333// CHECK: %[[VAL_20:.*]] = memref.load %[[VAL_9]]{{\[}}%[[VAL_3]]] : memref<?xindex>334// CHECK: %[[VAL_21:.*]] = scf.for %[[VAL_22:.*]] = %[[VAL_19]] to %[[VAL_20]] step %[[VAL_3]] iter_args(%[[VAL_23:.*]] = %[[VAL_8]]) -> (tensor<?x?xf32, #sparse{{[0-9]*}}>) {335// CHECK: %[[VAL_24:.*]] = memref.load %[[VAL_10]]{{\[}}%[[VAL_22]]] : memref<?xindex>336// CHECK: %[[VAL_25:.*]], %[[VAL_26:.*]], %[[VAL_27:.*]], %[[VAL_28:.*]] = sparse_tensor.expand %[[VAL_8]] : tensor<?x?xf32, #sparse{{[0-9]*}}> to memref<?xf32>, memref<?xi1>, memref<?xindex>337// CHECK: %[[VAL_29:.*]] = memref.load %[[VAL_11]]{{\[}}%[[VAL_22]]] : memref<?xindex>338// CHECK: %[[VAL_30:.*]] = arith.addi %[[VAL_22]], %[[VAL_3]] : index339// CHECK: %[[VAL_31:.*]] = memref.load %[[VAL_11]]{{\[}}%[[VAL_30]]] : memref<?xindex>340// CHECK: %[[VAL_32:.*]] = memref.load %[[VAL_14]]{{\[}}%[[VAL_2]]] : memref<?xindex>341// CHECK: %[[VAL_33:.*]] = memref.load %[[VAL_14]]{{\[}}%[[VAL_3]]] : memref<?xindex>342// CHECK: %[[VAL_34:.*]]:4 = scf.while (%[[VAL_35:.*]] = %[[VAL_29]], %[[VAL_36:.*]] = %[[VAL_32]], %[[VAL_37:.*]] = %[[VAL_28]], %[[VAL_38:.*]] = %[[VAL_23]]) : (index, index, index, tensor<?x?xf32, #sparse{{[0-9]*}}>) -> (index, index, index, tensor<?x?xf32, #sparse{{[0-9]*}}>) {343// CHECK: %[[VAL_39:.*]] = arith.cmpi ult, %[[VAL_35]], %[[VAL_31]] : index344// CHECK: %[[VAL_40:.*]] = arith.cmpi ult, %[[VAL_36]], %[[VAL_33]] : index345// CHECK: %[[VAL_41:.*]] = arith.andi %[[VAL_39]], %[[VAL_40]] : i1346// CHECK: scf.condition(%[[VAL_41]]) %[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_38]] : index, index, index, tensor<?x?xf32, #sparse{{[0-9]*}}>347// CHECK: } do {348// CHECK: ^bb0(%[[VAL_42:.*]]: index, %[[VAL_43:.*]]: index, %[[VAL_44:.*]]: index, %[[VAL_45:.*]]: tensor<?x?xf32, #sparse{{[0-9]*}}>):349// CHECK: %[[VAL_46:.*]] = memref.load %[[VAL_12]]{{\[}}%[[VAL_42]]] : memref<?xindex>350// CHECK: %[[VAL_47:.*]] = memref.load %[[VAL_15]]{{\[}}%[[VAL_43]]] : memref<?xindex>351// CHECK: %[[VAL_48:.*]] = arith.cmpi ult, %[[VAL_47]], %[[VAL_46]] : index352// CHECK: %[[VAL_49:.*]] = arith.select %[[VAL_48]], %[[VAL_47]], %[[VAL_46]] : index353// CHECK: %[[VAL_50:.*]] = arith.cmpi eq, %[[VAL_46]], %[[VAL_49]] : index354// CHECK: %[[VAL_51:.*]] = arith.cmpi eq, %[[VAL_47]], %[[VAL_49]] : index355// CHECK: %[[VAL_52:.*]] = arith.andi %[[VAL_50]], %[[VAL_51]] : i1356// CHECK: %[[VAL_53:.*]]:2 = scf.if %[[VAL_52]] -> (index, tensor<?x?xf32, #sparse{{[0-9]*}}>) {357// CHECK: %[[VAL_54:.*]] = memref.load %[[VAL_13]]{{\[}}%[[VAL_42]]] : memref<?xf32>358// CHECK: %[[VAL_55:.*]] = memref.load %[[VAL_16]]{{\[}}%[[VAL_43]]] : memref<?xindex>359// CHECK: %[[VAL_56:.*]] = arith.addi %[[VAL_43]], %[[VAL_3]] : index360// CHECK: %[[VAL_57:.*]] = memref.load %[[VAL_16]]{{\[}}%[[VAL_56]]] : memref<?xindex>361// CHECK: %[[VAL_58:.*]] = scf.for %[[VAL_59:.*]] = %[[VAL_55]] to %[[VAL_57]] step %[[VAL_3]] iter_args(%[[VAL_60:.*]] = %[[VAL_44]]) -> (index) {362// CHECK: %[[VAL_61:.*]] = memref.load %[[VAL_17]]{{\[}}%[[VAL_59]]] : memref<?xindex>363// CHECK: %[[VAL_62:.*]] = memref.load %[[VAL_25]]{{\[}}%[[VAL_61]]] : memref<?xf32>364// CHECK: %[[VAL_63:.*]] = memref.load %[[VAL_18]]{{\[}}%[[VAL_59]]] : memref<?xf32>365// CHECK: %[[VAL_64:.*]] = arith.mulf %[[VAL_54]], %[[VAL_63]] : f32366// CHECK: %[[VAL_65:.*]] = arith.addf %[[VAL_62]], %[[VAL_64]] : f32367// CHECK: %[[VAL_66:.*]] = memref.load %[[VAL_26]]{{\[}}%[[VAL_61]]] : memref<?xi1>368// CHECK: %[[VAL_67:.*]] = arith.cmpi eq, %[[VAL_66]], %[[VAL_4]] : i1369// CHECK: %[[VAL_68:.*]] = scf.if %[[VAL_67]] -> (index) {370// CHECK: memref.store %[[VAL_5]], %[[VAL_26]]{{\[}}%[[VAL_61]]] : memref<?xi1>371// CHECK: memref.store %[[VAL_61]], %[[VAL_27]]{{\[}}%[[VAL_60]]] : memref<?xindex>372// CHECK: %[[VAL_69:.*]] = arith.addi %[[VAL_60]], %[[VAL_3]] : index373// CHECK: scf.yield %[[VAL_69]] : index374// CHECK: } else {375// CHECK: scf.yield %[[VAL_60]] : index376// CHECK: }377// CHECK: memref.store %[[VAL_65]], %[[VAL_25]]{{\[}}%[[VAL_61]]] : memref<?xf32>378// CHECK: scf.yield %[[VAL_70:.*]] : index379// CHECK: }380// CHECK: scf.yield %[[VAL_71:.*]], %[[VAL_45]] : index, tensor<?x?xf32, #sparse{{[0-9]*}}>381// CHECK: } else {382// CHECK: scf.yield %[[VAL_44]], %[[VAL_45]] : index, tensor<?x?xf32, #sparse{{[0-9]*}}>383// CHECK: }384// CHECK: %[[VAL_72:.*]] = arith.cmpi eq, %[[VAL_46]], %[[VAL_49]] : index385// CHECK: %[[VAL_73:.*]] = arith.addi %[[VAL_42]], %[[VAL_3]] : index386// CHECK: %[[VAL_74:.*]] = arith.select %[[VAL_72]], %[[VAL_73]], %[[VAL_42]] : index387// CHECK: %[[VAL_75:.*]] = arith.cmpi eq, %[[VAL_47]], %[[VAL_49]] : index388// CHECK: %[[VAL_76:.*]] = arith.addi %[[VAL_43]], %[[VAL_3]] : index389// CHECK: %[[VAL_77:.*]] = arith.select %[[VAL_75]], %[[VAL_76]], %[[VAL_43]] : index390// CHECK: scf.yield %[[VAL_74]], %[[VAL_77]], %[[VAL_78:.*]]#0, %[[VAL_78]]#1 : index, index, index, tensor<?x?xf32, #sparse{{[0-9]*}}>391// CHECK: }392// CHECK: %[[VAL_79:.*]] = sparse_tensor.compress %[[VAL_25]], %[[VAL_26]], %[[VAL_27]], %[[VAL_80:.*]]#2 into %[[VAL_80]]#3{{\[}}%[[VAL_24]]] : memref<?xf32>, memref<?xi1>, memref<?xindex>, tensor<?x?xf32, #sparse{{[0-9]*}}>393// CHECK: scf.yield %[[VAL_79]] : tensor<?x?xf32, #sparse{{[0-9]*}}>394// CHECK: }395// CHECK: %[[VAL_81:.*]] = sparse_tensor.load %[[VAL_82:.*]] hasInserts : tensor<?x?xf32, #sparse{{[0-9]*}}>396// CHECK: return %[[VAL_81]] : tensor<?x?xf32, #sparse{{[0-9]*}}>397// CHECK: }398func.func @matmat(%arga: tensor<?x?xf32, #DCSR>,399 %argb: tensor<?x?xf32, #DCSR>) -> tensor<?x?xf32, #DCSR> {400 %c0 = arith.constant 0 : index401 %c1 = arith.constant 1 : index402 %d0 = tensor.dim %arga, %c0 : tensor<?x?xf32, #DCSR>403 %d1 = tensor.dim %argb, %c1 : tensor<?x?xf32, #DCSR>404 %cinit = tensor.empty(%d0, %d1) : tensor<?x?xf32, #DCSR>405 %0 = linalg.generic #trait_matmat406 ins(%arga, %argb: tensor<?x?xf32, #DCSR>,407 tensor<?x?xf32, #DCSR>)408 outs(%cinit: tensor<?x?xf32, #DCSR>) {409 ^bb(%a: f32, %b: f32, %c: f32):410 %1 = arith.mulf %a, %b : f32411 %2 = arith.addf %c, %1 : f32412 linalg.yield %2 : f32413 } -> tensor<?x?xf32, #DCSR>414 return %0 : tensor<?x?xf32, #DCSR>415}416