- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I have a question regarding the proper use of functions as arguments. I have a code in which I often pass functions as arguments and the program runs properly using ifort 10.1.
Here is a sample code
The code is organized in this way because mod_util module contains "crunching" procedures, which can get different functions to crunch from different parts of the code. Despite the probable bad programming practice, the code works fine under ifort 10.1. I have come across Steve's post http://software.intel.com/en-us/blogs/2009/09/02/doctor-fortran-in-think-thank-thunk/ where he mentions that use of interface blocks is not quite a good approach and using up-level references might lead to run-time errors. I wasn't aware of this before and since ifort didn't complain and the approach made sense to me i organized the entire code around that.
However, when I try compiling it on a differnent computer using pgf90, the code compiles but there is a segmentation error. The problem appears to be that Rn isn't defined in foo. I might find a way around it in this simple example, but there are other similar cases where this happens which would require the entire code to be rewritten. Am I doing something wrong with respect to FORTRAN standard, but what ifort is clever enough to correct?
Thanks a bunch,
Grgur
I have a question regarding the proper use of functions as arguments. I have a code in which I often pass functions as arguments and the program runs properly using ifort 10.1.
Here is a sample code
[plain]module mod_util implicit none contains function do_something(n,func) implicit none integer,intent(in) :: n real :: do_something(n+1) interface function func(x) implicit none real,intent(in) :: x(:) real :: func(size(x)) end function func end interface real :: t(n+1) t = 1.0/(n+1) do_something = func(cos(t))/(n+1) end function do_something end module mod_util !***************************************************************************** module module1 implicit none contains function get_Am(Rn,N) result(Am_in) use mod_util, only : do_something real,intent(in) :: Rn(:) integer,intent(in) :: N real :: Am_in(0:N) Am_in = 0.0 Am_in = do_something(N,foo) contains function foo(x) real,intent(in) :: x(:) real :: foo(size(x)) foo = 0.5*x*sum(Rn) end function foo end function get_Am end module module1 !***************************************************************************** program test_do_something use module1, only : get_Am implicit none integer,parameter :: N=5,NRn=2 real :: Rn(0:NRn),Am(0:N) Rn = 0.1 Am = get_Am(Rn,N) print *,' Am = ',Am end program test_do_something [/plain]
The code is organized in this way because mod_util module contains "crunching" procedures, which can get different functions to crunch from different parts of the code. Despite the probable bad programming practice, the code works fine under ifort 10.1. I have come across Steve's post http://software.intel.com/en-us/blogs/2009/09/02/doctor-fortran-in-think-thank-thunk/ where he mentions that use of interface blocks is not quite a good approach and using up-level references might lead to run-time errors. I wasn't aware of this before and since ifort didn't complain and the approach made sense to me i organized the entire code around that.
However, when I try compiling it on a differnent computer using pgf90, the code compiles but there is a segmentation error. The problem appears to be that Rn isn't defined in foo. I might find a way around it in this simple example, but there are other similar cases where this happens which would require the entire code to be rewritten. Am I doing something wrong with respect to FORTRAN standard, but what ifort is clever enough to correct?
Thanks a bunch,
Grgur
1 Solution
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't see a problem with your coide. As Tim correctly notes, passing an internal procedure as an argument is not standard F2003, but it is standard F2008, and the Intel compiler has supported this for many years.
It seems likely from your description that PGI does not support this extension - their support of F2003 is very limited to begin with, and they don't seem to try to match harder extensions (several vendors groused about this one at a Fortran standards meeting I attended - PGI is not on the committee.) I'm surprised that the compiler let you get away with it if they don't correctly support the extension in the manner the F2003 standard requires IF a compiler implements it.
As for the errors Tim mentioned, he used the Source Checker option which doesn't understand Fortran well at all.
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This message:
grg.f90(36): error #12145: function "DO_SOMETHING" is called as subroutine
grg.f90(61): error #12145: function "GET_AM" is called as subroutine
seems to be evidence of a compiler bug in current ifort 11.1.
Passing an internal procedure as a procedure argument (a fairly popular feature) wasn't permitted in f95 or f2003, and so is rejected by several compilers, although ifort should have supported it for a long time (and more compilers should begin doing so):
grg.f90(36): warning #7601: F2003 standard does not allow an internal procedure
to be an actual argument procedure name. (R1214.4). [FOO]
Am_in = do_something(N,foo)
grg.f90(36): error #12145: function "DO_SOMETHING" is called as subroutine
grg.f90(61): error #12145: function "GET_AM" is called as subroutine
seems to be evidence of a compiler bug in current ifort 11.1.
Passing an internal procedure as a procedure argument (a fairly popular feature) wasn't permitted in f95 or f2003, and so is rejected by several compilers, although ifort should have supported it for a long time (and more compilers should begin doing so):
grg.f90(36): warning #7601: F2003 standard does not allow an internal procedure
to be an actual argument procedure name. (R1214.4). [FOO]
Am_in = do_something(N,foo)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't see a problem with your coide. As Tim correctly notes, passing an internal procedure as an argument is not standard F2003, but it is standard F2008, and the Intel compiler has supported this for many years.
It seems likely from your description that PGI does not support this extension - their support of F2003 is very limited to begin with, and they don't seem to try to match harder extensions (several vendors groused about this one at a Fortran standards meeting I attended - PGI is not on the committee.) I'm surprised that the compiler let you get away with it if they don't correctly support the extension in the manner the F2003 standard requires IF a compiler implements it.
As for the errors Tim mentioned, he used the Source Checker option which doesn't understand Fortran well at all.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
I don't see a problem with your coide. As Tim correctly notes, passing an internal procedure as an argument is not standard F2003, but it is standard F2008, and the Intel compiler has supported this for many years.
It seems likely from your description that PGI does not support this extension - their support of F2003 is very limited to begin with, and they don't seem to try to match harder extensions (several vendors groused about this one at a Fortran standards meeting I attended - PGI is not on the committee.) I'm surprised that the compiler let you get away with it if they don't correctly support the extension in the manner the F2003 standard requires IF a compiler implements it.
As for the errors Tim mentioned, he used the Source Checker option which doesn't understand Fortran well at all.
Hi Tim, Steve,
Thanks a lot for your feedback. At least now I know I'm not crazy, I couldn't understand what's wrong with my code. Since I don't have an alternative to running the code on the computer with pgf90, do you have some suggestion/advice how to alter the code such that it conforms with their fortran implementation?
Thanks once again,
Grgur
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - gtokic
Since I don't have an alternative to running the code on the computer with pgf90, do you have some suggestion/advice how to alter the code such that it conforms with their fortran implementation?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - tim18
Unfortunately, if you want to make procedure arguments strictly compatible with f95 and f2003, you must use external procedures.
Hi Tim,
Thanks for the suggestion. Unfortunately indeed, but if that's the only way to get the code to run...
Best,
Grgur
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