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