Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Fortran中使用SCALAPACK分割错误?没有回溯?_Fortran_Lapack_Scalapack - Fatal编程技术网

在Fortran中使用SCALAPACK分割错误?没有回溯?

在Fortran中使用SCALAPACK分割错误?没有回溯?,fortran,lapack,scalapack,Fortran,Lapack,Scalapack,我试图用SCALAPACK和Fortran中的MPI来求厄米矩阵的特征值和特征向量。对于bug挤压,我使这个程序尽可能简单,但仍然会遇到分割错误。根据给有类似问题的人的答案,我试着把我所有的整数改成整数*8,把我所有的实数改成实数*8或实数*16,但我还是遇到了这个问题。最有趣的是,我甚至没有得到分段错误的回溯:程序在试图给我回溯时挂断,必须手动中止 另外,请原谅我知识的缺乏——我对大多数program-y的东西都不熟悉,但我已经尽力了。这是我的密码: PROGRAM easydiag

我试图用SCALAPACK和Fortran中的MPI来求厄米矩阵的特征值和特征向量。对于bug挤压,我使这个程序尽可能简单,但仍然会遇到分割错误。根据给有类似问题的人的答案,我试着把我所有的整数改成整数*8,把我所有的实数改成实数*8或实数*16,但我还是遇到了这个问题。最有趣的是,我甚至没有得到分段错误的回溯:程序在试图给我回溯时挂断,必须手动中止

另外,请原谅我知识的缺乏——我对大多数program-y的东西都不熟悉,但我已经尽力了。这是我的密码:

    PROGRAM easydiag
    IMPLICIT NONE 
  INCLUDE 'mpif.h'
  EXTERNAL BLACS_EXIT, BLACS_GET, BLACS_GRIDEXIT, BLACS_GRIDINFO
  EXTERNAL BLACS_GRIDINIT, BLACS_PINFO,BLACS_SETUP, DESCINIT 
  INTEGER,EXTERNAL::NUMROC,ICEIL
  REAL*8,EXTERNAL::PDLAMCH

  INTEGER,PARAMETER::XNDIM=4 ! MATRIX WILL BE XNDIM BY XNDIM
  INTEGER,PARAMETER::EXPND=XNDIM
  INTEGER,PARAMETER::NPROCS=1

  INTEGER COMM,MYID,ROOT,NUMPROCS,IERR,STATUS(MPI_STATUS_SIZE)
  INTEGER NUM_DIM
  INTEGER NPROW,NPCOL
  INTEGER CONTEXT, MYROW, MYCOL

  COMPLEX*16,ALLOCATABLE::HH(:,:),ZZ(:,:),MATTODIAG(:,:)
  REAL*8:: EIG(2*XNDIM) ! EIGENVALUES
  CALL MPI_INIT(ierr)
  CALL MPI_COMM_RANK(MPI_COMM_WORLD,myid,ierr)
  CALL MPI_COMM_SIZE(MPI_COMM_WORLD,numprocs,ierr)
  ROOT=0

  NPROW=INT(SQRT(REAL(NPROCS)))
  NPCOL=NPROCS/NPROW   
  NUM_DIM=2*EXPND/NPROW

  CALL SL_init(CONTEXT,NPROW,NPCOL)
  CALL BLACS_GRIDINFO( CONTEXT, NPROW, NPCOL, MYROW, MYCOL )

  ALLOCATE(MATTODIAG(XNDIM,XNDIM),HH(NUM_DIM,NUM_DIM),ZZ(NUM_DIM,NUM_DIM))
  MATTODIAG=0.D0

  CALL MAKEHERMMAT(XNDIM,MATTODIAG)

  CALL MPIDIAGH(EXPND,MATTODIAG,ZZ,MYROW,MYCOL,NPROW,NPCOL,NUM_DIM,CONTEXT,EIG)


  DEALLOCATE(MATTODIAG,HH,ZZ)




   CALL MPI_FINALIZE(IERR)


END

!****************************************************
SUBROUTINE MAKEHERMMAT(XNDIM,MATTODIAG)
  IMPLICIT NONE
  INTEGER:: XNDIM, I, J, COUNTER
  COMPLEX*16:: MATTODIAG(XNDIM,XNDIM)
  REAL*8:: RAND

  COUNTER = 1
  DO J=1,XNDIM
    DO I=J,XNDIM
        MATTODIAG(I,J)=COUNTER
        COUNTER=COUNTER+1
    END DO
  END DO




