首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Fortran中使用SCALAPACK分割故障?没有回溯?

在Fortran中使用SCALAPACK分割故障?没有回溯?
EN

Stack Overflow用户
提问于 2015-08-30 12:52:31
回答 2查看 371关注 0票数 1

我正在尝试使用Fortran中的SCALAPACK和MPI来寻找厄米特矩阵的特征值和特征向量。对于bug压缩,我把这个程序做得尽可能简单,但仍然得到了一个分段错误。根据对有类似问题的人的回答,我尝试将所有整数更改为整数*8,并将所有实数更改为实数*8或实数*16,但我仍然遇到此问题。最有趣的是,我甚至没有得到分段错误的回溯:程序在试图给我回溯时挂起,并且必须手动中止。

另外,请原谅我缺乏知识--我对大多数程序不熟悉,但我已经尽了最大努力。下面是我的代码:

代码语言:javascript
复制
    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函数上。我相当确定我使用它是正确的,因为这段代码是另一个运行良好的更复杂代码的更简单版本。为此,我只使用了一个处理器。

帮助!

EN

回答 2

Stack Overflow用户

发布于 2015-08-30 14:53:25

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

如果LWORK = -1,则LWORK是全局输入,并假定为工作区查询;该例程仅计算所有工作数组的最佳大小。这些值都会在相应工作数组的第一个条目中返回,并且PXERBLA不会发出错误消息。

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

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

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

代码语言:javascript
复制
LWORK = -1
LRWORK = -1
LIWORK = -1
ALLOCATE(WORK(LWORK))
ALLOCATE(RWORK(LRWORK))
ALLOCATE(IWORK(LIWORK))

在第一次调用PZHEEVX之后,工作数组的大小为

代码语言:javascript
复制
LWORK = INT(ABS(WORK(1)))
LRWORK = INT(ABS(RWORK(1)))
LIWORK =INT (ABS(IWORK(1)))

这看起来不一致(-1 vs 1)。因此,最好将分配修改为(*)

代码语言:javascript
复制
allocate( WORK(1), RWORK(1), IWORK(1) )

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

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

票数 2
EN

Stack Overflow用户

发布于 2015-08-31 04:47:14

在你的代码中有一段可疑的尺寸标注,这很容易导致段错误。在您的主程序中设置

代码语言:javascript
复制
EXPND=XNDIM=4
NUM_DIM=2*EXPND !NPROW==1 for a single-process test
ALLOCATE(MATTODIAG(XNDIM,XNDIM))   ! MATTODIAG(4,4)

然后将您的MATTODIAG,即厄米特矩阵传递给

代码语言:javascript
复制
CALL MPIDIAGH(EXPND,MATTODIAG,ZZ,MYROW,...)

它又被定义为

代码语言:javascript
复制
SUBROUTINE MPIDIAGH(EXPND,A,Z,MYROW,...)

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

这已经是一个不一致的问题,它可能会使该子例程中的计算变得混乱(即使没有段错误)。此外,子例程和scalapack认为A的大小是(8,8),而不是您在主程序中分配的(4,4),这会允许子例程溢出可用内存。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32293280

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档