我在Fortran中遇到MPI_BCAST问题。我使用MPI_CART_CREATE创建一个新的通信器(比如'COMM_NEW')。当我使用旧的通信器(即MPI_COMM_WORLD)从root广播数据时,它工作正常。但是,当我使用我刚刚创建的新通信器时,它会给出错误:
[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
答案 0 :(得分:2)
我认为您在问题顶部提供的错误与底部的代码不匹配,因为它抱怨MPI_COMM_WORLD上的Bcast并且您实际上并未在代码中执行此操作。
无论如何,如果您运行的进程多于维度,则某些进程将不会包含在COMM_NEW中。相反,当对MPI_CART_CREATE的调用返回时,它们将获得COMM_NEW的MPI_COMM_NULL而不是具有拓扑的新通信器。你只需要做一个检查,以确保你在做Bcast之前有一个真正的沟通者而不是MPI_COMM_NULL(或者只是让DIMS(1)之上的所有等级都没有进入Bcast。
答案 1 :(得分:2)
详细说明Wesley Bland的答案并澄清错误信息中的明显差异。当MPI_COMM_WORLD
中的MPI进程数大于创建的笛卡尔网格中的进程数时,某些进程将不会成为新笛卡尔通信器的成员并将获得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
”的内容。