Skip to content

Commit 34a1b8c

Browse files
[acc] acc.loop verifier now requires parallelism determination flag (#143720)
The OpenACC specification for `acc loop` describe that a loop's parallelism determination mode is either auto, independent, or seq. The rules are as follows. - As per OpenACC 3.3 standard section 2.9.6 independent clause: A loop construct with no auto or seq clause is treated as if it has the independent clause when it is an orphaned loop construct or its parent compute construct is a parallel construct. - As per OpenACC 3.3 standard section 2.9.7 auto clause: When the parent compute construct is a kernels construct, a loop construct with no independent or seq clause is treated as if it has the auto clause. - Additionally, loops marked with gang, worker, or vector are not guaranteed to be parallel. Specifically noted in 2.9.7 auto clause: If not, or if it is unable to make a determination, it must treat the auto clause as if it is a seq clause, and it must ignore any gang, worker, or vector clauses on the loop construct. The verifier for `acc.loop` was updated to enforce this marking because the context in which a loop appears is not trivially determined once IR transformations begin. For example, orphaned loops are implicitly `independent`, but after inlining into an `acc.kernels` region they would be implicitly considered `auto`. Thus now the verifier requires that a frontend specifically generates acc dialect with this marking since it knows the context.
1 parent 22fd11f commit 34a1b8c

File tree

5 files changed

+86
-63
lines changed

5 files changed

+86
-63
lines changed

mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2461,10 +2461,34 @@ LogicalResult acc::LoopOp::verify() {
24612461
if (hasDuplicateDeviceTypes(getAuto_(), deviceTypes) ||
24622462
hasDuplicateDeviceTypes(getIndependent(), deviceTypes) ||
24632463
hasDuplicateDeviceTypes(getSeq(), deviceTypes)) {
2464-
return emitError() << "only one of \"" << acc::LoopOp::getAutoAttrStrName()
2465-
<< "\", " << getIndependentAttrName() << ", "
2466-
<< getSeqAttrName()
2467-
<< " can be present at the same time";
2464+
return emitError() << "only one of auto, independent, seq can be present "
2465+
"at the same time";
2466+
}
2467+
2468+
// Check that at least one of auto, independent, or seq is present
2469+
// for the device-independent default clauses.
2470+
auto hasDeviceNone = [](mlir::acc::DeviceTypeAttr attr) -> bool {
2471+
return attr.getValue() == mlir::acc::DeviceType::None;
2472+
};
2473+
bool hasDefaultSeq =
2474+
getSeqAttr()
2475+
? llvm::any_of(getSeqAttr().getAsRange<mlir::acc::DeviceTypeAttr>(),
2476+
hasDeviceNone)
2477+
: false;
2478+
bool hasDefaultIndependent =
2479+
getIndependentAttr()
2480+
? llvm::any_of(
2481+
getIndependentAttr().getAsRange<mlir::acc::DeviceTypeAttr>(),
2482+
hasDeviceNone)
2483+
: false;
2484+
bool hasDefaultAuto =
2485+
getAuto_Attr()
2486+
? llvm::any_of(getAuto_Attr().getAsRange<mlir::acc::DeviceTypeAttr>(),
2487+
hasDeviceNone)
2488+
: false;
2489+
if (!hasDefaultSeq && !hasDefaultIndependent && !hasDefaultAuto) {
2490+
return emitError()
2491+
<< "at least one of auto, independent, seq must be present";
24682492
}
24692493

24702494
// Gang, worker and vector are incompatible with seq.
@@ -2482,8 +2506,7 @@ LogicalResult acc::LoopOp::verify() {
24822506
deviceTypeAttr.getValue()) ||
24832507
getGangValue(mlir::acc::GangArgType::Static,
24842508
deviceTypeAttr.getValue()))
2485-
return emitError()
2486-
<< "gang, worker or vector cannot appear with the seq attr";
2509+
return emitError() << "gang, worker or vector cannot appear with seq";
24872510
}
24882511
}
24892512

mlir/test/Dialect/OpenACC/canonicalize.mlir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,10 @@ func.func @testhostdataop(%a: memref<f32>, %ifCond: i1) -> () {
116116
acc.host_data dataOperands(%0 : memref<f32>) if(%false) {
117117
acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
118118
acc.yield
119-
} attributes { inclusiveUpperbound = array<i1: true> }
119+
} attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}
120120
acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
121121
acc.yield
122-
} attributes { inclusiveUpperbound = array<i1: true> }
122+
} attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}
123123
acc.terminator
124124
}
125125
return

