Skip to content

Commit b8ba223

Browse files
committed
[OpenACC] Implement present clause
1 parent e145a54 commit b8ba223

28 files changed

+1456
-72
lines changed

clang/README-OpenACC-design.md

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@ clarify these points in future versions of the OpenACC specification.
577577
* Data mapping attributes (DMAs), which describe the mapping and
578578
transfer of data between host and device:
579579
* `nomap` (default)
580+
* `present`
580581
* `copy`
581582
* `copyin`
582583
* `copyout`
@@ -703,7 +704,9 @@ clarify these points in future versions of the OpenACC specification.
703704
* *exp*|*imp* DA for a variable of incomplete type is an error.
704705
Notes:
705706
* A private or device copy is assumed to be allocatable in each of
706-
these cases, but allocation is impossible for incomplete types.
707+
these cases, but creating a new allocation or checking for a
708+
full existing allocation is impossible for incomplete types
709+
because the size is unknown.
707710
* It does not appear possible for any DA other than `copy`,
708711
`nomap`, or `shared` to be *imp* for a variable of incomplete
709712
type.
@@ -741,6 +744,9 @@ clarify these points in future versions of the OpenACC specification.
741744
* *exp* `copyin` or *exp* `firstprivate` is fine for a `const`
742745
variable. The local copy will have the original variable's
743746
value throughout its lifetime.
747+
* *exp* `present` is fine for a `const` variable as the
748+
initialization could have happened at the time of the
749+
allocation.
744750
* *imp* `copy` or *imp* `firstprivate` for a `const` variable
745751
should be fine for the same reasons as their *exp* versions.
746752
* *imp* `nomap` and *imp* `shared` are the only remaining *imp*
@@ -1103,6 +1109,52 @@ Clacc's current mapping of an `acc data` directive and its clauses to
11031109
OpenMP is as follows:
11041110

11051111
* `acc data` -> `omp target data`
1112+
* *exp* `present` is translated according to the
1113+
`-fopenacc-present-omp=KIND` command-line option:
1114+
* `KIND` is one of:
1115+
* `present` (default):
1116+
* *exp* `present` -> *exp* `map` with a `present,alloc`
1117+
map type.
1118+
* `alloc`:
1119+
* *exp* `present` -> *exp* `map` with an `alloc` map type.
1120+
* Notes:
1121+
* See the discussion of the `present` clause under "Supported
1122+
Features" in `README-OpenACC-status.md` for a description of
1123+
associated diagnostics and for an explanation of the impact
1124+
of this design on Clacc users.
1125+
* Clacc does not currently support translating `present` to
1126+
calls to `omp_target_is_present` for the following reasons:
1127+
* `omp_target_is_present` is fine for checking that data
1128+
is present when the data is a single byte. However, it
1129+
does not provide a means to check a range of *N* bytes
1130+
without requiring O(*N*) calls. Checking for just the
1131+
first and last bytes would be O(1), but that would not
1132+
handle some cases where the first and last byte are part
1133+
of multiple, separate, possibly non-contiguous
1134+
subarrays.
1135+
* A runtime error must be triggered when data is not
1136+
present. However, we are not aware of any OpenMP 5.0
1137+
API for triggering a runtime error. `fprintf`,
1138+
`stderr`, and `abort` might provide an obvious
1139+
mechanism, but that might not be how other runtime
1140+
errors are handled by every OpenMP runtime that might be
1141+
used by every OpenMP compiler. Do they print to
1142+
`stderr`, a log, or both? Does the runtime need to be
1143+
shut down somehow before `abort`? Moreover, there are
1144+
plans to introduce a runtime-error handling extension to
1145+
the OpenACC Profiling Interface, but there's no obvious
1146+
way for it to intercept calls to `fprintf` and `abort`.
1147+
* Clacc would need to insert either includes of headers
1148+
like `stdio.h` and `omp.h` or at least local
1149+
declarations of symbols like `omp_target_is_present`,
1150+
`omp_get_default_device`, `fprintf`, `stderr`, and
1151+
`abort`. Either way, such symbols could potentially
1152+
conflict with user-defined symbols or preprocessor macro
1153+
definitions.
1154+
* We will reconsider adding support for such a translation
1155+
if there is user demand, but we suspect the likelihood
1156+
that OpenMP TR8's `present` map type modifier will be
1157+
standardized means this option is likely not worthwhile.
11061158
* *exp* `copy` -> *exp* `map` with a `tofrom` map type.
11071159
* *exp* `copyin` -> *exp* `map` with a `to` map type.
11081160
* *exp* `copyout` -> *exp* `map` with a `from` map type.
@@ -1222,9 +1274,8 @@ to OpenMP is as follows:
12221274
However, this behavior shouldn't be observable given that it's
12231275
OpenACC's structured reference counter, which is guaranteed not
12241276
to fall to zero before the enclosing `acc data` ends either way.
1225-
* *exp*|*imp* `copy` -> *exp* `map` with a `tofrom` map type
1226-
* *exp* `copyin` -> *exp* `map` with a `to` map type
1227-
* *exp* `copyout` -> *exp* `map` with a `from` map type
1277+
* All DMAs are mapped in the same manner as when appearing on an `acc
1278+
data`. *imp* `copy` is mapped in the same manner as *exp* `copy`.
12281279
* *imp* `shared` -> *exp* `shared`
12291280
* *exp*|*imp* `reduction` -> *exp* `reduction`
12301281
* *exp*|*imp* `firstprivate` -> *exp* `firstprivate`

