4

在 Compac Fortran 中执行以下代码时出现堆栈溢出。专线:

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

我正在做的是从参数文件中读取 NX、NY、DX、DY。

有什么建议么?

       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

注意:从 更改(NGMAX=30000)(NGMAX=30)没有帮助。

是的,我已将 NGMAX 的所有实例更改为 30。

下面列出了新版本。


    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)

我很抱歉:我整天都在编写代码,最后它工作了。但是,我们不需要声明 NX 和 NY。我想从参数文件中读取这些参数。代码如下:


      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

4

4 回答 4

1

听起来子程序ANALYSIS正在根据传递给它的参数(NXNY)在堆栈上分配空间。如果这些值太大,则堆栈上可能没有足够的空间来分配数组。

您可以做的是打印出 和 从文件中读取的值,NXNY查看linana.para它们是否对您的应用程序有意义。

于 2009-06-20T02:05:36.310 回答
0

看起来你的代码是 Fortran77 如果是这样的话,下面应该是有意义的,如果不是它可能会给你一些线索。

在 Fortran77 语言标准中没有动态内存分配支持,许多编译器确实支持它,但使用编译器特定的扩展。您的代码不会触发任何类似这样的扩展记忆。

做你想做的事情的一种方法是生成一个主程序,该程序将声明数组空间,然后将数组作为参数传递给子程序。该主程序将被编译并与其余代码链接。每组值都会产生一个新的主程序。

例如 - 对于 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)

...返回结束

我不记得了,但可能可以在主程序中使用参数语句,因此您可以完全参数化上面的主程序。

于 2009-06-28T22:10:13.240 回答
0

假设异常发生在您提到的那一行,那么您的程序堆栈对于分配在其上的变量来说不够大。您需要在编译器中找到该标志以增加程序的默认堆栈分配。或者,如果您根本不使用递归,您可以将这些变量设为全局变量,这样它们就不会分配到堆栈上。

请注意您分配的大小:

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)

您正在为real四个数组XLSXLEYLSYLE. 那是 12,000,000 个值。假设 32 位值,它是 48 Meg 的内存。但我隐约记得在某些平台上,实数是 80 位?在这种情况下,它将是 120 Meg 的内存。

真的需要你的数组在一维上有 30,000 个元素吗?如果没有,减少该分配可能会对您有所帮助。

查看您正在使用的 FORTRAN 编译器的编译器选项。我记得 VAX/VMS FORTRAN 编译器有一个命令行选项可以使所有变量都静态化,也就是说不在堆栈上分配。假设您可以保证不会进行任何递归,这可能是解决问题的最快方法。

另一个选择是将所有大型数组放入一个 COMMON 块中,但请注意,一个公共块中的数组不能动态调整大小。

于 2009-06-20T02:22:25.497 回答
0

呵呵。嗯,从技术上讲,这可能属于 ServerFault,因为它是一个操作系统问题,但我认为那里也没有人会回答那里的 VMS 问题。对我和 VMS 来说已经有一段时间了,对 FORTRAN 来说甚至更长,但我会试一试......

好的,这就是你所得到的:ANALYSIS 子例程有 4 个数组,每个数组有 (30,000*100)=3,000,000 个单元格,每个单元格是 12M 单元格或每个 8 字节(我认为?)为 72Mbytes。再加上整数数组 IZ 和实数数组 VX、VY 和 VZ 占用的空间,我无法估计,因为我不知道 NX 和 NY 的最大值是多少。

无论如何,VAX 至少有 144,000 页或 Alpha 至少有 24,000 页(加上其他 4 个数组)。您的进程地址表需要至少是该地址表的 2 倍(实际上稍微多一点),因为用户堆栈只得到其中的一半。

所以,转到命令提示符并输入“SHOW PROC/MEM”并告诉我它说的是什么(我想我说得对)。

注意:NX、NY 只是 DIMENSION 的参数,它是占用堆栈的数组。

使数组全局可能不起作用,因为堆和静态分配空间并不比堆栈大。

好的,我看到你的最大 NX,NY 值是 5,000。那是另一个 4*25,000,000 或 100,000,000。每个 8 字节为 800MB 加上上面的 72MB。坏消息是,无论 VMS 进程设置如何,VAX 在架构上都限制为 1GB 的用户堆栈,所以我们希望浮点数是 4 字节(而不是 8 字节)或者您使用的是 Alpha。

于 2009-06-20T02:27:31.570 回答