omp task

Specifies the beginning of a code block whose execution may be deferred.

Syntax

#pragma omp task [clause[[,]clause ]...]

block

Arguments

clause

clause can be any of the following:

final(scalar_expression)

When the scalar_expression evaluates to true, it specifies that the generated task will be a final task.

Note

final task is a task that forces all of its descendant tasks to become included tasks.

All task constructs encountered during execution of a final task will generate included tasks.

Note that if a variable is used in a final clause expression of a task construct, it causes an implicit reference to the variable in all enclosing constructs.

Only a single final clause can appear in the task pragma.

private(list)

Specifies a list of variables that are to be considered private within the task.

firstprivate(list)

Specifies a list of variables that are private and in addition are initialized from a variable of the same name in the enclosing syntactic context at the time the task is created.

shared(list)

Specifies a list of variables in the enclosing syntactic context that will be referenced inside the task.

default(shared|none)

default(shared) specifies that the variables used in a task, but not explicitly declared in a private, firstprivate or shared clause will be made shared. default(none) specifies that the variables used in a task, but not explicitly declared in a private , firstprivate , or shared clause will be flagged with a syntax error at compile time.

untied

Specifies that the task is never tied to the thread that started its execution. Any thread in the team can resume the task region after a suspension. For example, during runtime, the compiler can start the execution of a given task on thread A, break execution, and later resume it on thread B.

if(scalar_expression)

Specifies that the enclosed code section is to be executed in parallel only if the scalar_expression evaluates to true. If this clause is not used, the region is executed as if an if(true) clause was specified.

If the scalar_expression evaluates to false, the encountering thread must suspend the current task region and begin execution of the generated task immediately. The suspended task region will not be resumed until the generated task is completed.

This clause is evaluated by the master thread before any data scope attributes take effect.

Only a single if clause may appear in the task pragma.

mergeable

When the generated task is an undeferred task or an included task, it specifies that the implementation may generate a merged task instead.

Note

An undeferred task is a task for which execution is not deferred with respect to its generating task region, that is, its generating task region is suspended until execution of the undeferred task is completed.

An included task is a task for which execution is sequentially included in the generating task region, that is, it is undeferred and executed immediately by the encountering thread.

A merged task is a task whose data environment, inclusive of internal control variables, is the same as that of its generating task region. Internal control variables (ICVs) are discussed in the latest OpenMP* specifications.

block

Is a structured block of statements or constructs. You cannot branch into or out of the block.

Description

When a thread encounters a task construct, a task is generated from the code for the associated structured block. The encountering thread may immediately execute the task, or defer its execution. In the latter case, any thread in the team may be assigned the task.

A thread that encounters a task scheduling point within the task region may temporarily suspend the task region. By default, a task is then tied and its suspended task region can only be resumed by the thread that started its execution. However, if the untied clause is specified in a task construct, any thread in the team can resume the task region after a suspension. The untied clause is ignored in following cases:

  • If a final clause has been specified in the same task construct and the final clause expression evaluates to true
  • If a task is an included task

A task construct may be nested inside an outer task, but the task region of the inner task is not a part of the task region of the outer task.

The task construct includes a task scheduling point in the task region of its generating task, immediately following the generation of the explicit task. Each explicit task region includes a task scheduling point at its point of completion. An implementation may add task scheduling points anywhere in untied task regions.

Note that when storage is shared by an explicit task region, you must add proper synchronization to ensure that the storage does not reach the end of its lifetime before the explicit task region completes its execution.

A program must not depend on any ordering of the evaluations of the clauses of the task pragma and it must not depend on any side effects of the evaluations of the clauses. A program that branches into or out of a task region is non-conforming.

Unsynchronized use of C++ I/O statements by multiple tasks on the same unit has unspecified behavior.

Example

struct node {
  struct node *left;
  struct node *right;
};

extern void process(struct node *);
int depth, limit;

void traverse( struct node *p ) {
  // When depth>limit, stop generating new tasks, and allow the 
  // compiler to avoid creating a new data environment.

  if (p->left)
  #pragma omp task final(depth>limit) mergeable
    // p is firstprivate by default
traverse(p->left);
if (p->right)
#pragma omp task final(depth>limit) mergeable
     // p is firstprivate by default
traverse(p->right);
process(p);
}

For more complete information about compiler optimizations, see our Optimization Notice.