xref: /llvm-project/mlir/test/Dialect/Tensor/transform-op-make-loop-independent.mlir (revision e4384149b58f7c3d19c5d38bc46038c660b77ca9)
177124386SMatthias Springer// RUN: mlir-opt %s -allow-unregistered-dialect \
2*e4384149SOleksandr "Alex" Zinenko// RUN:     -transform-interpreter -canonicalize \
377124386SMatthias Springer// RUN:     -split-input-file -verify-diagnostics | FileCheck %s
477124386SMatthias Springer
577124386SMatthias Springer// This is a test case where "high" padding depends on the IV.
677124386SMatthias Springer
777124386SMatthias Springer//       CHECK: #[[$map:.*]] = affine_map<()[s0, s1] -> (s0 - s1)>
877124386SMatthias Springer//       CHECK: #[[$map1:.*]] = affine_map<(d0)[s0, s1] -> (-d0 + s0 + s1 + 5)>
977124386SMatthias Springer// CHECK-LABEL: func @make_pad_loop_independent_1(
1077124386SMatthias Springer//  CHECK-SAME:     %[[lb:.*]]: index, %[[ub:.*]]: index, %[[step:.*]]: index,
1177124386SMatthias Springer//  CHECK-SAME:     %[[t:.*]]: tensor<?xf32>
1277124386SMatthias Springerfunc.func @make_pad_loop_independent_1(%lb: index, %ub: index, %step: index,
1377124386SMatthias Springer                                       %t: tensor<?xf32>, %f: f32) {
1477124386SMatthias Springer  // CHECK: scf.for %[[iv:.*]] = %[[lb]] to %[[ub]]
1577124386SMatthias Springer  scf.for %i = %lb to %ub step %step {
1677124386SMatthias Springer    // CHECK: %[[high:.*]] = affine.apply #[[$map]]()[%[[ub]], %[[lb]]]
1777124386SMatthias Springer    // CHECK: %[[padded:.*]] = tensor.pad %[[t]] low[5] high[%[[high]]]
1877124386SMatthias Springer    // CHECK: %[[dim:.*]] = tensor.dim %[[t]]
1977124386SMatthias Springer    // CHECK: %[[size:.*]] = affine.apply #[[$map1]](%[[iv]])[%[[ub]], %[[dim]]]
2077124386SMatthias Springer    // CHECK: %[[replacement:.*]] = tensor.extract_slice %[[padded]][0] [%[[size]]] [1]
2177124386SMatthias Springer    %high = affine.apply affine_map<(d0)[s0] -> (s0 - d0)> (%i)[%ub]
2277124386SMatthias Springer    %p = tensor.pad %t low[5] high[%high] {
2377124386SMatthias Springer    ^bb0(%arg1: index):
2477124386SMatthias Springer      tensor.yield %f : f32
2577124386SMatthias Springer    } : tensor<?xf32> to tensor<?xf32>
2677124386SMatthias Springer    // CHECK: "dummy.some_use"(%[[replacement]])
2777124386SMatthias Springer    "dummy.some_use"(%p) : (tensor<?xf32>) -> ()
2877124386SMatthias Springer  }
2977124386SMatthias Springer  return
3077124386SMatthias Springer}
3177124386SMatthias Springer
32*e4384149SOleksandr "Alex" Zinenkomodule attributes {transform.with_named_sequence} {
33*e4384149SOleksandr "Alex" Zinenko  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {
342f3ac28cSAlex Zinenko    %0 = transform.structured.match ops{["tensor.pad"]} in %arg1 : (!transform.any_op) -> !transform.any_op
352f3ac28cSAlex Zinenko    %1 = transform.tensor.make_loop_independent %0 {num_loops = 1} : (!transform.any_op) -> !transform.any_op
36*e4384149SOleksandr "Alex" Zinenko    transform.yield
37*e4384149SOleksandr "Alex" Zinenko  }
3877124386SMatthias Springer}
3977124386SMatthias Springer
4077124386SMatthias Springer// -----
4177124386SMatthias Springer
4277124386SMatthias Springer// This is a test case where "low" padding depends on the IV.
4377124386SMatthias Springer
4477124386SMatthias Springer//       CHECK: #[[$map:.*]] = affine_map<()[s0, s1] -> (s0 - s1)>
4577124386SMatthias Springer//       CHECK: #[[$map1:.*]] = affine_map<(d0)[s0, s1] -> (-d0 + s0 + s1 + 5)>
4677124386SMatthias Springer//       CHECK: #[[$map2:.*]] = affine_map<(d0)[s0] -> (d0 - s0)>
4777124386SMatthias Springer// CHECK-LABEL: func @make_pad_loop_independent_1(
4877124386SMatthias Springer//  CHECK-SAME:     %[[lb:.*]]: index, %[[ub:.*]]: index, %[[step:.*]]: index,
4977124386SMatthias Springer//  CHECK-SAME:     %[[t:.*]]: tensor<?xf32>
5077124386SMatthias Springerfunc.func @make_pad_loop_independent_1(%lb: index, %ub: index, %step: index,
5177124386SMatthias Springer                                       %t: tensor<?xf32>, %f: f32) {
5277124386SMatthias Springer  // CHECK: scf.for %[[iv:.*]] = %[[lb]] to %[[ub]]
5377124386SMatthias Springer  scf.for %i = %lb to %ub step %step {
5477124386SMatthias Springer    // CHECK: %[[low:.*]] = affine.apply #[[$map]]()[%[[ub]], %[[lb]]]
5577124386SMatthias Springer    // CHECK: %[[padded:.*]] = tensor.pad %[[t]] low[%[[low]]] high[5]
5677124386SMatthias Springer    // CHECK: %[[dim:.*]] = tensor.dim %[[t]]
5777124386SMatthias Springer    // CHECK: %[[size:.*]] = affine.apply #[[$map1]](%[[iv]])[%[[ub]], %[[dim]]]
5877124386SMatthias Springer    // CHECK: %[[offset:.*]] = affine.apply #[[$map2]](%[[iv]])[%[[lb]]]
5977124386SMatthias Springer    // CHECK: %[[replacement:.*]] = tensor.extract_slice %[[padded]][%[[offset]]] [%[[size]]] [1]
6077124386SMatthias Springer    %low = affine.apply affine_map<(d0)[s0] -> (s0 - d0)> (%i)[%ub]
6177124386SMatthias Springer    %p = tensor.pad %t low[%low] high[5] {
6277124386SMatthias Springer    ^bb0(%arg1: index):
6377124386SMatthias Springer      tensor.yield %f : f32
6477124386SMatthias Springer    } : tensor<?xf32> to tensor<?xf32>
6577124386SMatthias Springer    // CHECK: "dummy.some_use"(%[[replacement]])
6677124386SMatthias Springer    "dummy.some_use"(%p) : (tensor<?xf32>) -> ()
6777124386SMatthias Springer  }
6877124386SMatthias Springer  return
6977124386SMatthias Springer}
7077124386SMatthias Springer
71*e4384149SOleksandr "Alex" Zinenkomodule attributes {transform.with_named_sequence} {
72*e4384149SOleksandr "Alex" Zinenko  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {
732f3ac28cSAlex Zinenko    %0 = transform.structured.match ops{["tensor.pad"]} in %arg1 : (!transform.any_op) -> !transform.any_op
742f3ac28cSAlex Zinenko    %1 = transform.tensor.make_loop_independent %0 {num_loops = 1} : (!transform.any_op) -> !transform.any_op
75*e4384149SOleksandr "Alex" Zinenko    transform.yield
76*e4384149SOleksandr "Alex" Zinenko  }
7777124386SMatthias Springer}
7877124386SMatthias Springer
7977124386SMatthias Springer// -----
8077124386SMatthias Springer
8177124386SMatthias Springer//       CHECK: #[[$map:.*]] = affine_map<()[s0] -> (s0 * 2 - 2)>
8277124386SMatthias Springer// CHECK-LABEL: func @two_loops(
8377124386SMatthias Springerfunc.func @two_loops(%lb: index, %ub: index, %step: index,
8477124386SMatthias Springer                     %t: tensor<?xf32>, %f: f32) {
8577124386SMatthias Springer  scf.for %i = %lb to %ub step %step {
8677124386SMatthias Springer    scf.for %j = %lb to %ub step %step {
8777124386SMatthias Springer      // CHECK: affine.apply #map()[%{{.*}}]
8877124386SMatthias Springer      %low = affine.apply affine_map<(d0, d1)[] -> (d0 + d1)> (%i, %j)[]
8977124386SMatthias Springer      %p = tensor.pad %t low[%low] high[5] {
9077124386SMatthias Springer      ^bb0(%arg1: index):
9177124386SMatthias Springer        tensor.yield %f : f32
9277124386SMatthias Springer      } : tensor<?xf32> to tensor<?xf32>
9377124386SMatthias Springer      "dummy.some_use"(%p) : (tensor<?xf32>) -> ()
9477124386SMatthias Springer    }
9577124386SMatthias Springer  }
9677124386SMatthias Springer  return
9777124386SMatthias Springer}
9877124386SMatthias Springer
99*e4384149SOleksandr "Alex" Zinenkomodule attributes {transform.with_named_sequence} {
100*e4384149SOleksandr "Alex" Zinenko  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {
1012f3ac28cSAlex Zinenko    %0 = transform.structured.match ops{["tensor.pad"]} in %arg1 : (!transform.any_op) -> !transform.any_op
1022f3ac28cSAlex Zinenko    %1 = transform.tensor.make_loop_independent %0 {num_loops = 2} : (!transform.any_op) -> !transform.any_op
103*e4384149SOleksandr "Alex" Zinenko    transform.yield
104*e4384149SOleksandr "Alex" Zinenko  }
10577124386SMatthias Springer}
10677124386SMatthias Springer
10777124386SMatthias Springer// -----
10877124386SMatthias Springer
10977124386SMatthias Springerfunc.func @not_enough_loops(%lb: index, %ub: index, %step: index,
11077124386SMatthias Springer                            %t: tensor<?xf32>, %f: f32) {
11177124386SMatthias Springer  scf.for %i = %lb to %ub step %step {
11277124386SMatthias Springer    scf.for %j = %lb to %ub step %step {
11377124386SMatthias Springer      %low = affine.apply affine_map<(d0, d1)[] -> (d0 + d1)> (%i, %j)[]
11477124386SMatthias Springer      // expected-note@below {{target op}}
11577124386SMatthias Springer      %p = tensor.pad %t low[%low] high[5] {
11677124386SMatthias Springer      ^bb0(%arg1: index):
11777124386SMatthias Springer        tensor.yield %f : f32
11877124386SMatthias Springer      } : tensor<?xf32> to tensor<?xf32>
11977124386SMatthias Springer      "dummy.some_use"(%p) : (tensor<?xf32>) -> ()
12077124386SMatthias Springer    }
12177124386SMatthias Springer  }
12277124386SMatthias Springer  return
12377124386SMatthias Springer}
12477124386SMatthias Springer
125*e4384149SOleksandr "Alex" Zinenkomodule attributes {transform.with_named_sequence} {
126*e4384149SOleksandr "Alex" Zinenko  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {
1272f3ac28cSAlex Zinenko    %0 = transform.structured.match ops{["tensor.pad"]} in %arg1 : (!transform.any_op) -> !transform.any_op
12877124386SMatthias Springer    // expected-error@below {{could not find 2-th enclosing loop}}
1292f3ac28cSAlex Zinenko    %1 = transform.tensor.make_loop_independent %0 {num_loops = 3} : (!transform.any_op) -> !transform.any_op
130*e4384149SOleksandr "Alex" Zinenko    transform.yield
131*e4384149SOleksandr "Alex" Zinenko  }
13277124386SMatthias Springer}
13377124386SMatthias Springer
13477124386SMatthias Springer// -----
13577124386SMatthias Springer
13677124386SMatthias Springer// CHECK: #[[$map:.*]] = affine_map<(d0)[s0] -> (-d0 + s0)>
13777124386SMatthias Springer// CHECK: #[[$map1:.*]] = affine_map<()[s0, s1] -> (s0 - s1)>
13877124386SMatthias Springer// CHECK-LABEL: func @make_empty_loop_independent(
13977124386SMatthias Springer//  CHECK-SAME:     %[[lb:.*]]: index, %[[ub:.*]]: index, %[[step:.*]]: index)
14077124386SMatthias Springerfunc.func @make_empty_loop_independent(%lb: index, %ub: index, %step: index) {
14177124386SMatthias Springer  // CHECK: scf.for %[[iv:.*]] = %[[lb]] to %[[ub]]
14277124386SMatthias Springer  scf.for %i = %lb to %ub step %step {
14377124386SMatthias Springer    // CHECK: %[[slice_sz:.*]] = affine.apply #[[$map]](%[[iv]])[%[[ub]]]
14477124386SMatthias Springer    // CHECK: %[[empty_sz:.*]] = affine.apply #[[$map1]]()[%[[ub]], %[[lb]]]
14577124386SMatthias Springer    // CHECK: %[[empty:.*]] = tensor.empty(%[[empty_sz]]) : tensor<?xf32>
14677124386SMatthias Springer    // CHECK: %[[replacement:.*]] = tensor.extract_slice %[[empty]][0] [%[[slice_sz]]] [1]
14777124386SMatthias Springer    %sz = affine.apply affine_map<(d0)[s0] -> (s0 - d0)> (%i)[%ub]
14877124386SMatthias Springer    %empty = tensor.empty(%sz) : tensor<?xf32>
14977124386SMatthias Springer    // CHECK: "dummy.some_use"(%[[replacement]])
15077124386SMatthias Springer    "dummy.some_use"(%empty) : (tensor<?xf32>) -> ()
15177124386SMatthias Springer  }
15277124386SMatthias Springer  return
15377124386SMatthias Springer}
15477124386SMatthias Springer
155*e4384149SOleksandr "Alex" Zinenkomodule attributes {transform.with_named_sequence} {
156*e4384149SOleksandr "Alex" Zinenko  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {
1572f3ac28cSAlex Zinenko    %0 = transform.structured.match ops{["tensor.empty"]} in %arg1 : (!transform.any_op) -> !transform.any_op
1582f3ac28cSAlex Zinenko    %1 = transform.tensor.make_loop_independent %0 {num_loops = 1} : (!transform.any_op) -> !transform.any_op
159*e4384149SOleksandr "Alex" Zinenko    transform.yield
160*e4384149SOleksandr "Alex" Zinenko  }
16177124386SMatthias Springer}
162