I'm struggling with some Modern Fortran wrappers to some MPI scatter/gather routines. I am trying to have a wrapper interface that only has an array on input and returns the MPI-operated result on output, for several derived types, doing something like this:
type(mytype), allocatable :: chunk(:),whole(:)
! [...] chunk descends from previous parts of the code
! Get global array
whole = gatherv(array=chunk,receiver_node=cpuid)
I'm doing this using functions that return allocatable arrays. However, I'm getting segmentation fault on both gcc 6.2.0 and gcc 7.1.0 whenever I return a non-allocated result.
The reason I need a non-allocated result is that sometimes I need to gather the whole array only on a specified CPU, so I don't want to waste memory on all other nodes: the receiver node returns an allocated array with the data, and all other nodes receive an empty and deallocated array.
This is sample code that reproduces the issue:
program test_allocatable_fun
implicit none
integer, allocatable :: my_array(:)
integer :: n
n = 3; my_array = unallocated_array(n); print *, 'n=',n,' allocated(array)=',allocated(my_array)
n =-3; my_array = unallocated_array(n); print *, 'n=',n,' allocated(array)=',allocated(my_array)
n = 5; my_array = unallocated_array(n); print *, 'n=',n,' allocated(array)=',allocated(my_array)
n = 0; my_array = unallocated_array(n); print *, 'n=',n,' allocated(array)=',allocated(my_array)
return
contains
function unallocated_array(n) result(array)
integer, intent(in) :: n
integer, allocatable :: array(:)
integer :: j
if (n>0) then
allocate(array(n))
array(:) = [(j,j=1,n)]
else
if (allocated(array)) deallocate(array)
end if
end function unallocated_array
end program test_allocatable_fun
The segmentation fault happens at the assignment line, i.e.:
my_array = unallocated_array(n)
Has any of you had the same issue before? Or, am I violating anything in the standard? I can't see why a function returning an allocatable array should be forced to have the return value allocated. Isn't it the same as having an intent(out) dummy variable in a subroutine?
0size ? I suspect that might be the right way to go. That way your code doesn't need to be checking all the time for the allocation status of the returned array.size()intrinsic what would the difference be between an unallocated and a 0-size, allocated array in memory?