Fortran 尼瑟';MPI#U屏障';诺尔';BLACS#u屏障';不';不要停止处理器执行其命令
我正在研究ScaLAPACK,并试图习惯BLACS例程,这是使用ScaLAPACK所必需的 我上过一些关于MPI的基础课程,所以对MPI_COMM_WORLD的内容有一些粗略的了解,但对其内部工作原理等没有深入的了解 不管怎样,我正在尝试使用BLACS例程执行以下代码来打招呼Fortran 尼瑟';MPI#U屏障';诺尔';BLACS#u屏障';不';不要停止处理器执行其命令,fortran,mpi,scalapack,blacs,Fortran,Mpi,Scalapack,Blacs,我正在研究ScaLAPACK,并试图习惯BLACS例程,这是使用ScaLAPACK所必需的 我上过一些关于MPI的基础课程,所以对MPI_COMM_WORLD的内容有一些粗略的了解,但对其内部工作原理等没有深入的了解 不管怎样,我正在尝试使用BLACS例程执行以下代码来打招呼 program hello_from_BLACS use MPI implicit none integer :: info, nproc, nprow, npcol, &
program hello_from_BLACS
use MPI
implicit none
integer :: info, nproc, nprow, npcol, &
myid, myrow, mycol, &
ctxt, ctxt_sys, ctxt_all
call BLACS_PINFO(myid, nproc)
! get the internal default context
call BLACS_GET(0, 0, ctxt_sys)
! set up a process grid for the process set
ctxt_all = ctxt_sys
call BLACS_GRIDINIT(ctxt_all, 'c', nproc, 1)
call BLACS_BARRIER(ctxt_all, 'A')
! set up a process grid of size 3*2
ctxt = ctxt_sys
call BLACS_GRIDINIT(ctxt, 'c', 3, 2)
if (myid .eq. 0) then
write(6,*) ' myid myrow mycol nprow npcol'
endif
(**) call BLACS_BARRIER(ctxt_sys, 'A')
! all processes not belonging to 'ctxt' jump to the end of the program
if (ctxt .lt. 0) goto 1000
! get the process coordinates in the grid
call BLACS_GRIDINFO(ctxt, nprow, npcol, myrow, mycol)
write(6,*) 'hello from process', myid, myrow, mycol, nprow, npcol
1000 continue
! return all BLACS contexts
call BLACS_EXIT(0)
stop
end program
“mpirun-np 10./exe”的输出如下:
hello from process 0 0 0 3 2
hello from process 4 1 1 3 2
hello from process 1 1 0 3 2
myid myrow mycol nprow npcol
hello from process 5 2 1 3 2
hello from process 2 2 0 3 2
hello from process 3 0 1 3 2
除了“BLACS_BARRIER”(我在代码的左侧标记了(**))这一行之外,一切似乎都正常工作
我把这一行放在下面,这样输出的标题行总是打印在它的顶部
myid myrow mycol nprow npcol
hello from process 0 0 0 3 2
hello from process 4 1 1 3 2
hello from process 1 1 0 3 2
hello from process 5 2 1 3 2
hello from process 2 2 0 3 2
hello from process 3 0 1 3 2
问题是
感谢您阅读此问题。回答您的两个问题(以后最好分别发帖) 1) MPI_屏障、BLACS_屏障和我遇到的任何并行编程方法中的任何屏障都只会同步调用它的实际进程集。然而,I/O不仅仅由调用进程来处理,而是在操作系统中至少有一个,而且很可能还有更多的进程来处理I/O请求。这些不是由您的屏障同步的。因此,I/O的顺序不能通过简单的屏障来保证。我能想到的确保I/O顺序的唯一标准一致性方法是
- 让一个进程执行所有I/O或
- 更好的方法是直接或通过NetCDF或HDF5间接使用MPI I/O
call BLACS_GRIDINIT(ctxt, 'c', 3, 2)
为3×2流程网格创建上下文,因此保留6流程。如果使用6个以上的进程调用它,则只有6个进程将返回有效上下文,因为其他ctxt
应视为未初始化的值。例如,如果用8个进程调用它,6将返回有效的ctxt
,2将返回没有有效值的ctxt
。如果这两个用户现在尝试使用ctxt
,任何事情都是可能的,在您的情况下,您会遇到seg故障。你似乎看到了这是一个问题,就像后来你看到的一样
! all processes not belonging to 'ctxt' jump to the end of the program
if (ctxt .lt. 0) goto 1000
但我在BLACS_GRIDINIT的描述中没有看到任何东西可以确保非参与进程的ctxt小于零
此例程创建一个简单的NPROW x NPCOL进程网格。这个过程
网格将使用第一个NPROW x NPCOL进程,并将它们分配给
行或列中的网格主要按自然顺序排列。如果这些
进程到网格的映射是不可接受的,BLACS_GRIDINIT的更多
必须调用复杂的姊妹例程BLACS_GRIDMAP
如果流程不是结果网格的一部分,则没有提到什么是ctxt
——这是我在BLACS文档中经常发现的问题。此外,为了您自己的利益,请不要使用goto
。你以后会后悔的。如果。。。如果,则结束。我不记得上次在Fortran中使用goto
是什么时候了,很可能是10多年前了
最后祝你在使用BLACS时好运!根据我的经验,文档通常是不完整的,我建议只使用那些使用ScaLAPACK绝对必要的调用,并使用MPI,对于其余部分,MPI的定义要好得多。如果ScaLAPACK现在能与MPI一起使用,那就更好了。欢迎使用。我建议坐火车。请对所有Fortran问题使用tag。这些障碍不足以按照您的要求排序输出。他们在那一点上同步进程,但是,对于与处理I/O的操作系统的各种位相关的同步,没有什么可说的。保证I/O顺序的唯一实用方法是1)MPI I I/O 2)在进程上处理所有I/O,因为进程使用无效上下文调用blacs_屏障,所以您会得到一个segfault。创建一个具有6个过程的网格。只有6个过程是上下文的一部分。任何其他过程都不是上下文的一部分。因此,调用blacs_barrier会导致seg错误。您的输出在
myid
之前打印了进程0中的hello。除非这是一个复制/粘贴错误,否则您的程序中会有一些严重的内存损坏。Gilles的观点是,虽然来自不同进程的I/O很难排序,但来自单个给定进程的I/O应该始终按照您执行它的顺序。在您的代码中,秩为0的进程打印“myid…”,然后打印一些整数。在您的示例out put中,秩0的I/O是“错误”的,反之亦然。这不应该发生。谢谢你给我一个回复,它帮助我了解了一些BLACS和“上下文”的概念。我通常不使用“goto”语句,只是按照我在搜索ScaLAPACK的PDGEMR2D子例程的示例时发现的一个网站上的示例,在MPI进程()上分发我的矩阵。再次感谢您的回答,祝您愉快:)