Intel® Moderncode for Parallel Architectures
Support for developing parallel programming applications on Intel® Architecture.

Multiple module alignment of Fortran arrays

aidan_c_
Beginner
984 Views

Hi,

I'm having some difficulty getting some alignment between fortran modules (in particular of a 2D array) to be recognised during vectorisation by the compiler.

In module neighbours I declare the following array in the module:

    !> Linked cell list
    Integer( Kind = wi ), Allocatable, Public :: list(:,:)
    !DIR$ ATTRIBUTES ALIGN:64 :: list

and it is allocated with:

  Subroutine init_list(neigh,mxatdm)
    Class( neighbours_type ) :: neigh
    Integer( Kind = wi ), Intent( In    ) :: mxatdm
    Integer :: size_list

    size_list = neigh%max_list + 16-Mod(neigh%max_list,16)
    Allocate (neigh%list(-15:neigh%max_list,1:mxatdm))
    !DIR$ ASSUME_ALIGNED neigh%list(-15,1) : 64

The code uses some of the negative indices, and the main indices start at 1 (for vectorised section of loop). As Kind=wi results in 4 byte integers this should result in alignment being correct I think, and with -check assume, there is no error here.

In another module, this data is then used in a strip-mined loop:

    Do m=1,loop,STRIP_WIDTH
        !DIR$ NOFUSION
        Do n=0,STRIP_WIDTH-1,1
            t_ll(n) = -1
            t_kk(n) = -1
            ! atomic and type indices
            !DIR$ ASSUME_ALIGNED neigh%list(1,iatm) : 64
            jatm=neigh%list(m+n,iatm)
            aj=ltype(jatm)

....

Since its a 2D array, i believe I need to tell the compiler that each row is aligned, and I hoped I could do it in this way, but I'm not sure I can. Either way, this ASSUME_ALIGNED fails with -check assume:

forrtl: severe (408): fort: (28): Check for ASSUME_ALIGNED fails for 'NEIGH' in routine 'RDF_COLLECT' at line 188.

Without this ASSUME_ALIGNED the optimisation report believes neigh%list is not aligned (though it gets confused and believes the variable name is loop - seperate issue however). With the ASSUME_ALIGNED the compiler believes neigh%list is aligned, however it breaks at runtime. This is compiled with Intel 18 update 3 with flags -g -O3 -qopt-report=5 -xCOMMON-AVX512

What is the correct way to tell the compiler of the alignment of a 2D array that exists inside another module? Inside the neighbours module should I do 

!DIR$ ASSUME_ALIGNED neigh%list(-15,1) : 64
!DIR$ ASSUME Mod(size_list,16) == 0

or will that not be passed between modules?

0 Kudos
4 Replies
jimdempseyatthecove
Honored Contributor III
984 Views
    size_list = neigh%max_list + 16-Mod(neigh%max_list,16)
    Allocate (neigh%list(-15:size_list,1:mxatdm))
    !                        ^^^^^^^^^

 

Does that help?

IOW you wanted the first dimension to be a multiple of 16.

Jim Dempsey

0 Kudos
aidan_c_
Beginner
984 Views

Looks like an embarrassing typo, too long of a day - thanks Jim

0 Kudos
TimP
Honored Contributor III
984 Views

Normally, of course, you would set compile option -align:array32byte (or larger) to tell the compiler to align as many arrays as possible, although that shouldn't be necessary for allocatable arrays.

0 Kudos
jimdempseyatthecove
Honored Contributor III
984 Views

I might suggest that you not use the name size_list as it may be misleading. Maybe allocation_max_list might be a better choice of names.

Jim Dempsey

0 Kudos
Reply