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

How can I FOOL the optimizer ?

WSinc
New Contributor I
1,275 Views

I have a function called get_prime with no input arguments, returning an 8 byte integer.

Now if I call it TWICE, I should get two different results, i.e.

P=get_prime()

Q=get_prime()

where P and Q are two different integer(8) primes. The reason the answers are different, is

that it uses a random number generator within.

However, the compiler thinks it only has to call it ONCE, and copies the result to BOTH P and Q.

Is there a way to block the optimizer for this one particular case?

Or fool it somehow?

0 Kudos
10 Replies
Steven_L_Intel1
Employee
1,275 Views
Is get_prime declared PURE? If not, then the optimizer should not be doing this and I'd appreciate a test case. If it is declared PURE, then this is correct behavior and your routine is not qualified to be PURE.
0 Kudos
WSinc
New Contributor I
1,275 Views

I looked, and it is not declared either way.

So, is the default NOT pure? Here is the attached routine.

Why do the indents disappear?

--------------------------------------------------------------------------------------------------------

integer(8) function get_prime()

implicit NONE

include "primes.cmn"

include "params.inc"

integer(8) ii,P

integer(4) i1,i2,randint,chk,compar,nfail,itry,ntry

integer(4) A(0:BIGGEST),Amod(0:BIGGEST),pe(0:BIGGEST)

integer(4) BIG/1000000/

logical dbg/.false./

! pick a LARGE random odd integer

10 i1=randint(0,BIG+1)

i2=randint(0,BIG-1)

! print *,"i1,i2=",i1,i2

ii=BIG*int8(i2)+int8(i1)

p=2*ii+1

! print *,"ii=",ii

! print *,"P=",P

call extract(p,pe)

nfail=0

! now get A < P

do itry=1,100

15 call stuffit(3,A,0,chunk-1) ! 12 digits

if(compar(a,pe).ge.0)go to 15

if(dbg)call extprin("a =",A,chk)

call pwrmod(A,p,pe,Amod)

if(dbg)call extprin("Amod=",Amod,chk)

if(compar(Amod,A).eq.0)then

cycle

else

print *,"this prime failed:",P

nfail=nfail+1

go to 10

endif

end do

get_prime=P

end function

0 Kudos
Arjen_Markus
Honored Contributor II
1,275 Views

Isn't the optimizer allowed to do this (by the Fortran standard; if I remember correctly, that is the precise reason why random_number is a subroutine and not a function). The function get_prime() has no arguments and so the compiler/optimizer can assume that each invocation will give the same answer.

Regards,

Arjen

0 Kudos
Steven_L_Intel1
Employee
1,275 Views

I don't think the compiler is allowed to do this for a function not explicitly declared as PURE. RANDOM_NUMBER is a subroutine because all intrinsic functions are pure, but that doesn't mean user functions are. Let me look into this more.

Use the code insertion tool (yellow pencil) for code. It will keep the indents.

0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,275 Views
Quoting arjenmarkus

Isn't the optimizer allowed to do this (by the Fortran standard; if I remember correctly, that is the precise reason why random_number is a subroutine and not a function). The function get_prime() has no arguments and so the compiler/optimizer can assume that each invocation will give the same answer.

If you recall, that is (or was) the subject of a long-standing religious debate on comp.lang.fortran, mostly between James Giles and Richard Maine. However, while they stand on different positions what the Standard allows that the compiler might do, they agree that no current compiler does skip execution of a function unless it is explicitly declared PURE. So, while IVF optimizer might be correct in theory, users don't expect such behavior and Steve is (IMO) correct to treat it as a bug.

RANDOM_NUMBER is a subroutine for a reason similar to the one you describe, but not exactly so: all intrinsic FUNCTIONs are pure, so non-pure ones (DATE_AND_TIME is another example) are subroutines. But (AFAICT) this is a convention in the Standard rather than something dictated by the language (well, Richard Maine would probably disagree).

0 Kudos
Arjen_Markus
Honored Contributor II
1,275 Views

Yes, I remember that, but not the details ;). It is oneof thereasons I avoid functions that

have no arguments, if at all possible. If they are intended to always return the same information,

it is okay. (Another good reason, IMO, is that functions should not have side effects, that is my

more or less religious point of view).


Regards,

Arjen

0 Kudos
WSinc
New Contributor I
1,275 Views
It's easy enough to convert it to a subroutine, so that's what I'll do - - -
0 Kudos
Steven_L_Intel1
Employee
1,275 Views
Bill, can you attach a ZIP of a complete test case that builds and runs? I have, so far, been unable to reproduce the problem. It would also be useful to know if the function and caller were in the same source or separate, and which compiler options you used.
0 Kudos
WSinc
New Contributor I
1,275 Views

I will try -

there are a lot of soubroutines involved.

May take a while.

0 Kudos
WSinc
New Contributor I
1,275 Views

I will try -

There are a lot of subroutines involved.

It may take some time.

0 Kudos
Reply