views:

586

answers:

8

I am getting stack overflow when executing the following code in Compac Fortran. Specially for the line:

DIMENSION IZ(NX,NY),VX(NX-1,NY-1),VY(NX-1,NY-1),VZ(NX-1,NY-1)

What I am doing is to read the NX,NY,DX,DY from a parameter file.

Any suggestions?

       PARAMETER(NGMAX=30000)
       INTEGER NX,NY,DX,DY
       OPEN(6,FILE='MGSTAOriggroup15.asc',STATUS='old')
       OPEN(7,FILE='Gravity.asc',STATUS='old')
       OPEN(8,FILE='Gravity200.nor',STATUS='old')
       OPEN(9,FILE='linana.para',STATUS='old')
       OPEN(10,FILE='MGSTAOriggroup15coord.dat',STATUS='unknown')
       OPEN(12,FILE='MGSTAOriggroup15ncoord.dat',STATUS='unknown')
       OPEN(11,FILE='linana.fsn',STATUS='unknown')
       READ(9,*) NX,NY,DX,DY
       CALL ANALYSIS(NX,NY)
       Close(6)
       Close(7)
       Close(8)
       Close(9)
       Close(10)
       Close(11)
       Close(12)
C
       STOP 
     END
C 
      SUBROUTINE ANALYSIS(NX,NY)
      INTEGER NX,NY,DX,DY
      COMMON/COM1/ DX,DY
      PARAMETER(NGMAX=30000)
      DIMENSION KO(NGMAX)
      DIMENSION XLS(NGMAX,100),XLE(NGMAX,100),
     &          YLS(NGMAX,100),YLE(NGMAX,100)
      DIMENSION IZ(NX,NY),VX(NX-1,NY-1),VY(NX-1,NY-1),VZ(NX-1,NY-1)
      """"""""""""""""""""""""""""""""""""""""""""
      To the end

NOTE: Changing from (NGMAX=30000) to (NGMAX=30) did not help.

Yes I have changed all the instances of NGMAX to 30.

The new version is listed below.


    INTEGER NX,NY,DX,DY
    PARAMETER(NGMAX=30)
      COMMON /CM1/ FX(NGMAX),FY(NGMAX),FZ(NGMAX),FR(NGMAX),IL(NGMAX)
      COMMON /CM2/ JST(NGMAX),KST(NGMAX),JDP(NGMAX),KDP(NGMAX)
      COMMON /CM3/ XC(NGMAX),YC(NGMAX),ZC(NGMAX),KTYP(NGMAX)
      COMMON /CM4/ A(4,4),B(4),U(4)
    COMMON /CM5/ KO(NGMAX)
      COMMON /CM6/ XLS(NGMAX,10),XLE(NGMAX,10),
     &          YLS(NGMAX,10),YLE(NGMAX,10)
      OPEN(6,FILE='MGSTAOriggroup15.asc',STATUS='old')
      OPEN(7,FILE='Gravity.asc',STATUS='old')
      OPEN(8,FILE='Gravity200.nor',STATUS='old')
      OPEN(9,FILE='linana.para',STATUS='old')
      OPEN(10,FILE='MGSTAOriggroup15coord.dat',STATUS='unknown')
      OPEN(12,FILE='MGSTAOriggroup15ncoord.dat',STATUS='unknown')
      OPEN(11,FILE='linana.fsn',STATUS='unknown')
      READ(9,*) NX,NY,DX,DY
    CALL ANALYSIS(NX,NY)
      Close(6)
      Close(7)
      Close(8)
      Close(9)
      Close(10)
      Close(11)
      Close(12)
C
       STOP 
     END
C 
      SUBROUTINE ANALYSIS(NX,NY)
    INTEGER NX,NY,DX,DY
      COMMON/COM1/ DX,DY
    PARAMETER(NGMAX=30)
      COMMON /CM1/ FX(NGMAX),FY(NGMAX),FZ(NGMAX),FR(NGMAX),IL(NGMAX)
      COMMON /CM2/ JST(NGMAX),KST(NGMAX),JDP(NGMAX),KDP(NGMAX)
      COMMON /CM3/ XC(NGMAX),YC(NGMAX),ZC(NGMAX),KTYP(NGMAX)
      COMMON /CM4/ A(4,4),B(4),U(4)
    COMMON /CM5/ KO(NGMAX)
      COMMON /CM6/ XLS(NGMAX,10),XLE(NGMAX,10),
     &          YLS(NGMAX,10),YLE(NGMAX,10)
      DIMENSION IZ(NX,NY),VX(NX-1,NY-1),VY(NX-1,NY-1),VZ(NX-1,NY-1)

I am so sorry: I worked on the code all the day and finally its working. Howevere, declaring NX and NY, is what we do not need. I want to to read these parameters from the parameter file. The code is as follows:


      PARAMETER(NX=322,NY=399,NGMAX=30000)
