Developer Guide and Reference

ID 767251
Date 10/31/2024
Public
Document Table of Contents

DECLARE TARGET

OpenMP* Fortran Compiler Directive: Specifies that named variables, common blocks, functions, and subroutines are mapped to a device.

Syntax

!$OMP DECLARE TARGET [(extended-list)]

-or-

!$OMP DECLARE TARGET [clause[[,]clause]...]

extended-list

Is a list of one or more variables or array sections that are neither coindexed nor substrings, a common block name enclosed in slashes, or a procedure name. If you specify more than one extended-list item, they must be separated by commas. A common block name must appear between slashes (/ /); you cannot specify a blank common block.

The specified extended-list items can be used inside a target region that executes on the device.

Any list items that have appeared in a GROUPPRIVATE directive are treated as if they appear in an implicit LOCAL clause in the DECLARE TARGET directive; other list items with the SAVE attribute are treated as if they appear in an implicit ENTER clause on the DECLARE TARGET directive.

If the extended-list item is a procedure name, it must not be a generic name or entry name. A device-specific version of the routine is created that can be called from a target region.

If the extended-list item is a variable:

  • It is mapped to a corresponding variable in the device data environment. If the variable is initialized, the corresponding variable in the device data environment is initialized with the same value.

  • It can only appear in the scope in which it is declared.

  • It must be declared in the Fortran scope of a module, or it must have the SAVE attribute (explicitly or implicitly).

You cannot specify the following variables in the DECLARE TARGET directive:

  • A THREADPRIVATE variable

  • A variable that is part of another variable (for example, an element in an array or a field of a structure)

  • A variable that is an element of a common block

  • A variable that appears in an EQUIVALENCE statement

If the extended-list item is a common block:

  • It must be declared to be a common block in the same scoping unit in which the DECLARE TARGET directive appears.

  • If the DECLARE TARGET directive specifying the common block name appears in one program unit, a DECLARE TARGET directive must also appear in every other program unit that contains a COMMON statement specifying the same common block name. The directive must appear after the last relevant COMMON statement in the program unit.

clause

Is one of the following:

  • DEVICE_TYPE (device)

  • ENTER (extended-list)

    ENTER replaces TO, which has been deprecated.

    extended-list is a comma-separated collection of one or more list items or procedures.

    If a list item is a procedure, then a device-specific version of the procedure is created that can be called from a target region.

    If a list item is a variable, then the original variable is mapped to a corresponding variable in the device data environment as if it had appeared in a MAP clause with the map-type TO on the implicit TARGET DATA construct for each device.

    The list item is never removed from those device data environments.

  • INDIRECT [ (invoked-by-ptr-ref) ]

    invoked-by-ptr-ref is a constant scalar logical expression evaluated at compile time.

    If it evaluates to .TRUE., or if it is omitted, procedures specified in an ENTER clause can be called by an indirect device invocation. If it evaluates to .FALSE., procedures specified in an ENTER clause cannot be called by an indirect device invocation. See the Glossary, section I, for the definition of indirect device invocation.

    If the INDIRECT clause does not appear in the directive, procedures specified in an ENTER clause cannot be called by an indirect device invocation.

  • LINK (list)

    Maps the list items for specific device executions, supporting functions called in a TARGET region that refer to the list items. list items are mapped as if they had appeared in a MAP clause with a map-type of TOFROM.

    The list is a comma-separated list of one or more non-coindexed variables, arrays, array sections, named constants, associate names, or common block names enclosed in slashes (//).

    A LINK list item cannot be a variable for which NOHOST has been specified.

  • LOCAL (variable-list)

    Specifies that references to list items are references to device local copies of the list items stored in memory local to the device. The variable-list items can be variables or array sections.

  • TO (extended-list) - deprecated (see ENTER clause above)

    The extended-list is a comma-separated collection of one or more list items or procedures.

    If a list item is a procedure, then a device-specific version of the procedure is created that can be called from a target region.

    If a list item is a variable, then the original variable is mapped to a corresponding variable in the device data environment as if it had appeared in a MAP clause with the map-type TO on the implicit TARGET DATA construct for each device.

    The list item is never removed from those device data environments.

If you specify list, this directive can only appear in a specification part of a subroutine, function, program, or module. It is a pure directive, so it can appear in a Fortran PURE procedure.

If you do not specify list, the directive must appear in the specification part of the enclosing subroutine, function, or interface block.

If no clause and no extended-list appear, the behavior is as if an implicit ENTER clause appears with one list item that is the name of the enclosing subroutine or function.

If extended-list appears, no clauses can appear in the directive. If a clause appears, the directive must contain at least one ENTER, LINK, LOCAL, or TO clause. An object that has been declared in a GROUPPRIVATE directive cannot be a list item in a ENTER or LINK clause.

The DEVICE_TYPE clause indicates whether versions of the procedure should be compiled for the host, device, or both. Specifying HOST compiles only a host version, specifying NOHOST compiles a version for only the device, and specifying ANY indicates a version for both host and device should be compiled.

If no DEVICE_TYPE clause is present, it is as if DEVICE_TYPE (ANY) appears. Internal procedures contained in a procedure that has a DEVICE_TYPE clause in a DECLARE TARGET directive cannot contain DECLARE TARGET directives themselves; the enclosing DEVICE_TYPE clause implicitly applies to the internal procedures.

At most one DEVICE_TYPE clause can appear. If an INDIRECT clause appears and invoked-by-ptr-ref evaluates to .TRUE., DEVICE_TYPE must be ANY.

If a DECLARE TARGET directive is specified in an interface block for a procedure, it must match a DECLARE TARGET directive in the definition of the procedure, including the DEVICE_TYPE clause if it appears.

If a procedure is declared in a procedure declaration statement, any DECLARE TARGET directive containing the procedure name must appear in the same specification part.

A DECLARE TARGET directive with no clauses, or one that has a DEVICE_TYPE clause must appear in the specification part of a subroutine or function subprogram, or in an interface body.

A list item cannot appear as both an extended-list item in an ENTER clause in one DECLARE TARGET directive, and as a list item in a LINK clause in another DECLARE TARGET directive. An extended-list item in an ENTER clause must not have an initializer that references a list item in a LINK clause on a DECLARE TARGET directive.

The following additional rules apply to variables and common blocks:

  • The DECLARE TARGET directive must appear in the declaration section of a scoping unit in which the common block or variable is declared.

  • If a variable or common block is declared with the BIND attribute, the corresponding C entities must also be specified in a DECLARE TARGET directive in the C program.

Variables with static storage and procedures used in an OMP TARGET region are implicitly treated as OMP DECLARE TARGET:

MODULE VARS
  INTEGER X
END MODULE

REAL FUNCTION FOO()
END FUNCTION

!$OMP TARGET 
  X = FOO()       ! X and FOO are implicitly DECLARE TARGET
!$OMP END TARGET