Fortran + OpenMP + polymorphism: what exactly is not supported? - fortran

I am aware that the OpenMP 4.5 standard says that in Fortran "polymorphic entities" are not supported.
What exactly does this mean? Does this only exclude calls to type-bound procedures that have a PASS attribute, but I can still use an instance of a user-defined type that has type-bound procedures in other ways (e.g. accessing its components)?
Does this limitation only apply to the OMP PARALLEL block, or also to procedures called from this block, or to the entire compilation unit?
Would be great if someone could point me to some clarifying documentation.
Thanks!
EDIT: Made explicit that I meant type-bound procedures with the PASS attribute specified.

Related

Mixing integer types in Fortran

I have a code that I run on several different clusters, which all have different combinations of MPI & LAPACK.
This can cause problems. For example I currently use ifort's "-i8" option, which works fine with LAPACK, but now all MPI calls are broken, because it expects integer(4), rather than integer(8).
Is there an elegant & flexible way to adapt the integer type based on the local MPI & LAPACK installation?
Hard coding the types for every specific call seems is just very cumbersome and inflexible.
MPI calls do not expect INTEGER(4) nor INTEGER(8), they expect just INTEGER. And, as always, remember what those (4) and (8) actually mean Fortran: integer*4 vs integer(4) vs integer(kind=4)
With -i8 you are changing what INTEGER means, to which kind it corresponds. You can do that, but you have to compile the MPI library with the same settings. The library may or may not be prepared to be compiled that way, but theoretically it should be possible.
You could also try passing integer(int32) instead of integer to MPI. If it is the correct kind which correspond to the default kind of the MPI library, the TKR checks and all other checks should pass OK. But it is not recommended.
To stay strictly within the Fortran standard, when you promote the default integer kind, you should also promote the default real and logical kind.
To stay portable use integers that correspond to the API of the library you use and make sure the library is meant to be used with that particular compiler and with that particular compiler configuration.
Usually, for portability one should not rely on promoting the default kinds but one should use specific kinds which suit the given purpose in the specific part of the code.

Fortran with MPI error

I am working on Fortran code with MPI and introducing the following MPI command
call MPI_Gather(nlocal,1,MPI_INTEGER,counts,1,MPI_INTEGER,0&
&,comm_cart,ierror)
with in a particular subroutine gives following error:
This name does not have a type, and must have an explicit type. [MPI_INTEGER]
I understand that the compiler does not recognize the MPI part of this code. However, all other related variables such as nlocal, counts and comm_cart are recognized except the Fortran MPI data type MPI_INTEGER. Can someone throw light, where I am doing wrong?
Note: The compiler is Intel compiler
You must tell the compiler about the MPI stuff (mainly variables).
The modern way is introducing
use mpi
in every scope.
In the old days it was also done using
include "mpif.h"
but that has several disadvantages. Namely, because it is compatible with FORTRAN 77, it does not introduce explicit interfaces for any MPI subroutines and therefore the error checking is less thorough than with use mpi. The modern method will help you more in keeping your code correct.
On the other hand, if you use use mpi the module mpi must be compiled with the same compiler (sometimes even with the same version) which you use to compile your program.

How to get subroutine calling hierarchy in Fortran?

In a subroutine, I would like to know which upper subroutine is calling it when error occurs. Is there any way without using arguments? So users of the subroutine could be notified the upper subroutine.
There is nothing built in to Fortran which will give you the sort of information you seek. You could, as you suggest, write your own programs to report the information but it strikes me that doing so might burden your code with a lot of error-reporting infrastructure which obscures its meaning and materially affects its importance.
I suggest that you investigate your compiler's capabilities. Intel Fortran, for example, offers a traceback option which is often useful for diagnosing the causes of problems. Start your reading here. All the other Fortran compilers I've worked with offer similar facilities, check the documentation.

"Real world" use of parameter passing in Fortran

