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 mainThis 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_opandwrite_opto encapsulate read and write operations.We use co-arrays for
reads,writes,state,read_ops, andwrite_opsto allow sharing of data across images (parallel processes).The
run_stateful_coarraysubroutine 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
stateco-array and update the operation counters.The
sleepcalls simulate the time delay between operations.The
report_resultssubroutine 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_coarraysNote 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_coarraysThis 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.