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

data type or not?

diedro
Beginner
474 Views

Dear all,

I have a question regarding data type.

I have some big vector: PP,TT,PET. I would like to put them in a data type variable

  TYPE::tMACROCELLNODE
   INTEGER                                        :: nElem
   REAL(KIND=8),ALLOCATABLE,DIMENSION(:)          :: PP
   REAL(KIND=8),ALLOCATABLE,DIMENSION(:)          :: TT
   REAL(KIND=8),ALLOCATABLE,DIMENSION(:)          :: PET

In this way, my code should be easy to develop, to read and to parallelize.

I ask to my self if this type variable, with very big data, could create some problem. 

I do not know, stability, speed ecc ecc.

Thanks to all of you

 

 

0 Kudos
9 Replies
jimdempseyatthecove
Honored Contributor III
474 Views
TYPE tMACROCELLNODE
 INTEGER                                        :: nElem
 REAL(KIND=8),ALLOCATABLE,DIMENSION(:)          :: PP
 REAL(KIND=8),ALLOCATABLE,DIMENSION(:)          :: TT
 REAL(KIND=8),ALLOCATABLE,DIMENSION(:)          :: PET
END TYPE tMACROCELLNODE

TYPE tYourEnclosingType
  ... ! other sturr
  TYPE(tMACROCELLNODE) :: MacroCellNode
  ... ! other stuff
END TYPE tYourEnclosingType

...
  TYPE(tYourEnclosingType) :: diedro ! an instance

  ! CODE
...
  diedro%MacroCellNode%nElem = WhatYouWant
  ALLOCATE(diedro%MacroCellNode%PP(WhatYouWant))
  diedro%MacroCellNode%PP = 0.0_8
...

You should look at Type-Bound Procedures
It is probably best to look for some examples as the IVF compiler documentation is rather skimpy on this.

Jim Dempsey

0 Kudos
diedro
Beginner
474 Views

Dear Jim , Dear all,

I am quite new with data tytpe.

I do not understand the difference between my "type" and your "type".

Could you explain me? What do you mean for "IVF compiler"?

Thanks  a lot

0 Kudos
jimdempseyatthecove
Honored Contributor III
474 Views

The :: format is generally used with type declarations containing an attribute list.
The :: is optional when the type declaration does not contain an attribute list.

Your code sample did not include the END TYPE tMACROCELLNODE
So it was unclear as to if that were the problem or not.

Additionally, an omission in my code was explicit enough information as to where the TYPE declarations were made (I make assumptions too).

Jim Dempsey 

0 Kudos
Steven_L_Intel1
Employee
474 Views

Jim's use of IVF was intended as Intel Fortran. IVF is short for Intel Visual Fortran, a name used on Windows only.

0 Kudos
IanH
Honored Contributor II
474 Views

Do the PP, TT and PET components all get allocated to the same size?  Is nElem that size?

If so, then storing nElem may be superfluous, you can just get the size of the component arrays using the size intrinsic.

If so alternatively, you could use parameterized derived types, perhaps making nElem a length type parameter. 

(In the following, for the sake of example, I have also pulled out the real kind parameter of the components to a type parameter - perhaps that's not necessary - in which case rk could instead just be an ordinary named constant.)

TYPE::tMACROCELLNODE(rk,nElem)
  INTEGER, KIND                   :: rk
  INTEGER, LEN                    :: nElem
  REAL(KIND=rk),DIMENSION(nElem)  :: PP
  REAL(KIND=rk),DIMENSION(nElem)  :: TT
  REAL(KIND=rk),DIMENSION(nElem)  :: PET
  ...
END TYPE tMACROCELLNODE

TYPE(tMACROCELLNODE(8,100)) :: my_node
DO i = 1, my_node%nELem
  my_node%PP(i) = ...

In general, if the components PP, TT and PET are closely related to each other and are commonly manipulated together, then bundling them together in a derived type usually is a sensible thing to do.  A writer/reader of the source code only has to worry about passing one thing around that describes the properties of a node (or whatever), not three or more.

0 Kudos
Steven_L_Intel1
Employee
474 Views

You may also want to think about how these arrays are accessed and consider whether you want SOA (Strucure of Arrays, as you have), or AOS (Array of Structures). If you'll always be accessing the same indexed element of each array for each "step" of your algorithm, AOS is more efficient since the memory accesses are closer together. There's also less indirection through the allocatable array descriptors.

0 Kudos
jimdempseyatthecove
Honored Contributor III
474 Views

IanH,

That is neat and useful for smallish nElem values. Very large array sizes should be allocated from the heap (via type contained procedure).

BTW, is END TYPE implicit???

Jim Dempsey

0 Kudos
IanH
Honored Contributor II
474 Views

There you go - all fixed now.

If having a large object stored on the stack is of concern (which is reasonable), you can make the object itself allocatable.  This is something that you might do anyway, if the number of elements for the arrays is not known at compile time.

TYPE(tMACROCELLNODE(8,:)), ALLOCATABLE :: my_node
INTEGER :: my_length

! read my_length from a file or whatever.
ALLOCATE(tMACROCELLNODE(8,my_length) :: my_node)
...

 

0 Kudos
diedro
Beginner
474 Views

Dear all,

First of all, really really thank. I am learing a lot. 

In both cases (SOA and AOS), there is no stability problem, am I right? 

SOA is slower to access, am I right?

This is my example:

  TYPE::tMACROCELLNODE
   INTEGER                                        :: nElem
   INTEGER                                        :: AA
   INTEGER                                        :: IDnode
   INTEGER                                        :: IDmCell
   REAL(KIND=8),ALLOCATABLE,DIMENSION(:)          :: WFX
   REAL(KIND=8),ALLOCATABLE,DIMENSION(:)          :: WFY
   !
   REAL(KIND=8),ALLOCATABLE,DIMENSION(:)          :: WFtime
   REAL(KIND=8),ALLOCATABLE,DIMENSION(:)          :: WFpdf
   !
   REAL                                           :: qs
  ENDTYPE
  TYPE(tMACROCELLNODE) ,ALLOCATABLE,DIMENSION(:)  :: MACROCELLNODE

This what I do:

  ALLOCATE(MACROCELLNODE(npairs))

and in a cycle

OPEN(1,file=read_file_name,STATUS='old', ACTION='read',IOSTAT=IERR) 
DO i=1,npairs
     READ(1,*) MACROCELLNODE(i)%IDnode,MACROCELLNODE(i)%IDmCell
     ....
     ....
     ....
     READ(1,*) n, nmacronode
     n=n+1                          
     MACROCELLNODE(i)%nElem = n 
     AA = nmacronode*ADEM           
     MACROCELLNODE(i)%AA = AA
     !
     ALLOCATE(MACROCELLNODE(i)%WFX(n))
     ALLOCATE(MACROCELLNODE(i)%WFY(n))

This because "n" changes.

Is this correct?

Because I do not think that I can do

TYPE::tMACROCELLNODE(rk,n)

PP, TT and PET have the same number of element, consequently I will use AOS.

What do you think? Have I done some errors?

Do you have some suggestions?

Really really thanks again

 

0 Kudos
Reply