clang/README-OpenACC-status.md

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,14 @@ We have implemented and tested support for the following features:
2020
tested offloading target triples.
2121
* See the section "Interaction with OpenMP Support" in
2222
`README-OpenACC-design.md` for design details.
23+
* `-fopenacc-present-omp=KIND` where `KIND` is either `present` or
24+
`alloc`
25+
* See the discussion of the `present` clause below.
2326
* `-Wsource-uses-openacc`
2427
* `-Wopenacc-ignored-clause`
2528
* See the discussion of the `vector_length` clause below.
29+
* `-Wopenacc-omp-map-present`
30+
* See the discussion of the `present` clause below.
2631
* Notes:
2732
* See the section "Using" in `../README.md` for an
2833
introduction to Clacc's command-line options.
@@ -32,20 +37,79 @@ We have implemented and tested support for the following features:
3237
* run-time environment variables:
3338
* `OMP_TARGET_OFFLOAD=disabled` for targeting host
3439
* `data` directive:
40+
* `present` clause
41+
* Traditional compilation mode:
42+
* The `present` clause is fully supported.
43+
* Although the traditional compilation mode user typically
44+
does not need to be aware, the OpenMP translation of the
45+
`present` clause uses an OpenMP TR8 feature: the
46+
`present` map type modifier. This modifier is combined
47+
with the OpenMP `alloc` map type as opposed to, for
48+
example, `tofrom` in order to suppress device-to-host
49+
transfers in the case that there is a reference count
50+
decrement within the associated region.
51+
* If desired, it is possible to adjust the translation or
52+
related diagnostics by using the command-line options
53+
discussed below for source-to-source mode. The
54+
difference is that, by default in traditional
55+
compilation mode, the related diagnostics are disabled.
56+
* Source-to-source mode:
57+
* Occurrences of the `present` clause produce a
58+
compile-time error diagnostic by default. The purpose
59+
of the diagnostic is to ensure the user is aware that
60+
the translation includes the `present` map type modifier
61+
because it is unlikely to be supported yet by foreign
62+
OpenMP compilers.
63+
* The diagnostic is actually the warning enabled by
64+
`-Wopenacc-omp-map-present`, which is enabled and
65+
treated as an error by default in source-to-source mode.
66+
* To work around this issue, the following command-line
67+
options can be specified:
68+
* `-Wno-error=openacc-omp-map-present` converts the
69+
diagnostic to a warning to make it easier to find
70+
all occurrences.
71+
* `-Wno-openacc-omp-map-present` disables the
72+
diagnostic entirely. This is useful if the
73+
generated OpenMP will not be compiled or if the
74+
OpenMP compiler actually already supports the
75+
`present` map type modifier.
76+
* `-fopenacc-present-omp=alloc` suppresses the
77+
diagnostic by changing the translation to use the
78+
standard OpenMP `alloc` map type without the
79+
`present` modifier. In this case, there is no
80+
runtime error when the specified variable is not
81+
present on the device. However, this translation
82+
should be sufficient for OpenACC applications that
83+
are robust enough not to actually encounter this
84+
runtime error.
85+
* `-fopenacc[-ast]-print=acc`, `-ast-print`, `-ast-dump`,
86+
etc. mode:
87+
* Debugging modes like these do not actually print OpenMP
88+
source code, so they leave the aforementioned diagnostic
89+
disabled as in traditional compilation mode.
90+
* Currently, Clacc's implementation of the OpenMP TR8
91+
`present` map type modifier is not well tested outside of
92+
Clacc translations from OpenACC to OpenMP. Thus, it is not
93+
yet recommended for use in hand-written OpenMP code as it
94+
might not integrate well with some OpenMP features.
95+
* See the section "Data Directives" in
96+
`README-OpenACC-design.md` for a discussion of alternative
97+
translations that we considered for the OpenACC `present`
98+
clause.
3599
* `copy` clause and aliases `pcopy` and `present_or_copy`
36100
* `copyin` clause and aliases `pcopyin` and
37101
`present_or_copyin`
38102
* `copyout` clause and aliases `pcopyout` and
39103
`present_or_copyout`
40-
* in `copy`, `copyin`, and `copyout` clauses and their aliases,
41-
subarrays specifying contiguous blocks
104+
* in `present`, `copy`, `copyin`, and `copyout` clauses and their
105+
aliases, subarrays specifying contiguous blocks
42106
* any number of levels of nesting within other `data` directives
43107
* `parallel` directive:
44108
* use without clauses
45109
* data attributes:
46110
* implicit `copy` for non-scalars
47111
* implicit `firstprivate` for scalars
48-
* For `copy`, `copyin`, and `copyout` clauses and
112+
* For `present`, `copy`, `copyin`, and `copyout` clauses and
49113
their aliases, support is the same as for the `data`
50114
directive, as described above.
51115
* `firstprivate` clause
@@ -288,3 +352,26 @@ Clacc matures. Please report any cases not listed below.
288352
class to something more general like `ArrayRangeExpr` or
289353
`ArraySubscriptExtendedExpr`. See the todo on this class in the
290354
implementation.
355+
* OpenMP runtime error diagnostics are expressed in terms of OpenMP
356+
not OpenACC.
357+
358+
OpenMP Extensions
359+
=================
360+
361+
There are some OpenACC features for which Clacc depends on OpenMP
362+
extensions because we are not aware of standard OpenMP features that
363+
are sufficient. While this dependence should not affect traditional
364+
compilation using Clacc's compiler and OpenACC/OpenMP runtime, it can
365+
affect compilation using Clacc's source-to-source mode followed by a
366+
foreign OpenMP compiler or runtime. A goal of Clacc is to rely on
367+
standard OpenMP as much as possible, and to that end it might be
368+
worthwhile to propose these extensions for inclusion in the OpenMP
369+
specification. Currently, Clacc uses OpenMP extensions as follows:
370+
371+
* The `present` clause translation depends on the OpenMP TR8 map type
372+
modifier `present` by default:
373+
* See the discussion of the `present` clause above for details.
374+
* Some features of the OpenACC Profiling Interface depend on OMPT
375+
extensions:
376+
* See the section "OpenACC Profiling Interface" in
377+
`README-OpenACC-design.md` for details.

