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

Nested derived types addition - problem with deallocation of intermediate results

ZlamalJakub
New Contributor III
1,437 Views

I already published my problem with mathematic operations with derived types . I solved it but now I have different problem and I cannot solve it. Attached is source code (Visual studio project).

When I add two derived types everything works and there are no memory leaks.

subroutine TestDamapAdd()  ! no problem
	type(damap) d1,d2,d3
	call d1%init()
	call d2%init()
	d3=d1+d2
! deallocate damap types manually	
	call d1%deinit()
	call d2%deinit()
	call d3%deinit()
end subroutine

But when I try to add three derived types, there is memory leak, because intermediate result of two additions is not deallocated and I have no access to do it manually. Code works and calculates.

subroutine TestDamapAdd2()  
! problem when adding more than 2 damap objects, there is allocated some intermediate value but is not accissible to manual deallocation
	type(damap) d1,d2,d3,d4
	call d1%init()
	call d2%init()
	call d3%init()
	d4=d1+d2+d3			! here is memory leak, intermediate result of addition is not deallocated
	! deallocate damap types manually	
	call d1%deinit()
	call d2%deinit()
	call d3%deinit()
	call d4%deinit()
end subroutine

I tried to implement destructor to damap type to be able to deallocate also intermediate results, but program crashes because value of d4 is not assigned

subroutine TestDamapFinalAdd()  
! to overcome problem with deallocation of intermediate results created damap type with destructor
	type(damapFinal) d1,d2,d3,d4
	call d1%init()
	call d2%init()
	call d3%init()
	d4=d1+d2+d3
	write(*,*) d4%y(1)%coefs(1)  ! exception, d4%y is not allocated
end subroutine

I do not know if it is problem of compiler (IFX 2024.0.2) or my code.

9 Replies
FortranFan
Honored Contributor III
1,360 Views

@ZlamalJakub ,

Consider the following simple code:

module m
   type :: t
      integer, allocatable :: n
      character(len=100) :: name = "default"
   end type
   generic :: operator(+) => add_t
   !generic :: assignment(=) => assign_t  !<-- uncomment this line to get memory leak with Intel Fortran
contains
   function add_t( lhs, rhs ) result(r)
      ! Argument list
      type(t), intent(in) :: lhs(:)
      type(t), intent(in) :: rhs(:)
      ! Function result
      type(t), allocatable :: r(:)
      integer :: i
      ! Elided are any checks
      allocate( r(size(lhs)) )
      forall( i = 1:size(lhs) ) 
         r(i)%n = lhs(i)%n + rhs(i)%n
         r(i)%name = "function result variable in add_t procedure"
      end forall
      print *, "add_t invoked for ", trim(lhs(1)%name), " + ", trim(rhs(1)%name)
   end function
   subroutine assign_t( lhs, rhs )
      ! Argument list
      type(t), allocatable, intent(inout) :: lhs(:)
      type(t), intent(in)  :: rhs(:)
      integer :: i
      allocate( lhs(size(rhs)) )
      ! Elided are the checks
      forall( i = 1:size(lhs) ) lhs(i)%n = rhs(i)%n
   end subroutine
end module
   block
      use m
      integer, parameter :: N = 2
      type(t) :: y1(N), y2(N), y3(N)
      type(t), allocatable :: y4(:)
      forall ( integer :: i = 1:N )
         y1(i)%n = 1 ; y2(i)%n = i + 1 ; y3(i)%n = i + 2
         y1(i)%name = "y1" ; y2(i)%name = "y2" ; y3(i)%name = "y3"  
      end forall
      y4 = y1 + y2 + y3
      print *, "y4(1)%n: ", y4(1)%n, "; expected is [ 6 ]."
      print *, "y4(2)%n: ", y4(2)%n, "; expected is [ 8 ]."
   end block
end
C:\temp>ifx /free /standard-semantics p.f
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2023.2.0 Build 20230627
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.

Microsoft (R) Incremental Linker Version 14.36.32537.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:p.exe
-subsystem:console
p.obj

C:\temp>p.exe
 add_t invoked for y1 + y2
 add_t invoked for function result variable in add_t procedure + y3
 y4(1)%n:  6 ; expected is [ 6 ].
 y4(2)%n:  8 ; expected is [ 8 ].

I don't expect the resultant program to leak memory regardless of whether the defined assignment on line 7 is included.

Nonetheless Intel Fortran leaks memory with the defined assignment.

This is an Intel Fortran issue and you can seek support from Intel Support team to get the leak problem resolved.

 

Barbara_P_Intel
Employee
1,357 Views

@ZlamalJakub, I tried your reproducer with ifx, gfortran and NAG. The executables created by all 3 compilers fail at runtime on Linux with segmentation fault. Also fails at runtime with a newer version of ifx on Windows, access violation.

@FortranFan, what is the bug you see with ifx? Is the issue with your reproducer? I uncommented the line that says it causes a memory leak. Works ok for me with 2024.0.0. 

 

 

0 Kudos
FortranFan
Honored Contributor III
1,338 Views
 @Barbara_P_Intel wrote:

..

@FortranFan, what is the bug you see with ifx? Is the issue with your reproducer? I uncommented the line that says it causes a memory leak. Works ok for me with 2024.0.0. 


@Barbara_P_Intel ,

Please consider inspecting the code in the reproducer I posted upthread using Intel Inspector.

Intel Inspector can be expected to show you a memory leak when the line 7 in uncommented but not when it is commented out.  That should point you to the issue with Intel Fortran compiler, for the reproducer I provided should not encounter a memory leak either way in my opinion.

@ZlamalJakub ,

As I had suggested in your other thread, consider derived types for which you don't need to provide defined assignments nor an explicit final binding.

0 Kudos
ZlamalJakub
New Contributor III
1,225 Views

Dear @FortranFan ,

thank you for your source code sample and comments. I would like to follow your advice, but I have to deal with code that someone else prepared. I am gradually editing it, but sometimes I don't know what to do. I'll probably accept that there are memory leaks in code, run the code as an external program and avoid crashing my own application. It will be probably the easiest way.

 

Dear @Barbara_P_Intel ,

   thank you for analyzing my sample code. If you will discover some compiler problem can you leave a comment about it here in thread?

0 Kudos
Barbara_P_Intel
Employee
1,297 Views

I'm investigating.

On Linux ifx supports a sanitizer compiler option. -fsanitize=address checks for memory leaks and buffer overflows/underflows. On Windows the buffer overflows/underflows check is supported. See the Fortran DGR (Developer Guide and Reference) for details.

The memory leak for both reproducers is identified. I just don't know yet how to interpret the output.

 

 

0 Kudos
Barbara_P_Intel
Employee
1,187 Views

@FortranFan, I filed a bug report, CMPLRLLVM-55629, for your reproducer. Thank you for that!


0 Kudos
Barbara_P_Intel
Employee
1,187 Views

@ZlamalJakub, I'm still investigating your reproducer.



0 Kudos
Barbara_P_Intel
Employee
1,085 Views

@ZlamalJakub, I looked at your reproducer and had others review it, too. We don't believe this is a compiler bug. You know what it takes for it to complete successfully.

 

0 Kudos
Barbara_P_Intel
Employee
834 Views

@FortranFan, the memory leak issue identified with your reproducer is fixed in the upcoming release of ifx 2024.2.0. Look for that at mid-2024.

And the output from using the address sanitizer is clear up, too, in that same release.



0 Kudos
Reply