- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Consider the following minimal working example:
module lib
type FG_t
real,allocatable::g(:)
contains
procedure,private::FG_Assign
generic::assignment(=)=>FG_Assign
end type
interface operator(-)
procedure FG_Sub
end interface
contains
elemental subroutine FG_Assign(this,that)
class(FG_t),intent(inout)::this
class(FG_t),intent(in)::that
this%g=that%g
end
elemental type(FG_t) function FG_Sub(this,that)
class(FG_t),intent(in)::this
real,intent(in)::that
FG_Sub=FG_t(this%g-that)
end
end
program prog
use lib
type(FG_t)::arr(1000),arr_(SIZE(arr))
do i=1,SIZE(arr)
allocate(arr(i)%g(10))
end do
do i=1,100000
arr_=arr-1.
end do
end
When running the executable generated from the above-mentioned code with ifx (2022.2.1) or ifort (2021.7.1) the system memory fills up rapidly (which can lead to your PC crashing in the case of a higher number of iterations).
Memory vs time:
Using gfortran (11.1.0) or replacing 'elemental' before 'FG_Assign' with 'pure' fixes the problem for the latest versions of ifx and ifort. Thanks to a fruitful discussion on Stack overflow (https://stackoverflow.com/questions/75313786/memory-leak-in-the-assignment-using-intel-fortran-compiler), the most probable explanation for this behavior is the creation of a temporary array of FG_t object in the line 'FG_sub=FG_t(this%g-that)'. After use, the temporary array will be deallocated, but the '%g' components will not.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There was a bug fixed in this area in the 2023.0.0 release - please try that.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the reply! I just compiled the code with the ifx and ifort compiler from the 2023 release, and for both compilers the problem remains the same.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Always good to use the latest release for bug fixes and security patches!
@Michel-Heinz, what OS are you compiling and running on?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The OS used tor compiling and running is Ubuntu 22.04.1 LTS.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you!
I filed a bug report for you, CMPLRLLVM-44748.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Clearly an Intel problem in this instance but please note for future reference you may want to take care your code reproducers do not allow really smart processors to optimize away the crucial instructions of interest to you in a reproducer, particularly if you are cross-checking with different compilers, some of whom can be really sharp. You will note your loop over 100000 iterations in the original post. A really astute processor will notice no need to run the loop at all.
Including some dummy instructions like so to prevent the compiler from optimizing away may prove essential in other situations:
module lib
type FG_t
real,allocatable::g(:)
contains
procedure,private::FG_Assign
generic::assignment(=)=>FG_Assign
end type
interface operator(-)
procedure FG_Sub
end interface
contains
elemental subroutine FG_Assign(this,that)
class(FG_t),intent(inout)::this
class(FG_t),intent(in)::that
this%g=that%g
end
elemental type(FG_t) function FG_Sub(this,that)
class(FG_t),intent(in)::this
real,intent(in)::that
FG_Sub%g = this%g - that !<-- No need for structure constructor
end
end
program prog
use lib
integer, parameter :: N = 1000
integer, parameter :: M = 100000
type(FG_t)::arr(N),arr_(SIZE(arr))
real, allocatable :: x(:)
allocate( X(M) )
do i = 1, SIZE(arr)
allocate( arr(i)%g(10), source=0.0 ) ! define the component 'g' also
end do
do i = 1, M
arr_ = arr - 1.0
x(i) = sum( arr_(1)%g + arr_(N)%g ) ! dummy instructions to prevent the compiler from optimizing away
end do
print *, x(1), x(M) ! dummy instructions to prevent the compiler from optimizing away
end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The compiler team reports that the memory leak is fixed in the Fortran compiler that was released this week. It's part of oneAPI HPC Toolkit 2023.2.
Please install it and see how it works for you!
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page