For Programmers: Free Programming Magazines  


Home > Archive > Fortran > May 2005 > Program runs slower than the beginning









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Program runs slower than the beginning
zwang5@hotmail.com

2005-05-20, 3:59 pm

Hi all,

I am doing a simulation with 10000 runs for each of combination of
factors, with the total of 300 rounds. For example, it runs faster at
the first 10 rounds, but much slow for round 50 to 59 for the same size
of simulated data. To confirm this is "time related", I modified the
program and let it run only for the round 50 to 59, then it runs at the
speed of first 10 rounds.

I suspect this is memory related issue, please see the botton. I have
seen that SIZE and RSS increasing as the program runs. But even I used
allocate and deallocate, I don't see it helps a lot.

The program is not aweful long and I list it at the bottom. The program
was compiled using "lf95" and IMSL on Debian Linux.

Please advise what might go wrong and what information you think might
be helpful to pose here.

Thanks!

Zhu
15:55:16 up 27 days, 2:45, 1 user, load average: 1.08, 1.58, 1.67
54 processes: 52 sleeping, 2 running, 0 zombie, 0 stopped
CPU states: 25.0% user, 0.1% system, 0.0% nice, 74.9% idle
Mem: 2069312K total, 1478620K used, 590692K free, 162172K
buffers
Swap: 2000084K total, 17196K used, 1982888K free, 463548K cached

PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME COMMAND
8320 xxxx 18 0 664M 664M 712 R 99.9 32.8 1013m a.out
9390 xxxx 9 0 952 952 752 R 0.1 0.0 0:00 top
1 root 9 0 476 436 416 S 0.0 0.0 0:11 init
2 root 8 0 0 0 0 SW 0.0 0.0 0:00 keventd
3 root 18 19 0 0 0 SWN 0.0 0.0 0:00
ksoftirqd_CPU0
4 root 18 19 0 0 0 SWN 0.0 0.0 0:00
ksoftirqd_CPU1
5 root 19 19 0 0 0 SWN 0.0 0.0 0:00
ksoftirqd_CPU2
6 root 18 19 0 0 0 SWN 0.0 0.0 0:00
ksoftirqd_CPU3
7 root 9 0 0 0 0 SW 0.0 0.0 0:06 kswapd
8 root 9 0 0 0 0 SW 0.0 0.0 0:00 bdflush
9 root 9 0 0 0 0 SW 0.0 0.0 0:07 kupdated
10 root 9 0 0 0 0 SW 0.0 0.0 0:03 kjournald
91 root 9 0 0 0 0 SW 0.0 0.0 0:02 kjournald
92 root 9 0 0 0 0 SW 0.0 0.0 0:03 kjournald


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCC PROGRAM CCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCC

integer ntpv,nwpv,nmpv,nqpv,s,nn,pi,n(nn),max
integer iseed,nmiss,nm,resim,nrun
c integer iparam(7)
integer, allocatable :: iparam(:)
external rnset,rnwib,umach,logistic,drstable,dumi
nf,
& duming
real*8 fuzz, shape
parameter
(nn=5,max=75,s=10000,fuzz=0.0001,pi=3.141592654,shape=1)
parameter (npar=2)
real*8 alpha(6),scale2(10),tau,pval,mu,var,stde
rr
c & T1(max),T2(max),Tdiff(max),w(max),z(max)
,freq(max*(max-1)/2+1)
real*8, allocatable ::
T1(:),T2(:),Tdiff(:),z(:),freq(:),stat1(
:),
&stat2(:),rparam(:)
real*8, w(max)
c
real*8, tpow,wpow,mpow,qpow,t05(nn),m05(nn),
&q05(nn),
&muq,varq,sdq

integer nx
parameter (nx=2)
real*8 f,fscale,x(nx),xguess(nx),xscale(nx)
data xscale/1.0D0,1.0D0/,fscale/1.0D0/
data alpha/0.4D0,0.5D0,0.6D0,0.7D0,0.8D0,0.9D0/
common w,nm
open(unit=6,file='weib.out',access='sequential',
1 status='new')
if(nn.NE.5)then
print *,'the number of different sizes considered are 5'
stop
endif


