Skip to content

Commit 6c87019

Browse files
engineer-scientistclaudesbryngelson
authored
1687 fix: Make OpenMP no_create a documented no-op instead of aborting fypp. (#1724)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Spencer Bryngelson <sbryngelson@gmail.com>
1 parent 2ba5c23 commit 6c87019

2 files changed

Lines changed: 34 additions & 8 deletions

File tree

‎docs/documentation/gpuParallelization.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ This wraps the lines in `code` with parallelization calls to openACC or openMP,
7373
| `copyinReadOnly` | string list | None | Allocates and copies readonly data to GPU and then deallocated on exit |
7474
| `copyout` | string list | None | Allocates data on GPU on entrance and then deallocates and copies to CPU on exit |
7575
| `create` | string list | None | Allocates data on GPU on entrance and then deallocates on exit |
76-
| `no_create` | string list | None | Use data in CPU memory unless data is already in GPU memory |
76+
| `no_create` | string list | None | Use data in CPU memory unless data is already in GPU memory (OpenACC only) |
7777
| `present` | string list | None | Data that must be present in GPU memory. Increment counter on entrance, decrement on exit |
7878
| `deviceptr` | string list | None | Pointer variables that are already allocated on GPU memory |
7979
| `attach` | string list | None | Attaches device pointer to device targets on entrance, then detach on exit |
@@ -184,7 +184,7 @@ Uses FYPP call directive using `#:call`
184184
| `copyinReadOnly` | string list | None | Allocates and copies readonly data to GPU and then deallocated on exit |
185185
| `copyout` | string list | None | Allocates data on GPU on entrance and then deallocates and copies to CPU on exit |
186186
| `create` | string list | None | Allocates data on GPU on entrance and then deallocates on exit |
187-
| `no_create` | string list | None | Use data in CPU memory unless data is already in GPU memory |
187+
| `no_create` | string list | None | Use data in CPU memory unless data is already in GPU memory (OpenACC only) |
188188
| `present` | string list | None | Data that must be present in GPU memory. Increment counter on entrance, decrement on exit |
189189
| `deviceptr` | string list | None | Pointer variables that are already allocated on GPU memory |
190190
| `attach` | string list | None | Attaches device pointer to device targets on entrance, then detach on exit |
@@ -247,7 +247,7 @@ Uses FYPP call directive using `#:call`
247247
| `copyinReadOnly` | string list | None | Allocates and copies a readonly variable to GPU and then deallocated on exit |
248248
| `copyout` | string list | None | Allocates data on GPU on entrance and then deallocates and copies to CPU on exit |
249249
| `create` | string list | None | Allocates data on GPU on entrance and then deallocates on exit |
250-
| `no_create` | string list | None | Use data in CPU memory unless data is already in GPU memory |
250+
| `no_create` | string list | None | Use data in CPU memory unless data is already in GPU memory (OpenACC only) |
251251
| `present` | string list | None | Data that must be present in GPU memory. Increment counter on entrance, decrement on exit |
252252
| `deviceptr` | string list | None | Pointer variables that are already allocated on GPU memory |
253253
| `attach` | string list | None | Attaches device pointer to device targets on entrance, then detach on exit |

‎src/common/include/omp_macros.fpp‎

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,14 @@
6767
#:enddef
6868

6969
#:def OMP_NOCREATE_STR(no_create)
70-
#:if no_create is not None
71-
#:stop 'no_create is not supported yet'
72-
#:endif
70+
#! OpenMP has no no_create equivalent, so this is a documented no-op: the variable is
71+
#! left to whatever mapping the enclosing region already applies to it. Note that is
72+
#! NOT equivalent to no_create on most targets -- OMP_DEFAULT_STR emits nothing unless
73+
#! the caller passes default='present', and even then only CCE maps allocatables and
74+
#! pointers as present; NVHPC/PGI and the fallback map them tofrom, which copies rather
75+
#! than reuses, and LLVMFlang emits nothing at all.
76+
#! Do NOT #:stop here: GPU_DATA expands both backends before #if selects one, so
77+
#! aborting would break OpenACC builds, where no_create is supported natively.
7378
#:set no_create_val = ''
7479
$:no_create_val
7580
#:enddef
@@ -275,11 +280,32 @@
275280
& no_create_val.strip('\n') + present_val.strip('\n') + &
276281
& deviceptr_val.strip('\n') + attach_val.strip('\n') + &
277282
& default_val.strip('\n')
283+
#! An OpenMP `target data` region must carry at least one map, use_device_ptr or
284+
#! use_device_addr clause. no_create contributes none (it is a no-op here), and
285+
#! `default` is None by default, so GPU_DATA(no_create=x) with no other clause left
286+
#! clause_val empty and emitted a bare `!$omp target data` that no compiler accepts.
287+
#! Emit the body alone in that case -- a data region with nothing to map has nothing
288+
#! to do, which is what GPU_DATA's own #else branch already does when neither backend
289+
#! is enabled. A #:stop is not an option here, for the reason in OMP_NOCREATE_STR.
290+
#! Only no_create earns that silence. If the caller asked for some other clause and
291+
#! the backend produced nothing for it -- default='present' on LLVMFlang, where
292+
#! OMP_DEFAULT_STR returns an empty string -- keep emitting the bare directive so the
293+
#! build fails loudly rather than silently discarding a region that was asked for.
294+
#:set other_clause_requested = copy is not None or copyin is not None or &
295+
& copyinReadOnly is not None or copyout is not None or create is not None or &
296+
& present is not None or deviceptr is not None or attach is not None or &
297+
& default is not None
298+
#:set emitted_clause = clause_val.strip() != '' or extraOmpArgs_val.strip() != ''
299+
#:set has_clauses = emitted_clause or other_clause_requested
278300
#:set omp_directive = '!$omp target data ' + clause_val + extraOmpArgs_val.strip('\n')
279301
#:set end_omp_directive = '!$omp end target data'
280-
$:omp_directive
302+
#:if has_clauses
303+
$:omp_directive
304+
#:endif
281305
$:code
282-
$:end_omp_directive
306+
#:if has_clauses
307+
$:end_omp_directive
308+
#:endif
283309
#:enddef
284310
285311
#:def OMP_ENTER_DATA(copyin=None, copyinReadOnly=None, create=None, attach=None, extraOmpArgs=None)

0 commit comments

Comments
 (0)