当fortran代码读取linux集群上的文件时,会出现SIGBUS



当我用mpirun在linux集群上并行运行fortran代码时,我会得到一个sigbus错误。它发生在读取文件时,时间不规则,有时进行时不会出错。我尝试过调试编译选项,比如-g,但我还没有得到任何关于错误来自哪一行的信息。实际上,代码以前在三个不同的集群中执行过,没有出现此错误,但错误只发生在这台机器上。我个人怀疑这与机器的性能有关(尤其是存储I/o),但我不确定。

程序代码很简单。mpirun执行的每个进程读取与其等级对应的文件,如下所示。

!!!!!!!!!! start of code
OPEN(11, FILE='FILE_NAME_WITH_RANK', FORM='UNFORMATTED')
READ(11,*) ISIZE
ALLOCATE(SOME_VARIABLE(ISIZE))
DO I = 1, ISIZE
READ(11,*) SOME_VARIABLE(I)
ENDDO
READ(11,*) ISIZE2
ALLOCATE(SOME_VARIABLE2(ISIZE2))
DO I = 1, ISIZE2
READ(11,*) SOME_VARIABLE2(I)
ENDDO
! MORE VARIABLES
CLOSE(11)
!!!!!!!!!! end of code

我使用了191个cpu,它加载的191个文件的总大小约为11GB。

用于执行的集群由24个节点组成,每个节点有16个cpu(总共384个cpu),并使用与另一个集群共享的公共存储。我通过指定节点1到12作为主机文件来并行运行代码。

最初,我有191个cpu在同一时间按顺序读取所有文件。这样做之后,程序以sigbus错误结束。此外,对于某些节点,ssh连接被延迟,并且bashrc文件无法由出现过时文件句柄错误的节点找到。陈旧的文件句柄错误等待了一段时间,它似乎可以自行恢复,但我不确定系统管理员做了什么。所以,我把它改成了下面的代码,这样一次只有一个cpu可以读取文件。

!!!!!!!!!! start of code
DO ICPU = 0, NUMBER_OF_PROCESS-1
IF(ICPU.EQ.MY_PROCESS) CALL READ_FILE
CALL MPI_BARRIER(MPI_COMMUNICATOR,IERR)
ENDDO
!!!!!!!!!! end of code

这似乎适用于单次执行,但如果我同时运行多个这样的程序,第一个mpirun会停止,最终都会以sigbus错误结束。

我的下一个尝试是通过在读取数组时删除do语句来最大限度地减少read语句的执行。然而,由于时间有限,我无法测试这种修改的有效性。

以下是一些附加信息。

  • 如果我在运行并行程序时使用浏览器(如nautilus)执行搜索或复制文件,nautilus不会响应,或者运行的程序引发sigbus。在严重的情况下,我无法连接带有过时文件句柄错误的VNC服务器
  • 我使用OpenMPI 2.1.1,GNU Fortran 4.9.4。我用以下代码编译程序$OPENMPIHOME/bin/mpif90-mcmodel=larg-fmax-stack-var-size-64-cpp-O3$SOURCE-o$EXE我在gnome终端中执行以下程序$OPENMPIHOME/bin/mpirun-np$np-x$LD_LIBRARY_PATH--主机文件$hostfile$EXE
  • 据说该集群运行FLUENT这样的商业软件没有问题

综上所述,我个人怀疑集群的存储是由于我的代码产生了过多的磁盘I/O而被卸载的,但我不知道这是否有意义,因为我对集群一无所知。如果是,我想知道是否有一种方法可以最大限度地减少磁盘I/O,是否足以继续进行上面提到的矢量化I/O,或者是否还有其他部分。如果你能告诉我关于这个问题的任何事情,我将不胜感激。提前谢谢。

我写了一个代码示例。如上所述,可能不容易复制,因为发生的情况因机器而异。

PROGRAM BUSWRITE

IMPLICIT NONE

INTEGER, PARAMETER :: ISIZE1 = 10000, ISIZE2 = 20000, ISIZE3 = 30000
DOUBLE PRECISION, ALLOCATABLE :: ARRAY1(:), ARRAY2(:), ARRAY3(:)
INTEGER :: I
INTEGER :: I1, I2, I3
CHARACTER*3 CPUNUM

INCLUDE 'mpif.h'
INTEGER ISTATUS(MPI_STATUS_SIZE)
INTEGER :: IERR, NPES, MYPE

CALL MPI_INIT(IERR)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD,NPES,IERR)
CALL MPI_COMM_RANK(MPI_COMM_WORLD,MYPE,IERR)

