- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page