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

Allocatable arrays in structure definition

pfr
Beginner
1,263 Views
Dear everyone,
I am trying to compile a code using structures that contains allocatable arrays. These structures are declared as follows :
type :: data
real,dimension(:,:),allocatable :: waveform
real,dimension(:),allocatable :: E
integer :: npts,nbChan,srate
end type data


Then in the main program, I declare a dynamic structure "z" :

type(data),dimension(:),allocatable :: z

So to have a sort of "two-times allocatable" array.

This codes goes through the compilation step on my 32 bit workstation using ifort v10 without problems. It however yields wrong results when increasing the size of the "z"-array - but is fine when its size is one.

I then tried to compile it on a 64 bits machine, and ifort warns me that my "data are misaligned". I thus tried to use the -align all option, which didn't change much. At execution, I get a segmentation fault.

I wonder whether it is possible to actually use such kind of complicated and imbricated allocatable array structure with F90. If yes, why do I get these issues?

Thanks to all for reading.

Pierre-Franois.

0 Kudos
1 Reply
jimdempseyatthecove
Honored Contributor III
1,263 Views

Pierre,

The data misalignment comes from the

type(data),dimension(:),allocatable :: z

Where z(2) will not be (when allocated) aligned to a multiple of the largest entity in type data. And the largest entity in type data is a two dimension array descriptor for waveform. And the size of this array descriptor will vary dependent on compiling for 32-bit or 64-bit.

One way to correct for this, but which falls within disfavor of some programming purist, is with the use of UNIONs. Or by adding dummy padd variables but this is tricky as the number of padd variables is subject to change due to not only selection of 32/64 bit but also the size of the array descriptor is subject to change from version to version. An alternate way is to make your array of type(data) into an array of pointers to type data.

type :: data
real,dimension(:,:),allocatable :: waveform
real,dimension(:),allocatable :: E
integer :: npts,nbChan,srate
end type data
type dataPointer
type(data), pointer :: p
end type dataPointer
Then in the main program
type(dataPointer),dimension(:),allocatable :: z
integer :: zMax, zUsed
...
zMax = iGetZmax()
allocate(z(zMax))
zUsed = 0
... ! allocate type data

if(zUsed .eq. zMax) goto Full
zUsed = zUsed+1
allocate(z(zUsed).p)
! then initialize or allocate contents of z(zUsed).p
... ! Extract entry from array
N = z(i).p.npts

This requires that you have to have the funky ".p" inside the dereference of z.
However, you can also pass around the pointer to the data structure instead of passing the index of the pointer of the data structure.

pData => z(i).p
...
N = pData.npts

Note, when you deallocate z you will first have to make a run through the array z to deallocate the entries pointing to data entity.

Jim Dempsey

0 Kudos
Reply