clang/include/clang/AST/OpenACCClause.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ class ACCClause {
8787
SourceLocation getBeginLoc() const { return StartLoc; }
8888
/// Returns the ending location of the clause.
8989
SourceLocation getEndLoc() const { return EndLoc; }
90+
/// Returns the source range of the clause.
91+
SourceRange getSourceRange() const { return SourceRange(StartLoc, EndLoc); }
9092

9193
typedef StmtIterator child_iterator;
9294
typedef ConstStmtIterator const_child_iterator;
@@ -244,6 +246,70 @@ class ACCNomapClause final
244246
}
245247
};
246248

249+
/// This represents the clause 'present' (or any of its aliases) for
250+
/// '#pragma acc ...' directives.
251+
///
252+
/// \code
253+
/// #pragma acc parallel present(a,b)
254+
/// \endcode
255+
/// In this example directive '#pragma acc parallel' has clause 'present' with
256+
/// the variables 'a' and 'b'.
257+
class ACCPresentClause final
258+
: public ACCVarListClause<ACCPresentClause>,
259+
private llvm::TrailingObjects<ACCPresentClause, Expr *> {
260+
friend TrailingObjects;
261+
friend ACCVarListClause;
262+
friend class ACCClauseReader;
263+
264+
/// Build clause with number of variables \a N.
265+
///
266+
/// \param Determination How the clause was determined.
267+
/// \param StartLoc Starting location of the clause.
268+
/// \param LParenLoc Location of '('.
269+
/// \param EndLoc Ending location of the clause.
270+
/// \param N Number of the variables in the clause.
271+
ACCPresentClause(OpenACCDetermination Determination, SourceLocation StartLoc,
272+
SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N)
273+
: ACCVarListClause<ACCPresentClause>(ACCC_present, Determination,
274+
StartLoc, LParenLoc, EndLoc, N)
275+
{}
276+
277+
/// Build an empty clause.
278+
///
279+
/// \param N Number of variables.
280+
explicit ACCPresentClause(unsigned N)
281+
: ACCVarListClause<ACCPresentClause>(ACCC_present, N) {
282+
}
283+
284+
public:
285+
/// Creates clause with a list of variables \a VL.
286+
///
287+
/// \param C AST context.
288+
/// \param Determination How the clause was determined.
289+
/// \param StartLoc Starting location of the clause.
290+
/// \param LParenLoc Location of '('.
291+
/// \param EndLoc Ending location of the clause.
292+
/// \param VL List of references to the variables.
293+
static ACCPresentClause *Create(
294+
const ASTContext &C, OpenACCDetermination Determination,
295+
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
296+
ArrayRef<Expr *> VL);
297+
/// Creates an empty clause with the place for \a N variables.
298+
///
299+
/// \param C AST context.
300+
/// \param N The number of variables.
301+
static ACCPresentClause *CreateEmpty(const ASTContext &C, unsigned N);
302+
303+
child_range children() {
304+
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
305+
reinterpret_cast<Stmt **>(varlist_end()));
306+
}
307+
308+
static bool classof(const ACCClause *T) {
309+
return T->getClauseKind() == ACCC_present;
310+
}
311+
};
312+
247313
/// This represents the clause 'copy' (or any of its aliases) for
248314
/// '#pragma acc ...' directives.
249315
///

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3622,6 +3622,12 @@ bool RecursiveASTVisitor<Derived>::VisitACCNomapClause(ACCNomapClause *C) {
36223622
return true;
36233623
}
36243624

