move_alloc and memory leak

move_alloc and memory leak

Hi,It seems thatcall move_alloc(from, to)does not deallocate "to" if it is already allocated. It is a nice way to make memory leaks. I don't know what the Fortran standard has to say about it, but I don't see any reason why it should leak memory.I also realized that when "to" goes out of scope, is is not deallocated.Franois

11 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Do you have any test code to support your comments? The following code works just as expected (and the amount of memory used is always the same):

implicit none
integer :: i
real, allocatable :: a(:), b(:)
do i = 1, 10

    print '(("ALLOCATED(", A, ")=", L1))', 'a', ALLOCATED(a), 'b', ALLOCATED(B)

    allocate (a(100), b(100))

    a = 1

    b = 2

    call MOVE_ALLOC(a, b)
    print '(("ALLOCATED(", A, ")=", L1))', 'a', ALLOCATED(a), 'b', ALLOCATED(B)

    print '("b(1)=", G0)', b(1)

    call reset(b)
    read *

enddo
contains

    subroutine reset(x)

        real, allocatable, intent(OUT) :: x(:)

    end subroutine

end
The MOVE_ALLOC intrinsic is for ALLOCATABLE variables only ---which, by definition, DO NOT leak memory---. The deallocation of the "to" argument should occur, simply because it has INTENT(OUT); after that, the array descriptor from "from" is moved to "to", which means that on return the actual argument "to" is allocated and has the contents of the actual argument "from"... In simple terms, all MOVE_ALLOC does is changing the name of a variable.

The Fortran standard, does not specify implementation details, so I suppose the deallocation of an ALLOCATABLE variable that goes out of scope could be done asynchronously without any problem.

If you're using some memory debugging tool (e.g., valgrind), and your program does not rely heavily on pointers, just ignore the (false positive) messages regarding memory leaks.

John,I have some code to support my comments, but unfortunatly, I am not allowed to publish it. It is a 20,000 lines code that involve a lot of object-oriented Fortran. It involves only allocatable components, and no pointers.If you run the program, you see with a unix "top" that the programs eats more and more memory. This phenomena almost goes away if I put adeallocate(to)call move_alloc(from, to)instead of just the call move_alloc. Note that from and to are allocatable derived types with allocatable components.Unfortunatly, the problem does not show up with some tests code. I will continue to work and find a test code where it leaks. Could you please confirm that it should be impossible to leak memory from a code that does not use any pointer variable ?Francois

Are any of your variables, or components of your variables, polymorphic? I know there are issues with those.

MOVE_ALLOC(from, to)should deallocate the "to" if it is already allocated. If it is not being deallocated, that is a bug.

We need to be able to reproduce the problem in order to investigate it though.

Could youshare the original program in a privateresponse orthough premier support? Only Intel employees will be able to see a response that has been marked private.

Thanks,
Annalee

Hi.I think, I've tracked it down. Here is a sample code that shows the bug.

program main

    use cellStateArray_module, only : cellStateArray

    implicit none
    type(cellStateArray), allocatable :: myCellStateA, myCellStateB

    integer :: i, n

    integer :: nbLoops, k
    n = 1000000

    nbLoops = 20000
    allocate(myCellStateA)

    call myCellStateA%init(phi = [ (0.2, i = 1, n) ] )
    do k = 1, nbLoops

        allocate(myCellStateB)

        call myCellStateB%initWithObject(myCellStateA)

        call move_alloc(from = myCellStateB, to = myCellStateA)

    end do

end program main
module cellStateArray_module

    implicit none

    private
    type, public :: cellStateArray

        private

        integer :: n_

        real, allocatable, dimension(:) :: phi_

    contains

        private

        procedure, public :: init

        procedure, public :: initWithObject

    end type cellStateArray

contains

    subroutine init(this, phi)

        class(cellStateArray), intent(inout) :: this

        real, dimension(:), intent(in) :: phi
        this%n_ = size(phi)

        this%phi_ = phi

    end subroutine init
    subroutine initWithObject(this, that)

        class(cellStateArray), intent(inout) :: this

        class(cellStateArray), intent(in) :: that
        this%n_ = that%n_

        this%phi_ = that%phi_

    end subroutine initWithObject

end module cellStateArray_module
I compile it withifort -assume realloc_lhs -c object.f90ifort -assume realloc_lhs -c main.f90ifort -assume realloc_lhs -o main object.o main.oAnd you can see in a "top" that it leaks. What is interesting is that it does not leak if I remove the n_ instance variable.Franois

Thanks for the reproducer. I have escalated this issue to the developers.

The issue number is DPD200180054.

I will post any updates I receive onthe issueto this thread.

I found a temporary fix for the bug: move all allocatable members of the type at the beginning of the declaration. The memory leaks then disappears.

A fix has been found for this issue, we are planning to include it in the next major release which is scheduled for later this year.

Thank you for working on it.

This is issue has been fixed in Intel® Fortran Composer XE for Linux* 2013 which is now available at the Intel® Registration Center.

Regards,
Annalee
Intel Developer Support
* Other names and brands may be claimed as the property of others.

Login to leave a comment.