c simulate the following size of samples
n(1)=10
n(2)=20
n(3)=30
n(4)=50
n(5)=75
iseed=123457
call rnset(iseed)

call umach (2,nout)
do 15 k=1,nn
if(n(k).EQ.10)then
c nm=10
scale2(1)=1.0D0
scale2(2)=dexp(0.20D0)
scale2(3)=dexp(0.48D0)
scale2(4)=dexp(0.72D0)
scale2(5)=dexp(1.08D0)
scale2(6)=dexp(1.32D0)
scale2(7)=dexp(1.68D0)
scale2(8)=dexp(1.92D0)
scale2(9)=dexp(2.24D0)
scale2(10)=dexp(2.40D0)
t05(1)=2.262157
m05(1)=4.057
q05(1)=2.227
else
if(n(k).EQ.20)then
c nm=20
scale2(1)=1.0D0
scale2(2)=dexp(0.20D0)
scale2(3)=dexp(0.40D0)
scale2(4)=dexp(0.80D0)
scale2(5)=dexp(1.00D0)
scale2(6)=dexp(1.10D0)
scale2(7)=dexp(1.30D0)
scale2(8)=dexp(1.50D0)
scale2(9)=dexp(1.70D0)
scale2(10)=dexp(1.90D0)
t05(2)=2.093024
m05(2)=3.685
q05(2)=2.077
else
if(n(k).EQ.30)then
c nm=30
scale2(1)=1.0D0
scale2(2)=dexp(0.12D0)
scale2(3)=dexp(0.24D0)
scale2(4)=dexp(0.48D0)
scale2(5)=dexp(0.72D0)
scale2(6)=dexp(0.90D0)
scale2(7)=dexp(1.00D0)
scale2(8)=dexp(1.10D0)
scale2(9)=dexp(1.20D0)
scale2(10)=dexp(1.30D0)
t05(3)=2.045230
m05(3)=3.588
q05(3)=2.037

else
if(n(k).EQ.50)then
c nm=50
scale2(1)=1.0D0
scale2(2)=dexp(0.12D0)
scale2(3)=dexp(0.24D0)
scale2(4)=dexp(0.48D0)
scale2(5)=dexp(0.72D0)
scale2(6)=dexp(0.90D0)
scale2(7)=dexp(1.06D0)
scale2(8)=dexp(1.14D0)
scale2(9)=dexp(1.22D0)
scale2(10)=dexp(1.30D0)
t05(4)=2.009575
m05(4)=3.507
c must change this q05=2.017
q05(4)=2.004
else
if(n(k).EQ.75)then
c nm=75
scale2(1)=1.0D0
scale2(2)=dexp(0.12D0)
scale2(3)=dexp(0.24D0)
scale2(4)=dexp(0.48D0)
scale2(5)=dexp(0.60D0)
scale2(6)=dexp(0.72D0)
scale2(7)=dexp(0.90D0)
scale2(8)=dexp(1.06D0)
scale2(9)=dexp(1.14D0)
scale2(10)=dexp(1.22D0)
t05(5)=1.992543
m05(5)=3.455
q05(5)=1.988
endif
endif
endif
endif
endif
15 continue

write(6,*)'Number of simulations ',s
write(6,*)'round size alpha scale2 cor test1 test2 test3
& test4'

do 110 k=1,nn
do 40 m=1,6
do 30 ii=1,10

if(alpha(m).LT.0.OR.alpha(m).EQ.0.OR.alpha(m).GT.1.OR.
&alpha(m).EQ.1)then
write(6,*)'alpha must be between 0 and 1'
stop
endif
ntpv=0
nwpv=0
nmpv=0
nqpv=0
tau=0.0D0

do 10 i=1,s

