public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
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
>
>
>
>

      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).