Coarray nested loop

Like @milancurcic said you probably don’t need coarray here (or at least you don’t need an array explicitly declared with coindices). Here is an simple example following milan’s suggestions, but it’s for one dimensional array. For a 2D array it’s a bit more complicated as you have to judge if size(arr, dim=1) or size(arr, dim=2) is divisible by num_images() but the idea is the same.

module test_coarray
    use iso_fortran_env, only: i32 => int32, sp => real32
    implicit none

contains

    !> Add every element of an array to a value
    function co_add(val, arr) result(ret)
        real(sp), intent(in) :: val, arr(:)
        real(sp) :: ret
        integer(i32) :: njob, nrem, i

        ! Initialization
        ret = val 

        ! Number of jobs per image.
        njob = size(arr)/num_images() 

        ! For each image, sum part of the array.
        associate (x => this_image()*njob)
            ret = ret + sum([(arr(i), i=x - njob + 1, x)])
        end associate

        ! If size of the array is not divisible by num_images().
        nrem = mod(size(arr), num_images())
        if (nrem /= 0 .and. this_image() <= nrem) then
            ret = ret + arr(njob*num_images() + this_image())
        end if

        ! Wait for other images
        sync all 

        ! Result is stored on image 1.
        call co_sum(ret, result_image=1)
    end function co_add

end module test_coarray

program main

    use test_coarray
    implicit none

    real :: val

    val = co_add(0., [1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
    if (this_image() == 1) print *, val

end program main
1 Like