Hi,
atomic_capture-1.c contains the following bit:
...
fgot = 1.0;
fexp = 0.0;
#pragma acc data copy (fgot, fdata[0:N])
{
#pragma acc parallel loop
for (i = 0; i < N; i++)
{
float expr = 32.0;
#pragma acc atomic capture
fdata[i] = fgot = expr - fgot;
}
}
for (i = 0; i < N; i++)
if (i % 2 == 0)
{
if (fdata[i] != 31.0)
abort ();
}
else
{
if (fdata[i] != 1.0)
abort ();
}
...
The problem here is that the checking code assumes that the atomic
operations execute in a certain order, while that is not guaranteed by
the openacc standard.
This check happens to pass for nvptx accelerator, but not for gcn
accelerator.
Fixed by Julian's patch below, which makes the check order-independent.
Tested on x86_64 with nvptx accelerator.
Committed to trunk.
Thanks,
- Tom
[openacc, testsuite] Fix undefined behaviour in atomic_capture-1.c
2018-04-29 Julian Brown <jul...@codesourcery.com>
Tom de Vries <t...@codesourcery.com>
PR testsuite/85527
* testsuite/libgomp.oacc-c-c++-common/atomic_capture-1.c: Allow
arbitrary order for iterations of atomic subtract check.
---
.../libgomp.oacc-c-c++-common/atomic_capture-1.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/atomic_capture-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/atomic_capture-1.c
index ad958cd..9b71a08 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/atomic_capture-1.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/atomic_capture-1.c
@@ -795,17 +795,16 @@ main(int argc, char **argv)
}
}
+ int ones = 0, thirtyones = 0;
+
for (i = 0; i < N; i++)
- if (i % 2 == 0)
- {
- if (fdata[i] != 31.0)
- abort ();
- }
- else
- {
- if (fdata[i] != 1.0)
- abort ();
- }
+ if (fdata[i] == 31.0)
+ thirtyones++;
+ else if (fdata[i] == 1.0)
+ ones++;
+
+ if (ones != N / 2 || thirtyones != N / 2)
+ abort ();
/* BINOP = / */