mlir/test/Dialect/OpenACC/invalid.mlir

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
%1 = arith.constant 1 : i32
44
%2 = arith.constant 10 : i32
5-
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
5+
// expected-error@+1 {{gang, worker or vector cannot appear with seq}}
66
acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
77
"test.openacc_dummy_op"() : () -> ()
88
acc.yield
@@ -12,7 +12,7 @@ acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
1212

1313
%1 = arith.constant 1 : i32
1414
%2 = arith.constant 10 : i32
15-
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
15+
// expected-error@+1 {{gang, worker or vector cannot appear with seq}}
1616
acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
1717
"test.openacc_dummy_op"() : () -> ()
1818
acc.yield
@@ -22,7 +22,7 @@ acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
2222

2323
%1 = arith.constant 1 : i32
2424
%2 = arith.constant 10 : i32
25-
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
25+
// expected-error@+1 {{gang, worker or vector cannot appear with seq}}
2626
acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
2727
"test.openacc_dummy_op"() : () -> ()
2828
acc.yield
@@ -32,7 +32,7 @@ acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
3232

3333
%1 = arith.constant 1 : i32
3434
%2 = arith.constant 10 : i32
35-
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
35+
// expected-error@+1 {{gang, worker or vector cannot appear with seq}}
3636
acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
3737
"test.openacc_dummy_op"() : () -> ()
3838
acc.yield
@@ -42,7 +42,7 @@ acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
4242

4343
%1 = arith.constant 1 : i32
4444
%2 = arith.constant 10 : i32
45-
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
45+
// expected-error@+1 {{gang, worker or vector cannot appear with seq}}
4646
acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
4747
"test.openacc_dummy_op"() : () -> ()
4848
acc.yield
@@ -52,7 +52,7 @@ acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
5252

5353
%1 = arith.constant 1 : i32
5454
%2 = arith.constant 10 : i32
55-
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
55+
// expected-error@+1 {{gang, worker or vector cannot appear with seq}}
5656
acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
5757
"test.openacc_dummy_op"() : () -> ()
5858
acc.yield
@@ -62,7 +62,7 @@ acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
6262

6363
%1 = arith.constant 1 : i32
6464
%2 = arith.constant 10 : i32
65-
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
65+
// expected-error@+1 {{gang, worker or vector cannot appear with seq}}
6666
acc.loop {
6767
"test.openacc_dummy_op"() : () -> ()
6868
acc.yield
@@ -72,7 +72,7 @@ acc.loop {
7272

7373
// expected-error@+1 {{expected non-empty body.}}
7474
acc.loop {
75-
}
75+
} attributes {independent = [#acc.device_type<none>]}
7676

7777
// -----
7878

@@ -99,7 +99,7 @@ acc.loop {
9999

100100
%1 = arith.constant 1 : i32
101101
%2 = arith.constant 10 : i32
102-
// expected-error@+1 {{only one of "auto", "independent", "seq" can be present at the same time}}
102+
// expected-error@+1 {{only one of auto, independent, seq can be present at the same time}}
103103
acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
104104
acc.yield
105105
} attributes {auto_ = [#acc.device_type<none>], seq = [#acc.device_type<none>], inclusiveUpperbound = array<i1: true>}
@@ -168,7 +168,7 @@ acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32){
168168
// expected-error@+1 {{'acc.init' op cannot be nested in a compute operation}}
169169
acc.init
170170
acc.yield
171-
} attributes {inclusiveUpperbound = array<i1: true>}
171+
} attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}
172172

173173
// -----
174174

@@ -186,7 +186,7 @@ acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
186186
// expected-error@+1 {{'acc.shutdown' op cannot be nested in a compute operation}}
187187
acc.shutdown
188188
acc.yield
189-
} attributes {inclusiveUpperbound = array<i1: true>}
189+
} attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}
190190

191191
// -----
192192

@@ -198,7 +198,7 @@ acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
198198
acc.shutdown
199199
}) : () -> ()
200200
acc.yield
201-
} attributes {inclusiveUpperbound = array<i1: true>}
201+
} attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}
202202

203203
// -----
204204

