Clarification on DO CONCURRENT

Just because the description of unspecified locality bears some similarity to LOCAL locality, that doesn’t make them the same. When DO CONCURRENT was first introduced in F2008, there was no concept of locality in the standard. This got added in F2018. The current words about “unspecified locality” applied, in F2008, to all variables in an iteration. At the time, the thought was that compilers could figure out on their own whether a variable was local or shared, and compilers tried to do that but didn’t always get it right. Mirroring OpenMP, F2018 added locality clauses to allow the programmer to specify what was meant.

That INTENT(IN) dummy arguments can’t be LOCAL is irrelevant.

However… I find myself disagreeing with Intel regarding this case. The standard says “if it is referenced in an iteration it shall either be previously defined during that iteration, or shall not be defined or become undefined during any other iteration;”. That “or” is significant. a is not “previously defined” in any iteration, but neither is it “defined or become defined during any other iteration.” Therefore, the reference to a meets the requirements for unspecified locality, the example is conforming, and should produce the result you want.

I find it interesting that adding -qopenmp changes the behavior, because this source does not use any OpenMP features. Yes, ifort uses OpenMP to parallelize a DO CONCURRENT, but if I build with -qparallel, I get the “correct” answer. (With this example, -qparallel doesn’t parallelize because the compiler thinks there is insufficient work - reasonable.)

Note that the following modification does produce the desired result:

  function b(a)

    integer, dimension(2,2) :: b
    integer, intent(in), dimension(2) :: a
    integer, dimension(2) :: a2
    integer :: i,j

    a2 = a
    do concurrent(i=1:2, j=1:2)
      b(i,j) = a2(2) * i * j
    enddo

  end function b

I don’t see any functional difference between these two cases, and see no reason why simply adding -qopenmp should change the result. (In the past, one could sometimes blame that on this implicitly making all procedures recursive, but in the 2021 compiler, RECURSIVE is the default (since that’s F2018.)

6 Likes