The key to sending or receiving data with coarrays is understanding how to reference values on remote images. There are two ways to do this:
- Without square brackets–The reference is that of the local image; for example, the following will assign a value to coarray
aon the current image:a = 3.141 - With square brackets–The image is indicated with a scalar integer inside the brackets; for example:a[2] = 3.141
When indexing a coarray, the number inside the square brackets is called a coindex. A coindex must be within the bounds of existing images. If we run a program with images [1, 2, 3, 4], a coarray must not be coindexed outside of that range.
You are allowed to use a coindex that matches the local image. For example, this snippet
if (this_image() == 1) a[1] = 3.141
if (this_image() == 1) a = 3.141
Let’s look at a program that demonstrates various ways you can reference and copy data between remote images. We’ll first use an integer coarray a to send the value of a variable from image 1 to image 2, assign a new value to it on image 2, and then send it back from image 2 to image 1. Finally, we’ll confirm from image 2 that image 1 has updated its value of a:
caf coarrays.f90 -o coarrays
cafrun -n 2 ./coarrays
Image 1 has value 1
Image 1 sending new value to image 2
Image 2 has value 2
Image 2 sending new value to image 1
Image 2 sees that image 1 now has value 4
The following listing provides the complete code of the program.
Listing 7.4 Sending and receiving data between two images
program coarrays
implicit none
integer :: a[*] ❶
if (num_images() /= 2) &
error stop 'Error: This program must be run on 2 images'
a = 0 ❷
if (this_image() == 1) then ❸
a = 1 ❹
print *, 'Image ', this_image(), ' has value ', a
print *, 'Image ', this_image(), ' sending new value to image 2.'
a[2] = 2 * a ❺
end if
sync all ❻
if (this_image() == 2) then ❼
print *, 'Image ', this_image(), ' now has value ', a
print *, 'Image ', this_image(), ' sending new value to image 1.'
a[1] = 2 * a ❽
end if
sync all
if (this_image() == 2) &
print *, 'Image ', this_image(), &
' sees that image 1 now has value ', a[1]
end program coarrays
❶ Declares an integer scalar coarray
❷ Initializes to zero on all images
❸ Only image 1 will enter this if block.
❹ Assigns a value on this image
❺ Sends a value from this image to image 2
❻ All images wait for each other here.
❼ Only image 2 will enter this if block.
❽ Sends a value from this image to image 1
Compiling and running the program in listing 7.4 confirms that the sending and receiving of data between two images works as expected.
With this program, we exercised both assigning a value on all images using familiar syntax and assigning a local value to a remote coarray. Notice that I also used the sync all statement in this example. This ensures that image 2 doesn’t proceed into its if block before it receives the coarray from image 1. Let’s see in more detail how synchronization of images works.