#pragma omp teams
Purpose
The omp teams directive creates a collection of thread teams. The master thread of each team executes the teams region.
Syntax
.-+---+------. | '-,-' | V | >>-#--pragma--omp teams----+--------+-+------------------------>< '-clause-'
>>-block-------------------------------------------------------><
Parameters
clause is any of the
following clauses:
- default(none|shared)
- Specifies the default attribute of variables referenced inside the teams region. Specifying default(none) requires variables with no implicit data sharing attributes to be specified on firstprivate, private or shared clause.
- firstprivate(list)
- Similar to the private clause, except the private copy is initialized with the value of the original variable. Data variables in list are separated by commas.
- num_teams(exp)
- Specifies an upper limit on the number of teams created. You can obtain the number of teams in a thread by calling the omp_get_num_teams function. The expression represented by exp must evaluate to a positive integer value.
- private(list)
- Declares one or more list items to be private to the team. For every list item, a local copy is created for each team as if the variable was an automatic declared with no initializers. All references to the original list item in the teams region are replaced with references to the private copy. A copy is created per team; hence that copy is shared among the threads in the team. Data variables in list are separated by commas.
- reduction(reduction-identifier:list)
- Specifies a reduction operator and a list of reduction variables. For each reduction variable, a private copy is created and initialized with the value of the reduction-identifier. At the end of the teams region, the master threads of all teams perform a reduction into the value of the original variable.
- Scalar variables are supported in list. Items in list are separated by commas. reduction-identifier is one of the following operators: +, -, *, &, |, ^, &&, and ||.
- shared(list)
- Declares one or more list items to be shared among the teams. Data variables in list are separated by commas.
- thread_limit(exp)
- Specifies an upper limit on the number of threads inside each team. The expression represented by exp must evaluate to a positive integer value.
Usage
- For a target region without specifying teams, a single team is created and its master thread executes the target region.
- The omp teams directive must be strictly nested inside
the target region, that is, no code can exist between the omp target directive
and the omp teams directive. You must strictly nest the following
OpenMP regions inside the teams region:
- omp distribute
- omp distribute simd
- omp distribute parallel for
- omp distribute parallel for simd
- Parallel regions, including any parallel regions arising from combined constructs
- Basically, the compiler creates as many teams as you request.
However, if the number you request exceeds either of the following
numbers, teams of the smaller number between the two are created:
- The value specified on the num_teams clause
- 65536, which is the implementation defined limit
- Basically, the compiler creates as many threads per team as you
request. However, if the number you request exceeds either of the
following numbers, threads of the smaller number between the two are
created per team:
- The value specified on the thread_limit clause
- 992, which is the implementation defined limit
- After the teams are created, the number of teams remains constant for the duration of the teams region.
- When the omp teams directive is used as part of a combined construct, for example, the omp target teams directive, the expression used in the num_teams or thread_limit clause is evaluated on the host.
- Within a teams region, each team has a unique team number. Team numbers are consecutive integers that range from zero to one less than the number of teams. You can obtain the team number by calling the omp_get_team_num function.
Example
#include <stdlib.h>
#include <assert.h>
#include <omp.h>
int foo();
int main()
{
int res = 0, n = 0;
#pragma omp target teams num_teams(foo()) map(res, n) reduction(+:res)
{
res = omp_get_team_num();
if (omp_get_team_num() == 0)
n = omp_get_num_teams();
}
Assert (res == (n*(n-1))/2); // Sum of first n-1 natural numbers
}
In the preceding example, foo() is evaluated on the host and does not need to be specified using the declare target directive. The example performs a teams reduction on the mapped variable res. Because only the master thread of each team executes the team region, the team-private reduction variable res is safely updated to the team number of the thread. Teams are numbered from zero to the number of teams in the current teams region, which can be obtained at run time by calling the omp_get_num_teams function. Finally, to safely update n with the actual number of teams, only one master thread should perform the write.