Channel Synchronization in Co-array Fortran

Our first example demonstrates channel synchronization. We can use channels to synchronize execution across co-images. Here’s an example of using a blocking receive to wait for a co-image to finish. When waiting for multiple co-images to finish, you may prefer to use a sync statement.

module channel_sync
  implicit none
  
  integer :: done[*]
  
contains
  subroutine worker()
    use, intrinsic :: iso_fortran_env, only: output_unit
    implicit none
    
    write(output_unit, '(a)', advance='no') "working..."
    call sleep(1)
    write(output_unit, '(a)') "done"
    
    ! Signal that we're done
    done[1] = 1
    sync all
  end subroutine worker
  
end module channel_sync

program main
  use channel_sync
  implicit none
  
  ! Initialize the done variable
  done = 0
  
  ! Start a worker co-image
  sync all
  if (this_image() == 2) then
    call worker()
  end if
  
  ! Block until we receive a notification from the worker
  if (this_image() == 1) then
    do while (done == 0)
      sync memory
    end do
  end if
  
  sync all
end program main

To run the program:

$ cafrun -n 2 channel_synchronization
working...done

In this Co-array Fortran version:

  1. We use a co-array variable done to synchronize between co-images, similar to the channel in the original example.

  2. The worker subroutine is executed on the second co-image (image 2).

  3. The main program (image 1) waits for the done variable to be set, which is analogous to receiving from the channel.

  4. We use sync all and sync memory statements for synchronization between co-images.

  5. The program is executed with two co-images using the cafrun command.

If you removed the waiting loop from this program, the program might exit before the worker even started or finished its work.

Co-array Fortran doesn’t have built-in sleep functionality, so you might need to implement a sleep routine or use a vendor-specific one. The sleep call in this example is just for illustration.

This example demonstrates basic co-image synchronization in Co-array Fortran, which is conceptually similar to goroutine synchronization using channels in the original example.