0

我正在研究 ScaLAPACK 并尝试习惯使用 ScaLAPACK 必不可少的 BLACS 例程。

我上过一些关于 MPI 的初级课程,所以对 MPI_COMM_WORLD 的东西有一些粗略的了解,但对它内部的工作原理等没有深入的了解。

无论如何,我正在尝试使用 BLACS 例程按照代码打招呼。

   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. 我已经尝试将 BLACS_BARRIER 用于“ctxt_sys”、“ctxt_all”和“ctxt”,但它们都没有输出第一次打印标题行的输出。我也试过 MPI_Barrier(MPI_COMM_WORLD,info),但也没有用。我是否以错误的方式使用障碍物?

  2. 另外,我在使用BLACS_BARRIER到'ctxt'时得到了SIGSEGV,并且在执行mpirun时使用了6个以上的进程。为什么在这种情况下会发生 SIGSEGV?

感谢您阅读这个问题。

4

1 回答 1

1

回答你的 2 个问题(以后最好单独发帖)

1) MPI_Barrier、BLACS_Barrier 和我遇到的任何并行编程方法中的任何障碍仅同步调用它的实际进程集。然而,I/O 不仅由调用进程处理,而且在实际处理 I/O 请求的操作系统中至少有一个,而且很可能更多。这些不是由您的屏障同步的。因此,I/O 的顺序不能通过简单的屏障来确保。我能想到的确保 I/O 顺序的唯一符合标准的方法是

  • 让 1 个进程完成所有 I/O 或
  • 更好的是直接或间接使用 MPI I/O,例如通过 NetCDF 或 HDF5

2) 您对 BLACS_GRIDINIT 的第二次调用

 call BLACS_GRIDINIT(ctxt, 'c', 3, 2)

为 3 x 2 进程网格创建上下文,因此保留 6 个进程。如果您使用超过 6 个进程调用它,则只会返回 6 个带有有效上下文的进程,因为其他进程ctxt应被视为未初始化的值。因此,例如,如果您使用 8 个进程调用它,则 6 将返回有效值ctxt,2 将返回ctxt没有有效值。如果这两个现在尝试使用ctxt任何可能的方法,并且在您的情况下,您遇到了段错误。您似乎确实看到这是一个问题,因为稍后您会遇到

 ! all processes not belonging to 'ctxt' jump to the end of the program
 if (ctxt .lt. 0) goto 1000

但我在 BLACS_GRIDINIT 的描述中看不到任何内容,以确保 ctxt 对于非参与进程小于零 - 在https://www.netlib.org/blacs/BLACS/QRef.html#BLACS_GRIDINIT它说

此例程创建一个简单的 NPROW x NPCOL 过程网格。该进程网格将使用第一个 NPROW x NPCOL 进程,并以行或列优先的自然顺序将它们分配给网格。如果这些进程到网格的映射不可接受,则必须调用 BLACS_GRIDINIT 的更复杂的姊妹例程 BLACS_GRIDMAP。

没有提及ctxt如果该过程不是结果网格的一部分会发生什么 - 这是我经常在 BLACS 文档中发现的问题。也请不要使用goto,为了你自己。你以后会后悔的。使用If ... End If. 我不记得我上次使用gotoFortran 是什么时候了,可能是 10 多年前了。

最后祝您使用 BLACS 好运!以我的经验,文档通常是不完整的,我建议只使用那些对于使用 ScaLAPACK 和使用 MPI 绝对必要的调用,对于其余部分,MPI 的定义要好得多。如果现在 ScaLAPACK 只与 MPI 一起工作,那就更好了。

于 2020-05-09T07:49:58.440 回答