Intel® Fortran Compiler Classic and Intel® Fortran Compiler Developer Guide and Reference

ID 767251
Date 11/07/2023
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

TASKLOOP

OpenMP* Fortran Compiler Directive: Specifies that the iterations of one or more associated DO loops should be executed in parallel using OpenMP* tasks. The iterations are distributed across tasks that are created by the construct and scheduled to be executed.

Syntax

!$OMP TASKLOOP [clause[[,] clause]... ]

   do-loop

[!$OMP END TASKLOOP]

clause

Is one of the following:

  • ALLOCATE ([allocator :] list)

  • COLLAPSE (n)

  • DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE)

  • FINAL (scalar-logical-expression)

  • FIRSTPRIVATE (list)
  • GRAINSIZE ( [STRICT:] grain-size)

    Specifies that the number of logical loop iterations assigned to each created task is greater than or equal to the minimum of the value of the grain-size positive integer expression and the number of logical loop iterations, but less than two times the value of the grain-size expression.

    STRICT is only permitted for ifx.

    If STRICT is specified, each generated task is exactly grain-size, except for the task that contains the sequentially last iterations, which may have fewer iterations.

    At most one GRAINSIZE clause can appear in a TASKLOOP directive.

  • IF ([TASKLOOP:] scalar-logical-expression)

    If the scalar-logical-expression evaluates to false, undeferred tasks are generated. If a variable appears in the IF clause expression, it causes an implicit reference to the variable in all enclosing constructs.

    At most one IF clause can appear in a TASKLOOP directive.

  • IN_REDUCTION (reduction-identifier : list)

  • LASTPRIVATE ([CONDITIONAL:] list)

  • MERGEABLE

  • NOGROUP

    Specifies that no implicit taskgroup region is created.

  • NUM_TASKS ( [STRICT:] num-tasks)

    Causes the TASKLOOP construct to create as many tasks as the minimum of the num-tasks positive scalar integer expression and the number of logical loop iterations. Each task must have at least one logical loop iteration.

    STRICT is only permitted for ifx.

    If STRICT is specified, a loop with N iterations is partitioned such that each task is assigned N / num-tasks iterations. If num-tasks does not divide N evenly, the last task is assigned a partition of size MOD (num-tasks, N).

  • PRIORITY (priority-value)

  • PRIVATE (list)
  • REDUCTION ([DEFAULT,] reduction-identifier : list)

    If you specify this clause, you cannot specify the NOGROUP clause.

  • SHARED (list)
  • UNTIED

do-loop

Is one or more DO iterations (DO loops). The DO iteration cannot be a DO WHILE or a DO loop without loop control. The DO loop iteration variable must be of type integer.

If an END TASKLOOP directive follows a DO construct in which several loop statements share a DO termination statement, then the directive can only be specified for the outermost of these DO statements. The TASKLOOP construct inherits the restrictions of the loop construct.

If any of the loop iteration variables would otherwise be shared, they are implicitly made private for the loop-iteration tasks created by the TASKLOOP construct. Unless the loop iteration variables are specified in a LASTPRIVATE clause on the TASKLOOP construct, their values after the loop are unspecified.

You cannot branch out of a DO loop associated with a TASKLOOP directive.

If you do not specify GRAINSIZE or NUM_TASKS, the number of loop tasks created and the number of logical loop iterations assigned to these tasks is implementation defined. The GRAINSIZE clause and NUM_TASKS clauses are mutually exclusive; they cannot appear in the same TASKLOOP directive.

The binding thread set of the TASKLOOP region is the current team. A TASKLOOP region binds to the innermost enclosing parallel region.

When a thread encounters a TASKLOOP construct, the construct partitions the associated loops into tasks for parallel execution of the loop iterations. The data environment of the created tasks is created according to the clauses specified in the TASKLOOP construct, any data environment ICVs, and any defaults that apply. The order of the creation of the loop tasks is unspecified. Programs that rely on any execution order of the logical loop iterations are non-conforming.

If used, the END TASKLOOP directive must appear immediately after the end of the loop. If you do not specify an END TASKLOOP directive, an END TASKLOOP directive is assumed at the end of the do-loop.

By default, the TASKLOOP construct executes as if it was enclosed in a TASKGROUP construct with no statements or directives outside of the TASKLOOP construct. Therefore, the TASKLOOP construct creates an implicit TASKGROUP region.

When a REDUCTION clause appears in a TASKLOOP construct, it behaves as if a TASK_REDUCTION clause was applied to the implicit TASKGROUP construct enclosing the TASKLOOP construct. For each task that is generated by the TASKLOOP construct, an IN_REDUCTION clause with the same reduction-identifier and the same list items that appear in the REDUCTION clause is applied to the task. Each generated task participates in the reduction defined by the IN_REDUCTION clause applied to the implicit TASKGROUP construct.

When an IN_REDUCTION clause appears in a TASKLOOP construct, an IN_REDUCTION clause with the same reduction-identifier and the same list items of the IN_REDUCTION clause is applied to the generated tasks. The behavior is the same as if each generated task was defined by a TASK construct that contains an IN_REDUCTION clause with the same reduction-identifier and list items. The generated tasks participate in a reduction defined by a previous reduction scoping clause.

A list item must not appear in both a REDUCTION and IN_REDUCTION clause in the same TASKLOOP directive.

The following restrictions also apply:

  • A program that branches into or out of a TASKLOOP region is non-conforming.

  • All loops associated with the TASKLOOP construct must be perfectly nested. There must be no intervening code nor any other OpenMP* directive between any two loops.

NOTE:

This construct is not supported within a TARGET or a DECLARE TARGET region if the target hardware is spir64.