- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I've just notice a strange behavior of the fortran 2008 "storage_size" procedure when applied to simple derived-type variables.
If a derived-type is defined with only scalar variables, then the storage size of this derived-type is larger than the sum of the storage sizes of each individual components.
The above program,
[fortran]Program Main
implicit none
type :: My_Type
logical :: l0
integer :: i0
real(4) :: s0
real(8) :: d0
end type
type(My_Type) :: Var
write(*,"('Starting')")
write(*,"('Storage_Size(Var%l0) = ',g0)") Storage_Size(Var%l0)
write(*,"('Storage_Size(Var%i0) = ',g0)") Storage_Size(Var%i0)
write(*,"('Storage_Size(Var%s0) = ',g0)") Storage_Size(Var%s0)
write(*,"('Storage_Size(Var%d0) = ',g0)") Storage_Size(Var%d0)
write(*,"('SUM Storage_Size(Var%*) = ',g0)") Storage_Size(Var%l0) + Storage_Size(Var%i0) +Storage_Size(Var%s0) + Storage_Size(Var%d0)
write(*,"('Storage_Size(Var) = ',g0)") Storage_Size(Var)
write(*,"('Ending')")
End Program[/fortran]
gives the following result:
[bash]$ ifort main.f90; ./a.out
Starting
Storage_Size(Var%l0) = 32
Storage_Size(Var%i0) = 32
Storage_Size(Var%s0) = 32
Storage_Size(Var%d0) = 64
SUM Storage_Size(Var%*) = 160
Storage_Size(Var) = 192
Ending[/bash]
Why such a behavior ? Is there some hidden data stored somewhere in the derived-type ?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
d0 is misaligned, so we added 4 bytes of padding before it. This happens even if you make it a BIND(C) type, though I have to check if C does the same thing (in which case that would be correct.) You could add SEQUENCE to the declaration and that would remove the padding, or use -align norecords
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok, thanks.
3 questions:
- Is the SEQUENCE attribute depreciated ?
- Is it allowed to define TBP in a derived-type which has the SEQUENCE attribute ?
- Will there be any impact on performance by using the SEQUENCE attribute ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
SEQUENCE is not deprecated. I don't have my references handy but I don't see why SEQUENCE would interfere with TBPs. Yes, there is a performance impact to misaligned values, which is why we pad.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve Lionel (Intel) wrote:
SEQUENCE is not deprecated. I don't have my references handy but I don't see why SEQUENCE would interfere with TBPs. Yes, there is a performance impact to misaligned values, which is why we pad.
Based on my reading of Fortran 2003 and 2008 standards (as quoted below), types with SEQUENCE attribute
* cannot have type-bound procedures
19 C436 (R425) If SEQUENCE appears, each data component shall be declared to be of an intrinsic type or of a
20 sequence type, and a type-bound-procedure-part shall not appear.
* are not extensible
24 C431 (R425) If EXTENDS appears, SEQUENCE shall not appear.
* cannot have the BIND(C) attribute
7 C1501 (R425) A derived type with the BIND attribute shall not have the SEQUENCE attribute.
Hence I find SEQUENCE highly limiting and have generally stopped using it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok - as I said I didn't have the standard handy at the time. I also don't care for SEQUENCE as all the standard says is that it prevents reordering of the components. Making sure the components are naturally aligned to begin with is best.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
A suggestion: the documentation for SEQUENCE in the Intel Fortran Compiler Help is quite barren. Will it be possible for your writers to include all the caveats listed in the 2003 and 2008 standards? It will help many of the users who haven't made a habit of referencing the standards documentation (which can be very dense).
Thanks,
User and Reference Guide for the Intel® Fortran Compiler 14.0
SEQUENCE
Statement: Preserves the storage order of a derived-type definition.
SEQUENCE
Description
The SEQUENCE statement allows derived types to be used in common blocks and to be equivalenced.
The SEQUENCE statement appears only as part of derived-type definitions. It causes the components of the derived type to be stored in the same sequence they are listed in the type definition. If you do not specify SEQUENCE, the physical storage order is not necessarily the same as the order of components in the type definition.
If a derived type is a sequence derived type, then any other derived type that includes it must also be a sequence type.
Example
!DIR$ PACK:1TYPE NUM1_SEQSEQUENCEINTEGER(2)::int_valREAL(4)::real_valLOGICAL(2)::log_valEND TYPE NUM1_SEQTYPE num2_seqSEQUENCElogical(2)::log_valinteger(2)::int_valreal(4)::real_valend type num2_seqtype (num1_seq) num1type (num2_seq) num2character*8 t, t1equivalence (num1,t)equivalence (num2,t1)num1%int_val=2num1%real_val=3.5num1%log_val=.TRUE.t1(1:2)=t(7:8)t1(3:4)=t(1:2)t1(5:8)=t(3:6)print *, num2%int_val, num2%real_val, num2%log_valendParent topic: S
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The current thinking is that SEQUENCE should not be used - it doesn't do what most people want, which is to guarantee a particular layout of a derived type. BIND(C) does that better, though you're still subject to the choices made by the "companion C processor".
The age-old advice still stands - arrange your components so that all are naturally aligned, so you won't have to worry about padding.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Even if all components are naturally aligned you can get padding. Try it with the current example and appropriate arrangement, and various combinations of platform and BIND(C). The reason is the under at least some environments an array of a derived type should have all conponents of all elements aligned so you can't have a 20-byte derived type when one of its components requires 8-byte alignment.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
RO is correct, but the important point is that BIND(C) specifies that the layout and storage size must match what the "companion C processor" does for the equivalent struct. If the C compiler pads, then Fortran will too. Intel Fortran has directives and compile options to specify or disable padding, as do most C compilers.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page