Observed issues › nested/gcc-c-declare-mapper-pointer-member-section-gpu-fault
GCC: declare mapper with a pointer-member section faults on the GPU
Legality: independently confirmed. 2 independent readings find the program legal and the result required. How this is checked
GCC kernels fault when a declare mapper maps a section of a pointer member.
Affected variants
| Compiler | MI300A gfx942 unified memory (XNACK 1) | MI300A gfx942 copy (XNACK 0) | MI250X gfx90a copy (XNACK 0) | MI300X gfx942 copy (XNACK 0) | MI350X gfx950 copy (XNACK 0) | A100 sm_80 separate memory | A100 sm_80 managed memory |
|---|---|---|---|---|---|---|---|
| AFAR 24.3.0 | correct | correct | unknown not run | correct | correct | n/a | n/a |
| CCE 19.0.0 | correct | correct | unknown not run | unknown not run | unknown not run | n/a | n/a |
| CCE 20.0.2 | correct | correct | unknown not run | unknown not run | unknown not run | n/a | n/a |
| CCE 21.0.3 | correct | correct | unknown not run | unknown not run | unknown not run | n/a | n/a |
| CCE 21.0.4 | correct | correct | unknown not run | unknown not run | unknown not run | n/a | n/a |
| NVHPC 25.11 | n/a | n/a | n/a | n/a | n/a | fails another way | fails another way |
| NVHPC 26.9 | n/a | n/a | n/a | n/a | n/a | fails another way | fails another way |
| GCC 16.2.0 | correct | unknown varies between runs | behaves incorrectly | correct | correct | behaves incorrectly | n/a |
"behaves incorrectly" / "not supported": this issue, confirmed in up to four environments (another build directory, another node, a repeat). "fails another way": a different failure, not counted as this issue. "unknown": not run there, or the runs disagree.
Messages
| Result | Compiler and GPU | Message |
|---|---|---|
| behaves incorrectly | GCC 16.2.0, MI250X | showMemory access fault by GPU node-4 (Agent handle: 0x794640) on address 0xbed000. Reason: Unknown. |
| behaves incorrectly | GCC 16.2.0, A100 separate | showlibgomp: cuCtxSynchronize error: an illegal memory access was encountered libgomp: cuModuleGetFunction (__do_global_dtors__entry) error: an illegal memory access was encountered libgomp: cuMemFree_v2 error: an illegal memory access was encountered libgomp: device finalization failed |
| fails another way | NVHPC 25.11, A100 separate NVHPC 25.11, A100 managed NVHPC 26.9, A100 separate NVHPC 26.9, A100 managed | show"site-nested--gcc-c-declare-mapper-pointer-member-section-gpu-fault.c", line 38: error: invalid text in pragma
#pragma omp declare mapper(struct n0 v) map(tofrom: v) map(tofrom: v.a[0:NM])
^
1 error detected in the compilation of "site-nested--gcc-c-declare-mapper-pointer-member-section-gpu-fault.c". |
Reproduce
GCC 16.2.0, MI250X
export LD_LIBRARY_PATH=$GCC_16_2/lib64:/opt/rocm-7.2.1/lib $GCC_16_2/bin/gcc -fopenmp -foffload=amdgcn-amdhsa -foffload-options=amdgcn-amdhsa=-march=gfx90a -O2 repro.c -o repro HSA_XNACK=0 OMP_TARGET_OFFLOAD=mandatory ./repro
GCC 16.2.0, A100 separate
export PATH=/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH=$GCC_16_2/lib64 $GCC_16_2/bin/gcc -fopenmp -foffload=nvptx-none -foffload-options=nvptx-none=-march=sm_80 -foffload-options=nvptx-none=-latomic -O2 repro.c -o repro OMP_TARGET_OFFLOAD=mandatory ./repro
AFAR 24.3.0, MI300A unified (runs correctly)
$AFAR/bin/amdclang -fopenmp --offload-arch=gfx942 -O2 repro.c -o repro HSA_XNACK=1 OMP_TARGET_OFFLOAD=mandatory ./repro
Program (86 lines)
// # Finding (nested-data): GCC: a declare mapper for a structure with a pointer member that maps a section of the pointee makes
// # the kernel fault on the GPU
//
// - toolchains and modes that fail: gcc_g90 (GCC 16.2.0), gcc_sm80 (GCC 16.2.0); modes: copy; -O2
// - build: gcc -fopenmp -foffload=amdgcn-amdhsa -foffload-options=amdgcn-amdhsa=-march=gfx90a -O2 (gcc_g90); gcc -fopenmp
// -foffload=nvptx-none -foffload-options=nvptx-none=-march=sm_80 -foffload-options=nvptx-none=-latomic -O2 (gcc_sm80)
// - failure: crash
// - observed: `Memory access fault by GPU node-4 (Agent handle: 0x794640) on address 0xbed000. Reason: Unknown.` (killed by signal
// 6); identical signature on 1 of 2 failing cells (gcc_sm80 on a100-s: `libgomp: cuCtxSynchronize error: an illegal memory access
// was encountered` differ)
// - counted as this failure: gcc_sm80 (GCC 16.2.0): on the A100 the CUDA runtime reports the same dereference of the unattached
// pointer as an illegal memory access (libgomp: cuCtxSynchronize error, exit status 1) where the HSA runtime on the MI250X aborts
// with a GPU memory access fault; one defect, reported differently by the two runtimes (50 of 50 repeat runs fail on the A100,
// data/reports/nested-visibility/wt_repeat.log)
// - expected: compiles and prints `ha= 4028` with `check=pass`
// - rule: OpenMP 5.2 §5.8.8 p.164 l.1-2: "All map clauses that are introduced by a mapper are further subject to mappers
// that are in scope, except a map clause with list item var maps var without invoking a mapper": the mapper maps the
// structure and a section of its pointer member, and a map(tofrom: r) applies it; the expected result relies on the
// mapper attaching that section to the device copy of r (inside the region r.a must refer to the device copy of
// r.a[0:NM])
// - same-compiler control: controls/gp2-ctl-no-mapper-explicit-maps.c (one change from this file; correct on gcc_g90 (GCC 16.2.0),
// gcc_sm80 (GCC 16.2.0); rows results/nested/red/red15.jsonl, results/nested/red/tuo22.jsonl, results/nested/red/tuo23.jsonl,
// results/nested/red/wgs2.jsonl, results/nested/red/wnv2.jsonl)
// - other families: afar (AFAR 24.3.0), cce19 (CCE 19.0.0), cce20 (CCE 20.0.2), cce21 (CCE 21.0.3), cce21_4 (CCE 21.0.4) run the
// file correctly (rows results/nested/red/tuo23.jsonl, site rows, check case
// site-nested--gcc-c-declare-mapper-pointer-member-section-gpu-fault); nvhpc (NVHPC 25.11), nvhpc269 (NVHPC 26.9) fail it another
// way, e.g. `"site-nested--gcc-c-declare-mapper-pointer-member-section-gpu-fault.c", line 38: error: invalid text in pragma`
// - gate and confirmer: campaign gate of the programs below: 44 cells, 43 confirmed in the four environments (a-d; (c) on another
// node or GPU; rows results/nested/big/gate_reruns.part.<host>.1371141.jsonl,
// results/nested/big/gate_reruns.part.<host>.517665.jsonl,
// results/nested/big/gate_reruns.part.wingtip.501872.jsonl,
// results/nested/big/gate_reruns.part.wingtip.501873.jsonl,
// results/nested/big/gate_reruns.part.wingtip.711615.jsonl,
// results/nested/big/gate_reruns.part.wingtip.724122.jsonl, results/nested/big/rows.part.<host>.397000.jsonl,
// results/nested/big/rows.part.wingtip.3886921.jsonl,
// results/nested/main/gate_reruns.part.<host>.2711328.jsonl, results/nested/main/gate_reruns.part.<host>.351539.jsonl,
// results/nested/main/gate_reruns.part.wingtip.3582436.jsonl,
// results/nested/main/gate_reruns.part.wingtip.3582437.jsonl,
// results/nested/main/gate_reruns.part.wingtip.3637854.jsonl,
// results/nested/main/gate_reruns.part.wingtip.3639010.jsonl,
// results/nested/main/rows.part.<host>.2691037.jsonl, results/nested/main/rows.part.wingtip.3363229.jsonl,
// results/nested/main/rows.part.wingtip.3363230.jsonl)
// - programs (23): nd-c-omp-mapper-chain-d1-f314e872, nd-c-omp-mapper-chain-d2-647b801f, nd-c-omp-mapper-chain-d2-6cace278,
// nd-c-omp-mapper-chain-d2-724db78d, nd-c-omp-mapper-chain-d2-75564642, nd-c-omp-mapper-chain-d2-95162abf,
// nd-c-omp-mapper-chain-d2-9525642f, nd-c-omp-mapper-chain-d2-aa6b2219, nd-c-omp-mapper-chain-d2-b7881884,
// nd-c-omp-mapper-chain-d2-dbed9877, nd-c-omp-mapper-chain-d2-e3b718a2, nd-c-omp-mapper-chain-d3-12f05097,
// nd-c-omp-mapper-chain-d3-1eb36c71, nd-c-omp-mapper-chain-d3-70dd651f, nd-c-omp-mapper-chain-d3-ec8da702,
// nd-c-omp-mapper-chain-d4-0eb32acd, nd-c-omp-mapper-chain-d4-36e66203, nd-c-omp-mapper_enter-chain-d1-dc9d313d,
// nd-c-omp-mapper_enter-chain-d2-07229cfd, nd-c-omp-mapper_enter-chain-d2-df4f2688, nd-c-omp-mapper_enter-chain-d3-09a92f8a,
// nd-c-omp-mapper_enter-chain-d3-7babd15f, nd-c-omp-mapper_enter-chain-d3-ec1b1655
// - run condition: on gfx90a the GPU fault shows with all eight MI250X GCDs of the node visible to the program
// (ROCR_VISIBLE_DEVICES unset: the nested campaign's and the gate's run environment): 20 of 20 repeat runs on <host>
// and <host> (2026-11-03), and the campaign program nd-c-omp-mapper-chain-d2-647b801f 10 of 10. With a single GCD
// visible (the site matrix pinned one GPU per run) the same binary completes with the correct sum in 40 of 40 runs,
// environments a-d on two nodes, on every GCD 0-7, and so does the campaign program; two GCDs visible fault 15 of 15,
// four pass 10 of 10. The control passes either way (10 of 10 with all eight visible). The visible set changes the
// host address layout after HSA initialization and nothing else, so in both outcomes the device dereferences the host
// address of r.a, which the mapper did not attach: the fault and the silently right sum are how that one missing
// mapping surfaces, not two defects. The A100 build fails 50 of 50 runs whatever is visible. The site matrix therefore
// runs this case with every device visible on the gfx90a toolchain (the site block's devices line). Logs and scripts:
// data/reports/nested-visibility/
// - legality: the rules (offload.engine.rules) accept it; AFAR and CCE compile and run it correctly (front ends of two other
// families); NVHPC does not accept the directive in C
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
enum { NM = 8 };
struct n0 { int s; int *a; };
#pragma omp declare mapper(struct n0 v) map(tofrom: v) map(tofrom: v.a[0:NM])
int main(void)
{
int hf = 1, i, ha = 0, ok;
struct n0 r = {0};
#pragma omp target map(from: hf)
hf = omp_is_initial_device() ? 1 : 0;
r.a = malloc(NM * sizeof(int));
r.s = 10;
for (i = 0; i < NM; i++) r.a[i] = 100 + i;
#pragma omp target teams distribute parallel for map(tofrom: r)
for (int q = 0; q < NM; q++) r.a[q] = 500 + q;
for (i = 0; i < NM; i++) ha += r.a[i];
ok = ha == 4028;
printf("ha= %d\n", ha);
printf("RESULT ran_on_host=%d check=%s\n", hf, ok ? "pass" : "fail");
return 0;
}
Something to add? Dispute its legality · Report it fixed in a newer release · Report a mistake on this page
Expected and observed
Observed where it behaves incorrectly
Memory access fault by GPU node-4 (Agent handle: 0x794640) on address 0xbed000. Reason: Unknown.
What the specification requires
The specification text this program relies on and the compiler is expected to support.
OpenMP 5.2 §5.8.8 p.164 l.1-2
All map clauses that are introduced by a mapper are further subject to mappers that are in scope, except a map clause with list item var maps var without invoking a mapper
Evidence
Same compiler, one change
- one change from the finding; correct on gcc_g90, gcc_sm80: not run yet
Control program
// control: no mapper, the same two list items in the map clauses #include <stdio.h> #include <stdlib.h> #include <omp.h> enum { NM = 8 }; struct n0 { int s; int *a; }; int main(void) { int hf = 1, i, ha = 0, ok; struct n0 r = {0}; #pragma omp target map(from: hf) hf = omp_is_initial_device() ? 1 : 0; r.a = malloc(NM * sizeof(int)); r.s = 10; for (i = 0; i < NM; i++) r.a[i] = 100 + i; #pragma omp target teams distribute parallel for map(tofrom: r) map(tofrom: r.a[0:NM]) for (int q = 0; q < NM; q++) r.a[q] = 500 + q; for (i = 0; i < NM; i++) ha += r.a[i]; ok = ha == 4028; printf("ha= %d\n", ha); printf("RESULT ran_on_host=%d check=%s\n", hf, ok ? "pass" : "fail"); return 0; }
Other compilers run it correctly
AFAR 24.3.0, CCE 19.0.0, CCE 20.0.2, CCE 21.0.3, CCE 21.0.4