allocate (stat1(9),stat2(10), rparam(7),iparam(7))
allocate (z(n(k)))
allocate (T1(n(k)))
allocate (T2(n(k)))
allocate (Tdiff(n(k)))
c allocate (w(n(k)))
allocate (freq(n(k)*(n(k)-1)/2+1))
call drstable(n(k),1.0D0,alpha(m),z)

call drnwib(n(k),shape,T1)
call drnwib(n(k),shape,T2)
if(scale2(ii).NE.1.0D0)then
do j=1,n(k)
T2(j)=scale2(ii)*T2(j)
enddo
endif

do j=1,n(k)
T1(j)= T1(j) * z(j)**(-1/shape)
T2(j)= T2(j) * z(j)**(-1/shape)
enddo

call erset(0,0,0)
call dkendl(n(k),T1,T2,fuzz,stat1,freq)

tau=tau+stat1(1)

do j=1,n(k)
Tdiff(j)=T1(j)-T2(j)
enddo

do j=1,n(k)
w(j)=dlog(T2(j)/T1(j))
enddo

muq=0.0D0
do j=1,n(k)
muq=muq+w(j)
enddo
muq=muq/dfloat(n(k))
varq=0.0D0
do j=1,n(k)
varq=varq+(w(j)-muq)**2
enddo
varq=varq/dfloat(n(k)-1)
c sdq=dsqrt(varq/dfloat(n(k)))
sdq=dsqrt(varq)
nm=n(k)

xguess(1)=muq
xguess(2)=sdq

xguess(2)=dexp(xguess(2))
call du4inf (iparam,rparam)
call duminf (logistic,nx,xguess,xscale,fscale,
& iparam,rparam,x,f)
x(2)=dexp(x(2))

if(dsqrt(dble(n(k)))*dabs(x(1))/x(2).GT.m05(k))then
nmpv=nmpv+1
endif

if(dsqrt(dble(n(k)))*dabs(muq)/sdq.GT.q05(k))then
nqpv=nqpv+1
endif

mu=0.0D0
do j=1,n(k)
mu=mu+Tdiff(j)
enddo
mu=mu/dfloat(n(k))
var=0.0D0
do j=1,n(k)
var=var+(Tdiff(j)-mu)**2
enddo

var=var/dfloat(n(k)-1)
stderr=dsqrt(var/dfloat(n(k)))

if(dabs(mu/stderr).GT.t05(k))then
ntpv=ntpv+1
endif

call dsnrnk(n(k),Tdiff,fuzz,stat2,nmiss)

pval=2*stat2(4)
c print *,'pval=',pval
if(pval.LT.0.05D0)then
nwpv=nwpv+1
endif

deallocate (stat1,stat2, rparam,iparam)
deallocate (z)
deallocate (T1)
deallocate (T2)
deallocate (Tdiff)

deallocate (freq)
10 continue
c number of simulations
c write(6, *)'complete of simulation
of',(k-1)*60+(m-1)*10+ii,'round

tpow=ntpv/dfloat(s)
wpow=nwpv/dfloat(s)
mpow=nmpv/dfloat(s)
qpow=nqpv/dfloat(s)
cor=tau/dfloat(s)

write(6,99)(k-1)*60+(m-1)*10+ii, n(k),alpha(m),scale2(ii),cor,
&tpow,wpow,mpow,qpow
99 format (I5 I4,F6.2,F8.3,F8.3,F8.3,F8.3,F8.3,F8.3)

call flush(6)
30 continue
40 continue
110 continue
close(unit=6)
stop
end



CCCCCCCCCCCCCCCCCCCCCC
C subroutines
C
CCCCCCCCCCCCCCCCCCCCCC

subroutine logistic (nx,x,f)
integer nx,nm,max
parameter(max=75)
real*8 w(max),x(nx),f,v
common w,nm

f=0.0D0
do j=1,nm
f=f+(w(j)-x(1))/dexp(x(2))
&-x(2)-2.0D0*dlog(1.0D0+dexp((w(j)-x(1))/dexp(x(2))))
enddo
f=-f

