Procedures as arguments and setting dummy arguments

Procedures as arguments and setting dummy arguments

Hello everyone

I am quite experienced with FORTRAN but I really have problems with this issue.
I am trying to make the following code, where I want to use something
like function overloading, by setting one argument of one function to a
definite value when it is called (see NON working line)

I do not want to put the variable a as a global one for
parallel-processing reasons, but I cannot think of any way to make this
code work

Any help would be greatly appreciated

Best regards

Vincent

program dbg
implicit none

integer, parameter :: N = 10
real, dimension(N) :: xval

real :: junk

integer :: i

interface
function f1(x) result(res)
implicit none
real :: x, res
end function f1
end interface

interface
function f2(x, a) result(res)
implicit none
real :: x, res, a
end function f2
end interface

do i = 1, N
xval(i) = (i-1.)/N*5.
print *, "INIT :", xval(i), f1(x=xval(i)), f2(x=xval(i), a=2.)
end do

call print_values(xval, N, f=f1)
! call print_values(xval, N, f=f2(SOMETHING, a=2.)) <=== WILL NOT WORK

contains

subroutine print_values(x, npts, f)
implicit none
interface
function f(x) result(res)
implicit none
real :: x
real :: res
end function f
end interface

real :: junk

integer :: i, npts
real, dimension(:) :: x

do i = 1, npts
junk = f(x(i))
print *, x(i), junk
end do

end subroutine print_values

end program dbg

function f1(x) result(res)
real :: res, x

res = 2.*x

end function f1

function f2(x, a) result(res)
real :: res, x
real :: a

res = 2.*x*a

end function f2

8 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Steve Lionel (Intel)'s picture

I don't think I have anything to add to what you were told in comp.lang.fortran about this.

Steve

Steve,

I use this kind of "tricks", but I have a question. The compiler is capable of make the inlining of this routine, even if I call several times the subroutine with different procedure argument ??

Thanks

Steve Lionel (Intel)'s picture

I don't quite understand your question - the compiler will decide on inlining on a per-call (in the source) level - it doesn't decide dynamically during execution.

Steve

I know the inline is a compile time, but sometimes it is possible the inline.
In the next sources:

program dbg
implicit none

integer, parameter :: N = 10
real, dimension(N) :: xval

real :: junk
integer :: i

interface
function f1(x) result(res)
implicit none
real :: x, res
end function f1
function f2(x) result(res)
implicit none
real :: x, res
end function f2
end interface

do i = 1, N
xval(i) = (i-1.)/N*5.
print *, "INIT :", xval(i), f1(xval(i)), f2(xval(i))
end do

call print_values(xval, N, f=f1)
call print_values(xval, N, f=f2)
contains

subroutine print_values(x, npts, f)
implicit none
interface
function f(x) result(res)
implicit none
real :: x
real :: res
end function f
end interface

real :: junk

integer :: i, npts
real, dimension(:) :: x

do i = 1, npts
junk = f(x(i))
print *, x(i), junk
end do

end subroutine print_values

end program dbg

function f1(x) result(res)
real :: res, x

res = 2.*x

end function f1

function f2(x) result(res)
real :: res, x

res = 3.*x

end function f2

compiling with optimization report, the result show the functions inlined. The question is: always its possible or just in some specific cases??

INLINING REPORT: (MAIN__) [1/4=25.0%]

-> INLINE: dbg_.print_values_(7) (isz = 45) (sz = 54 (17+37))
-> INLINE: f2_(9) (isz = 2) (sz = 7 (3+4))
-> for_write_seq_lis(EXTERN)
-> for_write_seq_lis_xmit(EXTERN)
-> INLINE: dbg_.print_values_(4) (isz = 45) (sz = 54 (17+37))
-> INLINE: f1_(6) (isz = 2) (sz = 7 (3+4))
-> for_write_seq_lis(EXTERN)
-> for_write_seq_lis_xmit(EXTERN)
-> for_write_seq_lis_xmit(EXTERN)
-> INLINE: f2_(8) (isz = 2) (sz = 7 (3+4))
-> for_write_seq_lis_xmit(EXTERN)
-> INLINE: f1_(5) (isz = 2) (sz = 7 (3+4))
-> for_write_seq_lis_xmit(EXTERN)
-> for_write_seq_lis(EXTERN)
-> for_set_reentrancy(EXTERN)

Thanks.

Steve Lionel (Intel)'s picture

Inlining is not always possible. The compiler makes a decision based on how large the called routine is, what registers it might use, how often it thinks the routine is to be called, etc.

Steve

my mistake. I make the question in other way.
This kind of routines ( as argument ) have the same treatment for the inlining ?? or is most complicate for the compiler analyze it ??

Steve Lionel (Intel)'s picture

You can see in the report output that you posted that first the print routine got inlined (twice) and then the calls to f1 and f2 got inlined respectively. The compiler will do this sort of recursive inlining until it no longer makes sense, from its perspective.

In this case, the compiler knew exactly what the argument was - a routine. This in itself didn't affect the inlining of the print routine. It could then figure out that f1 and f2 were being called and it could inline those, as they were small.

I would say that in general the more code needed to evaluate an argument, the less likely inlining is, but simple argument types should not matter much.

Steve

Login to leave a comment.