Problem with threadprivate procedure pointers with gfortran 4.6

Janus Weil janus@gcc.gnu.org
Fri Aug 26 14:05:00 GMT 2011


Hi Andrew,

> (weird formatting due to the two threads writing simultaneously).

For me the typical output (with two threads) looks like this, also
with 4.7 trunk:

jweil@manzanita:~> ./a.out
           1              4196740
 do task 1
           0              4196740
 do task 1
           1              4196740
STOP wrong thread in Proc_To_Call1 do task 1

           1              4196740
 do task 1
           1              4196740


> When I encountered the similar problem with 4.4 I wasn't entirely sure that a
> threadprivate procedure pointer was valid (or if it's just an undefined
> situation).

Well, as noted by Jakub (and previously by Nick McLaren): OpenMP does
not include any F03 features so far. This means it is not even aware
of the concept of procedure pointers, so that it does not explicitly
forbid their usage, but it also does not say anything on how they
should be handled. So what you're doing is certainly undefined.

Actually I'm not sure how the situation would be with an analogous C
program. (Probably the same?)


> Assuming that it is valid, this seems to be a bug.

No, it's just undefined, so the compiler can do whatever it pleases.


> I haven't
> tested this in trunk yet, but I can try that tomorrow.

Trunk gives the same results as 4.5 and 4.6 for me (see above).


Btw, the following variant of your program:


program test
 use omp_lib
 implicit none

 procedure(), pointer, save :: globalProc
 !$omp threadprivate(globalProc)

 !$omp parallel
 do while (.true.)
   if (omp_get_thread_num() == 0) globalProc => Proc_To_Call0
   if (omp_get_thread_num() == 1) globalProc => Proc_To_Call1
   write (0,*) omp_get_thread_num(),loc(globalProc)
   call globalProc()
 end do
 !$omp end parallel

contains

 subroutine Proc_To_Call0
   print *,'do task 0'
   if (omp_get_thread_num() /= 0) stop 'wrong thread in Proc_To_Call0'
 end subroutine Proc_To_Call0

 subroutine Proc_To_Call1
   print *,'do task 1'
   if (omp_get_thread_num() /= 1) stop 'wrong thread in Proc_To_Call1'
 end subroutine Proc_To_Call1

end program test


is even rejected with:

jweil@manzanita:~> gfortran-4.7 -fopenmp test_omp.f90
test_omp.f90:13.18:

   call globalProc()
                  1
Error: SUBROUTINE attribute conflicts with THREADPRIVATE attribute in
'globalproc' at (1)
test_omp.f90:5.41:

 procedure(), pointer, save :: globalProc
                                         1
Error: SUBROUTINE attribute conflicts with THREADPRIVATE attribute in
'globalproc' at (1)


I'm not sure why this error is not thrown for the original program.

Cheers,
Janus



More information about the Fortran mailing list