Search code examples
fortrangfortranfortran90intel-fortrannag-fortran

Complications With Elemental Subroutines in Fortran


The Question

Are there any complications when marking a subroutine as elemental? This page seems to suggest so, but doesn't elaborate what they might be.

Note: I am tagging multiple fortran versions because I want to know if there are differences between these that one should be aware of when developing portable code.

Example

Suppose I wanted to write an elemental subroutine to convert between Cartesian and polar coordinates. This could be done as follows:

elemental subroutine calc_xy_from_rt( r, t, x, y )
    real*8, intent(IN)  :: r   ! radius
    real*8, intent(IN)  :: t   ! theta
    real*8, intent(OUT) :: x
    real*8, intent(OUT) :: y
    x = r * cos(t)
    y = r * sin(t)
end subroutine calc_xy_from_rt

Because it is elemental, it could be called in the following context:

program main
    implicit none

    real*8, dimension(1:100) :: r
    real*8, dimension(1:100) :: t
    real*8, dimension(1:100) :: x
    real*8, dimension(1:100) :: y

    ! (Initialize r and t arrays here)

    ! Calculate x and y for each element
    call calc_xy_from_rt( r, t, x, y )   ! gets called 100 times
end program main

I'm guessing there wouldn't be side effects for this simple procedure, but I am providing an example to make discussion concrete and to provide a MWE that could be extended to illustrate possible side effects.


Solution

  • The obvious complication with an elemental subroutine is that all dummy arguments must be scalar. There are times where one desires the elemental actions having access to a shared array: that cannot happen through the arguments.

    Further, if an elemental subroutine is pure, it is subject to all of the restrictions coming from that nature.

    Whether it is pure or not, an elemental subroutine is subject to further constraints:

    • the dummy arguments must not be pointers or allocatable;
    • the dummy arguments must not be coarrays;
    • the dummy arguments must be data objects.

    As to how these restrictions vary over time and implementations, there is little to worry about.

    Before Fortran 2008 all elemental subroutines were pure and the prohibition on coarray dummy arguments was meaningless.

    Also, compilers must be able to detect violations of those restrictions stated and I'm not aware of any extensions relaxing them.

    Finally, there were however various compiler bugs all those years ago when elemental procedures came about. One needn't worry too much about those unless picking up the machine found in great uncle's garage.