我想创建一个大量使用 SCALAPACK 的并行程序。SCALAPACK 的基础是 BLACS,它本身依赖 MPI 进行进程间通信。
我想以定义数量的进程(例如机器上的内核数)启动程序,并让算法决定如何使用这些进程进行计算。
作为测试用例,我想使用 10 个进程。其中 9 个进程应排列成网格 ( BLACS_GRIDINIT
),第 10 个进程应等到其他进程完成。
不幸的是,OpenMPI 崩溃是因为最后一个进程没有从 BLACS 进入 MPI 上下文,而其他进程却进入了。
问题:使用 BLACS 处理比需要的更多的正确方法是什么?
我做了一些额外的MPI_INIT
和MPI_FINALIZE
调用的实验,但我的尝试都没有成功。
我从 Intel MKL 的示例代码开始(稍微缩短了一点):
PROGRAM HELLO
* -- BLACS example code --
* Written by Clint Whaley 7/26/94
* Performs a simple check-in type hello world
* ..
* .. External Functions ..
INTEGER BLACS_PNUM
EXTERNAL BLACS_PNUM
* ..
* .. Variable Declaration ..
INTEGER CONTXT, IAM, NPROCS, NPROW, NPCOL, MYPROW, MYPCOL
INTEGER ICALLER, I, J, HISROW, HISCOL
* Determine my process number and the number of processes in
* machine
CALL BLACS_PINFO(IAM, NPROCS)
* Set up process grid that is as close to square as possible
NPROW = INT( SQRT( REAL(NPROCS) ) )
NPCOL = NPROCS / NPROW
* Get default system context, and define grid
CALL BLACS_GET(0, 0, CONTXT)
CALL BLACS_GRIDINIT(CONTXT, 'Row', NPROW, NPCOL)
CALL BLACS_GRIDINFO(CONTXT, NPROW, NPCOL, MYPROW, MYPCOL)
* If I'm not in grid, go to end of program
IF ( (MYPROW.GE.NPROW) .OR. (MYPCOL.GE.NPCOL) ) GOTO 30
* Get my process ID from my grid coordinates
ICALLER = BLACS_PNUM(CONTXT, MYPROW, MYPCOL)
* If I am process {0,0}, receive check-in messages from
* all nodes
IF ( (MYPROW.EQ.0) .AND. (MYPCOL.EQ.0) ) THEN
WRITE(*,*) ' '
DO 20 I = 0, NPROW-1
DO 10 J = 0, NPCOL-1
IF ( (I.NE.0) .OR. (J.NE.0) ) THEN
CALL IGERV2D(CONTXT, 1, 1, ICALLER, 1, I, J)
END IF
* Make sure ICALLER is where we think in process grid
CALL BLACS_PCOORD(CONTXT, ICALLER, HISROW, HISCOL)
IF ( (HISROW.NE.I) .OR. (HISCOL.NE.J) ) THEN
WRITE(*,*) 'Grid error! Halting . . .'
STOP
END IF
WRITE(*, 3000) I, J, ICALLER
10 CONTINUE
20 CONTINUE
WRITE(*,*) ' '
WRITE(*,*) 'All processes checked in. Run finished.'
* All processes but {0,0} send process ID as a check-in
ELSE
CALL IGESD2D(CONTXT, 1, 1, ICALLER, 1, 0, 0)
END IF
30 CONTINUE
CALL BLACS_EXIT(0)
1000 FORMAT('How many processes in machine?')
2000 FORMAT(I)
3000 FORMAT('Process {',i2,',',i2,'} (node number =',I,
$ ') has checked in.')
STOP
END
更新:我调查了源代码,BLACS
看看那里发生了什么。
如果以前没有发生这种情况,该调用BLACS_PINFO
会使用 初始化 MPI 上下文。MPI_INIT
这意味着,在这一点上,一切都按预期工作。
最后,调用BLACS_EXIT(0)
应该释放所有资源BLACS
,如果参数是0
,它也应该调用MPI_FINALIZE
。不幸的是,这没有按预期工作,我的最后一个过程没有调用MPI_FINALIZE
.
作为一种解决方法,如有必要,可以询问MPI_FINALIZED
并致电。MPI_FINALIZE
更新 2:我之前的尝试是使用Intel Studio 2013.0.079
和OpenMPI 1.6.2
on完成的SUSE Linux Enterprise Server 11
。
在阅读了cteo的回答后,我尝试使用Ubuntu 12.04
(gfortran 4.6.3, OpenMPI 1.4.3, BLACS 1.1
)给出的工具编译这个例子并且成功了。
我的结论是,英特尔的实施似乎有问题。我将在不久的将来使用 的最新服务版本重试此示例Intel Studio
,但不要期望任何更改。
但是,我将不胜感激任何其他(也许更好)的解决方案。