END
!****************************************************
SUBROUTINE MPIDIAGH(EXPND,A,Z,MYROW,MYCOL,NPROW,NPCOL,NUM_DIM,CONTEXT,W)
    IMPLICIT NONE
  EXTERNAL DESCINIT 
  REAL*8,EXTERNAL::PDLAMCH

  INTEGER EXPND,NUM_DIM
  INTEGER CONTEXT
  INTEGER MYCOL,MYROW,NPROW,NPCOL
  COMPLEX*16 A(NUM_DIM,NUM_DIM), Z(NUM_DIM,NUM_DIM)
  REAL*8 W(2*EXPND)

  INTEGER N
  CHARACTER JOBZ, RANGE, UPLO
  INTEGER IL,IU,IA,JA,IZ,JZ
  INTEGER LIWORK,LRWORK,LWORK
  INTEGER M, NZ, INFO

  REAL*8  ABSTOL, ORFAC, VL, VU

  INTEGER DESCA(50), DESCZ(50)
  INTEGER IFAIL(2*EXPND), ICLUSTR(2*NPROW*NPCOL)
  REAL*8 GAP(NPROW*NPCOL)
  INTEGER,ALLOCATABLE:: IWORK(:)
  REAL*8,ALLOCATABLE :: RWORK(:)
  COMPLEX*16,ALLOCATABLE::WORK(:)

  N=2*EXPND
  JOBZ='V'
  RANGE='I'
  UPLO='U' ! This should be U rather than L
  VL=0.d0
  VU=0.d0
  IL=1  ! EXPND/2+1
  IU=2*EXPND  !  EXPND+(EXPND/2)   ! HERE IS FOR THE CUTTING OFF OF THE STATE
  M=IU-IL+1
  ORFAC=-1.D0
  IA=1
  JA=1
  IZ=1
  JZ=1


  ABSTOL=PDLAMCH( CONTEXT, 'U')
  CALL DESCINIT( DESCA, N, N, NUM_DIM, NUM_DIM, 0, 0, CONTEXT, NUM_DIM, INFO )
  CALL DESCINIT( DESCZ, N, N, NUM_DIM, NUM_DIM, 0, 0, CONTEXT, NUM_DIM, INFO )



  LWORK = -1
  LRWORK = -1
  LIWORK = -1
  ALLOCATE(WORK(LWORK))
  ALLOCATE(RWORK(LRWORK))
  ALLOCATE(IWORK(LIWORK))


  CALL PZHEEVX( JOBZ, RANGE, UPLO, N, A, IA, JA, DESCA, VL, &
                VU, IL, IU, ABSTOL, M, NZ, W, ORFAC, Z, IZ, &
                JZ, DESCZ, WORK, LWORK, RWORK, LRWORK, IWORK, &
                LIWORK, IFAIL, ICLUSTR, GAP, INFO )

  LWORK = INT(ABS(WORK(1)))
  LRWORK = INT(ABS(RWORK(1)))
  LIWORK =INT (ABS(IWORK(1)))

  DEALLOCATE(WORK)
  DEALLOCATE(RWORK)
  DEALLOCATE(IWORK)

  ALLOCATE(WORK(LWORK))
  ALLOCATE(RWORK(LRWORK))
  ALLOCATE(IWORK(LIWORK))


         PRINT*, LWORK, LRWORK, LIWORK

  CALL PZHEEVX( JOBZ, RANGE, UPLO, N, A, IA, JA, DESCA, VL, &
                VU, IL, IU, ABSTOL, M, NZ, W, ORFAC, Z, IZ, &
                JZ, DESCZ, WORK, LWORK, RWORK, LRWORK, IWORK, &
                LIWORK, IFAIL, ICLUSTR, GAP, INFO )





  RETURN
END
问题在于第二个PZHEEVX函数。我相当肯定我正确地使用了它,因为这段代码是另一段工作正常的更复杂代码的简单版本。为此,我只使用一个处理器

救命啊

根据 设置LWORK=-1似乎要求PZHEEVX例程返回所有工作数组的必要大小,例如

如果LWORK=-1,则LWORK是全局输入和工作区查询 假设;该例程仅计算对象的最佳大小 所有工作数组。这些值中的每一个都在第一个 输入相应的工作数组,不显示任何错误消息 由PXERBLA发布

