ALLOCATE(E(nlength),STAT=allo_stat)
IF(MemoryError('E',error)) GOTO 9999
E = 0.0d0
I believe the error is due to allocate a big array and the system does
not have sufficient memory. MemoryError is a function for reporting
this error. However, instead of getting meaningful error message, the
system crashed instead. Can somebody tell me why and how to present
such situations? I cannot even get the system return the value for
allo_stat.
Thanks in advance for your help!
There is insufficient information to give any help.
--
steve
I'd generally agree with Steve's comment, with the following specifics.
1. What do you mean by "Cannot even get the system to return the value
for allo_stat?" That pretty much doesn't make any sense, so you wil have
to tell us what you actually mean. I'm sure you did not get a message
saying "system cannot return value for allo_stat." Did you try printing
the value to see what it was? I see no evidence of any such printing.
Evidence that you don't actually show (such as the code of memoryerror)
does *NOT* count.
2. You say nothing useful about this "memoryerror" function. As *ALWAYS*
with help requests, describing what you think something does is usualy
useless. You need to show - not describe. Showing would involve the
complete code for this memoryerror function. I repeat - a description is
not enough. Also, complete declarations for everything are critical. You
show no declarations here for anything. Yes it matters. A lot. (For
example, it looks like you are assuming that memoryerror is logical, but
if it isn't declared that way, odd things can result). The way you are
calling it also doesn't look to make much sense, but there is
insufficient information to tell what is supposed to be going on - much
less what is going on. I see no obvious way that the memoryerror
function would know whether or not there was an error.
3. As a really, really wild guess, my cracked and foggy crystal ball
shows an image of someone who intended to pass allo_stat to memoryerror,
but accidentally passed error instead. Lacking some strange equivalence
or other arcane connection between them, those two would not have much
to do with each other. Yes, if that caused memoryerror to return
.false., one would expect a crash from the subsequent attempt to assign
values to the E array that was not successfully allocated.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
Well I agree with Steve, there's not nearly enough info here to
diagnose what is going on. However up until this point I thought the
issue might be lazy allocation ...
> I cannot even get the system return the value for
> allo_stat.
>
But I'm far from sure now, unless you mean allo_stat is zero. How does
your code crash? How are you compiling it and how are you running it?
What is the declaration of E? What is the value of nlength? How does
MemoryError check the value of allo_stat? In fact what do you mean by
"MemoryError is a function for reporting this error"?
That'll do for starters. When I've digested my half bottle of wine
I'll probably think of more!
Ian
> I recently met a problem with allocate. The code runs smoothly all the
> way till the following segment:
> ALLOCATE(E(nlength),STAT=allo_stat)
> IF(MemoryError('E',error)) GOTO 9999
I would expect an IF statement testing allo_stat at this point.
Why is it testing MemoryError instead? Did you want to test
and then call MemoryError?
> E = 0.0d0
If E isn't actually allocated then bad things happen here.
-- glen
Without knowing what MemoryError does, you cannot come
to this conclusion. MemoryError may cause the program to
terminate after printing an error message.
--
steve
As Maine has cautioned, OP has to provide more details.
-- mecej4
Thanks a lot for your replies. Sorry for not providing more
information.
E is declared as
REAL,ALLOCATABLE:: E(:)
nlength is an integer number the value of which is known at this
point.
MemoryError function is as follows with error as a global character
variable:
FUNCTION MemoryError(vari_name,error)
LOGICAL ::MemoryError
CHARACTER(*),INTENT(IN) ::vari_name
CHARACTER(*),INTENT(OUT)::error
error=''
MemoryError=.FALSE.
IF(allo_stat/=0) THEN
error='Memory error: allocate '//TRIM(vari_name)
MemoryError=.TRUE.
ENDIF
END FUNCTION MemoryError
For debugging purpose, I modified the segment of code as follows:
ALLOCATE(E(nlength),STAT=allo_stat)
write(*,*) allo_stat
IF(MemoryError('E',error)) GOTO 9999
write(*,*)"I am here"
E = 0.0d0
stop
The computer (WinXP SP3) outputs:
0
I am here
Then the code crashed.
...
> E is declared as
> REAL,ALLOCATABLE:: E(:)
>
> nlength is an integer number the value of which is known at this
> point.
>
> MemoryError function is as follows with error as a global character
> variable:
>
> FUNCTION MemoryError(vari_name,error)
> LOGICAL ::MemoryError
> CHARACTER(*),INTENT(IN) ::vari_name
> CHARACTER(*),INTENT(OUT)::error
> error=''
> MemoryError=.FALSE.
> IF(allo_stat/=0) THEN
> error='Memory error: allocate '//TRIM(vari_name)
> MemoryError=.TRUE.
> ENDIF
> END FUNCTION MemoryError
...
Hint -- Put
IMPLICIT NONE
inside the function MemoryError and all should become clear...
--
Hint**2
Remove stat=allo_stat from the allocate statement.
--
steve
> MemoryError function is as follows with error as a global character
> variable:
>
> FUNCTION MemoryError(vari_name,error)
No error is not a "global character variable" because
1. Within memoryerror it is a dummy argument.
2. I don't know what the actual argument is, but it is not a "global
character variable" because Fortran has no such thing as global
variables. I'm quite sure I mentioned before about showing instead of
describing. Showing would involve seeing source code. "Global character
variable" is a description, and further an incorrect description. What
it actually is, I have trouble guessing from that description. I'd need
to see the actual code of the declaration.
You also don't show any declaration of memoryerror except the one in the
function itself. I cannot repeat often enough that declarations are
critical - all of them. If you don't have any other declaration of
memoryerror, and it is an external function, then that is an error. I
recommend against using external procedures. THay have lots of
complications, this being one of them. If it is not an external
function, then there is other missing context, such as module and USE
statements.
As dpb suggests, implicit none in the function ought to tell you things.
In fact, implicit none used everywhere might tell you more. I have been
known to tell people that I declined to be of further help in debugging
until after they put implicit none throughout their codes.
Hint. When implicit none tells you about the variable with undefined
type, it would be useful to think about why it doesn't seem to have a
type instead of just throwing in a type declaration without thinking.
Further hint. Declaring something on one procedure doesn't declare it in
all procedures, and even if you declare something with the same name in
two different procedures, that doesn't make it the same thing in those
two procedures. That would be two different things that have the sam
ename and the same type, but nothing else necessarily in common.
Let me provide more details:
MemoryError is one of subroutine located in a Module
MODULE GlobalDataFun
IMPLICIT NONE
INTEGER:: allo_stat
FUNCTION MemoryError(vari_name,error)
LOGICAL ::MemoryError
CHARACTER(*),INTENT(IN) ::vari_name
CHARACTER(*),INTENT(OUT)::error
error=''
MemoryError=.FALSE.
IF(allo_stat/=0) THEN
error='Memory error: allocate '//TRIM(vari_name)
MemoryError=.TRUE.
ENDIF
END FUNCTION MemoryError
!* this module also include many other functions/subroutines.
END MODULE GlobalDataFun
In the piece of code causing the problem, USE GlobalDataFun.
IMPLICIT NONE is also used.
It seems to me from my previous email about the output, the error
happens at E=0.0d0.
On Aug 30, 10:44 pm, nos...@see.signature (Richard Maine) wrote:
Show us the actual code, not what you think you need to show
us. The code below cannot be correct because it is missing
a CONTAINS statement.
> MemoryError is one of subroutine located in a Module
>
> MODULE GlobalDataFun
>
> IMPLICIT NONE
>
> INTEGER:: allo_stat
>
> FUNCTION MemoryError(vari_name,error)
> LOGICAL ::MemoryError
> CHARACTER(*),INTENT(IN) ::vari_name
> CHARACTER(*),INTENT(OUT)::error
> error=''
> MemoryError=.FALSE.
> IF(allo_stat/=0) THEN
> error='Memory error: allocate '//TRIM(vari_name)
> MemoryError=.TRUE.
> ENDIF
> END FUNCTION MemoryError
>
> !* this module also include many other functions/subroutines.
>
> END MODULE GlobalDataFun
>
> In the piece of code causing the problem, USE GlobalDataFun.
> IMPLICIT NONE is also used.
Show us the code. You've only been asked 5 times in this
thread.
--
steve
> Let me provide more details:
[and he did]
Hmm. That starts to look like enough to base at least some guesses on.
It isn't quite all of the details asked for, but it is enough of them to
narrow things down a lot.
The one thing I still don't see is the declaration of the actual
argument error. It is possible that something about it could cause a
crash, either in the invocation of memoryerror or in the attempt to
assign a value to error. For example, if the actual argument error
happened to have an invalid address (as could happen if it were a
non-present dummy argument for example), that would quite likely cause a
crash. For the moment, I'll ignore that possibility, but I haven't
actually ruled it out. That's one guess. Perhaps not the most likely
one, but possible.
> It seems to me from my previous email about the output, the error
> happens at E=0.0d0.
Possibly. While I'd have to investigate more deeply to be very confident
at all, a theory that occurs to me is that the allocate might suceed in
terms of allocating virtual memory space, but then the operating system
might be unable to assign physical memory, as becomes necessary when you
actually put data (including zero values) in the array. Or something
like that. I think I'll shakily put that at the top of my guess list.
That would take some OS-dependent investigation outside of Fortran.
I'm far from certain of that. but it's a theory.
That's what I was refering to when I mentioned lazy allocation, and so
why I asked what the value of nlength is. However what we've seen of
the code is still possible that that is at fault,
Ian
Why do I always think that I have one of your books? Have you published
a book?
--
Uno
> On Aug 30, 10:04 pm, Hifi-Comp <wenbinyu.hea...@gmail.com> wrote:
>> Sorry for the mistake saying that error is a global variable. It is
>> not as Richard pointed out.
>>
<--CUT-->
> Show us the code. You've only been asked 5 times in this
> thread.
>
> --
> steve
In view of the OP's apparent retentiveness w.r.t. lines of code, it may be
worthwhile to try another way.
Here is a complete program that I put together from the various pieces
posted by the OP. It allocates 4 GB of memory to array E and then assigns a
value to E, and runs without any error on my system (GFortran 4.5, Linux
x64, 8 GB RAM).
Perhaps, OP can modify this program and post a modified version with which
the same problematic symptoms occur.
-- mecej4
=========================================
MODULE GlobalDataFun
IMPLICIT NONE
INTEGER:: allo_stat
CONTAINS
FUNCTION MemoryError(vari_name,error)
IMPLICIT NONE
LOGICAL ::MemoryError
CHARACTER(*),INTENT(IN) ::vari_name
CHARACTER(*),INTENT(OUT)::error
error=''
MemoryError=.FALSE.
IF(allo_stat/=0) THEN
error='Memory error: allocate '//TRIM(vari_name)
MemoryError=.TRUE.
ENDIF
END FUNCTION MemoryError
END MODULE GlobalDataFun
program tst
use GlobalDataFun
implicit none
integer :: nlength=1000000000
character(50) :: error
REAL,ALLOCATABLE:: E(:)
ALLOCATE(E(nlength),STAT=allo_stat)
write(*,*) 'allo_stat = ',allo_stat
IF(MemoryError('E',error)) GOTO 9999
write(*,*)'Allocated size of E is ',size(E)
E = 1d-2
write(*,*)' Sum(E) is ',sum(E)
9999 stop
end program tst
The obvious questions are:
1. What is the value of nlength ?
2. Did you print it immediately before the ALLOCATE statement?
3. The statement after ALLOCATE does not print the value of allo_stat.
Why haven't you done that ?
>Thanks a lot for your replies. Sorry for not providing more
>information.
>E is declared as
>REAL,ALLOCATABLE:: E(:)
>nlength is an integer number the value of which is known at this
>point.
What is it? Did you print it immediately before the ALLOCATE
statement is executed? If not why not ?
>MemoryError function is as follows with error as a global character
>variable:
Is it? There is no IMPLICIT NONE in this function.
nlength is defined as default INTEGER and passed to this segment with
INTENT(IN) and has a specific value.
error is a defined as CHARACTER(300)::error, it has INTENT(OUT) for
this piece of code we are looking at.
Although there is no IMPLICIT NONE in MemoryError, there is an
IMPLICIT NONE in the beginning of the MODULE which contains it. I
thought it has the same effect.
For further debugging purpose, I inserted three write commands to get
the information needed for your guys to debug
WRITE(*,*)"nlength=",nlength, "error= ",error
ALLOCATE(E(nlength),STAT=allo_stat)
WRITE(*,*)"allo_stat=",allo_stat
IF(MemoryError('E',error)) GOTO 9999
WRITE(*,*) "I am here ", "error=",error
E = 0.0d0
stop
The code outputs:
nlength= 83824188 error=
allo_stat= 0
I am here error=
Then crashed.
However, if I put stop right above E=0.0d0. The code stops normally.
> error is a defined as CHARACTER(300)::error, it has INTENT(OUT) for
> this piece of code we are looking at.
What piece is that? There are multiple pieces in question. One of the
multitude of problems with describing instead of showing is that
descriptions are so often vague or incomplete (and sometimes downright
incorrect). Are you saying that it is intent(out) in the same place
where it is declared to have length 300, or is this two different
places? If you have declared a dummy argument to be a character of
length 300, then that has a fair chance of being a problem that could
cause a crash. Dummy character arguments should almost always be
declared as assumed length. I'm guessing that's not what you meant, but
that's what the above seems to say.
> For further debugging purpose, I inserted three write commands to get
> the information needed for your guys to debug
[elided]
That seems to support the "lazy allocation" theory.
error is declared Outside as CHARACTER(300)::error and passed to this
segment of code as an argument, which is declared using
CHARACTER(*),INTENT(OUT)::error
I hope now it is clear.
If it is indeed "lazy allocation" problem, what should I do to avoid
it?
> If it is indeed "lazy allocation" problem, what should I do to avoid
> it?
I can't help with that one (well, not without a lot of work and
experimentation that I'm not prepared to do). That's probably more of an
OS question than a Fortran one.
Well nobody pays me royalties!
Ian
Unfortunately, that's how it is for a lot of people who write technical
books for niche markets. Meanwhile, Sarah Palin can't pen a cohesive
paragraph and has bestsellers.
I was in Salt Lake City for x-mas, and old friends gave me a glenn beck
book as a gag gift. It was to be autobiographical. He writes of how
his father died and they had to fend for themselves? The problem?
Whoever sired the revisionist fascist is still alive.
I don't know how to appraise the last weekend in D.C.
--
Uno
| Thanks a lot for all your quick and helpful replies. The overall code
| is many thousands of lines. That is why I was missing pieces of
| information here and there. I hope this time I have it all.
[...]
Now we might be getting somewhere.
Do you have array subscript bounds checks turned on,
substring checks turned on,
and all other checks tuirned on?