Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29276 Discussions

Use of loop counter as subroutine argument - causes different results

Ed2359
Beginner
1,477 Views

We're having a problem with inconsistent results of our Fortran program depending on whether we useloop counters as subroutine arguments.

When loop counters are used as arguments, thosearguments are not changed within the called subroutine, only read. We get different results when using the loop counter itself as the argument versus using a local var copy as the argument. Conceptually, the following illustrates the issue:

The following code:

integer i
...
do i=1,100
call myroutine(i,other_vars)
...
enddo

gives different results than

integer i,i1
...
do i=1,100
i1 = i
call myroutine(i1,other_vars)
...
enddo

We feel this shouldn't be happening and might indicate some unrecognized problem in our code. Our code is complex and I can't post it; unfortunately I was unable to reproduce the problem with a simple example. We are running Fortran compiler version 9.1.031; with compiler flags:

-g -xW -vec_report0 -save -zero -align all -CB -fpe0 -u -r8

The problemdoesn't happen with all cases of counters passed as arguments, only certain ones. Also, only happens when the code is compiled with optimization flags enabled. When using -O0and no -xW the problem doesn't happen at all. We are on RHE Linux with kernel 2.6.9-89.ELsmp on an x86_64.

Any suggestions on why this might be happening and what to look for? Thanks very much.

0 Kudos
5 Replies
Steven_L_Intel1
Employee
1,477 Views
When the compiler sees you use a loop control variable as a routine argument, it assumes that you might change the value of the variable in the subroutine. Doing so would not be legal Fortran, but we allow it as an extension. The practical effect of this is that the loop changes from one where the loop count is determined at the start of the loop to one where the variable is tested each time through the loop.

What you might have is something in the subroutine modifying memory it isn't supposed to, overwriting the loop variable. That's one thing I have seen in the past.

I will comment that compiler version 9.1 is quite old.... What you might try doing is adding a WRITE statement to write the value of the variable to a file or the terminal each time through the loop to see if it is changing inappropriately.
0 Kudos
SergeyKostrov
Valued Contributor II
1,477 Views
I understoodthat Fortrandoesn't allow to declare a parameter in the function with additional specificator 'constant' in order to prevent modifications. Is that correct?Something like:

...
myroutine( constant i, ... )
...

Or, maybe it willallow in somefuture releases?

Anyway,the advise regardinga 'WRITE statement' in the body of myroutine function to find a problemwill definetely work.

Best regards,
Sergey
0 Kudos
TimP
Honored Contributor III
1,477 Views
Sergey,
Perhaps you are thinking of INTENT(IN) which forbids a PURE function from returning a modified argument.
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,477 Views
Can you tell if your myroutine is inlined or not?

If I recall correctly, there were some issues with version 9.n.mm where in some cases inlining would not properly use/save registers. Not olny could your loop control variable get bunged-up but other registerized variables as well. A compiler update might be in order.

Or force your call tosubroutine to compile as out-of-inline.

Jim Dempsey
0 Kudos
Steven_L_Intel1
Employee
1,477 Views
INTENT(IN) tells the compiler that you will not modify or change the definition status of the argument. If the compiler sees an explicit interface for the called procedure (does not have to be a function or PURE) with INTENT(IN), it should know that it doesn't need to worry about the variable changing. However, if you didn't intend to change it, then my previous suggestion is the best first approach.
0 Kudos
Reply