3625+
template <typename Derived>
3626+
bool RecursiveASTVisitor<Derived>::VisitACCPresentClause(ACCPresentClause *C) {
3627+
TRY_TO(VisitACCClauseList(C));
3628+
return true;
3629+
}
3630+
36253631
template <typename Derived>
36263632
bool RecursiveASTVisitor<Derived>::VisitACCCopyClause(ACCCopyClause *C) {
36273633
TRY_TO(VisitACCClauseList(C));

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,7 @@ def OpenMP : DiagGroup<"openmp", [
11131113
// OpenACC warnings.
11141114
def SourceUsesOpenACC : DiagGroup<"source-uses-openacc">;
11151115
def OpenACCIgnoredClause : DiagGroup<"openacc-ignored-clause">;
1116+
def OpenACCOMPMapPresent : DiagGroup<"openacc-omp-map-present">;
11161117

11171118
// Backend warnings.
11181119
def BackendInlineAsm : DiagGroup<"inline-asm">;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10368,6 +10368,17 @@ def note_acc_implied_as_gang_reduction : Note<
1036810368
"implied as gang reduction here">;
1036910369
def err_acc_no_data_clause : Error<
1037010370
"expected at least one data clause for '#pragma acc %0'">;
10371+
def warn_acc_omp_map_present : Warning<
10372+
"the OpenACC '%0' clause translation uses the 'present' map type modifier, "
10373+
"which is an OpenMP TR8 feature that might not be supported yet by other "
10374+
"compilers">,
10375+
InGroup<OpenACCOMPMapPresent>, DefaultIgnore;
10376+
def note_acc_alternate_omp : Note<
10377+
"an alternative OpenMP translation can be specified with, for example, "
10378+
"'-fopenacc-%0-omp=%1'">;
10379+
def note_acc_disable_diag : Note<
10380+
"or you can just disable this diagnostic with "
10381+
"'-Wno-openacc-omp-map-present'">;
1037110382
} // end of OpenACC category
1037210383

1037310384
let CategoryName = "Related Result Type Issue" in {

clang/include/clang/Basic/LangOptions.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ LANGOPT(OpenMPCUDABlocksPerSM , 32, 0, "Number of blocks per SM for CUDA device
231231
LANGOPT(OpenMPCUDAReductionBufNum , 32, 1024, "Number of the reduction records in the intermediate reduction buffer used for the teams reductions.")
232232
LANGOPT(OpenMPOptimisticCollapse , 1, 0, "Use at most 32 bits to represent the collapsed loop nest counter.")
233233
LANGOPT(OpenACC , 1, 0, "OpenACC support")
234+
ENUM_LANGOPT(OpenACCPresentOMP, OpenACCPresentOMPKind, 1,
235+
OpenACCPresentOMP_Present,
236+
"The OpenMP translation of the OpenACC 'present' clause")
234237
LANGOPT(RenderScript , 1, 0, "RenderScript")
235238

236239
LANGOPT(CUDAIsDevice , 1, 0, "compiling for CUDA device")

clang/include/clang/Basic/LangOptions.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,21 @@ class LangOptions : public LangOptionsBase {
108108
DCC_RegCall
109109
};
110110

111+
enum OpenACCPresentOMPKind {
112+
OpenACCPresentOMP_Present,
113+
OpenACCPresentOMP_Alloc,
114+
OpenACCPresentOMP_Last = OpenACCPresentOMP_Alloc
115+
};
116+
static StringRef getOpenACCPresentOMPValue(OpenACCPresentOMPKind K) {
117+
switch (K) {
118+
case OpenACCPresentOMP_Present:
119+
return "present";
120+
case OpenACCPresentOMP_Alloc:
121+
return "alloc";
122+
}
123+
llvm_unreachable("unexpected OpenACCPresentOMPKind");
124+
}
125+
111126
enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
112127

113128
// Corresponds to _MSC_VER

0 commit comments

Comments
 (0)