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
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
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:
the collective subroutine, contrary to my first guess, must be called in all images
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
The summed variable may be a coarray but this is not required (as in the above sample)