Dear Tobias, hi all,

On 21.12.22 09:40, Tobias Melson via Fortran wrote:
I am wondering about alignment of allocatable arrays: Does the
gfortran compiler in its latest version automatically align arrays to
the 64 byte boundary? For comparison, the Intel compiler has a flag
"-align array64byte", which forces alignment of all arrays (except for
the ones in COMMON). I did not find something similar in the gfortran
documentation.

I concur that this feature is useful. But I think that's currently not
possible.

Workaround: Do the allocation with C. The more invasive method is with
pointers and the 'call c_f_pointer'. The more flexible method, using
allocatables (or pointers) is to use the C descriptor on the C side
(CFI_allocate etc.) – for the latter GCC 12 (or later) is recommended as
there were several bugfixes.

(Side remark: "!$omp allocators allocate(align(64) : foobar);
allocate(foobar...)" or (deprecated) "!$omp allocate(foobar) align(64);
allocate(foobar...)" would do something like that – but that's not yet
implemented in GCC/gfortran. [Support is planned, but will take a while,
only parsing-only support is nearly ready.].)

Best regards from Munich
Tobias

Best regards – usually but not currently also from Munich,

Tobias

PS: Regarding the C array descriptor, I mean something like, which is
GCC specific as other compilers might do more complex things inside
CFI_allocate – GCC only does:
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libgfortran/runtime/ISO_Fortran_binding.c#l212
and calls a normal 'free' on deallocate.

#include <ISO_Fortran_binding.h>
#include <stdlib.h>

void my_allocate_rank1 (CFI_cdesc_t *dv, const size_t lower_bounds[],
              const size_t upper_bounds[], size_t alignment)
{
// Using 'dv->elem_len' assumes no 'character(len=:)' as type, cf. CFI_allocate
// in the ISO Fortran standard and in libgfortran's implementation
  size_t sz = upper_bounds[0] < lower_bounds[0] ? 0
   : upper_bounds[0} - lower_bounds[0] + 1;
  posix_memalign (&dv->base_addr, alignment, dv->elem_len * sz);
  dv->dim[0].extend = sz;
  dv->dim[0].lower_bound = lower_bounds[0];
  dv->dim[0].sm = elem_len;
}

And something like the following (unfortunately 'type(*)' is not permitted
with allocatable, hence 'real' is used):

interface
  subroutine my_allocate_rank1 (x, lower_bounds, upper_bounds, alignment) 
bind(C)
    use iso_c_binding
    real, allocatable :: x(:)
    ! intent(out) :: x  ! to auto-deallocate
    integer(c_size_t) :: lower_bounds(1), upper_bounds(1)
    integer(c_size_t), value :: alignment
  end
end interface
real, allocatable :: var(:)
call my_allocate_rank1 (var, [1], [N], 64)
end

-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955

Reply via email to