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

TARGET VARIANT DISPATCH

Offloading Compiler Directive: Conditionally calls a procedure offload variant if the device is free; otherwise, executes the procedure on the host. This directive is an Intel® language extension. This feature is only available for ifx.

!$OMP TARGET VARIANT DISPATCH [clause[[,] clause]]

CALL subr (...)

-or-

!$OMP TARGET VARIANT DISPATCH [clause[[,] clause]]

var = func (...)

clause

Is one or more of the following:

This directive causes the compiler to emit conditional dispatch code around the associated subroutine or function call that follows the directive. If the default device is available, the variant version is called. If DEVICE (integer-expression) is specified, the variant is called only if device integer-expression is available. If SUBDEVICE is specified, the variant is called only if the specified tiles or compute slices are available. If both DEVICE(n) and SUBDEVICE are specified, the variant is called only if the specified tiles or compute slices are available on device n. Otherwise, the base version of the procedure is called on the host.

The NOWAIT clause, if present, indicates calls to the procedure can occur asynchronously. If NOWAIT is not present, calls occur synchronously.

The name of the subroutine or function associated with the TARGET VARIANT DISPATCH directive must have appeared in a DECLARE VARIANT directive in the specification part of the calling scope. The interface of the variant procedure must be accessible in the base procedure where the DECLARE VARIANT directive appears.

The procedure called in the statement following the TARGET VARIANT DISPATCH directive must have an explicit interface accessible at the call site.

The variant version of the procedure has an identical interface as the base function, except the variant has an additional argument in the last position which is of type C_PTR. This final argument does not appear in the TARGET VARIANT DISPATCH call, rather, the compiler inserts it if the variant is called.

Example

MODULE vecadd
  INTEGER,PARAMETER  :: n = 1024
CONTAINS
  FUNCTION vecadd_gpu_offload (ptr)RESULT (res)
    USE,INTRINSIC :: ISO_C_BINDING, ONLY : c_ptr
    !$DEC ATTRIBUTES NOINLINE :: vecadd_gpu_offload
    REAL              :: res
    REAL,DIMENSION(n) :: a, b
    INTEGER           :: k

    res   = a(k) + b(k)
    PRINT *, "GPU version of vecadd called"
  END FUNCTION vecadd_gpu_offload

  FUNCTION vecadd_base ()RESULT (res)
    !$DEC ATTRIBUTES NOINLINE :: vecadd_base
    !$OMP DECLARE VARIANT (vecadd_gpu_offload) match(construct={target variant dispatch}&
    !$OMP&                ,device = {arch (gen)} )
    REAL              :: res
    REAL,DIMENSION(n) :: a, b
    INTEGER           :: k

    Res   = a(k) + b(k)
    PRINT *, "CPU version of vecadd called"
  END FUNCTION vecadd_base
END MODULE vecadd

PROGRAM main
  USE vecadd
  REAL    :: result = 0.0

  !$OMP TARGET VARIANT DISPATCH 
  result = vecadd_base ()
  !$OMP END TARGET VARIANT DISPATCH

  IF (result == 1048576.0) then
    PRINT *, "PASSED: correct results"
  ELSE 
    PRINT *, "FAILED: incorrect results"
  ENDIF
END PROGRAM