Am 17.06.26 um 11:09 AM schrieb Richard Biener:
On Wed, Jun 17, 2026 at 10:57 AM Dhruv Chawla <[email protected]> wrote:

On 17/06/26 14:03, Kyrylo Tkachov wrote:
Yes, that is what it turned out to be - a caller-allocated stack array
used as return storage for a callee (`compute` in the test case) got
hoisted outside the loop (as its address was loop-invariant for a
single thread), so multiple threads ended up writing to the same address
thus leading to garbage output. This doesn't occur in the pot3d function,
so it is safe to ignore this bug.

But it must be possible to classify a conservatively safe subset of
do concurrent loops from inside the frontend?  I'd really prefer that.

I do also see the data race for the temporary for the array-valued
function result of compute with -fsanitize=thread, which does not
occur when I use an ordinary OpenMP do loop instead of do concurrent.

So how does OpenMP annotate the temporary (it should be PRIVATE)?
And can this be used to annotate frontend-generated temporaries
for the auto-parallelizer?

(BTW: the testcase runs a factor of 10 faster for me when I replace

     tmp(k) = tmp(k) + (-1.0_real64)**(j+1) / real( 2*j-1 )

by

     tmp(k) = tmp(k) + (-1)**(j+1) / real( 2*j-1, real64)

because the power of integer (-1) is expanded inline.)

autopar is essentially unmaintained ... but clearly the can_be_parallel
flag isn't correct for the IL as-is?  While I looked into autpar years
ago I don't remember much in what guarantees it makes, but I think
all of the safety is with the dependence analysis we skip with
can_be_parallel annotated loops.

I think the loop is fine (Fortran-wise).

I also tried to use an explicit temporary and making compute
a subroutine, like

...
  real(real64), dimension(nsplit) :: mytmp
...
  do concurrent (i = 1:nsplit) local (mytmp)
     call compute( low(i), high(i) , mytmp)
     pi(i) = sum (mytmp)
  end do

This avoids frontend-generated temporaries, but still has the same
data race.

Cheers,
Harald


Reply via email to