return
end

subroutine drstable (n, scale, alpha, rngstab)
integer n
real*8 pi,scale, alpha, skewness,beta,u,v,t,B,S,X,rngstab(n)
parameter (skewness=1,pi=3.141592654)

scale=1.0D0
beta=skewness
if(alpha.GE.1.0D0 .OR. alpha.LE.0.0D0)then
print *,'interval 0 < index < 1'
stop
endif
if(skewness.NE.1.0D0)then
print *,'not equal to 1'
stop
endif

do 100 i=1,n
u=0.0D0
if(u.EQ.0.0D0 .OR. u.EQ.1.0D0)then
u=pi*(drnunf() - 0.5D0)

endif
v=0.0D0
if(v.EQ.0.0D0)then
call drnexp(1,v)

endif
t = beta * dtan ((pi/2.0D0) * alpha)

B = datan (t) / alpha

S = (1.0D0 + t * t)**(1.0D0/(2.0D0 * alpha))

X = S * dsin (alpha * (u + B)) / (dcos (u)**(1.0D0 /
alpha))
& * (dcos (u - alpha * (u + B)) / v)**((1.0D0 - alpha) / alpha)
rngstab(i) = scale * X

100 continue
return
end

Richard E Maine

2005-05-20, 3:59 pm

In article <1116606151.141882.56180@f14g2000cwb.googlegroups.com>,
zwang5@hotmail.com wrote:

> I am doing a simulation with 10000 runs for each of...300 rounds.
> For example, it runs faster at
> the first 10 rounds, but much slow for round 50 to 59 for the same size
> of simulated data. To confirm this is "time related", I modified the
> program and let it run only for the round 50 to 59, then it runs at the
> speed of first 10 rounds.
>
> I suspect this is memory related issue, please see the botton. I have
> seen that SIZE and RSS increasing as the program runs. But even I used
> allocate and deallocate, I don't see it helps a lot.


First, just some side comments on unrelated coding things.

1. You use the nn parameter before its value is defined; that's not
allowed by the standard (or by many compilers).

2. Two nonstandard extra commas in

> real*8, w(max)
> real*8, tpow,...


3. A missing comma in
> 99 format (I5 I4,F6.2,F8.3,F8.3,F8.3,F8.3,F8.3,F8.3)


I'm mildly surprised that the compiler let this last one by.

Anyway, on to your question. I didn't spend a lot of time studying the
program - certainly not enough to really figure out what was going on in
any detail. But I suspect that your allocates and deallocates might be
the source of the problem. You have:


> do 10 i=1,s
>
> allocate (stat1(9),stat2(10), rparam(7),iparam(7))
> allocate (z(n(k)))
> allocate (T1(n(k)))
> allocate (T2(n(k)))
> allocate (Tdiff(n(k)))
> c allocate (w(n(k)))
> allocate (freq(n(k)*(n(k)-1)/2+1))

.....
(appropriate deallocates)

where s has your 10000 value, and this whole thing is inside of the
loops that presumably total 300 cases. So each one of those allocates
gets executed 3 million times. That's a fair number of allocates.

Allocation and deallocation is, in general, relatively expensive. It can
get increasingly expensive if you get memory fragmentation as a result
of repeated allocations and deallocations of various-sized things. I bet
that is what is happening here.

Your allocates do depend on the outer loop variables (elided from what I
quoted above), so I see that you do need them. But the allocates don't
depend on the i variable. (In fact, I didn't off-hand see anything that
depended explicitly on the i variable, but I suppose there is probably
saved state between the loop passes).

I would suggest hoisting the above allocates out of the i loop (but
still in the outer loops) so that each one happens only 300 times
instead of 3 million. Of course, correspondingly move the deallocates.

Might not be your problem, but I think it a plausible guess.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
zwang5@hotmail.com

2005-05-20, 8:57 pm

Thanks for your reply. First, side comments 1 and 3 are accepted.
However, regarding side comment 2, if I used

