Possible bug in OpenMP code with shared DO-loop indices

Possible bug in OpenMP code with shared DO-loop indices

Let's start by saying that I regard this as a misdesign in OpenMP.  However, both gcc and Sun/Oracle disagree with Intel ifort.  NAG regards it as a user error.  However, my reading is that it is legal, and I quote the specification later.  No, I didn't write it, but it was written as a horrible example following a debate about what OpenMP actually permits.

Program ugh
  Use omp_lib
  Real x(200)
  Integer i
  i = 42
  !$OMP PARALLEL SHARED(i) NUM_THREADS(5)
    !$OMP SINGLE
      Do i=1,Size(x)
        x(i) = 0
      End Do
    !$OMP END SINGLE
    !$OMP CRITICAL
      Print *,omp_get_thread_num(),':',i
    !$OMP END CRITICAL
  !$OMP END PARALLEL
End Program

gfortran and Sun print 201, 5 times.  Intel prints 42, 5 times.

Let's use OpenMP 3.1, as I have it to hand.

2.9.1.1 page 85, lines 21-22 "Variables with predetermined data-sharing attributes may not be listed in data-sharing attribute clauses, except for the cases listed below."

2.9.1.1 page 86, lines 3-5 "Variables used as loop iteration variables in sequential loops in a parallel or task construct may be listed in data-sharing clauses on the construct itself, and on enclosed constructs, subject to other restrictions."

A.9 page 182 Example A.9.2f.

Comments (other than "Ugh"!) gratefully accepted!

7 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

What happens with:

...
end do
!$OMP FLUSH(I)
!$OMP END SINGLE

Jim Dempsey

www.quickthreadprogramming.com

I do not think the standard supports your code.  Looking at the referenced lines and reading that section of the standard it seems to me that

1) Iteration variables of DO or PARALLEL DO loops are predetermined as private (p 85 line 13)

2) Predetermined sharing may not be overridden (p 85 line 21)

3) Except (p 85 line 22)

4) Iteration variables in DO or PARALLEL DO constructs (p86 line 1)

5)Which can be listed as private or lastprivate (p86 line 2)

This says to me that yes, you may override the sharing attribute of "i" in your parallel block, but the only valid sharing attributes you may assign it are private and lastprivate.  The attribute shared is not supported by the standard.

With that said, the example in A.9 does use the shared attribute i that context (in a single block as you are no less), though it does disclaim it as and "exceptional case".  I'll have to try and reconcile that later.

I should also note, that your program as written has your Do loop being optimized out as a memset/memcpy by ifort.  However, using a modified loop that does get iterated does not change the results.

Sorry, but that loop is NOT a DO or PARALLEL DO construct, so page 86 lines 1-2 do not apply!  It's a sequential loop in a PARALLEL construct, and so lines 3-5 apply - I quoted them above.

To Jim Dempsey:  dunno, but there is supposed to be a barrier at the END SINGLE.  What I am interested in is Intel's view on whether this is valid or invalid - I think that we can agree that it is horrible.  In my course, I already say "Don't do this sort of thing!"

>> dunno, but there is supposed to be a barrier at the END SINGLE.

The explicit flush was suggested as test and work around for a potential bug in programming that manifests itself as releasing the threads upon satisfying the barrier condition but also while not having the cache system of all CPUs/Threads invalidated of line for i (after updating RAM by master thread of outer region). After more thought, should this situation have arisen, then the observaton would have been the master thread of the outer region showing the correct result (201), and the other team members showing different results, this was not the case.

I have not reproduced the error here, what happens is the loop control variable (and references in the loop) is changed to iZ, then after loop but inside single insert i=iZ?

In looking through the IVF document I found something that needs to be clarified (as it seems to be stated incorrectly):

Consider the following:

----------------- snip ------------------

!$OMP SECTIONS LASTPRIVATE(B)

!$OMP SECTION

      B = 2

!$OMP SECTION

      B = 4

!$OMP SECTION

      D = 6

!$OMP END SECTIONS

In this case the thread that executes the lexically last SECTION updates the original variable B to have a value of 4. However, variable D was not specified in the LASTPRIVATE clause, so it has an undefined value after the construct is exited.

------------ end snip ---------------

 IOW, the last section is executed without respect to order, but none the less is executed. If D is shared (default) then D ought to be defined (to 6) on exit of sections.

If this is an error in documentation, then please correct.

Jim Dempsey

www.quickthreadprogramming.com

Thanks.  Yes, but I worked around the original problem by writing even more defensive code!  What I am trying to do is to get another opinion on whether this is legal, illegal or well, eagle?  Consensus seems to be "ugh" :-(

With regard to your SECTIONS example, I agree - it would be different if D were accessed in another section (it wouldn't even need to be set).  But there is another misleading aspect: B could be set to 2 if the sections were executed in reverse order (as is allowed).

Faça login para deixar um comentário.