14

I recently discovered the use of pure functions and subroutines in Fortran. From what the Fortran manual indicates, it seems that most of my subroutines can actually be defined as pure (since I always specify the intent of all the arguments, and usually I dont have "save", "pause", or external I/O in most of my subroutines). My question is then: Should I do it? I was wondering if the compiler optimizes better pure subroutines or if it just does not matter, or if it can make things worse. Thanks !

Tibo
  • 195
  • 3
  • 8

2 Answers2

22

You work with the compiler to generate good code, and the more information you provide the compiler, the better a job the two of you can do together.

Whether it's labelling with intent(in) any dummy arguments you don't change, or using parameter for constants, or explicitly making pure any subprogram which doesn't have any side effects, or using forall when you don't really care about the order a loop is calculated in, by being more explicit about what you want to happen, you benefit because:

  • the compiler can now flag more errors at compile time - hey, you modified that argument you said was intent 'in', or you modified that module variable in a pure subroutine
  • your code is clearer to the next person to come to it without knowing what it's supposed to be doing (and that person could well be you three months later)
  • the compiler can be more aggressive with optimization (if the compiler has a guarantee from you that nothing is going to change, it can crankup the optimization).

Of those three benefits, the optimization is probably not the most important; in the case of pure subroutines, a smart compiler can probably see just through static analysis that your subroutine has no side effects. Still, the more guarantees you can give it, the better a job it can do of optimizing your code while maintaining correctness.

Jonathan Dursi
  • 50,107
  • 9
  • 127
  • 158
  • 1
    I would just add that using `do concurrent` is now recommended over `forall`. See for instance [page 23 of this Intel document](https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0CDIQFjAB&url=https%3A%2F%2Fsoftware.intel.com%2Fsites%2Fdefault%2Ffiles%2Fparallel_mag_issue11.pdf&ei=OIxIVYjaIcb0UufjgcAL&usg=AFQjCNFwOikfX3mcuuFfRSQIjIuNj_UZBA&sig2=6d9TpqMl_8BCKU2ePIli5g&bvm=bv.92291466,d.d24). – max May 05 '15 at 09:28
  • 2
    You can use the `pure` keyword as a side effect detector. Just declare all functions you write as `pure`. If the function has side effects the compiler will complain. If that happens think if you can refactor it to be side effect free, otherwise drop `pure`. That way you will gain a better understanding of your code and automatically write cleaner code. – user26756 Mar 15 '16 at 09:41
5

As far as I know, it just does not matter in a sequential mode. But if you activate "auto parallelization" options, then a compiler may sometimes take advantage of the PURE declaration to parallelize loops (multi-threading) containing calls to pure subroutines (it cannot take the risk if the subroutines are not pure). For the same reason, the PURE declaration is also useful for the programmer who wants to set manually // directives (OpenMP for instance) because the risk of trouble with such procedures is rather limited. It is often possible to parallelize loops with calls to non pure subroutines, but this needs a deep verification...

Francois Jacq
  • 1,244
  • 10
  • 18