https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110547
Bug ID: 110547
Summary: Improper finalization calls with OpenMP tasks
Product: gcc
Version: 14.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: abensonca at gcc dot gnu.org
Target Milestone: ---
Here's an example code (highly simplified from the actual code I'm working
on) that causes seemingly wrong behavior resulting in calling a destructor when
it should not be called:
module taskerMod
type :: tasker
integer :: depth=-1
contains
final :: taskerDestruct
procedure :: compute => taskerCompute
end type tasker
contains
subroutine taskerDestruct(self)
!$ use :: OMP_Lib
implicit none
type(tasker), intent(inout) :: self
write (0,*) "DESTRUCT FROM DEPTH ",self%depth !$ ," :
",omp_get_thread_num()
return
end subroutine taskerDestruct
recursive subroutine taskerCompute(self)
!$ use :: OMP_Lib
implicit none
class(tasker), intent(inout) :: self
!$omp atomic
self%depth=self%depth+1
write (0,*) "DEPTH ",self%depth !$ ," : ",omp_get_thread_num()
if (self%depth < 3) then
!$omp task untied
call self%compute()
!$omp end task
end if
return
end subroutine taskerCompute
end module taskerMod
program testTasks
use :: taskerMod
implicit none
type(tasker) :: tasker_
tasker_=tasker(0)
!$omp parallel
!$omp single
!$omp taskgroup
!$omp task untied
call tasker_%compute()
!$omp end task
!$omp end taskgroup
!$omp end single
!$omp end parallel
end program testTasks
Compiling without OpenMP results in the expected behavior:
$ gfortran test.F90
$ ./a.out
DESTRUCT FROM DEPTH -1
DEPTH 1
DEPTH 2
DEPTH 3
There's a call to the finalizer for the tasker class (on assignment), and then
it simply reports the 3 levels of recursion that I've set it to go through.
But, if I compile with OpenMP and run just a single thread (the same problem
occurs with multiple threads also):
$ gfortran test.F90 -fopenmp
$ ./a.out
DESTRUCT FROM DEPTH -1
DEPTH 1
DEPTH 2
DESTRUCT FROM DEPTH 2
DEPTH 3
DESTRUCT FROM DEPTH 3
I now see calls to the finalizer from the 2nd and 3rd recursive calls to the
taskerCompute function. Since self is intent(inout) to this function I
wouldn't expect it to be finalized.
This happens with versions 12.0.0, 13.0.1, and the current HEAD of the GCC git
repo. But, ifort, does not produce the extra finalizer calls when used to
compile the above with OpenMP.