TASK

OpenMP* Fortran Compiler Directive: Defines a task region.

Syntax

c$OMP TASK [clause[[,] clause] ... ]

   block

c$OMP END TASK

c

Is one of the following: C (or c), !, or * (see Syntax Rules for Compiler Directives).

clause

Is one of the following:

  • DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE)
  • FIRSTPRIVATE (list)
  • IF ( scalar_logical_expression)

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

    If the scalar_logical_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 can appear in the directive.

  • PRIVATE (list)
  • SHARED (list)
  • UNTIED

    Specifies 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.

block

Is a structured block (section) of statements or constructs. You cannot branch into or out of the block (the parallel region).

The TASK and END TASK directive pair must appear in the same routine in the executable section of the code.

The END TASK directive denotes the end of the task.

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 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.

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.

Example

The following example calculates a Fibonacci number. The Fibonacci sequence is 1,1,2,3,5,8,13, etc., where the current number is the sum of the previous two numbers. If a call to function fib is encountered by a single thread in a parallel region, a nested task region will be spawned to carry out the computation in parallel.

RECURSIVE INTEGER FUNCTION fib(n)

INTEGER n, i, j

IF ( n .LT. 2) THEN

fib = n

ELSE

!$OMP TASK SHARED(i)

i = fib( n-1 )

!$OMP END TASK

!$OMP TASK SHARED(j)

j = fib( n-2 )

!$OMP END TASK

!$OMP TASKWAIT ! wait for the sub-tasks to

! complete before summing

fib = i+j

END IF

END FUNCTION

The following example generates a large number of tasks in one thread and executes them with the threads in the parallel team. While generating these tasks, if the implementation reaches the limit generating unassigned tasks, the generating loop may be suspended and the thread used to execute unassigned tasks. When the number of unassigned tasks is sufficiently low, the thread resumes execution of the task generating loop.

real*8 item(10000000)

integer i

!$omp parallel

!$omp single ! loop iteration variable i is private

do i=1,10000000

!$omp task

! i is firstprivate, item is shared

call process(item(i))

!$omp end task

end do

!$omp end single

!$omp end parallel

end

The following example modifies the previous one to use an untied task to generate the unassigned tasks. If the implementation reaches the limit generating unassigned tasks and the generating loop is suspended, any other thread that becomes available can resume the task generation loop.

real*8 item(10000000)

!$omp parallel

!$omp single

!$omp task untied

! loop iteration variable i is private

do i=1,10000000

!$omp task ! i is firstprivate, item is shared

call process(item(i))

!$omp end task

end do

!$omp end task

!$omp end single

!$omp end parallel

See Also