Fortran

Guide To Learn

Sending and receiving data

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:

  1. Without square brackets–The reference is that of the local image; for example, the following will assign a value to coarray a on the current image:a = 3.141
  2. 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

is semantically equivalent to

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.

Sending and receiving data

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top