Is there performance advantage of using intent(in) and intent(out)?

@CRquantum ,

Sorry I just noticed your reply. First, please note the goal and purpose of good tools will be that no one has to be a “grandmaster” to use them; Fortran is ultimately just a tool and a hope and vision for it has to be that at least in the domains for which it is optimized, say scientific and technical computing, it will be simple enough that no one, especially me, will go around staking a “grandmaster” title with it!!

Second, please note the reason I directed you to the book is because there are several details that are pertinent to your inquiry about performance and dummy argument INTENTs. As such, your inquiry becomes rather broad-based to be fully captured and understood in an online thread. The book by Clerman and Spector makes an attempt to address this specifically, hence my opinion it is a good place to start.

This all starts with the fact there are some differences when it comes to Fortran language and its standard between IN, INOUT, and OUT (and also undeclared INTENT!) . As pointed out to you, INTENT(OUT), for example, leaves a dummy argument undefined until it is defined in the procedure. Depending on the purpose of that argument (e.g., problem data or work area, etc.), this aspect can even lead to undesired or incorrect program behavior or cause crashes, a far deeper issue that precedes any performance considerations.

Also, everything pertaining to the so-called “processors” in Fortran (hardware, compilers, etc.) have advanced so much that when it comes to sequential programming, it would take a lot of attention to detail and effort to meaningfully differentiate between performance differences in cases - usually microbenchmarks - that really capture what INTENT attribute can deliver.

As you will know, a lot of the real performance advantages now, but more so in the near future, are going to be with non-sequential aspects of program execution. Such as parallelization, concurrency, vectorization, etc. With these, you will notice the promises or rather declarations or demands by program authors in the form of PURE, ELEMENTAL, and soon SIMPLE procedures will be critical for the compilers to oblige and yield the authors with performance gains.

Here again you will know the language requires you to explicitly state the INTENTs with pure/elemental and simple procedures. Not just specify INTENTs but follow specific rules with them also.

The book by Clerman and Spector gets into this as well. Also other books e.g., Numerical Computing with Modern Fortran by Hanson and Hopkins. Hence my suggestion.

By the way, it’s my own personal opinion only - it has nothing to do with the admins/moderators of this forum - books are a better place to start when it comes to matters that involve details and various subtleties.

5 Likes

The above was a replay to @kargl’s post but I cannot see it. Has it been deleted?

1 Like

Strange, that reply disappered. kargl is basically saying that,

subroutine f(x,res)
integer :: i
real :: x
real :: res
do i=1,100
    res = sin(x)
enddo
end

I do not remember exactly, though.

Without setting x as intent(in) and res as intent(out), the complier may really run the loop for 100 times.
However, set x as intent(in) and res as intent(out), and realizing that sin is a pure function, the compiler will become smart and just return res = sin(100).
I forgot the reason why the compiler just becomes that smart with those intent stuff.
But it looks like, whenever possible, specifying intent in/out do no harm at all, actually it is good to do so, as all the gentlemen here pointed out.
So, one word,
use intent in/out.

Thank you @FortranFan You earned my respect!
I am sorry for being a little aggressive at the beginning. It does look like you are a Fortran grandmaster, though :slight_smile:
So, in all, the conclusion seems to be, it is good to always add intent(in) or (out). It does not harm.
No wonder, in Chapman’s book, FORTRAN FOR SCIENTISTS & ENGINEERS: Chapman, Stephen: 9780073385891: Amazon.com: Books
page 345 7.6.1 Summary of Good programming practice, 2. he said

Always specify the INTENT of every dummy argument in every procedure to help catch programming errors.

also through the whole book he always use INTENT everywhere. After absorbing the knowledge here I understand more. Although in my code INTENT does not bring much performance difference.

Thanks!

I think that in this example (which should be a subroutine, not function) given that the compiler knows that intrinsic SIN is PURE, the whole loop can be collapsed to just the last iteration, irrespective of whether INTENT is provided. Also, not good form to give INTEGER argument to SIN.

1 Like

Thank you very much indeed!
I modified that part. It is strange that kargl’s post disappeared.

kargl has been deleting their posts after a day or two as a matter of personal policy.

1 Like

Just to clarify, the use of intent(in) and intent(out) does not prevent bugs in argument declarations, but does help prevent errors in the usage of the arguments in the function. There are associated optimizations that can also occur. The most common is that a nonpointer intent(in) argument cannot be redefined in the called procedure, so reloading it from memory for subsequent references can be avoided.

3 Likes

The gcc compiler can do this:
gcc -fsave-optimization-record

it will dump huge amounts of data that isn’t particularly human readable. But we are getting there :wink:

2 Likes

I was not aware of the -fsave-optimization-record option . Great stuff!.

I thought I would take a well established and well-used library such as the reference BLAS where the results could be shared, and test what if any effects there are from a rote conversion to a module using generally recommended post-f77 features. The reference BLAS is not platform-optimized (intentionally) and is very heavily reviewed and has a nice test suite as well as being in wide-spread use. So far, no “automatic” performance gains (I was expecting some inlining gains); performance numbers are virtually unchanged this time; but it still needs a few day’s effort as basically the main thing done so far is to put it into a module. The reference BLAS is VERY clean compared to other codes that are nearly pre-f90; but It is nice to have an automatic interface and it would be trivial (unless there is an unexpected got-cha) to make generic routines with descriptive names which I would personally like (I seem to always have to look up the names but I don’t use them daily either). If I get any interesting performance changes (good, bad, or ugly) I will report it back here. Have tried with three compilers so far (gfortran, nvfortran, ifort) and plan on doing more when I get a chance; but if anyone gets a chance or has some recommended changes feel free.
It is set up as an fpm or gmake build in github at M_blas.

Because there are many vendor-optimized variants of BLAS routines I have been surprised by the clone activity,
especially without any announcement it was present, so there may be interest or a need I had not anticipated for an updated version (but I have not heard directly from anyone); perhaps it should become a fortran-lang supported fpm(1) package or be part of fortran-lang stdlib(3f) (?) but that is turning into a new topic.

So that is definitely giving me something to try the -fsave-optimization-record option on.

We analysed the use of INTENT in several large codes. Most are proprietary and we can’t name them here, but they included WRF and TELEMAC. What we found was:
i. The error rate in declaring arguments INTENT(IN) when they were actually passed down into other routines and written to was about 2%. This seemed dangerous, so:
ii. We re-engineered the codes to remove all non-mandatory INTENT specifications. The outputs did not change by a single bit. Detailed path analysis did not reveal a single change. In most cases the compilers tested (gfortran 7.5.0 and ifort (Forgive me, I don’t have the version to hand) appeared to ignore the INTENT specifications. If you want to repeat this analysis, fpt (http://simconglobal.com) has commands to check and to remove INTENT. We also tested some codes with Sun Studio, g95, ftn95 and CVF.
iii. All the compilers we tested correctly trapped INTENT(IN) violations when sufficient information was available to the compiler (e.g. when the routine interfaces were all visible). We think this is very valuable. INTENT(OUT) violations (where the argument can be read before it is assigned) were less reliably detected.

I believe that the situation where significant optimisations can be achieved are where non-contiguous array sections are passed as arguments. The compiler can then avoid reconstructing the array for INTENT(IN) arguments, or constructing it on input for INTENT(OUT) arguments.

Best wishes,
John

4 Likes

It would be very interesting to see what the NAG Fortran Compiler (free trials are available) with maximum error checking finds and to see what the HPE/Cray Compiler (with interprocedural optimization turned on) can do.

3 Likes