Before we dive into the implementation of teams in the tsunami simulator, let’s look at the syntax of forming new teams, which will apply to any parallel program that uses them. In the beginning of the program, there’s only one team, and we’ll refer to it as the initial team. All images that run the program start in the initial team by default. If you intend to work with teams at all, the first thing you’ll do is form new teams within the initial team using the form team statement. You can make as many new teams as you want. In this example, we’ll create two new teams–one for the first half of all images and the other for the rest–as shown in the following listing.
Listing 12.2 Forming two new teams with equal numbers of images
program form_team
use iso_fortran_env, only: team_type ❶
implicit none
type(team_type) :: new_team ❷
integer :: team_num ❸
team_num = 1 ❹
if (this_image() > num_images() / 2) team_num = 2 ❺
form team(team_num, new_team) ❻
end program form_team
❶ Imports team_type from the iso_fortran_env module
❷ Declares a new team_type instance
❸ Team number variable that we’ll use to identify sibling teams
❹ All images will go to team 1 by default.
Besides the basic housekeeping, like importing the team_type from the iso_fortran _env module and declaring the team and team number variables, there are two key elements here. First, we decide how many new teams to create and which images will go to each team. We do this by assigning values to the integer variable team_num on every image. Second, we execute the form team statement, which creates new teams and internally assigns the images to them. If you compile and run this program, there will be no output. This is expected, as a form team statement on its own doesn’t emit any output.
A form_team statement must be executed by all images on the current team. The first form team statement in the program is thus always executed by all images in the program. This statement also synchronizes all the images on the team, implying a sync all under the hood. (See chapter 8 for a refresher on synchronizing images.) This is the syntax of the form team statement:
form team(team_num, team_variable[, new_index, stat, errmsg])
team_numis a positive, scalar, integer constant or expression that uniquely identifies the team to be created.team_variableis a scalar variable of typeteam_type.new_indexis a scalar integer that allows you to specify an image number that this image will have on the new team.statis the integer status code, with a zero value in case of success and nonzero otherwiseerrmsgis the character string with an informative error message, ifstatreturns a nonzero value.
team_num and team_variable are required input parameters. The value of team_num across images determines how many teams will be created with the form team statement and which image will belong to which new team. If multiple new teams are created, their numbers don’t need to be contiguous, but they need to be unique positive integers. new_index is an optional input parameter that you can use to specify the number of the image on the new team, which is otherwise compiler-dependent. If provided, the values of new_index must be unique and less than or equal to the number of images being assigned to the new team. stat and errmsg, both optional output parameters, have the same meaning and behavior as they do in the allocate and deallocate statements in chapter 5. As you’ll see throughout the remainder of this chapter, all parallel features introduced by Fortran 2018 have error handling built in.