Alignment of Allocatable Arrays & Pointers in Intel Fortran Compiler

ID 659008
Updated 12/27/2018
Version Latest
Public

author-image

By

The Intel® Parallel Studio XE 2017 or later for Fortran Windows* and Linux* have a feature enhancement supporting ASSUME_ALIGNED directive at point of use for allocatable arrays or pointers.

For below example:

mod.f90:

module tmod 
  implicit none 
  real, allocatable, dimension(:) :: A, B, C
  !dir$ attributes align:32 :: A, B, C
  !dir$ assume_aligned A:32, B:32, C:32
end module tmod

 

t.f90:

subroutine test
  use tmod 
  implicit none 
  integer :: i

  do i = 1, 1024
        A(i) = 2.*B(i) + C(i) 
  enddo 
end 

The lower bound of array A, B and C in the module will be 32 byte aligned because of the ATTRIBUTES ALIGN directive; however, Intel Fortran compiler version 16.0 or older will not generate aligned load for B and C at the point of use (Store to A is aligned only due to dynamic loop peeling):

ifort -c -xavx -qopt-report=4 -qopt-report-file=stderr -qopt-report-phase=vec t.f90
…
 remark #15388: vectorization support: reference tmod_mp_a_ has aligned access   [ t.f90(6,5) ]
 remark #15389: vectorization support: reference tmod_mp_b_ has unaligned access   [ t.f90(6,5) ]
 remark #15389: vectorization support: reference tmod_mp_c_ has unaligned access   [ t.f90(6,5) ]

The lower bound of an allocatable array or pointer may have been changed at the point of use by array reallocation or pointer re-association so the compiler can’t know the lower bound of A, B or C, especially whether they all have the SAME alignment to generate aligned load for them in subroutine “test”. For the same reason the ASSUME_ALIGNED directive for an allocatable array or pointer at the point of declaration in a module will be ignored by the compiler.

The feature enhancements in Intel Fortran compiler 17.0 or later include support of specifying ASSUME_ALIGNED directive at point of use for an allocatable array or pointer. In the new syntax user must specify which array element is aligned. For above example, user can specify the alignment of A, B and C prior to the loop as:

!DIR$ ASSUME_ALIGNED  A(1):32, B(1):32, C(1):32

Then the compiler will generate aligned load and stores for all arrays:

ifort -c -xavx -qopt-report=4 -qopt-report-file=stderr -qopt-report-phase=vec t.f90
…
   remark #15388: vectorization support: reference a_(i) has aligned access   [ t.f90(7,5) ]
   remark #15388: vectorization support: reference b_(i) has aligned access   [ t.f90(7,15) ]
   remark #15388: vectorization support: reference c_(i) has aligned access   [ t.f90(7,22) ]

With the new syntax user can specify alignment of any array element, e.g.

ALLOCATE (A(-4:1025), B(-12:1033), C(1024))
!DIR$ ASSUME_ALIGNED  A(-4):32, B(-12):32, C(1):32

The alignment assertion by the directive must be true at runtime. If the check assume compiler option is specified and address is not aligned on an n-byte boundary at run-time, an error message is displayed and execution is aborted. 

Refer to the Intel® Parallel Studio XE 2019 or later for Fortran product documentation for additional details.