59 lines
1.6 KiB
MLIR
59 lines
1.6 KiB
MLIR
// RUN: mlir-opt %s --linalg-fuse-elementwise-ops | FileCheck %s
|
|
|
|
#SV = #sparse_tensor.encoding<{ map = (d0) -> (d0 : compressed) }>
|
|
|
|
#trait = {
|
|
indexing_maps = [
|
|
affine_map<(i) -> (i)>, // A
|
|
affine_map<(i) -> (i)> // B (out)
|
|
],
|
|
iterator_types = ["parallel"],
|
|
doc = "B(i) = OP A(i)"
|
|
}
|
|
|
|
// CHECK-LABEL: func @sparse_fusion
|
|
// CHECK: linalg.generic
|
|
// CHECK: arith.addf
|
|
// CHECK: linalg.generic
|
|
// CHECK: math.exp
|
|
// CHECK: arith.maximumf
|
|
// CHECK-NOT: linalg.generic
|
|
// CHECK: return
|
|
func.func @sparse_fusion(%argA: tensor<100xf64, #SV>) -> tensor<100xf64> {
|
|
%c1 = arith.constant 1.0 : f64
|
|
%c100 = arith.constant 100.0 : f64
|
|
|
|
//
|
|
// Densifying op.
|
|
// Should not be fused with subsequent dense ops.
|
|
//
|
|
%t0 = tensor.empty() : tensor<100xf64>
|
|
%l0 = linalg.generic #trait
|
|
ins(%argA: tensor<100xf64, #SV>) outs(%t0: tensor<100xf64>) {
|
|
^bb0(%in0: f64, %out0: f64):
|
|
%b0 = arith.addf %in0, %c1 : f64
|
|
linalg.yield %b0 : f64
|
|
} -> tensor<100xf64>
|
|
|
|
|
|
//
|
|
// Two following dense ops.
|
|
// Should be fused, but not with above.
|
|
//
|
|
%t1 = tensor.empty() : tensor<100xf64>
|
|
%l1 = linalg.generic #trait
|
|
ins(%l0: tensor<100xf64>) outs(%t1: tensor<100xf64>) {
|
|
^bb0(%in1: f64, %out1: f64):
|
|
%b1 = math.exp %in1 : f64
|
|
linalg.yield %b1 : f64
|
|
} -> tensor<100xf64>
|
|
%t2 = tensor.empty() : tensor<100xf64>
|
|
%l2 = linalg.generic #trait
|
|
ins(%l1: tensor<100xf64>) outs(%t2: tensor<100xf64>) {
|
|
^bb0(%in2: f64, %out2: f64):
|
|
%b2 = arith.maximumf %in2, %c100 : f64
|
|
linalg.yield %b2 : f64
|
|
} -> tensor<100xf64>
|
|
|
|
return %l2 : tensor<100xf64>
|
|
}
|