@@ -797,7 +797,7 @@ func.func @acc_loop_container() {
797797
scf.yield
798798
}
799799
acc.yield
800-
} attributes { collapse = [2], collapseDeviceType = [#acc.device_type<none>] }
800+
} attributes { collapse = [2], collapseDeviceType = [#acc.device_type<none>], independent = [#acc.device_type<none>]}
801801
return
802802
}
803803

@@ -816,6 +816,6 @@ func.func @acc_loop_container() {
816816
scf.yield
817817
}
818818
acc.yield
819-
} attributes { collapse = [3], collapseDeviceType = [#acc.device_type<none>] }
819+
} attributes { collapse = [3], collapseDeviceType = [#acc.device_type<none>], independent = [#acc.device_type<none>]}
820820
return
821821
}

mlir/test/Dialect/OpenACC/legalize-data.mlir

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ func.func @test(%a: memref<10xf32>) {
9696
acc.loop control(%i : index) = (%lb : index) to (%c10 : index) step (%st : index) {
9797
%ci = memref.load %a[%i] : memref<10xf32>
9898
acc.yield
99-
}
99+
} attributes {independent = [#acc.device_type<none>]}
100100
acc.yield
101101
}
102102
return
@@ -109,7 +109,7 @@ func.func @test(%a: memref<10xf32>) {
109109
// CHECK: acc.loop control(%[[I:.*]] : index) = (%{{.*}} : index) to (%{{.*}} : index) step (%{{.*}} : index) {
110110
// DEVICE: %{{.*}} = memref.load %[[CREATE:.*]][%[[I]]] : memref<10xf32>
111111
// CHECK: acc.yield
112-
// CHECK: }
112+
// CHECK: } attributes {independent = [#acc.device_type<none>]}
113113
// CHECK: acc.yield
114114
// CHECK: }
115115

@@ -134,7 +134,7 @@ func.func @test(%a: memref<10xf32>) {
134134
acc.loop control(%i : index) = (%lb : index) to (%c10 : index) step (%st : index) {
135135
%ci = memref.load %a[%i] : memref<10xf32>
136136
acc.yield
137-
}
137+
} attributes {independent = [#acc.device_type<none>]}
138138
acc.yield
139139
}
140140
return
@@ -147,7 +147,7 @@ func.func @test(%a: memref<10xf32>) {
147147
// CHECK: acc.loop control(%[[I:.*]] : index) = (%{{.*}} : index) to (%{{.*}} : index) step (%{{.*}} : index) {
148148
// DEVICE: %{{.*}} = memref.load %[[PRIVATE:.*]][%[[I]]] : memref<10xf32>
149149
// CHECK: acc.yield
150-
// CHECK: }
150+
// CHECK: } attributes {independent = [#acc.device_type<none>]}
151151
// CHECK: acc.yield
152152
// CHECK: }
153153

@@ -172,7 +172,7 @@ func.func @test(%a: memref<10xf32>) {
172172
acc.loop private(@privatization_memref_10_f32 -> %p1 : memref<10xf32>) control(%i : index) = (%lb : index) to (%c10 : index) step (%st : index) {
173173
%ci = memref.load %a[%i] : memref<10xf32>
174174
acc.yield
175-
}
175+
} attributes {independent = [#acc.device_type<none>]}
176176
acc.yield
177177
}
178178
return
@@ -185,7 +185,7 @@ func.func @test(%a: memref<10xf32>) {
185185
// CHECK: acc.loop private(@privatization_memref_10_f32 -> %[[PRIVATE]] : memref<10xf32>) control(%[[I:.*]] : index) = (%{{.*}} : index) to (%{{.*}} : index) step (%{{.*}} : index) {
186186
// DEVICE: %{{.*}} = memref.load %[[PRIVATE:.*]][%[[I]]] : memref<10xf32>
187187
// CHECK: acc.yield
188-
// CHECK: }
188+
// CHECK: } attributes {independent = [#acc.device_type<none>]}
189189
// CHECK: acc.yield
190190
// CHECK: }
191191

@@ -210,7 +210,7 @@ func.func @test(%a: memref<10xf32>) {
210210
acc.loop control(%i : index) = (%lb : index) to (%c10 : index) step (%st : index) {
211211
%ci = memref.load %a[%i] : memref<10xf32>
212212
acc.yield
213-
}
213+
} attributes {seq = [#acc.device_type<none>]}
214214
acc.yield
215215
}
216216
return
@@ -223,7 +223,7 @@ func.func @test(%a: memref<10xf32>) {
223223
// CHECK: acc.loop control(%[[I:.*]] : index) = (%{{.*}} : index) to (%{{.*}} : index) step (%{{.*}} : index) {
224224
// DEVICE: %{{.*}} = memref.load %[[PRIVATE:.*]][%[[I]]] : memref<10xf32>
225225
// CHECK: acc.yield
226-
// CHECK: }
226+
// CHECK: } attributes {seq = [#acc.device_type<none>]}
227227
// CHECK: acc.yield
228228
// CHECK: }
229229

0 commit comments

Comments
 (0)