C I need to change NX and NY to read from the parameter file
      CHARACTER infile1*80,infile2*80,infile3*80,outfile1*80
     &,outfile2*80,outfile3*80
      DIMENSION KO(NGMAX)
      DIMENSION XLS(NGMAX,100),XLE(NGMAX,100),
     &          YLS(NGMAX,100),YLE(NGMAX,100)
      DIMENSION IZ(NX,NY),VX(NX-1,NY-1),VY(NX-1,NY-1),VZ(NX-1,NY-1)
      DIMENSION FX(NGMAX),FY(NGMAX),FZ(NGMAX),FR(NGMAX),IL(NGMAX)
      DIMENSION JST(NGMAX),KST(NGMAX),JDP(NGMAX),KDP(NGMAX)
      DIMENSION XC(NGMAX),YC(NGMAX),ZC(NGMAX),KTYP(NGMAX)
      DIMENSION A(4,4),B(4),U(4)
C
    CALL getenv('INFILE1',infile1)
    CALL getenv('INFILE2',infile2)
    CALL getenv('INFILE3',infile3)
    CALL getenv('OUTFILE1',outfile1)
    CALL getenv('OUTFILE2',outfile2)
    CALL getenv('OUTFILE3',outfile3)
    OPEN(1,FILE='Alaa1.para',STATUS='old')
    READ(1,*)DX,DY,infile1,infile2,infile3,outfile1,outfile2
     &,outfile3
C
       OPEN(6,FILE=infile1,STATUS='old')
       OPEN(7,FILE=infile2,STATUS='old')
       OPEN(8,FILE=infile3,STATUS='old')
       OPEN(10,FILE=outfile1,STATUS='unknown')
       OPEN(12,FILE=outfile2,STATUS='unknown')
       OPEN(11,FILE=outfile3,STATUS='unknown')

       TO THE END


+1  A: 

It sounds like the subroutine ANALYSIS is allocating space on the stack based on the parameters passed into it (NX and NY). If those values are too large, then there may not be enough space on the stack to allocate the arrays.

What you can do is print out the values of NX and NY as read from the linana.para file to see whether they make sense for your application.

Greg Hewgill
A: 

Load of thanks Greg NX and NY never exceed 5000 On declaring the exact NX and NY values it goes well, however, I need an automation without declaration of the exact values. Any suggestions?

Alaa

A: 

Assuming the exception is happening on the line you mention, then your program's stack is insufficently large for the variables being allocated on it. You need to find the flag in your compiler to increase the default stack allocation on your program. Or, if you are not using recursion at all, you can make those variables global variables so they are not allocated on the stack.

Note the size you're allocating:

PARAMETER(NGMAX=30000)
DIMENSION KO(NGMAX)
DIMENSION XLS(NGMAX,100),XLE(NGMAX,100),YLS(NGMAX,100),YLE(NGMAX,100)
DIMENSION IZ(NX,NY),VX(NX-1,NY-1),VY(NX-1,NY-1),VZ(NX-1,NY-1)

You're allocating space for 30000 * 100 values (reals, I assume) for each of the four arrays XLS, XLE, YLS, and YLE. That's 12,000,000 values. Assuming 32-bit values, it's 48 Meg of memory. But I vaguely recall that on some platforms, reals are 80 bits? In that case it would be 120 Meg of memory.

Do you really need your arrays to be 30,000 elements long in one dimension? If not, reducing that allocation may help you.

Look at the compiler options for the FORTRAN compiler you're using. I remember that the VAX/VMS FORTRAN compiler had a command-line option to make all variables static, which is to say not allocated on the stack. Assuming you can guarantee that you will not do any recursion, this may be the quickest solution to your problem.

Another option you have is putting all of the large arrays into a COMMON block, but note that arrays in a common block cannot be dynamically sized.

Eddie
There is no such switch for compilers on VMS. That's controlled by the Process parameters, which are set (normally) by the users Authorization file settings, which in turn are limited by the SYSGEN system parameter settings, which finally are bound by the architectural limits of the VMS Operating System and the hardware (either VAX or Alpha). Which is why I say that it is probably a Server/Admin issue.
RBarryYoung
Sorry, I meant: no such switch to control the Stack size.
RBarryYoung
I know for a fact that you're wrong, because I personally programmed under VAX/VMS in FORTRAN in the late 80s and the 90s. We in fact compiled our programs so that all variables were static, the equivalent of "static" in C, so the variables were not on the stack. I don't remember what the command-line parameter was, but I know for a fact that such a command-line option existed for the VAX/VMS FORTRAN compiler.
Eddie
Ah, I posted at the same time as your SECOND comment! Yes, we did not use any switch to control stack size. Instead, we compiled so that all variables were NOT allocated on the stack, but statically. This means direct recursion is not possible. For times when you don't need recursion, it allows having very large allocations that won't fit on the stack.
Eddie
Yeah, sorry about that. I missed that you mentioned two different possible switches. I do not know about the NoStack switch but it makes sense as that was how Fortran originally worked (that is, it had no stack). That switch *might* work for him because it *may* throw the unused stack space onto the static and heap space. But even if, I suspect that he is way more than 2x off.
RBarryYoung
Yes, it's entirely possible that this application is just using too much memory and as you say will need administrator system changes.
Eddie
A: 

