Stuck trying to get coarrays to do simple thing

Hi all,
I reached the Coarray section of the modern Fortran book, and wanted to experiment with very simple tasks first.

I wrote this piece of code to just add a one to a gather variable, although the output isn’t what I want.
For example I want it to out put 7 if I use 7 images.

program test_1
  implicit none


  integer,codimension[*] :: sum
  integer,codimension[*] :: gather
  integer :: i

  sum=1

  gather=0

 
  do i=1,num_images()
     if (this_image()==i) then
        gather[1]=gather[1]+sum[this_image()]
     end if
  end do

  sync all

  print *, gather[1]

  


end program test_1

Thanks

What you try to do is adding values to the same chunk of memory (gather[1], i.e. variable gather in the first image), in parallel, from all images. This is bad idea as images can pick up gather[1] value (from other image) which has not been yet incremented by other images.
What you should do is rather prepare sum[*] values in images, be it just assigning 1 or doing fancy 2-hours calculations, and then adding it up from a single image only, typically image #1, like:

program test_1
  implicit none

  integer,codimension[*] :: sum
  integer :: gather=0    ! no need to make it a coarray
  integer :: i

  sum=1
  sync all   ! make sure all sum[*] are ready
  if (this_image()==1) then    ! adding up sum[*] in image #1
    do i=1,num_images()
      gather=gather+sum[i]
    end do
    print *, gather
  end if
end program

Thank you for this ! So from what I gather, if I don’t make something a Coarray it won’t be copied across images ?

Not really, all images have all variables declared in the code. The coarrays, however, are the only objects inter-accessible between the images.

Actually, Fortran 2018 has added collective subroutines which make operations like summing values computed in images easier and possibly faster. I have very little experience with those, but I succeeded in getting your simple task working:

program test_1
  implicit none

  integer :: sum

  sum=1
  sync all             ! as above
  call co_sum(sum, result_image=1)  ! see remarks below
  sync all             ! not sure if really needed
  if (this_image()==1) then
    print *, sum
  end if

end program

Remarks:

  1. the collective subroutine, contrary to my first guess, must be called in all images
  2. In case of co_sum, values of its first argument are summed across all the images (or the team images in more advanced usage) and put into the same argument (inout) either on all images or, if result_image arg is present, only on the image given by this optional arg
  3. The summed variable may be a coarray but this is not required (as in the above sample)

Alright, thank you !