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
Novo colaborador I
1.276 Visualizações

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 Respostas
Steven_L_Intel1
Funcionário
1.276 Visualizações
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.
WSinc
Novo colaborador I
1.276 Visualizações

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

Arjen_Markus
Colaborador honorário II
1.276 Visualizações

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

Steven_L_Intel1
Funcionário
1.276 Visualizações

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.

Jugoslav_Dujic
Contribuidor valorado II
1.276 Visualizações
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).

Arjen_Markus
Colaborador honorário II
1.276 Visualizações

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

WSinc
Novo colaborador I
1.276 Visualizações
It's easy enough to convert it to a subroutine, so that's what I'll do - - -
Steven_L_Intel1
Funcionário
1.276 Visualizações
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.
WSinc
Novo colaborador I
1.276 Visualizações

I will try -

there are a lot of soubroutines involved.

May take a while.

WSinc
Novo colaborador I
1.276 Visualizações

I will try -

There are a lot of subroutines involved.

It may take some time.

Responder