对于LRWORK=-1,可以找到类似的解释。至于我的工作

IWORK(本地工作区)整数数组 返回时,IWORK(1)包含整数工作空间的数量 必需的

但是在您的程序中,工作数组被分配为

LWORK = -1
LRWORK = -1
LIWORK = -1
ALLOCATE(WORK(LWORK))
ALLOCATE(RWORK(LRWORK))
ALLOCATE(IWORK(LIWORK))
在第一次调用PZHEEVX之后,工作阵列的大小如下所示:

LWORK = INT(ABS(WORK(1)))
LRWORK = INT(ABS(RWORK(1)))
LIWORK =INT (ABS(IWORK(1)))
这看起来不一致(-1对1)。因此,最好将分配修改为(*)

中的一个示例似乎也以这种方式分配工作数组。另一个值得关注的问题是INT()在多个地方使用(例如,
NPROW=INT(SQRT(REAL(NPROCS)))
,但我想最好使用NINT()来避免舍入错误的影响


(*)更准确地说,使用-1分配数组是无效的,因为分配数组的大小变为0(由于@francescalus)。您可以通过打印大小(a)或(:)来验证这一点。为了防止此类错误,附加编译器选项,如-fcheck=all(对于gfortran)或-check(对于ifort)非常有用.

在代码中有一个可疑的尺寸标注,它很容易导致segfault。在主程序中,您可以设置

EXPND=XNDIM=4
NUM_DIM=2*EXPND !NPROW==1 for a single-process test
ALLOCATE(MATTODIAG(XNDIM,XNDIM))   ! MATTODIAG(4,4)
然后,将Hermitian矩阵传递给

CALL MPIDIAGH(EXPND,MATTODIAG,ZZ,MYROW,...)
这又被定义为

SUBROUTINE MPIDIAGH(EXPND,A,Z,MYROW,...)

COMPLEX*16 A(NUM_DIM,NUM_DIM)   ! A(8,8)

这已经是一种不一致性,它可能会打乱该子例程中的计算(即使没有segfault)。此外,该子例程与scalapack一起认为
a
的大小是
(8,8)
,而不是
(4,4)
您在主程序中分配的,允许子例程溢出可用内存。

原始代码使用诸如allocate(work(-1))之类的负标量分配work(:)等。虽然gfortran接受这一点,但我不确定这是否适用于其他编译器…实际上,在工作区查询模式下使用专用变量捕获LAPACK函数的输出更简单。我会使用
complex*16::tmpwork;real*8::tmpwork;integer::tmpwork
,然后将这些变量放入子例程调用inst分别读取
work
rwork
iwork
。之后我才分配相应的数组,大小为
dble(tmpwork)
tmprwork
tmpiwork
,分别使用从double到integer的隐式转换。@AndrasDeak使用参数关键字。人们甚至可以编写
重塑(顺序=(/3,1,2/),形状=(/n3,n1,n2/),source=var(1:n1,1:n2,1:n3))
,但
重塑(var(1:n1,1:n2,1:n3),(/n3,n1,n2/),顺序=(/3,1,2/)
非常有效。@SamNorris,它们只是指使用编译开关,如
gfortran-fcheck=all-o easydiag easydiag.f
ifort-C-o easydiag easydiag.f
。如果您有一个标准的
makefile
,您可能必须将这些开关添加到
FFLAGS
。它们将打开所有类型的检查,包括运行时array绑定支票(我们现在感兴趣)。因此,编译、运行并查看消息是什么,如果有。如果segfault发生在lapack函数中,您可能无法获得其他信息,那么您必须仔细检查lapack调用的输入变量。此外,如果不是针对MPI,我建议您在
gdb
或任何其他调试器中运行程序,这将让您捕获错误回溯和探索变量的值和维度。虽然我只是用它调试C++,但我不知道它和MPI有多好。想想看,你得到一个StEngRebug是很奇怪的,但是这个程序看起来是同时的。你确定它不仅仅是并行环境在捉弄你吗?而且如果你能做到的话。修复segfault,输入矩阵不是Hermitian,PZHEEVX会不会难过?至少我不知道你的示例
MAKEHERMMAT
将如何创建一个(实)对称矩阵。这个问题有任何更新吗?:)
SUBROUTINE MPIDIAGH(EXPND,A,Z,MYROW,...)

COMPLEX*16 A(NUM_DIM,NUM_DIM)   ! A(8,8)