Stateful Goroutines in Co-array Fortran
module stateful_coarrays
implicit none
private
type :: read_op
integer :: key
integer :: resp
end type read_op
type :: write_op
integer :: key
integer :: val
logical :: resp
end type write_op
type(read_op), allocatable :: reads(:)[:]
type(write_op), allocatable :: writes(:)[:]
integer :: state(5)[*]
integer(kind=8) :: read_ops[*] = 0
integer(kind=8) :: write_ops[*] = 0
public :: initialize, run_stateful_coarray, report_results
contains
subroutine initialize()
allocate(reads(100)[*])
allocate(writes(10)[*])
end subroutine initialize
subroutine run_stateful_coarray()
integer :: i, key, val
real :: r
do i = 1, 100
call random_number(r)
key = int(r * 5) + 1
reads(i)%key = key
reads(i)%resp = state(key)
read_ops = read_ops + 1
call sleep(1)
end do
do i = 1, 10
call random_number(r)
key = int(r * 5) + 1
call random_number(r)
val = int(r * 100)
writes(i)%key = key
writes(i)%val = val
state(key) = val
writes(i)%resp = .true.
write_ops = write_ops + 1
call sleep(1)
end do
end subroutine run_stateful_coarray
subroutine report_results()
if (this_image() == 1) then
print *, "readOps:", read_ops
print *, "writeOps:", write_ops
end if
end subroutine report_results
end module stateful_coarrays
program main
use stateful_coarrays
implicit none
call initialize()
call run_stateful_coarray()
sync all
call report_results()
end program main
This example demonstrates how to implement stateful operations using Co-array Fortran. Co-array Fortran provides a parallel programming model that allows for shared memory-style programming in a distributed memory environment.
In this implementation:
We define two derived types
read_op
andwrite_op
to encapsulate read and write operations.We use co-arrays for
reads
,writes
,state
,read_ops
, andwrite_ops
to allow sharing of data across images (parallel processes).The
run_stateful_coarray
subroutine simulates the behavior of multiple goroutines performing read and write operations. It uses random number generation to simulate the random access pattern.Instead of channels, we directly modify the shared
state
co-array and update the operation counters.The
sleep
calls simulate the time delay between operations.The
report_results
subroutine prints the final operation counts, but only on the first image to avoid duplicate output.
To run this program:
$ gfortran -fcoarray=single stateful_coarrays.f90 -o stateful_coarrays
$ ./stateful_coarrays
Note that this implementation uses a single-image coarray model for simplicity. In a real-world scenario, you would typically run this across multiple images to take advantage of parallelism:
$ gfortran -fcoarray=lib stateful_coarrays.f90 -o stateful_coarrays -lcaf_mpi
$ cafrun -np 4 ./stateful_coarrays
This Co-array Fortran version provides a different approach to managing shared state compared to the original example. Instead of using goroutines and channels, it uses co-arrays to share data across parallel processes. The synchronization is implicit in the co-array operations, providing a different model for concurrent programming.