Clarification on DO CONCURRENT

There is non mention on the standard of threads, even though both ifort and ifx need the -qopenmp option, and clearly ifort uses (wrongly) multiple threads.

But, as the phrasing is similar to that used in openmp, who wrote the standard was thinking about threads and on how to make easier for the compiler to parallelize a do concurrent.

do concurrent is not related to coarrays, that is the way to achieve parallelism in Fortran with multiple images and share memory between these images (not really share, as the share concept is not present in the standard).

It implies nothing. The compiler is free to execute a classical do loop, a classical do loop but out of order, to launch thread with OpenMP or any other API, to launch new processes with MPI or whatever…

The equivalent OpenMP code would rather be with aa = a*2, not aa = a*2**i, as in the do concurrent version a is reset to the global value at the begining of each iteration.

My apologies for not understanding the new standard, although I do find this approach a bit baffling.
Why introduce this “local_init(a)” approach when using “aa = a*2” would be less confusing to Fortran users.
Is this an unnecessary change to Fortran ?

This avoids declaring an new variable, but the point is also that this is just an example to illustrate how it works, and which is well simpler than many usage cases.

You could also argue that the OpenMP firstprivate is useless for the very same reason.

@PierU
Firstprivate does have a use in OMP PARALLEL DO for initialising private copies.

If I understand your explanation, I am struggling to understand why “local_init(a)” is defined as re-setting the value of “a” for each itteration of the DO CONCURRENT.
There is no other construct in Fortran, so makes a very significant change to the way DO loops are approached. I think this is a very unnecessary change to the concept of a Fortran loop, with so little gain. Using aa = a*2 is a much easier and Fortran compatible approach.

I just wonder how this concept was introduced into the Fortran standard.

Or have I misunderstood your description ?

Indeed, but firstprivate(a) could be replaced by

!$OMP PARALLEL PRIVATE(aa)
aa = 2*a
...

Does gfortran support SHARED, LOCAL_INIT, LOCAL within the do concurrent construct? I’ve tested do concurrent using gfortran, ifx, ifort, and nvfortran, and it seems that they might not be implemented in gfortran.

As of gfortran 13.2, it does not:

$ gfortran do_concurr.f90
do_concurr.f90:6:28:

    6 |     do concurrent(i = 1:NP) local_init(a)
      |                            1
Error: Syntax error in DO statement at (1)
1 Like

Just as a followup to my March 2022 reply, Intel’s LLVM-based ifx compiler does not support -parallel at all. It will (attempt to) parallelize DO CONCURRENT if you enable OpenMP, even if you don’t use OpenMP otherwise.

1 Like

GFortran does not support the locality specifiers. There are two feature requests for this in the GCC database: 101602 – [F2018] local and local_init are not supported in DO CONCURRENT and 106005 – (F2023) Support for REDUCE clause in DO CONCURRENT loop.

OpenMP PRIVATE and FIRSTPRIVATE are different from DO CONCURRENT LOCAL and LOCAL_INIT. Like mentioned before OpenMP data-sharing attributes privatize per thread, while DO CONCURRENT privatizes per iteration. OpenMP’s specification is clear about that a thread receives such a private copy (with initialization in case of FIRSTPRIVATE). DO CONCURRENT on the other had does not have the notion of threads. It just says the loop can be executed in any order. So, you cannot assume that there are even threads (and how many of them) or some other form of concurrency (like SIMD). So, LOCAL_INIT has to re-init the variable for every iteration as this is the only way to have a well-defined definition of the variable in the loop body for all different concurrent execution mechanisms.

As side note: when implementing this on top of OpenMP, one can actually map LOCAL init to PRIVATE, as the a value from a previously executed iteration can viewed as some random, uninitialized value. For LOCAL_INIT, the closest OpenMP correspondence would be LINEAR(variable:0).

1 Like

To be honest, adding the locality specifiers was supposed to be part of my GSOC project last year :joy: