Fortran

Guide To Learn

Changing execution between teams

Now that we have two new teams, how do we instruct images on each team to do certain kinds of work? Recall that by default, all images start on the same team. We need to switch each image to a new team to get it to work on a different task. We do this with the change team construct. Following the form_team statement in listing 12.2, we’ll add this snippet:

change team(new_team)                                       ❶
  print *, 'Image', this_image(), 'of', num_images(), &     ❷
           'is on team', team_number()                      ❷
end team                                                    ❸

❶ Switches execution to a new team

❷ Reports the image and team number

❸ Returns to the parent team

Now you understand why change team is a construct–every change team statement must be paired with a matching end team statement. A change team statement instructs all images that execute it to switch to the team specified in parentheses. The code inside the change team construct executes on the new (child) team until the end team statement, when the images return to the original (parent) team. Similar to this_image, which returns the image number, team_number returns a scalar integer value of the current team.

Let’s save this program in a file called change_team.f 90, compile it, and run it on five images:

caf change_team.f90 -o change_team                          ❶
cafrun -n 5 --oversubscribe ./change_team                   ❷
  Image           1 of           2 is on team          1    ❸
  Image           2 of           2 is on team          1    ❸
  Image           1 of           3 is on team          2    ❸
  Image           2 of           3 is on team          2    ❸
  Image           3 of           3 is on team          2    ❸

❶ Compiles the program using the OpenCoarrays compiler wrapper

❷ Runs the program on five parallel processes

❸ The output of the program

What’s happening here? Each image prints three numbers to the screen: its own image number (this_image()), the total number of images (num_images()), and its team number (team_number()). Let’s look at the values in reverse, from right to left. First, we see that there are two images on team 1 and three on team 2. This is what we expected, as we instructed form team to first assign two images (out of five total) to team 1, and the rest to team 2. So far, so good. Second, notice that two of the images report a total number of images of 2, and the remaining three report a total number of images of 3. This means that when executed within the change team construct, num_images() now doesn’t represent the total number of images running the whole program, but the total number of images within the current team. Finally, looking at the current image number, it seems that our original images 3, 4, and 5 now have numbers 1, 2, and 3 on their new team. Conclusion: when executed within the change team construct, functions this_image and num_images operate in the context of the current team.

Note that the Fortran Standard doesn’t prescribe what the new image numbers on the newly formed teams will be, and leaves the numbering of images on new teams as implementation- (compiler-) dependent. If you need to ensure specific image indices on new teams (or preserve the ones from the initial team), use the new_index argument in the form team statement, described in the previous subsection.

The syntax for the change team construct is

[name:] change team(team_value[, stat, errmsg])     ❶
  ...                                               ❷
end team [name]                                     ❸

❶ Switches all images to the new team with team_value

❷ All code here is executed in the context of the new team.

❸ Synchronizes images and returns them to the original team

where

  • team_value is an input scalar variable or expression of type team_type.
  • stat and errmsg are optional output parameters that have the same meaning as in the form team statement.
  • name is an optional label for the construct, much like a labeled do loop.

At the beginning of a change team construct, all images that execute it switch to the team provided in parentheses. Inside the construct, these images execute within the new team. When they reach the end team statement, the images automatically synchronize and return to the original (parent) team that they were on immediately before the change team statement.

Exercise 1: Hunters and gatherers

Write a parallel program that models a tribe of hunter-gatherers using teams. Form the teams such that this is how they operate:

  • Gatherers comprise 1/2 of all villagers, and they go foraging for fruit and vegetables. When they reach their destination, they split into teams of 2 for more efficient foraging.
  • Hunters comprise 1/3 of all villagers, and they go hunting. When they reach their destination, they split into teams of 3 for more efficient hunting.
  • The remaining 1/6 of villagers are elders, who stay together in the village and rest by the fire pit.

For this exercise, make each team report to the screen:

  1. How many villagers are in each team
  2. When they leave the village
  3. When they engage in an activity

Hint: use a form team statement within a change team construct to create new teams within teams.

The solution to this exercise is given in the “Answer key” section near the end of the chapter.

Changing execution between teams

Leave a Reply

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

Scroll to top