Looking back at figure 7.9, it’s obvious who the neighbors are for each image. For image 1, the left and right neighbors are images 3 and 2, respectively. For image 2, they’re images 1 and 3. And for image 3, they’re images 2 and 1. Let’s generalize this rule so that it works for any number of images. Try to implement it as an external function! It’s a necessary ingredient for getting the parallel tsunami simulator to work, so you can also skip ahead and use it out of the box. I defined it in the mod_parallel module in src/ch07/mod_parallel.f 90.
Exercise 2: Writing a function that returns the indices of neighbor images
To exchange data with the neighbors, we need to know who they are! Write a function that can be invoked on any image and that returns the image numbers of the neighbors to the left and to the right. The right neighbor of the last image should be the first image, and the left neighbor of the first image should be the last image, to satisfy the periodic boundary condition.
- The function should take no input arguments.
- All you need is the
this_imageandnum_imagesfunctions to work out the logic. - Use
integer::tile_neighbors(2)to store the results into a single variable.
The solution is given in the “Answer key” section near the end of this chapter, and is included in src/ch07/mod_parallel.f90.
In the the main program, each image will invoke this function and store the neighbor image indices in local variables:
integer(int32) :: neighbors(2) ❶
integer(int32) :: left, right ❷
neighbors = tile_neighbors() ❸
left = neighbors(1) ❹
right = neighbors(2) ❹
❶ Temporary array to store results of tile_neighbors()
❷ Variables that will hold the indices
❸ Invokes the function and stores the result into a temporary array
❹ Copies from the temporary array into target variables
Now that we know who our neighbors are, the next step is to determine the start and end indices on each image and to allocate the coarrays.