1

The following code produces a memory error when compiled with recent versions of gfortran (10.3 or later):

module distributed_array

  implicit none

  type :: darray_segment
    integer::rank
    integer::offset
    integer::length
    real(kind=8), allocatable::data(:)
  contains
  end type darray_segment

  type :: darray
    type(darray_segment), allocatable::segments(:)
  end type darray

contains

  function new_darray(segments)
    class(darray_segment), intent(in)::segments(:)
    type(darray)::new_darray

    new_darray%segments = segments

  end function new_darray

end module distributed_array

program test_darray

  use distributed_array, ONLY: darray, darray_segment, new_darray

  implicit none

  integer, parameter::np_src = 4
  integer, parameter::np_dest = 3
  type(darray)::src_darray
  type(darray)::dest_darray

  type(darray_segment)::src_segments(np_src)
  type(darray_segment)::dest_segments(np_dest)

  src_darray = new_darray(src_segments)
  dest_darray = new_darray(dest_segments)

end program test_darray

The output produced is as follows:

darray_test: malloc.c:2385: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.

Program received signal SIGABRT: Process abort signal.

Backtrace for this error:
#0  0x7f727c59fbf0 in ???
#1  0x7f727c59ee45 in ???
#2  0x7f727c20d83f in ???
    at /build/glibc-vjB4T1/glibc-2.28/signal/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
#3  0x7f727c20d7bb in __GI_raise
    at ../sysdeps/unix/sysv/linux/raise.c:51
#4  0x7f727c1f8534 in __GI_abort
    at /build/glibc-vjB4T1/glibc-2.28/stdlib/abort.c:79
#5  0x7f727c255a67 in __malloc_assert
    at /build/glibc-vjB4T1/glibc-2.28/malloc/malloc.c:298
#6  0x7f727c257e6e in sysmalloc
    at /build/glibc-vjB4T1/glibc-2.28/malloc/malloc.c:2382
#7  0x7f727c2592c8 in _int_malloc
    at /build/glibc-vjB4T1/glibc-2.28/malloc/malloc.c:4133
#8  0x7f727c25a3e2 in __GI___libc_malloc
    at /build/glibc-vjB4T1/glibc-2.28/malloc/malloc.c:3049
#9  0x401f10 in __distributed_array_MOD_new_darray
    at /test/src/test/darray_tests.F90:23
#10  0x402933 in test_darray
    at /test/src/test/darray_tests.F90:44
#11  0x402aaf in main
    at /test/src/test/darray_tests.F90:31

The code runs without error when compiled with gfortran 4.9.4 and 10.2, but the above error occurs with versions 10.3 and 11.

The problem appears to be related to the assignment operation new_darray%segments = segments. If I declare segments as type(darray_segment) instead of class(darray_segment), then the program no longer crashes. So apparently the problem is triggered by assignment from a polymorphic variable. Is such assignment supposed to be allowed per the Fortran standard?

jhaiduce
  • 408
  • 4
  • 13
  • 3
    My eyes hurt from the `kind=8` in otherwise modern code. – Vladimir F Героям слава May 27 '21 at 18:23
  • If you replace `class` in function `new_darray` with `type`, does the code compile and run? – steve May 27 '21 at 18:54
  • Yes, it does. The question is, should this be necessary? Is assignment from a polymorphic allowed under the standard? – jhaiduce May 27 '21 at 18:57
  • 1
    If you allocate data(:) in all the "darray_segment" objects before calling new_darray(), is there any change in the output? (I guess referring to unallocated arrays on the RHS of polymorphic assignment may be illegal) – roygvib May 27 '21 at 19:00
  • @VladimirF, how do you declare a 64-bit real then? I thought kind=8 was the modern way (as opposed to the older real*8). – jhaiduce May 27 '21 at 19:00
  • 1
    @roygvib, this code does seem to work if I allocate them (even if I allocate them as zero-size arrays). But in the more complex code this example is based on I still get a memory error even when they're allocated. That more complex code also works on older gfortran versions and fails on 10.3 like this one does. – jhaiduce May 27 '21 at 19:12
  • I think you should be able to use `class`, but the code to support `class` is much newer than the code to support `type`. If it works with `type`, this is a clue to where in the code generation path that gfortran mishandles `class`. It's a step in debugging the issue. YMMV. – steve May 27 '21 at 19:15
  • 1
    Then, could you also try (1) changing "new_darray%segments = segments" to "allocate( new_darray%segments, source= segments )", and if it doesn't help, try also (2) declaring the result variable of "function new_darray(segments)" explicitly (rather than using the function name as the result variable)? In my experience, these two points often help avoid possible compiler issues. – roygvib May 27 '21 at 19:18
  • 1
    @jhaiduce For 64-bit See https://stackoverflow.com/questions/838310/fortran-90-kind-parameter – Vladimir F Героям слава May 27 '21 at 19:19
  • 1
    @roygvib explicitly allocating new_darray%segments "allocate( new_darray%segments, source= segments )" works. Declaring a different name for the result variable didn't change the result. – jhaiduce May 27 '21 at 19:24
  • 1
    Works for me with ifort (IFORT) 2021.1 Beta 20201112 and ifx (IFORT) 2021.1 Beta 20201113. Apart from the real( 8 ) abomination looks fine to me. Suspect compiler bug, but I don't claim to be a true expert on this new fangled stuff. – Ian Bush May 27 '21 at 19:54
  • 1
    @jhaiduce "That more complex code also works on older gfortran versions and fails on 10.3 like this one does." I'm also using Gfortran (now 10.2) so sharing the same concern... . In my case I still avoid "constructor functions" (to avoid possible compiler issues and also copy of objects), while using "constructor subroutine" (which goes by reference and use polymorphic allocation inside). Anyway, I think it would be nice to compare/check results from different compilers (which I think now easier with OneAPI :) – roygvib May 28 '21 at 08:05
  • Sounds like this is likely a compiler bug, so I filed a bug report at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100814. In the meantime I have a couple workarounds, thanks all! – jhaiduce May 28 '21 at 14:02

0 Answers0