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

Elemental Subroutine Vs. Looping

ScottBoyce
Beginner
579 Views

For my code I was wondering if there is a benefit to having a subroutine with an explicit loop across a vector compared to making an elemental subroutine.

What I really have are complex Derived Data Types that are dimensioned and I can either loop through them with a subroutine or pass them as an elemental subroutine. The only real code difference is having an extra loop and allocating space for the index of the loop.

This is a basic example of what I am talking about (There maybe some bugs cause i just quickly wrote this in the window...but its more to illustrate the difference that I am talking about). 

    
MODULE TYPDEF
  !
  TYPE MYTYP
              INTEGER, DIMENSION(5):: X,Y,Z
  END TYPE
  !
  CONTAINS
  !------------------------------------------------------------
  PURE ELEMENTAL ELEMENTAL_SUB(TYP)
     TYPE(MYTYP), INTENT(INOUT):: TYP
     !
     TYP%Z = TYP%X + TYP%Y
     !
  END SUBROUTINE
  !------------------------------------------------------------
  PURE REGULAR_SUB(TYP)
     TYPE(MYTYP), DIMENSION(:), CONTIGUOUS, INTENT(INOUT):: TYP
     INTEGER:: I
     !
     DO CONCURRENT (I=1:SIZE(TYP))
                                   TYP(I)%Z = TYP(I)%X + TYP(I)%Y
     END DO
     !
  END SUBROUTINE
  !------------------------------------------------------------
END MODULE
    
PROGRAM MAIN
USE TYPDEF
!
TYPE(MYTYP), DIMENSION(10):: TYP
  INTEGER:: I, J
  
  !JUST SOME RANDOM INITIALIZTING
  DO I=1,10
      DO J=1,5
              TYP(I)%X(J) = I + J
              TYP(I)%X(J) = I * J - J + I
      END DO
  END DO
  
  CALL ELEMENTAL_SUB(TYP)  !IS ELEMENTAL BETTER/FASTER?
  
  CALL REGULAR_SUB(  TYP)  !OR SHOULD IT USE EXPLICIT LOOPS
  
END PROGRAM

Which would be better, to process the derived data type?

Thanks,

Scott

0 Kudos
4 Replies
IanH
Honored Contributor II
579 Views

If it is execution performance you are concerned with, then you would probably have to measure for your specific use case.  Ultimately, if the compiler is being reasonable, I wouldn't expect much of a difference.

From the point of view of the source code, I consider the elemental case to be more succinct. 

Beyond that, the elemental form has broader application - it can also be applied to a scalar, or a non-contiguous array without potential performance implications.


 

0 Kudos
Arjen_Markus
Honored Contributor I
579 Views

It is extremely difficult to give generally valid advice on this matter. (Note that you forgot the keyword SUBROUTINE in your code ;)).

Normally I would say that the first concern is whether your code is simpler - more readable, with elemental routines or not. Since you put the do-loop inside the routine, using either does not really matter. This would matter in the case of elemental functions - you would otherwise have to put the do-loop in the calling subprogram.

A second advantage of elemental routines is that you do not have to worry about providing multiple versions for scalar variables or one-dimensional, two-dimensional etc. arrays. That is still valid in your case. A variable (not an array) of type MY_TYPE could still be passed to ELEMENTAL_SUB, but for REGULAR_SUB you would need a different version.

Now the question about performance: the only advice I could give is, measure it. If it does not make a noticeable and significant difference, then use elemental routines. Elemental routines might be slower (according to common wisdom, no idea how accurate that was or still is), but if you substantial work - in this case you are using them for operations on array components, I doubt you will be able to measure a difference.

0 Kudos
jimdempseyatthecove
Honored Contributor III
579 Views

You might want to consider using:

DO CONCURRENT (I=LBOUND(TYP):UBOUND(TYP))

Arrays are not necessarily 1 based. Or you could call your subroutine using a slice

CALL ELEMENTAL_SUB(TYP(Ifrom:Ito))

Jim Dempsey

0 Kudos
Arjen_Markus
Honored Contributor I
579 Views

LBOUND and UNBOUND are not passed on automatically to routines for this reason.

0 Kudos
Reply