real*8 allocatable,
T1(:),T2(:),Tdiff(:),z(:),freq(:),stat1(
:),stat2(:),rparam(:)

the compiler does allow me.

Back to the main point about allocate and deallocate. I have tried to
change the code to

do 110 k=1,nn
allocate (z(n(k)))
allocate (T1(n(k)))
allocate (T2(n(k)))
allocate (Tdiff(n(k)))
allocate (w(n(k)))
allocate (freq(n(k)*(n(k)-1)/2+1))
do 40 m=1,6
do 30 ii=1,10
.....
.....
30 continue
40 continue
deallocate (stat1,stat2, rparam,iparam)
deallocate (z)
deallocate (T1)
deallocate (T2)
deallocate (Tdiff)
deallocate (freq)
110 continue

But after running 10 rounds, I still haven't seen the speed difference
before and after the change. For example, the first round takes less
than 30 seconds, but running 5 rounds takes about 10 minutes. In
addition, I have seen the similar increasing of SIZE and RSS. For
example, they are about 80M after running 6 rounds with 14 minutes.

I am curious what might be wrong.

Thanks,

Zhu

James Giles

2005-05-20, 8:57 pm

zwang5@hotmail.com wrote:
> Thanks for your reply. First, side comments 1 and 3 are accepted.
> However, regarding side comment 2, if I used
>
> real*8 allocatable,
> T1(:),T2(:),Tdiff(:),z(:),freq(:),stat1(
:),stat2(:),rparam(:)
>
> the compiler does allow me.


The above declares a scalar variable called ALLOCATABLE
and several arrays with deferred sizes. These latter shouldn't
have been allowed without the POINTER or ALLOCATABLE
attribute unless the arrays are dummy arguments. Apparently
your compiler accepts this as an extension.

As to your main problem, I haven't any idea. It looks like a
memory leak or some internal fragmentation problem in the
memory manager.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


Dick Hendrickson

2005-05-20, 8:57 pm



zwang5@hotmail.com wrote:
> Thanks for your reply. First, side comments 1 and 3 are accepted.
> However, regarding side comment 2, if I used
>
> real*8 allocatable,
> T1(:),T2(:),Tdiff(:),z(:),freq(:),stat1(
:),stat2(:),rparam(:)
>
> the compiler does allow me.
>
> Back to the main point about allocate and deallocate. I have tried to
> change the code to
>
> do 110 k=1,nn
> allocate (z(n(k)))
> allocate (T1(n(k)))
> allocate (T2(n(k)))
> allocate (Tdiff(n(k)))
> allocate (w(n(k)))
> allocate (freq(n(k)*(n(k)-1)/2+1))
> do 40 m=1,6
> do 30 ii=1,10
> ....
> ....
> 30 continue
> 40 continue
> deallocate (stat1,stat2, rparam,iparam)
> deallocate (z)
> deallocate (T1)
> deallocate (T2)
> deallocate (Tdiff)
> deallocate (freq)
> 110 continue
>

Others have suggested some sort of memory fragmentation
problem. Try putting the deallocates in the reverse
order of the allocates. That might allow the system to
reclaim memory more gracefully. If fred is the last thing
you allocate, then make it the first thing you deallocate.
Also, you don't show a deallocate of w here. Maybe that's
just a cut and paste effect, but if you don't, then you
should try to allocate it first, so that the system doesn't
have to do allocates and deallocates around it.

Memory management is sometimes more efficient if the
allocates and deallocates let it work like a last-in
first-out stack.

Dick Hendrickson
> But after running 10 rounds, I still haven't seen the speed difference
> before and after the change. For example, the first round takes less
> than 30 seconds, but running 5 rounds takes about 10 minutes. In
> addition, I have seen the similar increasing of SIZE and RSS. For
> example, they are about 80M after running 6 rounds with 14 minutes.
>
> I am curious what might be wrong.
>
> Thanks,
>
> Zhu
>


Richard E Maine

2005-05-20, 8:57 pm

