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:
We use a co-array variable
done
to synchronize between co-images, similar to the channel in the original example.The
worker
subroutine is executed on the second co-image (image 2).The main program (image 1) waits for the
done
variable to be set, which is analogous to receiving from the channel.We use
sync all
andsync memory
statements for synchronization between co-images.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.