Types with pointer-elements are very large

Hello, I am exploring a memory usage issue in a program. When I have a program like this:

module m_ptrsize
   implicit none

   type :: t1
      integer :: i1
      integer :: i2
   end type

   type :: t2
      integer :: i1
      integer :: i2
      integer, pointer :: pi(:) => null()
   end type

   type :: t3
      integer :: i1
      integer :: i2
      integer, pointer :: pi(:) => null()
      real, pointer :: pr(:) => null()
   end type
end module m_ptrsize

program ptrsize
   use iso_c_binding
   use m_ptrsize

   implicit none
   type(t1) :: arr1(5)
   type(t2) :: arr2(5)
   type(t3) :: arr3(5)

   write(*,*) "arr1 elem size = ", int(storage_size(arr1(1))/8, kind=c_size_t)
   write(*,*) "arr2 elem size = ", int(storage_size(arr2(1))/8, kind=c_size_t)
   write(*,*) "arr3 elem size = ", int(storage_size(arr3(1))/8, kind=c_size_t)

end program ptrsize

Compiling this with nvfortran produces this result:

$ nvfortran ptrsize.f90 -o ptrsize
$ ./ptrsize
 arr1 elem size =                         8
 arr2 elem size =                       152
 arr3 elem size =                       296

This suggests that nvfortran’s internal representation of the pointer members are 144 bytes each.

The GNU gfortran compiler does somewhat better, yielding these results indicating a 64-byte pointer size:

 arr1 elem size =                     8
 arr2 elem size =                    72
 arr3 elem size =                   136

I’m sure there is some metadata managed by the Fortran compiler to provide the appropriate array abstraction in the language, but we are working with very large arrays in our programs, and such overhead becomes a very serious issue for us.

Are there any compiler switches or other techniques I might use to reduce this pointer-size overhead?

Thanks in advance for any input you can provide.

Hi pinkston3,

Fortran uses descriptors as part of allocatable arrays and pointers that are used to store things such as bounds, shape, and other information about the array. Not much we can do about the size since this is required in order to support most intrinsics. There’s extra info in there that you probably don’t need such as if the array is on the device or not, but having a variable descriptor size would break too many things.

My only suggestion would be to look at using C-style pointers instead, either via ISO_C_BINDING or the older Cray pointers. In this case no descriptor is used, but of course you wouldn’t be able to use most instrinsics.