I always assumed that fortran passed entities "by reference" to a dummy argument. Then I got this answer (the actual argument of the answer was related, but not on this)
The standard never specifies that and,
indeed goes quite a lot out of its way
to avoid such specification. Although
yours is a common misconception, it
was not strictly accurate even in most
older compilers, particularly with
optimization turned on. A strict
pass-by-reference would kill many
common optimizations.
With recent standards,
pass-by-reference is all but
disallowed in some cases. The standard
doesn't use those words in its
normative text, but there are things
that would be impractical to implement
with pass-by-reference.
When you start getting into things
like pointers, the error of assuming
that everything is pass-by-reference
will start making itself more evident
than before. You'll have to drop that
misconception or many things wil
confuse you.
I think other people have answered the
rest of the post adequately. Some also
addressed the above point, but I
wanted to emphasize it.
See here for attribution.
According to this answer, then, there's nothing in the standard specifying how data are shipped from the caller to the callee. In practical terms, how this should be interpreted in terms of actually working with it (regardless of the practical effects resulting from how compilers implement the standard) in particular when it comes to intent() specification?
Edit: I'd like to clarify my question. What I am trying to understand is how the standard expects you to work when you are performing calls. Given that the actual compiler strategy used to pass entities is undefined by the standard, you cannot in principle (according to the standard) expect that passing an argument to a function will actually behave as a "pass-by-reference", with all its related side-effects, because this behavior is compiler and optimization dependent. I assume therefore the standard imposes you a programming style you have to follow to work regardless of the actual implementation strategy.
Yes, that's true. Fortran standard doesn't specify the exact evaluation strategy for different INTENT attributes. For example, for a dummy argument with INTENT(OUT) some Fortran compiler can use call-by-reference or call-by-copy-restore evaluation.
But I do not understand why do you really need to know which evaluation strategy is used? What is the reason? I think Fortran do it right. Humans concern is (high-level) argument intent, and computers concern is (low-level) evaluation strategy. "Render unto man the things which are man’s and unto the computer the things which are the computer’s." N. Wiener
I think the standard contains enough information on the usage of different INTENT attributes. Section "5.1.2.7 INTENT attribute" of Final Committee Draft of Fortran 2003 standard (PDF, 5 MB) is a good starting point.
As the others have said, you don't have to know how the compiler works, as long as it works correctly. Fortran >=90 allows you to specify the purpose of an argument: input, output or both, and then the compiler takes care of passing the argument. As long as the compiler is correctly implemented so that both sides (caller and callee) use the same mechanism, why should the programmer care? So the Fortran standard tries not to limit how compiler writers implement their compilers, allowing them to design and optimize as they wish.
In terms of programming style, decide the purpose of your procedure arguments, and declare them with the appropriate intent. Then, for example, if you accidentally try to modify an intent(in) argument in a procedure, the compiler will issue an error message, preventing you from making this mistake. It might even do this before emitting object code, so the actual argument passing mechanism has nothing to do with enforcing this requirement of the language.
C is a lower-level language and the programmer needs to choose between passing by value or by reference for various reasons. But for problems such as scientific programming this is an unnecessary aspect to have to control. It can be essential in embedded or device driver programming.
If there is a reason that you must control of the argument passing mechanism, such as interfacing to another language, Fortran 2003 provides the ISO C Binding (which is already widely implemented). With this you can match the C method of argument passing.
I'm not sure I understand your question, but one way of seeing things is that as long as one writes standard-conforming code, one does not need to be concerned with how argument passing is implemented. The compiler makes sure (well, barring compiler bugs, of course) that arguments are passed in a way that conforms to the standard.
Now, if you play tricks e.g. with C interop or such, say by comparing argument addresses you might be able to determine whether the compiler uses pass by reference, copy-in/copy-out or something else in some particular case. But generally speaking, at that point you're outside the scope of the standard and all bets are off.

Writing and calling pure subroutines in Fortran 90 using gfortran

