Coarray Fortran counter

CoCount

CoCount

A cross-image counter with multiple ranges.

Purpose

There are situations in which you want to compute something like

do i=0, Ni
    do j=0, Nj
        do k=0, Nk
            results(i,j,k) = seriously_heavy_computation(i,j,k)
        end do
    end do
end do

And maybe it would be a good idea to parallelize. Possible solutions include: * do concurrent * OpenMP * Coarray Fortran

We will focus on the Coarray solution.

Solution

Use CoCount:

program main
    use cocount, only: ccnext => next, ccinit => initialize
    use my_computation_library, only: seriously_heavy_computation, ...
    implicit none

    integer :: index_list(3)
    integer :: Ni, Nj, Nk
    double precision, allocatable :: results(:,:,:)[:]

    Ni = 300
    Nj = 500
    Nk = 8000

    allocate(results(Ni, Nj, Nk)[*])

    ! And whatever you need to do for your computation
    ! ...

    ! Initialize counter
    call ccinit([Ni, Nj, Nk])

    sync all

    do while(ccnext(index_list)) ! Get next values into `index_list(:)`
        results(index_list(1),index_list(2),index_list(3))[1] = &
            seriously_heavy_computation(index_list(1),index_list(2),index_list(3))
    end do

    sync all

    ! Don't forget to save your results ...
    if (this_image() == 1) then
        ! ...
    end if
end program

Usage

Note that if you have guix in your system, you can quickly get started by running:

guix shell -m manifest.scm

This command will install * OpenCoarrays * fpm the Fortran Package Manager * gfortran in the newly created shell environment.

Install with fpm

fpm install

Include in your fpm project

# in your fpm.toml

# ...

[dependencies]
# ...
cocount = {git = "https://codeberg.org/moriglia/cocount.git", tag="0.1.0"}
# ...

Run the example

fpm run --example --compiler caf --runner="cafrun -np 5"

Developer Info

Marco Origlia