[J3] Question: Aliasing in Parallel Procedure Instances in OpenMP Parallel Regions
Jeff Hammond
jehammond at nvidia.com
Mon Feb 12 09:54:00 UTC 2024
I don’t think you should use the term UB here. In an ISO language context, UB means the implementation can launch nuclear weapons. In your example, without OpenMP, everything is fine. With OpenMP, it is inadequately specified behavior. I don’t think there’s anything wrong with it in practice unless the compiler decides to give each thread a private copy, since only one thread writes to the variable and there’s an OpenMP barrier between the write and the reads. I have a hard time imagining how a compiler would see shared(variable2) and create a copy, unless some members of the Fortran compiler team in question are not aware that OpenMP is supported.
Jeff
On 12. Feb 2024, at 11.43, Klemm, Michael <Michael.Klemm at amd.com> wrote:
External email: Use caution opening links or attachments
[AMD Official Use Only - General]
Hi Jeff, hi Reinhold,
Thanks for confirming by interpretation of the Fortran standard. 😊 I was one of the ones who argued that we’re outside of a well-defined Fortran world and thus are suffering from UB for the case I’m showing below. I will take this to the OpenMP ARB and implement a clarification about this.
Kind regards,
-michael
From: Bader, Reinhold <Reinhold.Bader at lrz.de>
Sent: Saturday, February 10, 2024 6:45 PM
To: General J3 interest list <j3 at mailman.j3-fortran.org>
Cc: Jeff Hammond <jehammond at nvidia.com>; Klemm, Michael <Michael.Klemm at amd.com>
Subject: AW: Question: Aliasing in Parallel Procedure Instances in OpenMP Parallel Regions
Hi Michael,
I agree with the below. Given the rules in section 15.5.2.14 of the current Fortran standard, you might consider adding language to OpenMP that states
* dummy arguments of procedures invoked within a currently executing threaded region that are associated with (part of the) same ultimate argument that is
shared are considered aliased. (This could of course even be different procedures, or even the procedure that declares the ultimate argument!).
This might require a rewording of the subsequent text to be put into the OpenMP standard of course, like “Action that affects the allocation status of the entity or a
subobject thereof shall be taken through the dummy argument.” --> like “Action that affects the allocation status of the entity or a subobject thereof
shall be taken on on at most one of the currently executing threads.”
* Some text corresponding to the exceptions in (3) and (4) will be needed (in analogy to (d) and (e), respectively). I would note that this was initially
overlooked by the Fortran committees, causing meaningful coarray library calls to be inadvertently non-conforming. See also NOTE 5, further below.
Also note that some of the exceptions in that section (e.g. those that refer to copy-in / copy-out situations) may cause additional complications – for such procedures,
procedure-internal OpenMP sync would likely be insufficient to avoid race conditions that arise upon copy-out; you need to require that OpenMP sync is done
on the procedure call.
(Looking at OpeMP 5.2, section 1.4.6, I see the wording “flush the same variable”. It might be easiest to add language-specific paragraphs in this section that clarify what
“same variable” means, accounting for the above.)
Regards,
Reinhold
Von: J3 <j3-bounces at mailman.j3-fortran.org<mailto:j3-bounces at mailman.j3-fortran.org>> Im Auftrag von Jeff Hammond via J3
Gesendet: Samstag, 10. Februar 2024 17:41
An: General J3 interest list <j3 at mailman.j3-fortran.org<mailto:j3 at mailman.j3-fortran.org>>
Cc: Jeff Hammond <jehammond at nvidia.com<mailto:jehammond at nvidia.com>>
Betreff: Re: [J3] Question: Aliasing in Parallel Procedure Instances in OpenMP Parallel Regions
Except for omp_get_thread_num(), OpenMP is invisible to the consideration of Fortran compliance in that program, because the directives are only comments.
When you activate OpenMP in a Fortran compiler, you willfully step outside of the Fortran standard and enter the domain language defined by the OpenMP extensions to the Fortran language implemented by your compiler. You cannot reason about what OpenMP semantics due to a Fortran program from the Fortran standard alone, unless you ignore OpenMP altogether, because OpenMP is not Fortran.
If the OpenMP extensions to the Fortran language define the below program, then it is defined. If you were to write it with DO CONCURRENT, then you could employ the Fortran specification to reason about it, and in the translation I imagine for that, it is not a legal program because of the data race. The equivalent coarray program is straightforward to write in a correct way.
Jeff
From: J3 <j3-bounces at mailman.j3-fortran.org<mailto:j3-bounces at mailman.j3-fortran.org>> on behalf of Klemm, Michael via J3 <j3 at mailman.j3-fortran.org<mailto:j3 at mailman.j3-fortran.org>>
Date: Saturday, 10. February 2024 at 17.51
To: General J3 interest list <j3 at mailman.j3-fortran.org<mailto:j3 at mailman.j3-fortran.org>>
Cc: Klemm, Michael <Michael.Klemm at amd.com<mailto:Michael.Klemm at amd.com>>
Subject: [J3] Question: Aliasing in Parallel Procedure Instances in OpenMP Parallel Regions
External email: Use caution opening links or attachments
[Public]
Hi folks,
In the OpenMP Language Committee at discussion happened about the below piece of Fortran code. There was some dissent in the discussion, so I'm hoping for some clarification.
In the example, someone spawns a few threads and calls a Fortran procedure, passing along a variable that's shared in the parallel region. We understand that dummy arguments cannot alias. But what about the "variable" dummy argument that aliases in two parallel instances of the same procedure? It seems that the wording of the aliasing rule does not define that at all (which is not surprising, given that Fortran does not know threads).
So, the question is: Are we in UB land with the below example? Does the definition of dummy-argument aliasing in Fortran extend to the parallel case, too?
Kind regards,
-michael
subroutine test(variable)
use omp_lib, only : omp_get_thread_num
implicit none
integer :: variable
!$omp single
variable = 1234
!$omp end single
if (variable .ne. 1234) then
print '(A,I0,A,I0)', "ERROR: variable=", variable, ", TID=",omp_get_thread_num()
endif
end subroutine test
program main
implicit none
integer :: variable2
interface
subroutine test(variable)
implicit none
integer :: variable
end subroutine test
end interface
variable2 = -42
!$omp parallel shared(variable2)
call test(variable2)
!$omp end parallel
end program main
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.j3-fortran.org/pipermail/j3/attachments/20240212/511e422c/attachment-0001.htm>
More information about the J3
mailing list