a very weird problem on calling subroutine

I am trying to write a simple program, which is expected to be used in generating random numbers between 0~1. The programming is performed on the Linux platform with pgf90 compiler.

If directly generating the numbers in the main program, I can get normal results. However, when putting the generating function into a subroutine, I found that the main program gave different results. It is quite weird, for both programs work normaly in Microsoft Powerstation and can give completely same results.

The two programs are listed as below, I wish somebody experienced in Pgf90 can help me. Thanks in advance.

test1.f90 (can’t work normaly)


IX=65535
IC=125
IM=65536
AM=0.
XS=0.
yfl=0.0
open (1,file=‘test1.txt’,status=‘unknown’)
do i=1,1000
call randu3(ix,ic,im,yfl)
enddo
end

SUBROUTINE RANDU3(IX,IC,IM,YFL)
real yfl
IF(YFL.NE.0.) GOTO 1
AX=real(IX)
AM=real(IM)
AC=real(IC)
YFL=AX/AM
1 YFL=ACYFL
YFL=YFL-real(IFIX(YFL))
write(1,
)‘yfl final’,yfl
RETURN
END


test2.f90 (seems to be OK)


IX=65535
IC=125
IM=65536
AM=0.
XS=0.
yfl=0.0
open (2,file=‘test2.txt’,status=‘unknown’)
do i=1,1000
IF(YFL.NE.0.) GOTO 1
AX=real(IX)
AM=real(IM)
AC=real(IC)
YFL=AX/AM
1 YFL=ACYFL
YFL=YFL-real(IFIX(YFL))
write(2,
)‘yfl final’,yfl
enddo
end


Hi chonp1977,

The difference between these two codes is the values of AX, AM, and AC are saved from iteration to iteration in test2. For test1, these values are local to the subroutine, hence they not saved from call to call. To fix your code, you need to add the “SAVE” attribute to these variables:

SUBROUTINE RANDU3(IX,IC,IM,YFL)
real yfl
real, save :: AX, AM, AC
IF(YFL.NE.0.) GOTO 1
AX=real(IX)
AM=real(IM)
AC=real(IC)
YFL=AX/AM
1 YFL=AC*YFL
YFL=YFL-real(IFIX(YFL))
write(1,*)'yfl final',yfl
RETURN
END

Or you can use the flag “-Msave”, which applies the save attribute to all local variables.

Hope this helps,
Mat

Thanks a lot, Dr. Mkcolg. It does work!

However, I am still a little confused about Test1.f90. Since there are lines which input fixed values to AX, AM and AC through the dummy varibles (IX, IM, IC) during each call procedure, why values of the three variables are changed from call to call?

Hi chonp1977,

However, I am still a little confused about Test1.f90. Since there are lines which input fixed values to AX, AM and AC through the dummy varibles (IX, IM, IC) during each call procedure, why values of the three variables are changed from call to call?

A subroutine’s local variables are stored on the ‘stack’ and created each time your subroutine is called. Once the subroutine exits, the local variable’s memory is reclaimed for use by the next subroutine call. It’s not that AX, AM, and AC get changed, rather they get recreated each time RANDU3 is called.

When you add the SAVE attribute, the variables will now be stored in your program’s data segment (BSS). The memory has a lifetime for the entire program so does not get created or destroyed with each call.

Hope this helps,
Mat