In article <1116614859.747445.261350@g49g2000cwa.googlegroups.com>,
zwang5@hotmail.com wrote:

> Thanks for your reply. First, side comments 1 and 3 are accepted.
> However, regarding side comment 2, if I used
>
> real*8 allocatable,
> T1(:),T2(:),Tdiff(:),z(:),freq(:),stat1(
:),stat2(:),rparam(:)
>
> the compiler does allow me.


Really? I'd XXXXX rather loudly at the compiler vendor then. And I have
no idea what that would do. As Giles says, the "allocatable" there is a
variable name instead of an attribute. And since the other variables
don't get the allocatable attribute (or pointer, or dummy), it shouldn't
be valid to declare them with dimensions like that. Is this really
exactly what the line looks like, or have you miscopied the punctuation?

If the line really looks like that, have you been ignoring all warning
messages that the compiler produces? If so, I'd recommend against that.
To look at them and decide they are ok is one thing, but to ignore them
completely without even reading them is a practice I'd recommend
strongly against.

If the line really looks like this and compiler doesn't give you any
warning messages, well... I thought better of the Lahey compiler than
that. I haven't bothered to check, but the standard probably even
mandates diagnostics for some of the resulting issues... though perhaps
those diagnostics are off by default.

> Back to the main point about allocate and deallocate.

