allocatable function result

Dear all,

I think I found a major pgi fortran memory leak bug:

I was trying to test the following code (adapted from allocatable function results example at: http://www.nag.co.uk/nagware/np/doc/tr.asp)

module array_mod
  contains
    function allocate_a(i)
      integer, allocatable, dimension(:) :: allocate_a
      integer :: i
      allocate(allocate_a(i))
      allocate_a = 1
    end function
end module

program test
  use array_mod
  integer, allocatable, dimension(:) :: x
  allocate(x(10))
  x = allocate_a(10)
  print *,x
  deallocate(x)
end

The output of this program is
1 1 1 1 1 1 1 1 1 1

When I try to run it with valgrind however, the output is:

...
total heap usage: 6 allocs, 2 frees, ...
...

Indicating 4 unfreed memory blocks (from which 3 are still reachable, 1 is lost).

According to what I found, allocatable function results should be supported from the TR15581 extension. Why does valgrind report memory leaks?

gfortran doesn’t even compile this code, so I cannot test what valgrind reports then.

Is this normal behavior or is this due to valgrind?
Aren’t automatic allocated arrays automatically unallocated after being used at subroutine exits (unless save is specified)?
Aren’t they automatically unallocated at function exits?


Edit:
For the sake of completeness, my end goal is to make a module with a function which returns an array from which we don’t know the size until runtime. I want to do this with convenience for the user, meaning the following:

  • The user doesn’t have to declare the dimensions of the array containing the function results in the main program.
  • The user doesn’t have to deallocate anything. It should be done automatically. Just call the function, that’s it!
  • The function should be callable several times in the same main program.
  • The program also has to be compatible with gfortran.

My solution: An implementation with pure pointers (although the second requirement is not met):

module array_mod
contains
  function allocate_a_(x,k)
    implicit none
    integer :: x(:)
    integer, dimension(:,:), pointer :: allocate_a_
    integer :: k, n
    integer :: i, j, counter

    nullify(allocate_a_)
    n = size(x)
    if (n .eq. k) then
      allocate(allocate_a_(k,1))
      allocate_a_(:,1) = x
    else
      allocate(allocate_a_(k,n))
      allocate_a_(:,1) = x(1:k)
      allocate_a_(:,2:) = reshape((/ (x(1:k)+i,i=1,n-1) /),(/k,n-1/))
    endif
  end function
end module

program test
  use array_mod
  implicit none
  integer x(5)
  data x /1, 2, 3, 4, 5/
  integer, pointer :: f_(:,:)

  f_ => allocate_a_(x,5)
  print *,f_
  deallocate(f_)

  f_ => allocate_a_(x,3)
  print *,f_
  deallocate(f_)
end

The output is correct:

1            2            3            4            5

1            2            3
2            3            4
3            4            5
4            5            6
5            6            7

When running valgrind on the gfortran compiled version, 14 allocks and frees are detected. With the pgi fortran version, 33 allocks and 27 frees ==> memory leaks

How can this problem be solved? Why is there a leak?


Any ideas would help tremendously!

keywords: TR15581, allocatable, memory leak, valgrind, heap, lost blocks, function result, dynamic arrays, array pointers

Hi,

Thank you for reporting this to us. No, valgrind does not fool you in this case. We are aware of the issue. We deallocate allocated memory. However, we have kept a limited amount of allocated memory around for optimization purpose.

Hongyon

Thank you for the quick reply.

So does that mean that the reported leaks will crash our computers over time?

I’m especially worried about our parallel processing jobs which work with a huge amount of allocatable arrays of big sizes. We also use pointers a lot. I have seen strange memory consumptions on our supercomputers when we run those models.

However, we have have kept a limited amount of allocated memory around for optimization purpose.

Valgrind reports roughly 25% of that allocated memory as being lost. Will this issue be fixed or kept as a feature?

I doubt that it will crash for this particular case unless there is really a memory leak somewhere else. If you are worried about this, please send request or express concern to trs@pgroup.com.

Thank you,
Hongyon