I1=MOD(MYPE/100,10)+48
I2=MOD(MYPE/10 ,10)+48
I3=MOD(MYPE    ,10)+48
CPUNUM=CHAR(I1)//CHAR(I2)//CHAR(I3)

OPEN(11, FILE=CPUNUM//'.DAT', FORM='UNFORMATTED')
ALLOCATE(ARRAY1(ISIZE1))
ALLOCATE(ARRAY2(ISIZE2))
ALLOCATE(ARRAY3(ISIZE3))
DO I = 1, ISIZE1
ARRAY1(I) = I
WRITE(11) ARRAY1(I)
ENDDO
DO I = 1, ISIZE2
ARRAY2(I) = I**2
WRITE(11) ARRAY2(I)
ENDDO
DO I = 1, ISIZE3
ARRAY3(I) = I**3
WRITE(11) ARRAY3(I)
ENDDO
CLOSE(11)

CALL MPI_FINALIZE(IERR)
END PROGRAM
mpif90 -ffree-line-length-0 ./buswrite.f90 -o ./buswrite
mpirun -np 32 ./buswrite

我有32 000.DAT~031.DAT

PROGRAM BUSREAD

IMPLICIT NONE

INTEGER, PARAMETER :: ISIZE1 = 10000, ISIZE2 = 20000, ISIZE3 = 30000
DOUBLE PRECISION, ALLOCATABLE :: ARRAY1(:), ARRAY2(:), ARRAY3(:)
INTEGER :: I
INTEGER :: I1, I2, I3
CHARACTER*3 CPUNUM

INCLUDE 'mpif.h'
INTEGER ISTATUS(MPI_STATUS_SIZE)
INTEGER :: IERR, NPES, MYPE

CALL MPI_INIT(IERR)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD,NPES,IERR)
CALL MPI_COMM_RANK(MPI_COMM_WORLD,MYPE,IERR)

I1=MOD(MYPE/100,10)+48
I2=MOD(MYPE/10 ,10)+48
I3=MOD(MYPE    ,10)+48
CPUNUM=CHAR(I1)//CHAR(I2)//CHAR(I3)

OPEN(11, FILE=CPUNUM//'.DAT', FORM='UNFORMATTED')
ALLOCATE(ARRAY1(ISIZE1))
ALLOCATE(ARRAY2(ISIZE2))
ALLOCATE(ARRAY3(ISIZE3))
DO I = 1, ISIZE1
READ(11) ARRAY1(I)
IF(ARRAY1(I).NE.I) STOP
ENDDO
DO I = 1, ISIZE2
READ(11) ARRAY2(I)
IF(ARRAY2(I).NE.I**2) STOP
ENDDO
DO I = 1, ISIZE3
READ(11) ARRAY3(I)
IF(ARRAY3(I).NE.I**3) STOP
ENDDO
CLOSE(11)

CALL MPI_BARRIER(MPI_COMM_WORLD,IERR)
IF(MYPE.EQ.0) WRITE(*,*) 'GOOD'
CALL MPI_FINALIZE(IERR)
END PROGRAM
mpif90 -ffree-line-length-0 ./busread.f90 -o ./busread
mpirun -np 32 ./busread

正如预期的那样,我从终端得到了"GOOD"输出文本,但有问题的机器在运行busread时因sigbus错误而终止。

设备重新启动后未发现该问题。尽管我在相同的条件下同时运行了4个程序,但没有出现任何问题。此外,其他使用该设备的团队也遇到了类似的问题,这些问题在重新启动后得到了解决。这个结论有点可笑,但如果有人遇到类似的问题,我想总结如下。

如果您的程序在读取或写入文件时由于内存错误(如sigbus和sigsegov)而异常终止,您可以检查以下内容。

  • 确保程序中没有错误。检查错误发生的时间是恒定的还是不规则的,其他程序是否有相同的症状,它在其他机器上是否运行良好,以及使用valgrind等内存错误检查工具运行时是否存在问题
  • 优化文件I/O部分。在fortran的情况下,处理整个数组的速度是按元素处理的速度的几十倍
  • 错误发生后,请立即尝试ssh连接到机器(或节点),以检查连接是否顺畅,以及文件系统是否可以很好地访问。如果您无法访问bashrc文件或出现文件句柄陈旧等错误,请在结合以上审查信息后与系统经理联系

如果有人有什么要添加的,或者如果这篇文章不合适,请告诉我。

相关内容

  • 没有找到相关文章

最新更新