From: Andrew Benson <abenson@carnegiescience.edu>
To: gfortran <fortran@gcc.gnu.org>
Cc: Andrew Benson <abenson@carnegiescience.edu>
Subject: Re: Possible problems with OpenMP task parallelism
Date: Tue, 4 Jul 2023 08:23:34 -0700 [thread overview]
Message-ID: <CAM3HiBenpH0hRJDfedO3KOOJnBqCh3+sbSoeDvfw+RT1Av0Evw@mail.gmail.com> (raw)
In-Reply-To: <6924139.eB1hRhsCpy@abensonca-precision-7540>
[-- Attachment #1: Type: text/plain, Size: 6070 bytes --]
I've opened PRs for both of these issues:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110547
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110548
-Andrew
--
* Andrew Benson: http://users.obs.carnegiescience.edu/abenson
* Galacticus: https://github.com/galacticusorg/galacticus
On Wed, Jun 28, 2023, 5:01 PM Andrew Benson <abenson@carnegiescience.edu>
wrote:
> I've been starting to try using OpenMP task parallelism, but I'm running
> into
> some issues. I'm not sufficiently experienced with task parallelism in
> OpenMP
> to know if I'm misunderstanding how it should work, or if there's a
> compiler
> bug.
>
> Here's an example code (highly simplified from the actual code I'm working
> on):
>
> 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. But, this is where I doubt my
> understanding of how tasks should behave.
>
> 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.
>
> Does anyone have any insights into whether or not the finalizer should be
> called in this situation?
>
> Another issue I find with a modified version of the above:
>
> module taskerMod
>
> type :: helper
> end type helper
>
> 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,helper_)
> !$ use :: OMP_Lib
>
>
>
> implicit none
> class(tasker), intent(inout) :: self
> class(helper), intent(inout), optional :: helper_
>
> !$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(helper_)
> !$omp end task
>
>
>
> end if
> return
> end subroutine taskerCompute
>
> end module taskerMod
>
> program testTasks
> use :: taskerMod
> implicit none
> type(tasker) :: tasker_
> type(helper) :: helper_
>
> 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
>
> This one causes a segfault:
> $ gfortran test1.F90 -fopenmp
> $ ./a.out
> DESTRUCT FROM DEPTH -1
> DEPTH 1
>
> Program received signal SIGSEGV: Segmentation fault - invalid memory
> reference.
>
> Backtrace for this error:
> #0 0x2ac99289a1ef in ???
> #1 0x401840 in ???
> #2 0x2ac9925a9606 in GOMP_task
> at ../../../gcc-git/libgomp/task.c:644
> #3 0x401588 in ???
> #4 0x40197b in ???
> #5 0x2ac9925a77a4 in gomp_barrier_handle_tasks
> at ../../../gcc-git/libgomp/task.c:1650
> #6 0x2ac9925b058f in gomp_team_barrier_wait_end
> at ../../../gcc-git/libgomp/config/linux/bar.c:116
> #7 0x2ac9925aeffc in gomp_team_end
> at ../../../gcc-git/libgomp/team.c:956
> #8 0x401692 in ???
> #9 0x4016cd in ???
> #10 0x2ac992886d0c in ???
> #11 0x401128 in ???
> Segmentation fault
>
> This appears to be due to the optional argument, helper_. If it is present
> in
> the initial call, i.e.:
> call tasker_%compute(helper_)
>
> then this runs without a segfault.
>
> -Andrew
>
> --
>
> * Andrew Benson: https://abensonca.github.io
>
> * Galacticus: https://github.com/galacticusorg/galacticus
>
>
>
>
prev parent reply other threads:[~2023-07-04 15:23 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-29 0:01 Andrew Benson
2023-07-04 15:23 ` Andrew Benson [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAM3HiBenpH0hRJDfedO3KOOJnBqCh3+sbSoeDvfw+RT1Av0Evw@mail.gmail.com \
--to=abenson@carnegiescience.edu \
--cc=fortran@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).