PSyclone
PSyclone copied to clipboard
OpenMP Parallel data sharing clauses doesn't always generate legal code
PSyclone will relatively easily produce the following code which has race condition at k=1
:
subroutine my_subroutine()
integer, dimension(10,10) :: a
integer, dimension(10,10) :: b
integer :: i
integer :: j
integer :: k
!$omp parallel default(shared), private(i,j)
k = 1
!$omp single
!$omp task private(i, j), shared(a, a), depend(in: k, b(i, j) ), depend(out: a(i, j) )
do i = 1, 10, 1
do j = 1, 10, 1
a(i,j) = k
a(i,j) = b(i,j) + 1
enddo
enddo
!$omp end task
!$omp end single
do i = 1, 10, 1
do j = 1, 10, 1
a(i,j) = 0
enddo
enddo
!$omp end parallel
end subroutine my_subroutine
The task data share clauses I'm still working on, but they don't affect what is produced by the parallel region. I expected that k
should be declared as private as well.
This is actually discussed in the documentation of OMPParallelDirective:
# Check if the write access is inside the parallel loop. If
# the write is outside of a loop, it is an assignment to
# a shared variable. Example where jpk is likely used
# outside of the parallel section later, so it must be
# declared as shared in order to have its value in other loops:
# !$omp parallel
# jpk = 100
# !omp do
# do ji = 1, jpk
I feel like this access is a race condition, but PSyclone probably has previously assume this was safe (as all the parallel work would be done in a openmp do, and can't do things like jpk = omp_get_thread_num()
or any variable result.
This ends up being complicated for tasking as there is a lot of potential usage of firstprivate
(this would be needed to pass this kind of variable into a task correctly). My current strategy was to base the difference on shared and firstprivate for this case on whether the parent parallel declared the variable as private
or shared
, but with the current implementation I can't think of a way to end up with a firstprivate variable. This might be ok, but it creates additional dependencies on shared variables sometimes.
Does the current strategy cause no issues in PSyclone generated code? And if so I'll try to remove the firstprivate clause generation code.
Adding a
do i = 1, 10, 1
k = i
enddo
as a first loop then makes k
private, even though its almost realistically the same as the k=1
statement.
@sergisiso Looking through old issues I came across this - what do you think?
I don't think this is a common use case but certainly looks strange to me.