100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Parallel Programming with Coarrays

Learn how Fortran's native coarray feature enables SPMD parallel programming across multiple images without external message-passing libraries.

Practical FortranIntermediate10 min readJul 10, 2026
Analogies

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

fortran
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

Was this page helpful?

Topics covered

#Programming#FortranStudyNotes#ParallelProgrammingWithCoarrays#Parallel#Coarrays#Declaring#Minimal#Concurrency#StudyNotes#SkillVeris