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

class(*) pointer memory usage

Patrice_l_
Beginner
1,292 Views

Hi,

I just discovered that when using a class(*) pointer in a code, the intel compiler 15.0.2 or 16b  use almost 6 times more bytes than gfortran. if the class(*) pointer is removed then the memory allocation looks correct. Any reason/ideas for that behavior ?  (In the code below in the usage not the leaks of the pointer i do not deallocate).

Thanks

program toto
implicit none

type t
        type(t),pointer :: tp
        
        class(*),pointer :: val ! comment this and the bytes usage is the same.
end type

integer :: i,n
type(t),pointer :: m
type(t),allocatable , dimension(:) :: tab

n=100000

allocate(tab(n))

do i=1,n
allocate(m)
!m%i=90
tab(i)%tp => m
m=>null()
end do

end program toto

 

 

 ifort main2.f90 
 valgrind ./a.out 
==14216== Memcheck, a memory error detector
==14216== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==14216== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==14216== Command: ./a.out
==14216== 
==14216== 
==14216== HEAP SUMMARY:
==14216==     in use at exit: 27,200,032 bytes in 100,002 blocks
==14216==   total heap usage: 100,003 allocs, 1 frees, 27,200,048 bytes allocated
==14216== 


gfortran  main2.f90
valgrind ./a.out 
==14224== Memcheck, a memory error detector
==14224== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==14224== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==14224== Command: ./a.out
==14224== 
==14224== 
==14224== HEAP SUMMARY:
==14224==     in use at exit: 4,800,000 bytes in 100,001 blocks
==14224==   total heap usage: 100,024 allocs, 23 frees, 4,812,324 bytes allocated


 

0 Kudos
6 Replies
Steven_L_Intel1
Employee
1,292 Views

What do you mean by "correct"? For a polymorphic pointer we have to save a LOT of information about the type. It may be that gfortran does it more efficiently, but as long as the program works according to the standard, it is correct.

0 Kudos
Patrice_l_
Beginner
1,292 Views

 

Yes "correct" is not the right word here. But I was expecting the pointer to be like a void* so nothing more than a memory address,  especially when it is not use =>null(). And then when it is pointed to a concrete type, to cast it properly. In my implementation it reserves Gbs of memory, when it is actually nothing but an empty pointer. Is there documentation that say how/why save so much information about the type ?

Thanks.

0 Kudos
Steven_L_Intel1
Employee
1,292 Views

It is certainly NOT like a void(*). It carries ALL the dynamic type information, including finalizers, initializers and everything as if you had declared the full type, and since we don't know WHAT that type will be, we have to be prepared for anything. The layout of this information is not documented.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,292 Views

If you are concerned about memory consumption, create a user defined type, that contains a pointer to a type t object, Then create your table of the pointers to this type. This will require two allocations but will be more efficient on memory consumption when your table is partially filled.

Jim Dempsey

0 Kudos
Patrice_l_
Beginner
1,292 Views

Hi,

Thanks for the tip for an array, but in reality this is going in a list , so even if my list contains integer the problem will still be there because of the class(*). I've read a lot on the generic polymorphism solutions and so I haven't set my mind about using class(*) select type or the include/macro solution.

I have read on the windows forum that the bug regarding reporting "If the target is unlimited polymorphic, the pointer object must be unlimited polymorphic, or of a type with the BIND or SEQUENCE attribute." has been fixed. But the following code still does not produce an error in 15.0.2 and 16beta

 

program foo
implicit none


class(*),pointer,dimension(:) :: vect
integer,pointer,dimension(:) :: y

allocate(integer::vect(10))

y=>vect
y=10

print *,y

end program foo

 

0 Kudos
Steven_L_Intel1
Employee
1,292 Views

You don't have that fix yet. It will be in 16.0 Beta Update 2 and the final release.

0 Kudos
Reply