Introduction to Coarrays
Coarrays are a native parallel programming feature added to the Fortran standard in Fortran 2008 and extended in Fortran 2018. They let a program run as several replicated copies, called images, that execute the same code (the SPMD model, Single Program Multiple Data) but each hold their own private data. A coarray is declared by adding square-bracket codimensions after the normal array dimensions, for example real :: temperature(100)[*], and any image can read or write another image's copy of that variable directly using square-bracket syntax, without hand-written message-passing calls.
Cricket analogy: Like a T20 franchise fielding identical playing elevens in five simultaneous exhibition matches across five stadiums, each squad (image) runs the same game plan but keeps its own scoreboard, and captains can phone another ground for a live score update.
Declaring and Using Coarrays
A coarray variable such as real :: x(10)[*] declares a rank-1 array of 10 reals that is replicated on every image, and the asterisk in the codimension means the number of images is determined at run time. To reference another image's copy, you append a bracket with the image index, as in x(:)[3], which reads or writes the array on image 3 from wherever the statement executes. Local access, x(:) with no brackets, always refers to the calling image's own copy and behaves exactly like ordinary Fortran array syntax, so existing array code is easy to extend into a coarray-aware program.
Cricket analogy: Like a DRS review system where each stadium keeps its own replay footage array, but the third umpire can pull frame data from the neutral venue's array by specifying that venue's index explicitly.
A Minimal Coarray Program
program coarray_demo
implicit none
integer :: me, np
real :: x(10)[*]
me = this_image()
np = num_images()
x = real(me) ! each image fills its own copy
sync all ! barrier: everyone finishes writing first
if (me == 1) then
print *, 'Value on image 2:', x(1)[2] ! read image 2's copy
end if
sync all
end program coarray_demo
Synchronization: sync all, sync images, and critical
Coarray accesses are not automatically ordered between images, so the standard requires explicit synchronization whenever one image depends on data another image has written. sync all is a full barrier that blocks every image until all of them arrive; sync images(list) synchronizes only with a named subset, which is cheaper when only two or three images actually exchange data. The critical construct wraps a block of code so that only one image executes it at a time, which is essential for safely updating a shared accumulator or writing to a shared log file without interleaving.
Cricket analogy: Like the drinks break in a Test match: play (data writes) pauses for everyone until every fielder is confirmed back in position, exactly what sync all enforces before anyone reads the next over's data.
Reading or writing a coarray on a remote image without an intervening sync all, sync images, or sync memory is a data race: the standard does not guarantee the writing image has finished, or that the reading image sees a consistent value. This is a common source of silent, hard-to-reproduce bugs in coarray programs — always pair remote accesses with explicit synchronization.
Collective Subroutines and Practical Use
Fortran 2018 added collective intrinsic subroutines — co_sum, co_max, co_min, co_reduce, and co_broadcast — that perform a reduction or broadcast across all images in a single call instead of requiring a hand-rolled loop of point-to-point coarray accesses. For example, call co_sum(partial, result) adds together the partial value held by every image and returns the total to result on every image (or to a chosen result_image). On the toolchain side, gfortran implements coarrays either as -fcoarray=single for serial testing or, more usefully, via the OpenCoarrays library with -fcoarray=lib, which maps images onto MPI processes under the hood, so a coarray program can be launched with cafrun -np 4 ./a.out much like an MPI job.
Cricket analogy: Like a tournament scorer summing each ground's run total into one grand total for the league table, exactly what co_sum does across images in one call instead of manually cabling each ground.
OpenCoarrays (opencoarrays.org) is the de facto runtime for gfortran's -fcoarray=lib option and layers Fortran's coarray model on top of MPI. In practice this means a coarray program's performance characteristics and debugging tools (e.g. mpirun-style launchers, MPI-aware profilers) closely resemble those of an equivalent MPI program, even though the source code never mentions MPI directly.
- Coarrays are a native Fortran (2008/2018) parallel feature using the SPMD model, where each replica is called an image.
- Declare a coarray with a trailing bracket codimension, e.g. real :: x(10)[*]; the asterisk defers the image count to run time.
- Local access uses no brackets; remote access names the target image explicitly, e.g. x(:)[3].
- sync all is a full barrier; sync images(list) synchronizes a subset; critical serializes access to shared resources.
- Unsynchronized remote coarray access is a data race and a common source of nondeterministic bugs.
- Collective intrinsics (co_sum, co_max, co_broadcast, co_reduce) replace hand-written reduction loops across images.
- gfortran typically runs coarrays via OpenCoarrays with -fcoarray=lib, mapping images onto MPI processes under the hood.
Practice what you learned
1. What does the codimension in real :: x(10)[*] represent?
2. What must happen before image 1 safely reads x(:)[2] after image 2 has written to x?
3. Which intrinsic call sums a value contributed by every image into a single total?
4. How does gfortran typically execute a real multi-image coarray program?
5. What is the purpose of the critical construct in coarray code?
Was this page helpful?
You May Also Like
OpenMP in Fortran
Learn how to parallelize loops and accumulate results safely across shared-memory threads using Fortran's !$omp directives.
MPI Basics in Fortran
Get started with distributed-memory parallelism in Fortran using MPI's rank/size model, point-to-point messages, and collective operations.
Numerical Computing in Fortran
Master precision control, whole-array operations, LAPACK/BLAS integration, and floating-point pitfalls for reliable numerical Fortran code.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics