Range Over Channels in Co-array Fortran

In a previous example, we saw how do loops provide iteration over basic data structures. We can also use this syntax to iterate over values received from a channel-like construct in Co-array Fortran.

program range_over_channels
    use iso_fortran_env
    implicit none

    character(len=10) :: queue(2)[*]
    integer :: i, num_images

    num_images = num_images()

    ! We'll iterate over 2 values in the `queue` co-array.
    if (this_image() == 1) then
        queue(1) = "one"
        queue(2) = "two"
    end if

    sync all

    ! This do loop iterates over each element in the `queue`.
    ! Because we're using a fixed-size co-array, the iteration
    ! terminates after processing the 2 elements.
    do i = 1, 2
        print *, queue(i)[1]
    end do

end program range_over_channels

To run the program:

$ gfortran -coarray=single range_over_channels.f90
$ ./a.out
 one
 two

This example demonstrates how to use co-arrays in Fortran to achieve a similar effect to channels in other languages. While Fortran doesn’t have built-in channel constructs, co-arrays provide a way to share data between images (analogous to processes or threads) in a parallel program.

In this case, we’re using a single image for simplicity, but in a real parallel program, you could have multiple images communicating via co-arrays. The sync all statement ensures that all images have consistent data before we start reading from the queue.

This example also shows that it’s possible to initialize a co-array on one image and read its values from other images, which is conceptually similar to sending and receiving values through a channel.