[took my suggestion and it didn't help]

Sorry, but I'm out of simple ideas on this then.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
zwang5@hotmail.com

2005-05-20, 8:57 pm

I should say

real*8 allocatable,
T1(:),T2(:),Tdiff(:),z(:),freq(:),stat1(
:),stat2(:),rparam(:)

the compiler DOESN'T allow me.

In fact, I found an example online to use

real*8, allocatable, ...

"If the line really looks like that, have you been ignoring all warning
messages that the compiler produces?"

No error or warning.

Thanks,

Zhu

zwang5@hotmail.com

2005-05-20, 8:57 pm

I don't show a deallocate of w here because I didn't allocate w since
the compiler doesn't allow due to (I guess) w is declaired in common
block.

Richard E Maine

2005-05-20, 8:57 pm

In article <1116625032.565690.110210@z14g2000cwz.googlegroups.com>,
zwang5@hotmail.com wrote:

> real*8 allocatable,
> T1(:),T2(:),Tdiff(:),z(:),freq(:),stat1(
:),stat2(:),rparam(:)
>
> the compiler DOESN'T allow me.


Ah. That makes more sense. The right syntax for this is (well, ignoring
the real*8 business, which isn't related)

real*8 allocatable :: T1(:),T2(:),Tdiff(:), ...

Note the double colon. That is needed when you specify attributes (such
as the "allocatable" here) in the same statement. Without the double
colon, there is nothing to tell the compiler where the attributes stop
and the variable names begin. Remember than Fortran doesn't have
reserved names, so "allocatable" is a perfectly fine variable name.

I personally have adopted a style of using the double colon all the time
for consistency. That way I don't have to bother with figuring out
whether it is needed or not, since using it is always ok. There are a
few other things that can make it needed. But that's just my personal
choice, not necessarily a recommendation.

Sorry but I haven't looked further at your real question, though some of
the other suggestions made sound at least plausible to me.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
zwang5@hotmail.com

2005-05-20, 8:57 pm

I guess I am more frustrated with other stuff. But to correct myself,
the related code is:
real*8, allocatable ::
T1(:),T2(:),Tdiff(:),z(:),freq(:),stat1(
:),
&stat2(:),rparam(:)

Note not
real*8 allocatable :: T1(:), T2(:), ...
in order to be compiled free of error or warning.

James Giles

2005-05-20, 8:57 pm

Richard E Maine wrote:
> In article <1116625032.565690.110210@z14g2000cwz.googlegroups.com>,
> zwang5@hotmail.com wrote:
>
>
> Ah. That makes more sense. The right syntax for this is (well,
> ignoring the real*8 business, which isn't related)
>
> real*8 allocatable :: T1(:),T2(:),Tdiff(:), ...
>
> Note the double colon. That is needed when you specify attributes
> (such as the "allocatable" here) in the same statement. Without the
> double colon, there is nothing to tell the compiler where the
> attributes stop and the variable names begin. [...]


Unfortunately that's not quite true. A type name followed by a
comma indicates that the next thing is an attribute. If that is then
followed by another comma, another attribute is expected. Etc.
A space instead of a comma after the last attribute is sufficient
to identify where the attributes end and the names being declared
begin. The language only requires the double colon if any of
the names being declared are followed by initialization expressions.

The reason for the double colon comes from the old fixed source
form. Without requiring the double colon, the following might be
either an assignment statement or a declaration:

real a = 1.5

But, since the double colon is required in declarations that contain
initializations, the compiler can unambiguously determine that this
is an assignment to a variable called REALA. In this case, the
standard could have allowed the double colon to be optional in
free source form, but the committee didn't choose to do that.

I would prefer the rule that double colon always be required for
type declarations (if the type is a derived type) and never be allowed
in attribute specification statements. Then the standard could
have omitted the requirement that derived type declarations must
use the TYPE keyword.

type save
integer :: abc
end type save

save :: x ! declares X to be of type SAVE

save y ! declares that Y has the SAVE attribute

But, the committee didn't do that. :-(


--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


Richard E Maine

2005-05-20, 8:57 pm

I have to make this quick, but I think I can.

In article
<kutje.798929$w62.436577@bgtnsc05-news.ops.worldnet.att.net>,
"James Giles" <jamesgiles@worldnet.att.net> wrote:

> Richard E Maine wrote:
[color=darkred]
>
> Unfortunately that's not quite true. A type name followed by a
> comma indicates that the next thing is an attribute.


I'll claim that is is not quite true that this is not quite true. :-)

Well, ok if it is just a type name, but there are more forms than names
allowed. There is a (obsolescent) case of character that allows an
optional comma in a spot that seems spurious to me. Darned if I know why
that comma is allowed, but there must have been a reason, I suppose. It
goes back to f77.

> The language only requires the double colon if any of
> the names being declared are followed by initialization expressions.


I won't exactly disagree, but I do feel it important to note the sense
in which Giles is using "the language ... requires". In particular, note
that this is not about what the standard *DOES* require, but instead
about what Giles thinks could, in abstract, have been done. Yes, the
words are ok, but I want to make sure that someone else doesn't misread
them to think this is describing the standard. The distinction between
"the language requires" vs "the standard requires" is being made here.

> The reason for the double colon comes from the old fixed source
> form.


Well, that's certainly a big part of it. I'd say that the reason comes
from a combination of several things rather than from any one alone. But
yes, fixed form is probably the biggest single contributor. It "messed
up" other things too (the pointless parens in parameter statements being
a prime example).

I proposed in my f90 public comments to make at least one rule different
between fixed and free source form, but that one didn't get accepted
either. (I wanted implicit none to be the default in free source form).

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
James Giles

2005-05-21, 3:58 am

Richard E Maine wrote:
....
> I won't exactly disagree, but I do feel it important to note the
> sense in which Giles is using "the language ... requires". In
> particular, note that this is not about what the standard *DOES*
> require, but instead about what Giles thinks could, in abstract,
> have been done. Yes, the words are ok, but I want to make sure
> that someone else doesn't misread them to think this is describing
> the standard. The distinction between "the language requires" vs
> "the standard requires" is being made here.


Yes, that's what I was getting at. The implementation might be
allowing the double colon to be omitted because it can, at least
in principle, still unambiguously determine the intent of the
declaration. The only place where there's really an ambiguity
is in fixed source form when there's an initialization. Of course,
upon looking at the BNF in the standard I notice that if attributes
are present and the double colon is absent, it's is one of those
errors the implementation is required to be able to detect and
report. :- (Though it may be that the implementation "contains
the capability" to detect and report such a violation, but that
capability is not on by default.)

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


James Giles

2005-05-21, 3:58 am

Richard E Maine wrote:
....
> Well, ok if it is just a type name, but there are more forms than
> names allowed. There is a (obsolescent) case of character that
> allows an optional comma in a spot that seems spurious to me.
> Darned if I know why that comma is allowed, but there must have
> been a reason, I suppose. It goes back to f77.


This made me curious, so I went and checked. Yes, the comma
is allowed in F77 too. On the other hand, there are implementations
that sometimes don't accept it. Consider:

character*5, , parameter :: message="Stop!"

This is refused by the compilers I tried, though it's permitted by
the numbered syntax rules of the standard document. Those
compilers *do* accept:

character*5, message
parameter (message="Stop!")

It's standard conforming to reject the program (the standard doesn't
specify the limits of complexity the implementation must handle, it
only requires that the implementation report the reason it rejects
a given program - and saying that the comma is not accepted here
sufficiently satisfies that requirement).

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


glen herrmannsfeldt

2005-05-21, 3:58 am

Richard E Maine wrote:

(snip)

> Well, ok if it is just a type name, but there are more forms than names
> allowed. There is a (obsolescent) case of character that allows an
> optional comma in a spot that seems spurious to me. Darned if I know why
> that comma is allowed, but there must have been a reason, I suppose. It
> goes back to f77.


That reminds me of the optional comma added to the DO statement
somewhere along the line. If you have an optional comma in one
place, you might just as well have them other places.

-- glen

Dick Hendrickson

2005-05-21, 3:56 pm



James Giles wrote:
> Richard E Maine wrote:
> ...
>
>
>
> This made me curious, so I went and checked. Yes, the comma
> is allowed in F77 too. On the other hand, there are implementations
> that sometimes don't accept it. Consider:
>
> character*5, , parameter :: message="Stop!"
>
> This is refused by the compilers I tried, though it's permitted by
> the numbered syntax rules of the standard document.

[snip]
I think you missed constraint C420 (in F2003) (which is the
same as the 6th constraint after R510 in F95) which says
the optional comma after the *5 is only allowed if there
is no :: .

But, to be fair, it took me a while to find that.

Dick Hendrickson

Dick Hendrickson

James Giles

2005-05-21, 3:56 pm

Dick Hendrickson wrote:
> James Giles wrote:

.....
> [snip]
> I think you missed constraint C420 (in F2003) (which is the
> same as the 6th constraint after R510 in F95) which says
> the optional comma after the *5 is only allowed if there
> is no :: .


Yike! A syntax rule expressed as a constraint? Bletch.

Well, actually not quite that bad. I use a semantic constraint
in my preprocessor to express a syntax rule:

LParen = '(' | '[' | '{'
RParen = ')' | ']' | '{'

And the constraint is that '(' must match ')', '[' must match ']',
and '{' must match '}'.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


zwang5@hotmail.com

2005-05-23, 8:57 pm

Thanks to all but I found the problem myself.

In my code I used "call erset(0,0,0)", which calls IMSL routine to
control warning error message. Specifically, this call requests not
print warning message. So if I didn't have this call, then there is no
any memory issue and the program runs as fast as the beginning. The
drawback is that all warning error messages appear on the screen. In
fact, if I do something like
../a.out > file.out
for a large simulation, then I will have trouble because file.out grows
to a large file and due to the limitation of size, the program cannot
finish.

So if you can think of a Linux script to reduce/remove automaticlly
file.out without interferring with the program, it will be great.

Thanks,
Zhu

Joost

2005-05-23, 8:57 pm



> ./a.out > file.out
> for a large simulation, then I will have trouble because file.out

grows
> to a large file and due to the limitation of size, the program cannot
> finish.
>
> So if you can think of a Linux script to reduce/remove automaticlly
> file.out without interferring with the program, it will be great.


../a.out > /dev/null

Cheers,

Joost

zwang5@hotmail.com

2005-05-23, 8:57 pm

Wow!!!

That helps beautifully.

Thanks,

Zhu

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com