When writing and calling pure subroutines in Fortran 90 using gfortran, how do I find out why the compiler emits this error?
Error: Subroutine call to XXXX at (1) is not PURE
I'll try to pose my question as specifically as I can while at the same time being general enough to be useful to others, so I'll avoid pasting in my actual code and instead will sketch what happened.
I understand there are various rules about pure procedures in Fortran 90, which I think basically boil down to not permitting side-effects in either functions or subroutines, and not permitting changes to subroutine parameters declared with intent(in). I've a series of subroutines which initially were not declared to be pure, and whose parameters didn't have declared intent, but which nevertheless didn't perform side-effects. First, I changed all parameter declarations to have explicitly-declared intent, either in, out, or inout. Then, I declared all the subroutines to be PURE. Naturally, many errors occurred on the first attempt, but the compiler told me what the errors were (such-and-such parameter with intent(in) is being modified, for example), so one-by-one I fixed them all.
There are calls among these procedures, however, and so now I still get many errors of the form shown above: Subroutine call to XXXX at (1) is not PURE. What I don't understand is why the call is not pure. I've done everything I can think of to make XXXX pure, but the compiler still thinks it isn't.
So my question --rephrased-- is: how do I get gfortran to tell me WHY it thinks XXXX is not pure?
"Placed all the PURE subroutines in the library I'm working on, into a MODULE (which my client code then USEd). ...... Not sure why ....., but after doing this more useful error messages appeared which allowed me to track down the remaining impurities."
Placing the subroutines into a module and then using them makes the interface explicit. This allows the compiler to check agreement between the call and the subroutine and generate error messages if there is a discrepancy. Very useful, so placing subroutines and functions into modules good practice.
The other way of making an interface explicit is to write an interface, but that is extra work and an extra step to get wrong.
There is a long list of requirements on pure subroutines/functions. If you have Fortran 95/2003 Explained by Metcalf, Reid and Cohen, see section 6.10. For example, no "save" variables, no stop statement, no IO on external file, ...
You can also try other compilers to see if their error message is more helpful. Other free ones, depending on OS, include g95 and Sun Studio.
I'll try to be more clear about my question in my answer. I was reluctant to post my code for these reasons.
I don't expect other people to debug my code for me. That's way too much to ask.
I wanted my question and its answer(s) to be more general.
It seemed gfortran was telling me my subroutines were not PURE, but it wasn't telling me WHY it considered them not to be pure.
So I hoped to find out, not how to fix my code and make the procedures PURE, but rather to find out how to coax more useful information from gfortran, in order to help me fix my code.
Two things that I did helped fulfill these goals. Of course, your results may vary.
Added this flag to the gfortran command-line: -fmax-errors=100
Of course, I'd done that earlier, but it still seemed not to tell me what I needed to know.
Placed all the PURE subroutines in the library I'm working on, into a MODULE (which my client code then USEd). Since this library's ancestry is as Fortran77, originally, this was not the case. Not sure why (which is why I stress that "your results may vary"), but after doing this more useful error messages appeared which allowed me to track down the remaining impurities.
It's kind of a nebulous question, I know, and I'm not sure how useful it will be. Still, thanks to everyone who read, commented on, and added answer(s).
Probably because it's not marked as PURE. The fact that a subroutine is pure is not related to what it does or not with its arguments, but to the fact that it's declared as PURE. (Of course, once declared as pure, what you do with the arguments comes into play and is checked.)
I am Fortran beginner and last week I reached chapter about Fortran procedures in my book. May be I'm not right but... So if you will excuse my English there are some remarks:
It's not good style to declare subroutines pure. It's advisable for functions.
Pure procedures were introduced in Fortran 95 standard. Not in Fortran 90.
You problem probably arises from item C1270 in (Fortran 2003 Standard) which read as follows:
If a procedure that is neither an intrinsic procedure nor a statement function is used in a context that requires it to be pure, then its interface shall be explicit in the scope of that use. The interface shall specify that the procedure is pure.
I hope that it is useful information.