Intel® Fortran Compiler 18.0 Developer Guide and Reference

MEMKIND

General Compiler Directive: Enables High Band Width (HBW) memory or non-HBW memory allocation for the lexically next ALLOCATE statement. This directive only applies to Intel® 64 architecture targeting the Intel® Xeon Phi™ product family x200 (formerly code name Knights Landing) and it is only available for Linux* systems.

!DIR$ MEMKIND : memory[, ALIGN:n ]

memory

Specifies the requested memory kind. It must be one of the following:

  • HBW

    Enables High Band Width memory allocation for arrays in the lexically next ALLOCATE statement

  • DDR

    Enables non-HBW memory (Double Data Rate Random Access Memory) allocation for arrays in the lexically next ALLOCATE statement

n

Is a positive integer constant expression. Its value must be a positive power of 2, that is, 1, 2, 4, 8, 16, etc, between 1 and 2097152 == 2**21 == 2MB on Linux*. It specifies the requested memory alignment in bytes for this allocation.

This directive must be placed lexically immediately before an ALLOCATE statement (intervening comments and blank lines are allowed; statements and other directives are not allowed). The MEMKIND specified in this directive overrides any ATTRIBUTE MEMKIND that is associated with the object being allocated.

You can inquire about the memory allocation space of a variable using the FOR_GET_MEMKIND intrinsic function.

The following rules apply to deallocation of a variable:

The MEMKIND setting for a variable can be affected by statements other that ALLOCATE and DEALLOCATE:

Example

In the following example, various allocations and deallocations show how MEMKIND is handled.

USE IFCORE
REAL, ALLOCATABLE :: R(:)
!DIR$ ATTRIBUTES MEMKIND:HBW :: R
ALLOCATE(R(100))
PRINT *, FOR_GET_MEMKIND®     ! prints 1 for HBW

CALL DEALLOCME®               ! MEMKIND of R was changed by DEALLOCME 
PRINT *, FOR_GET_MEMKIND®     ! prints 0 for DDR

CALL REALLOCME_HBW®           ! MEMKIND of R is still HBW
print *, for_get_memkind(r)     ! prints 1 for HBW

!DIR$ MEMKIND:DDR, ALIGN:32
ALLOCATE(R(1000))               ! Allocated in DDR, 32-byte aligned
PRINT *, FOR_GET_MEMKIND®     ! prints 0 for DDR

DEALLOCATE®                     ! MEMKIND reverted to HBW, as declared
PRINT *, FOR_GET_MEMKIND®     ! prints 1 for HBW

CALL REALLOCME®               ! MEMKIND of R is HBW at entrance
PRINT *, for_get_memkind®     ! prints 1 for HBW

CONTAINS
   SUBROUTINE DEALLOCME(X)
   REAL, ALLOCATABLE :: X(:)
   DEALLOCATE (X)             ! No attribute on the dummy; revert to DDR
   END SUBROUTINE DEALLOCME

   SUBROUTINE REALLOCME(X)
   REAL, ALLOCATABLE :: X(:)
   ALLOCATE(X(100))           ! Use MEMKIND from the actual argument
   END SUBROUTINE REALLOCME

   SUBROUTINE REALLOCME¬_HBW(X)
   REAL, ALLOCATABLE :: X(:)
   !DIR$ ATTRIBUTES MEMKIND:HBW :: X
   ALLOCATE(X(100))           ! Use MEMKIND specified on dummy argument
   END SUBROUTINE REALLOCME
END

In the following example, allocations and deallocations of pointers are simpler; their MEMKIND always reverts to DDR:

REAL, POINTER :: PR(:)        ! MEMKIND always starts as DDR
print *, for_get_memkind(pr)  ! prints 0 for DDR

!DIR$ MEMKIND:HBW
ALLOCATE(PR(100))             ! Allocate in HBW memory
PRINT *, FOR_GET_MEMKIND(PR)  ! prints 1 for HBW

DEALLOCATE(PR)                ! Resets MEMKIND to DDR
PRINT *, FOR_GET_MEMKIND(PR)  ! prints 0 for DDR

ALLOCATE(PR(55))              ! Allocated in DDR
PRINT *, FOR_GET_MEMKIND(PR)  ! prints 0 for DDR
END

See Also