https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127973

            Bug ID: 127973
           Summary: caf_shmem: collectives do not report an exhausted
                    shared memory pool through STAT= and ERRMSG=
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libfortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jvdelisle at gcc dot gnu.org
  Target Milestone: ---

With -fcoarray=shared, CO_SUM, CO_MIN, CO_MAX, CO_REDUCE and CO_BROADCAST
need a buffer in the shared memory pool that is larger than the data
(for the reductions, the data times the number of images).  When the
pool cannot hold it, the collective neither sets STAT= nor ERRMSG=.  One
image error terminates with

  Fortran runtime error: Shared memory exhausted; increase
  GFORTRAN_SHARED_MEMORY_SIZE

and the other images hang forever.

Reproducer:

program co_sum_pool
  implicit none
  real(8), allocatable :: a(:)
  integer :: st
  character(80) :: msg

  allocate (a(4*1024*1024))       ! 32 MiB per image
  a = this_image ()
  st = 0
  msg = ''
  call co_sum (a, stat=st, errmsg=msg)
  print '(a,i0,a,i0,2a)', 'image ', this_image (), ': stat=', st, &
        ' errmsg=', trim (msg)
end program co_sum_pool

$ gfortran -fcoarray=shared co_sum_pool.f90
$ GFORTRAN_SHARED_MEMORY_SIZE=64M GFORTRAN_NUM_IMAGES=4 ./a.out
Fortran runtime error: Shared memory exhausted; increase
GFORTRAN_SHARED_MEMORY_SIZE
ERROR: Image 4(pid: 2772604) failed with signal 0, exitstatus 1.
(hangs)

CO_BROADCAST of a 128 MiB array with the same settings behaves the same.

Expected: every image returns from CO_SUM with a nonzero STAT and an
ERRMSG saying the shared memory is exhausted, as ALLOCATE of a coarray
does since PR127751.

Cause: get_collsub_buf in libgfortran/caf/shmem/collective_subroutine.c
grows the team's collective buffer with allocator_shared_malloc_or_die
while it holds the buffer's mutex.  The image that grows it terminates
with the mutex still locked, so the others block in
pthread_mutex_lock in get_collsub_buf:

  #1 pthread_mutex_lock
  #2 get_collsub_buf (size=134217728) collective_subroutine.c:201
  #3 collsub_reduce_array collective_subroutine.c:346
  #4 _gfortran_caf_co_sum shmem.c:956

get_collsub_buf also calls the allocator without allocator_lock, so it
races with ALLOCATE or FORM TEAM running in another team.

A fix needs get_collsub_buf to report the failure instead of terminating,
in a way that every image of the collective sees, and
collsub_reduce_array and collsub_broadcast_array need a result besides
"an image terminated" so that the _gfortran_caf_co_* entry points can set
STAT= and ERRMSG=.

Raised by Mikael Morin in the review of PR127751.

Reply via email to