Waitgroups in Co-array Fortran

Our program demonstrates the use of a synchronization mechanism similar to WaitGroups in Co-array Fortran. Here’s the full source code:

program waitgroups
  use iso_fortran_env
  implicit none

  integer :: i
  integer :: num_images
  integer, codimension[*] :: counter = 0

  num_images = num_images()

  do i = 1, 5
    call worker(i)
  end do

  sync all

contains

  subroutine worker(id)
    integer, intent(in) :: id
    
    print *, "Worker", id, "starting on image", this_image()
    
    ! Simulate an expensive task
    call sleep(1)
    
    print *, "Worker", id, "done on image", this_image()
    
    counter[1] = counter[1] + 1
  end subroutine worker

end program waitgroups

This is the main program that demonstrates the concept of synchronization in Co-array Fortran:

  1. We use the iso_fortran_env module for access to the num_images() function.
  2. We declare a co-array variable counter to keep track of completed tasks across all images.
  3. We launch 5 worker tasks using a do loop.
  4. After launching all tasks, we use sync all to wait for all images to complete their work.

The worker subroutine simulates an expensive task:

  1. It prints a message when starting and finishing.
  2. It uses the sleep function to simulate work (note: sleep is not standard Fortran, you may need to use a different method depending on your compiler).
  3. After completing, it increments the shared counter on image 1.

To run the program, compile it with a Co-array Fortran-capable compiler and execute it:

$ caf waitgroups.f90 -o waitgroups
$ cafrun -np 4 ./waitgroups
Worker 1 starting on image 3
Worker 2 starting on image 3
Worker 3 starting on image 3
Worker 4 starting on image 3
Worker 5 starting on image 3
Worker 1 starting on image 2
Worker 2 starting on image 2
Worker 3 starting on image 2
Worker 4 starting on image 2
Worker 5 starting on image 2
Worker 1 starting on image 1
Worker 2 starting on image 1
Worker 3 starting on image 1
Worker 4 starting on image 1
Worker 5 starting on image 1
Worker 1 starting on image 4
Worker 2 starting on image 4
Worker 3 starting on image 4
Worker 4 starting on image 4
Worker 5 starting on image 4
Worker 1 done on image 3
Worker 2 done on image 3
Worker 3 done on image 3
Worker 4 done on image 3
Worker 5 done on image 3
Worker 1 done on image 2
Worker 2 done on image 2
Worker 3 done on image 2
Worker 4 done on image 2
Worker 5 done on image 2
Worker 1 done on image 1
Worker 2 done on image 1
Worker 3 done on image 1
Worker 4 done on image 1
Worker 5 done on image 1
Worker 1 done on image 4
Worker 2 done on image 4
Worker 3 done on image 4
Worker 4 done on image 4
Worker 5 done on image 4

The order of workers starting up and finishing is likely to be different for each invocation and will depend on the number of images used.

Note that this approach uses Co-array Fortran’s built-in synchronization mechanisms. For more advanced use cases, you might need to implement custom synchronization routines or use additional libraries.