https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127347
Bug ID: 127347
Summary: [COARRAY] Wrong code at runtime can hang.
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: ---
While working on PR126781, I discovered some issues with how we handle STOP and
STAT. After I get previously mentioned PR approved and pushed, I will focus
here.
With -fcoarray=lib -lcaf_shmem, a program in which one image terminates
while the others keep running can hang, or can get a STAT= value that
does not conform to F2023. Six related defects:
1. ERROR STOP does not terminate the other images. The image that
executes ERROR STOP exits, and the rest block forever in their next
SYNC ALL. F2023 requires error termination of all images.
2. A normal STOP on one image leaves the remaining images blocked in
SYNC ALL. The stopped image is never dropped from the team's
barrier count.
3. SYNC IMAGES corrupts its synchronization table once an image has
stopped. The row stride used is the shrinking team image count
instead of the total number of images.
4. Collective subroutines (CO_SUM, CO_BROADCAST, ...) hang when the
current team contains a stopped image. F2023 16.6 p6 requires an
error condition, with STAT_STOPPED_IMAGE when STAT is present.
5. STAT= is classified using program-wide counts instead of the images
involved. An image that stops in one team makes SYNC ALL in a
sibling team return STAT_STOPPED_IMAGE, which should be 0 there.
SYNC TEAM never reports stopped or failed images at all.
6. SYNC ALL / SYNC TEAM with STAT= and a stopped image still wait for
the other images. F2023 11.7.11 p6 says the effect is that of
SYNC MEMORY. This deadlocks a conforming program (3 images):
program p
use iso_fortran_env, only : stat_stopped_image
integer :: s
sync all
if (this_image () == 3) stop
do while (image_status (3) /= stat_stopped_image)
end do
if (this_image () == 1) then
sync all (stat=s) ! should return at once
sync images (2)
else if (this_image () == 2) then
sync images (1)
sync all (stat=s)
end if
print *, this_image (), s
end program p
$ gfortran -fcoarray=lib p.f90 -lcaf_shmem
$ GFORTRAN_NUM_IMAGES=3 ./a.out # hangs
Expected: images 1 and 2 print 6000 (STAT_STOPPED_IMAGE).