Atomic Counters in Co-array Fortran
Our example demonstrates the use of atomic operations for managing shared state across multiple parallel processes. In Co-array Fortran, we’ll use atomic subroutines to achieve similar functionality.
program atomic_counters
use iso_fortran_env
implicit none
integer(atomic_int_kind) :: ops[*]
integer :: i, c
! Initialize the atomic counter
call atomic_define(ops, 0)
! Synchronize all images before starting
sync all
! Each image will increment the counter 1000 times
do c = 1, 1000
call atomic_add(ops, 1)
end do
! Wait for all images to complete
sync all
! Image 1 prints the final result
if (this_image() == 1) then
print *, "ops:", ops
end if
end program atomic_counters
In this Co-array Fortran program:
We use an atomic integer
ops
as a co-array, which is shared across all images (similar to goroutines in the original example).The
atomic_define
subroutine is used to initialize the counter to 0.Instead of creating separate goroutines, we utilize the parallel nature of Co-array Fortran where each image (similar to a process) runs the same code.
The
atomic_add
subroutine is used to atomically increment the counter, ensuring thread-safety.We use
sync all
statements to ensure all images have completed their operations before reading the final value.Finally, we print the result from image 1 (equivalent to the main thread in the original example).
To run the program:
$ gfortran -coarray=single atomic_counters.f90 -o atomic_counters
$ ./atomic_counters
ops: 1000
Note that this example assumes a single-image execution for simplicity. In a multi-image environment, you would see a larger final value, as each image would contribute 1000 increments.
When running with multiple images (e.g., 50 images to match the original example):
$ gfortran -coarray=lib atomic_counters.f90 -o atomic_counters
$ cafrun -n 50 ./atomic_counters
ops: 50000
This demonstrates the power of atomic operations in Co-array Fortran for managing shared state across parallel processes, similar to the use of atomic operations in concurrent programming with other languages.