- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
With the Fortran 90/95 standard, the name of an internal procedure must not be passed as an argument to another procedure. This means that if you have a single procedure P1, that depends on arbitrary other procedures which share a common interface P2, you either have to:
A) Make many versions of P1 for each version of P2 you are likely to encounter. P2 can be then be internal, external, or module procedures in P1.
B) Declare all P2 as external, and lose all benefits of the use of modules and host association.
I am in a position whereby A) is too tedious since there are lots of P2's, and replication of P1 could lead to errors. Also, my code is structured in such a way that it would become really annoying if I lost the benefits of host association by making the P2's external. Finally, I realise that Compaq Visual Fortran allows one to pass internal procedures as an extension, but I wish to keep my code to the standard, so that it is easily portable.
Has anyone got a work around for this problem which sticks to the fortran 90/95 standard please?
Thanks alot,
Paul.
A) Make many versions of P1 for each version of P2 you are likely to encounter. P2 can be then be internal, external, or module procedures in P1.
B) Declare all P2 as external, and lose all benefits of the use of modules and host association.
I am in a position whereby A) is too tedious since there are lots of P2's, and replication of P1 could lead to errors. Also, my code is structured in such a way that it would become really annoying if I lost the benefits of host association by making the P2's external. Finally, I realise that Compaq Visual Fortran allows one to pass internal procedures as an extension, but I wish to keep my code to the standard, so that it is easily portable.
Has anyone got a work around for this problem which sticks to the fortran 90/95 standard please?
Thanks alot,
Paul.
Link Copied
8 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No replies... Presumably because there is no work around.
Its just an annoying restriction in f90/95.
For those that are interested, there is probably one way of getting around the problem. Upgrade to f2000. I found this document:
Proposals for new features in f2000
which contains this text:
--------------------------------------------
Number: 42 |
Title: Allow internal procedures as actual arguments
Submitted By: UK
Status: For Consideration for F2000
References:
Basic Functionality: Allow internal procedures as actual arguments.
Rationale: The data for a numerical problem is often expressed in the
form of a procedure as well as a set of numbers. Examples are to
integrate a function over an interval, to optimize a function over a
region, and to solve an equation. Procedure dummy arguments are
intended to provide this functionality, but are restricted in
Fortran 90, in that the corresponding actual argument is not
permitted to be an internal procedure. This prohibits a very
convenient mechanism to allow calls of the dummy procedure to access
other local data. Here is an example
The lack of this facility has meant that library codes often use
"reverse communication", where a return is made in place of each call
of the dummy procedure. The above example becomes
This is unnatural at the point of call and leads to poorly structured
code in the library procedure. It also means that the library code has
either to use the SAVE attribute for its local data (which inhibits
parallelism), to make copies of this data on each return, or rely on
arrays provided by the user (which may be accidentally corrupted by the
user).
Estimated Impact: The reason for this restriction is that the host
might be a recursive procedure, in which case an indicator of the
instance would need to be passed from the dummy procedure argument to
the actual argument. However, ... (Malcolm: please add words to explain
why this is not a problem). The additions needed to the standard will
not be great since all that is needed is to remove a restriction. Note
that the interface has to be explicit anyway.
Detailed Specification: Allow internal procedures as actual arguments.
Its just an annoying restriction in f90/95.
For those that are interested, there is probably one way of getting around the problem. Upgrade to f2000. I found this document:
Proposals for new features in f2000
which contains this text:
--------------------------------------------
Number: 42 |
Title: Allow internal procedures as actual arguments
Submitted By: UK
Status: For Consideration for F2000
References:
Basic Functionality: Allow internal procedures as actual arguments.
Rationale: The data for a numerical problem is often expressed in the
form of a procedure as well as a set of numbers. Examples are to
integrate a function over an interval, to optimize a function over a
region, and to solve an equation. Procedure dummy arguments are
intended to provide this functionality, but are restricted in
Fortran 90, in that the corresponding actual argument is not
permitted to be an internal procedure. This prohibits a very
convenient mechanism to allow calls of the dummy procedure to access
other local data. Here is an example
CALL SOLVE (F, A, B, X) ! Solve F(X)=0 in the interval (A,B) ............ CONTAINS FUNCTION F(X) ! By host association, F has access to REAL F, X ! any data that it needs from the environment ! at the point of call of SOLVE.
The lack of this facility has meant that library codes often use
"reverse communication", where a return is made in place of each call
of the dummy procedure. The above example becomes
CONTROL = 1 ! Integer variable that controls the calls DO ! Solve F(X)=0 in the interval (A,B) : ! Code to calculate F(X) CALL SOLVE (CONTROL, A, B, X, F) IF (CONTROL==0) EXIT ! The solution has been found END DO
This is unnatural at the point of call and leads to poorly structured
code in the library procedure. It also means that the library code has
either to use the SAVE attribute for its local data (which inhibits
parallelism), to make copies of this data on each return, or rely on
arrays provided by the user (which may be accidentally corrupted by the
user).
Estimated Impact: The reason for this restriction is that the host
might be a recursive procedure, in which case an indicator of the
instance would need to be passed from the dummy procedure argument to
the actual argument. However, ... (Malcolm: please add words to explain
why this is not a problem). The additions needed to the standard will
not be great since all that is needed is to remove a restriction. Note
that the interface has to be explicit anyway.
Detailed Specification: Allow internal procedures as actual arguments.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry. The link seems to have gone wrong. The URL for the F2000 proposals is:
http://www.mailbase.ac.uk/lists/comp-fortran-90/files/n1144.txt
Paul
http://www.mailbase.ac.uk/lists/comp-fortran-90/files/n1144.txt
Paul
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You didn't allow much time for people to respond before you gave up! I don't have an answer, though. It's not clear what "upgrade to F2000" does for you here - there is no such standard at present, just a draft. Once it becomes a standard, it would be rather pointless to instantly declare your solution standard if in practice it means that few compilers support the feature.
As you note, Compaq Fortran already supports this, so if you stick to our compilers, you're all set! :-)
Steve
As you note, Compaq Fortran already supports this, so if you stick to our compilers, you're all set! :-)
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Good fair comments. Cheers. Actually I will probably do exactly what you said, and use the Compaq extension to the standard.
At the moment the code is run and tested on a Windows based single-processor PC, but our department has purchased a Compaq multi-processor supercomputer to be arriving shortly. Presumably the supercomputer will come with compaq high performance fortran.
Do you know if this will also allow the extension to the f90/95 standard?
Cheers,
Paul
At the moment the code is run and tested on a Windows based single-processor PC, but our department has purchased a Compaq multi-processor supercomputer to be arriving shortly. Presumably the supercomputer will come with compaq high performance fortran.
Do you know if this will also allow the extension to the f90/95 standard?
Cheers,
Paul
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
All Compaq Fortran 95 compilers support this extension.
Steve
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's great. Cheers Steve and forall.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For those that are interested...
I have been in contact with a representative from NAG who also happens to be on the committee that decides on fortran standards, and have managed to obtain the following useful info:
The latest versions of the drafts of the new standard (f2000) and many other committee documents can be found at
http://www.j3-fortran.org/
Another useful link which contains details on the public consultation period for the new standard, plus links to a summary of the new features can be found at
http://www.bcs.org/siggroup/fortran/f200xf.htm
With regards to the passing of internal procedure names as actual arguments, since the UK was the only country which requested such an extension to the f90/95 standard, it did not actually gain sufficient support to gain approval. So we shouldn't expect to see it in f2000.
However, I found a work around which was simple to implement, and sticks to the f95 standard, the net personal consequence of which was that I had to use host association within a module to share some information, and alter one procedure so that it was no longer PURE. What I didn't realise is that internal, external, and module procedures are all classed as being independent, and that module procedures ARE allowed to be passed as actual arguments to other procedures, even though internal ones aren't. Therefore, I simply moved my internal procedures outside such that they were module procedures, (and I had to use host association within the module to transfer some data between the two).
In summary (or if what I just said didn't seem to make much sense), if you have a module which does contains a routine which integrates a function,
then the following isn't allowed...
but the following IS allowed
under the f95 standard. I hope that's clear.
Paul
I have been in contact with a representative from NAG who also happens to be on the committee that decides on fortran standards, and have managed to obtain the following useful info:
The latest versions of the drafts of the new standard (f2000) and many other committee documents can be found at
http://www.j3-fortran.org/
Another useful link which contains details on the public consultation period for the new standard, plus links to a summary of the new features can be found at
http://www.bcs.org/siggroup/fortran/f200xf.htm
With regards to the passing of internal procedure names as actual arguments, since the UK was the only country which requested such an extension to the f90/95 standard, it did not actually gain sufficient support to gain approval. So we shouldn't expect to see it in f2000.
However, I found a work around which was simple to implement, and sticks to the f95 standard, the net personal consequence of which was that I had to use host association within a module to share some information, and alter one procedure so that it was no longer PURE. What I didn't realise is that internal, external, and module procedures are all classed as being independent, and that module procedures ARE allowed to be passed as actual arguments to other procedures, even though internal ones aren't. Therefore, I simply moved my internal procedures outside such that they were module procedures, (and I had to use host association within the module to transfer some data between the two).
In summary (or if what I just said didn't seem to make much sense), if you have a module which does contains a routine which integrates a function,
MODULE int_mod CONTAINS REAL FUNCTION integrate(fun) INTERFACE REAL FUNCTION fun(x) REAL, INTENT(IN) x END FUNCTION fun END INTERFACE ... END FUNCTION integrate END MODULE int_mod
then the following isn't allowed...
MODULE mod_A CONTAINS SUBROUTINE sub_1 USE int_mod ... result=integrate(fun) ... CONTAINS ! function fun declared as an internal procedure REAL FUNCTION fun(x) ... END FUNCTION fun END SUBROUTINE sub_1 END MODULE mod_A
but the following IS allowed
MODULE mod_A CONTAINS SUBROUTINE sub_1 USE int_mod ... result=integrate(fun) ... END SUBROUTINE sub_1 ! function fun declared as a module procedure REAL FUNCTION fun(x) ... END FUNCTION fun END MODULE mod_A
under the f95 standard. I hope that's clear.
Paul
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just a side remark: the (slight) disadvantage of that method vs. "pure" implementation in the language is inability to inherit automatic variables from the "host" procedure (since module variables are typically implemented as static). For example, variables in RECURSIVE procedures are automatic unless explicitly SAVEd.
That may sound exotic, but I've encountered ugly bugs in GUI codes related with my failures to declare routines RECURSIVE or variables (non-standardly) AUTOMATIC. You have no idea what an innocently-looking call to MessageBox function can do to execution path of your code :-).
Jugoslav
That may sound exotic, but I've encountered ugly bugs in GUI codes related with my failures to declare routines RECURSIVE or variables (non-standardly) AUTOMATIC. You have no idea what an innocently-looking call to MessageBox function can do to execution path of your code :-).
Jugoslav

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page