How to make NX and NY globals Eddie?

A: 

Heh. Well, technically, this probably belongs on ServerFault because it's an OS problem, but I don't think that there's anyone over there who going to answer VMS questions over there either. IT been a while for me and VMS and even longer for FORTRAN, but Ill give it a go...

OK, here's what you've got: the ANALYSIS subroutine has 4 arrays with (30,000*100)=3,000,000 cells each that's 12M cells or 8 bytes each (I think?) for 72Mbytes. Add to that the space taken up by the integer array IZ and the real arrays VX, VY and VZ, which I cannot estimate because I do not know what the max values of NX and NY are.

Anyway, that's a minimum of 144,000 pages on a VAX or 24,000 pages for an Alpha (plus add to that the other 4 arrays). Your process address table needs to be at least 2x that (slighty more, actually), because the user stack only get's half of that.

So, go to the command prompt and type "SHOW PROC/MEM" and tell me what it says (I think I've got that right).

Note: NX, NY are just the parameters to the DIMENSION, it the arrays that are taking up the stack.

Making the arrays Global probably won't work because the heap and static allocation spaces aren't any larger than the stack.

OK, I see your max NX, NY values are 5,000. That's another 4*25,000,000 or 100,000,000. At 8 bytes each that's 800MB plus the 72MB above. The bad news is that the VAX is architecurally limited to a user stack of 1GB, regardless of the VMS Process settings, so let's hope either that the Floats are 4bytes (and not 8) or that you are on an Alpha.

RBarryYoung
This isn't an OS problem, it's a programming problem!
Eddie
Well, it can proabaly only be fixed by a privileged Admin, so what would you call that?
RBarryYoung
What about moving the huge arrays off the stack?
Eddie
He needs to extend his process address table, I just cannot remember the specific name of that parameter (there's about a dozen process memory parameters and this one is obscure, and may actually be a SYSGEN parameter). But I think that if I see the names, I will remember which is which.
RBarryYoung
I can't think of a single way that this **isn't** a programming problem.
Marc Gravell
Marc: Here's how I like to put it: "If you can't lower the size of your allocations, then you will need to ask your sysadmins to raise your page table limit." Since his allocations are driven by job parameters, that pretty much leaves only the second option. I tend to categorize problems according to their available solutions which puts this one squarely in the OS/Admins camp.
RBarryYoung
Marc: I think see our disconnect now: I did say that I thought that this is an Admin problem, however, I did *not* say that I thought that it **isn't** a programming problem. After all, it can be *both*. (I think that's why we have tags instead of folders here ;-) ). The problem is that there is an "either or" mindset over some of these categorizations that doesn't always make sense. I had not intended for my off-hand observation to be taken as an argument to move this question to ServerFault.
RBarryYoung
A: 

I have changed the dimension to:

PARAMETER(NGMAX=3000)
  DIMENSION KO(NGMAX)
  DIMENSION XLS(NGMAX,20),XLE(NGMAX,20),
 &          YLS(NGMAX,20),YLE(NGMAX,20)
  DIMENSION IZ(NX,NY),VX(NX-1,NY-1),VY(NX-1,NY-1),VZ(NX-1,NY-1)

Still not working

Help

For the sake of trying, try to make NGMAX=30 -- if this does not run into the stack overflow, then that setting is the problem.
Eddie
A: 

Really Its amazing This is my first time to share solving a problem via a forum like this. I really appreciate the replies.

waiting for a solution

By the way, the best way to respond to answers and to leave feedback is to edit your original question. I believe you can do this even with a very low reputation. Under your question, look for a small word "edit" and click on that to edit your question.
Eddie
But when you add information to your question, don't delete the original contents! Just add to the end.
Eddie
A: 

It looks like your code is Fortran77 if so the following should make some sense if not it might give you some clues.

In Fortran77 there is no dynamic memory allocation support in the language standard, a number of compilers did have some support for it but by using compiler specific extensions. Your code does not trigger any memory of an extension looking like that.

One way of doing what you wanted would be to generate a main program which would declare the array space and then pass the arrays as parameters to subroutines. This main program would be compiled and linked with the rest of the code. Each set of values would produce a new main program.

For example - for NX=2456 & NY=789

  PROGRAM MAIN
  INTEGER NX, NY
  DIMENSION IZ(2456,789),VX(2455,788),VY(2455,788),VZ(2455,788)
  NX=2456
  NY=789
  CALL ANALYSIS(NX,NY,IZ,VX,VY,VZ)
  STOP
  END

  SUBROUTINE ANALYSIS(NX,NY,IZ,VX,VY,VZ)
  INTEGER NX,NY,DX,DY
  DIMENSION IZ(NX,NY),VX(NX-1,NY-1),VY(NX-1,NY-1),VZ(NX-1,NY-1)

... RETURN END

I cannot remember but it may have been possible to use the parameter statement in the main program so you fully parameterize the main program above.

hugok