1

我在 Fortran 中遇到 MPI_BCAST 问题。我使用 MPI_CART_CREATE(比如“COMM_NEW”)创建了一个新的通信器。当我使用旧的通信器(即 MPI_COMM_WORLD)从根广播数据时,它工作正常。但是,当我使用刚刚创建的新通信器时,它会出现错误:

[compute-4-15.local:15298] *** An error occurred in MPI_Bcast
[compute-4-15.local:15298] *** on communicator MPI_COMM_WORLD
[compute-4-15.local:15298] *** MPI_ERR_COMM: invalid communicator
[compute-4-15.local:15298] *** MPI_ERRORS_ARE_FATAL (your MPI job will now abort)

它确实从 COMM_NEW 中涉及的处理器获得结果,以及上述错误,认为问题出在 COMM_NEW 中不包含但存在于 MPI_COMM_WORLD 中的其他处理器上。任何帮助将不胜感激。是不是因为 COMM_NEW 中的处理器数少于总处理器数。如果是这样,我如何在一组小于总数的处理器中广播。谢谢。我的示例代码是:

!PROGRAM TO BROADCAST THE DATA FROM ROOT TO DEST PROCESSORS
PROGRAM MAIN
IMPLICIT NONE
INCLUDE 'mpif.h'
!____________________________________________________________________________________
!-------------------------------DECLARE VARIABLES------------------------------------
INTEGER :: ERROR, RANK, NPROCS, I
INTEGER :: SOURCE, TAG, COUNT, NDIMS, COMM_NEW
INTEGER :: A(10), DIMS(1)
LOGICAL :: PERIODS(1), REORDER
!____________________________________________________________________________________
!-------------------------------DEFINE VARIABLES-------------------------------------
SOURCE = 0; TAG = 1; COUNT = 10
PERIODS(1) = .FALSE.
REORDER = .FALSE.
NDIMS = 1
DIMS(1) = 6
!____________________________________________________________________________________
!--------------------INITIALIZE MPI, DETERMINE SIZE AND RANK-------------------------
CALL MPI_INIT(ERROR)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD, NPROCS, ERROR)
CALL MPI_COMM_RANK(MPI_COMM_WORLD, RANK, ERROR)
!
CALL MPI_CART_CREATE(MPI_COMM_WORLD, NDIMS, DIMS, PERIODS, REORDER, COMM_NEW, ERROR)

IF(RANK==SOURCE)THEN
DO I=1,10
  A(I) = I
END DO
END IF
!____________________________________________________________________________________
!----------------BROADCAST VECTOR A FROM ROOT TO DESTINATIONS------------------------

CALL MPI_BCAST(A,10,MPI_INTEGER,SOURCE,COMM_NEW,ERROR)

!PRINT*, RANK
!WRITE(*, "(10I5)") A

CALL MPI_FINALIZE(ERROR)

END PROGRAM
4

2 回答 2

2

详细说明 Wesley Bland 的答案并澄清错误消息中的明显差异。当其中的 MPI 进程MPI_COMM_WORLD数大于创建的笛卡尔网格中的进程数时,一些进程将不会成为新笛卡尔通信器的成员,并且会得到MPI_COMM_NULL- 无效的通信器句柄 - 结果。调用集体通信操作需要有效的通信器间或通信器内句柄。与MPI_PROC_NULL在点对点操作中的允许用法不同,在集体调用中使用无效的通信器句柄是错误的。最后一条语句没有明确写在 MPI 标准中 - 相反,使用的语言是:

如果comm是内部通信器,那么... 如果comm是内部通信器,那么...

由于MPI_COMM_NULL既不是内部通信器,也不是内部通信器,因此它不属于定义的两种行为类别中的任何一种,因此会导致错误情况。

由于通信错误必须在某些上下文中发生(即在有效的通信器中),Open MPI 替换MPI_COMM_WORLD为对错误处理程序的调用,因此错误消息显示为“ *** on communicator MPI_COMM_WORLD”。这是来自 的相关代码部分ompi/mpi/c/bcast.c,在哪里MPI_Bcast实现:

if (ompi_comm_invalid(comm)) {
    return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM, 
                               FUNC_NAME);
}
...
if (MPI_IN_PLACE == buffer) {
    return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
}

您的代码在第一次检查中触发错误处理程序。在所有其他错误检查comm中使用(因为它被确定为有效的通信器句柄)并且错误消息将声明类似“ *** on communicator MPI COMMUNICATOR 5 SPLIT FROM 0”的内容。

于 2013-06-23T11:12:51.127 回答
2

我认为您在问题顶部给出的错误与底部的代码不匹配,因为它抱怨 MPI_COMM_WORLD 上的 Bcast 而您实际上并没有在代码中执行此操作。

无论如何,如果您运行的进程多于维度,则某些进程将不会包含在 COMM_NEW 中。相反,当对 MPI_CART_CREATE 的调用返回时,他们将获得 COMM_NEW 的 MPI_COMM_NULL 而不是具有拓扑的新通信器。在进行 Bcast 之前,您只需要检查以确保您有一个真正的通信器而不是 MPI_COMM_NULL(或者只是让所有高于 DIMS(1) 的等级都没有进入 Bcast。

于 2013-06-22T15:07:36.750 回答