Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29487 Discussions

Automatic deallocation of derived types

Tim_Gallagher
New Contributor II
1,366 Views
Back again!

I saw some forum postings about problems in the Intel compiler related to deallocating the ALLOCATABLE components of a derived type when variable is no longer in scope (at the end of a subroutine when the variable is local for example).

However, when derived types are nested, the automatic deallocation does not occur resulting in a memory leak. I've attached a very basic code to demonstrate this. Here's the output of ifort -V

Intel Fortran Intel 64 Compiler Professional for applications running on Intel 64, Version 11.1 Build 20100414 Package ID: l_cprof_p_11.1.072
Copyright (C) 1985-2010 Intel Corporation. All rights reserved.
FOR NON-COMMERCIAL USE ONLY

And when I run valgrind, I get:

==7681== Memcheck, a memory error detector
==7681== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==7681== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==7681== Command: ./a.out
==7681==
==7681==
==7681== HEAP SUMMARY:
==7681== in use at exit: 200,000,032 bytes in 100,001 blocks
==7681== total heap usage: 100,002 allocs, 1 frees, 200,000,048 bytes allocated
==7681==
==7681== 18,000 bytes in 9 blocks are possibly lost in loss record 2 of 3
==7681== at 0x4C26C3A: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==7681== by 0x41015A: for_alloc_allocatable (in /home/tgallagher/fortranTests/memLeak/a.out)
==7681== by 0x402DC0: datatype_mp_createmytype_t1_ (typeModule.f90:34)
==7681== by 0x403054: datatype_mp_createmytype_t2_ (typeModule.f90:45)
==7681== by 0x403212: somethingmodule_mp_dosomething_ (something.f90:14)
==7681== by 0x403248: MAIN__ (leak.f90:10)
==7681== by 0x402C2B: main (in /home/tgallagher/fortranTests/memLeak/a.out)
==7681==
==7681== 199,982,000 bytes in 99,991 blocks are definitely lost in loss record 3 of 3
==7681== at 0x4C26C3A: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==7681== by 0x41015A: for_alloc_allocatable (in /home/tgallagher/fortranTests/memLeak/a.out)
==7681== by 0x402DC0: datatype_mp_createmytype_t1_ (typeModule.f90:34)
==7681== by 0x403054: datatype_mp_createmytype_t2_ (typeModule.f90:45)
==7681== by 0x403212: somethingmodule_mp_dosomething_ (something.f90:14)
==7681== by 0x403248: MAIN__ (leak.f90:10)
==7681== by 0x402C2B: main (in /home/tgallagher/fortranTests/memLeak/a.out)
==7681==
==7681== LEAK SUMMARY:
==7681== definitely lost: 199,982,000 bytes in 99,991 blocks
==7681== indirectly lost: 0 bytes in 0 blocks
==7681== possibly lost: 18,000 bytes in 9 blocks
==7681== still reachable: 32 bytes in 1 blocks
==7681== suppressed: 0 bytes in 0 blocks
==7681== Reachable blocks (those to which a pointer was found) are not shown.
==7681== To see them, rerun with: --leak-check=full --show-reachable=yes
==7681==
==7681== For counts of detected and suppressed errors, rerun with: -v
==7681== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)

The leak goes away if at the end of the subroutine the DestroyMyType() routine is called, but this shouldn't be needed (I don't think).

Thanks,

Tim
0 Kudos
5 Replies
Tim_Gallagher
New Contributor II
1,366 Views
I found the assumption made by the compiler. If

TYPE :: MyType
INTEGER, DIMENSION(:), ALLOCATABLE :: array
END TYPE MyType

TYPE :: MyType2
TYPE(MyType) :: t1
END type MyType2

is changed to:

TYPE :: MyType
INTEGER, DIMENSION(:), ALLOCATABLE :: array
END TYPE MyType

TYPE :: MyType2
TYPE(MyType), DIMENSION(:), ALLOCATABLE :: t1
END type MyType2

then it correctly propagates the deallocation. I dunno if that helps,

Tim
0 Kudos
Kevin_D_Intel
Employee
1,366 Views
Thank you for the analysis and test case, Tim. I confirmed and directed to Development for their analysis (see internal tracking id below) and will post when I have an update.

(Internal tracking id: DPD200159004)

(Resolution Update on 11/30/2010): This defect is fixed in the Intel Fortran Composer XE 2011 initial release (12.0.0.084 - Linux)
0 Kudos
Kevin_D_Intel
Employee
1,366 Views
Development root-caused the defect and said the problem only occurs when the "outer" type has no allocatable fields of its own. It only has a contained record which happens to have allocatable fields. They also said a simple workaround is to add an unused allocatable field to the outermost type.

I'll update again about a fix as I learn it.
0 Kudos
Kevin_D_Intel
Employee
1,366 Views

I confirmed this issue will be fixed in the next major release available in the coming month.

I'll update again around that time. Until then, the identified work around will need to be used.

0 Kudos
Kevin_D_Intel
Employee
1,366 Views
The Intel Fortran Composer XE 2011 initial release (12.0.0.084 - Linux) with the fix is available from the Intel Registration Center: https://registrationcenter.intel.com

Here are the current results:

$ ifort -V -c typeModule.f90
Intel Fortran Intel 64 Compiler XE for applications running on Intel 64, Version 12.0.0.084 Build 20101006
Copyright (C) 1985-2010 Intel Corporation. All rights reserved.

Intel Fortran 12.0-1176

$ ifort -V -c something.f90
Intel Fortran Intel 64 Compiler XE for applications running on Intel 64, Version 12.0.0.084 Build 20101006
Copyright (C) 1985-2010 Intel Corporation. All rights reserved.

Intel Fortran 12.0-1176

$ ifort -V -o memLeak leak.f90 typeModule.o something.o
Intel Fortran Intel 64 Compiler XE for applications running on Intel 64, Version 12.0.0.084 Build 20101006
Copyright (C) 1985-2010 Intel Corporation. All rights reserved.

Intel Fortran 12.0-1176
GNU ld version 2.17.50.0.6-5.el5 20061020

$ valgrind --leak-check=full memLeak
==31151== Memcheck, a memory error detector.
==31151== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.
==31151== Using LibVEX rev 1884, a library for dynamic binary translation.
==31151== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP.
==31151== Using valgrind-3.4.1, a dynamic binary instrumentation framework.
==31151== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al.
==31151== For more details, rerun with: -v
==31151==
==31151==
==31151== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 5 from 1)
==31151== malloc/free: in use at exit: 32 bytes in 1 blocks.
==31151== malloc/free: 100,002 allocs, 100,001 frees, 200,000,048 bytes allocated.
==31151== For counts of detected errors, rerun with: -v
==31151== searching for pointers to 1 not-freed blocks.
==31151== checked 151,736 bytes.
==31151==
==31151== LEAK SUMMARY:
==31151== definitely lost: 0 bytes in 0 blocks.
==31151== possibly lost: 0 bytes in 0 blocks.
==31151== still reachable: 32 bytes in 1 blocks.
==31151== suppressed: 0 bytes in 0 blocks.
==31151== Reachable blocks (those to which a pointer was found) are not shown.
==31151== To see them, rerun with: --leak-check=full --show-reachable=yes

0 Kudos
Reply