Fortran 将MPI\u BCAST与MPI\u CART\u CREATE一起使用时出现问题

Fortran 将MPI\u BCAST与MPI\u CART\u CREATE一起使用时出现问题,fortran,mpi,Fortran,Mpi,我在Fortran中使用MPI_BCAST时遇到问题。我使用MPI\u CART\u create创建一个新的通信器,比如“COMM\u new”。当我使用旧的通信器(即MPI_COMM_WORLD)从根目录广播数据时,它工作正常。但是,当我使用刚创建的新通信器时,会出现以下错误: [compute-4-15.local:15298] *** An error occurred in MPI_Bcast [compute-4-15.local:15298] *** on communicator

我在Fortran中使用MPI_BCAST时遇到问题。我使用MPI\u CART\u create创建一个新的通信器,比如“COMM\u 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

我认为您在问题顶部给出的错误与底部的代码不匹配,因为它在抱怨MPI_COMM_WORLD上的Bcast,而您实际上在代码中没有这样做


无论如何,如果运行的进程多于维度,则COMM_NEW中不会包含某些进程。相反,当对MPI_CART_CREATE的调用返回时,它们将获得COMM_NEW的MPI_COMM_NULL,而不是具有拓扑结构的新通信器。在进行Bcast之前,您只需要做一个检查,确保您有一个真正的通信器,而不是MPI_COMM_NULL,或者只是让DIMS1上面的所有列组都不要输入Bcast。

我认为您在问题顶部给出的错误与底部的代码不匹配,因为它在抱怨MPI_COMM_WORLD上的Bcast,而您不要在代码中实际执行一个


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

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

如果comm是内部通信程序,则。。。如果comm是一个内部通讯器,那么

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

由于通信错误必须发生在某些上下文中,即在有效的通信器中,因此Open MPI在调用错误处理程序时替换MPI_COMM_WORLD,因此错误消息在通信器MPI_COMM_WORLD上显示***。这是ompi/mpi/c/bcast.c中的相关代码部分,其中实现了mpi_bcast:

如果ompi_comm_invalidcomm{ 返回OMPI_ERRHANDLER_INVOKEMPI_COMM_WORLD,MPI_ERR_COMM, FUNC_名称; } ... 如果MPI_IN_PLACE==缓冲区{ 返回OMPI\u ERRHANDLER\u INVOKEcomm、MPI\u ERR\u ARG、FUNC\u NAME; }
您的代码在第一次检查中触发错误处理程序。在所有其他错误检查中,将使用comm,因为它被确定为有效的通信器句柄,并且错误消息将在通信器MPI通信器5上声明类似***的内容,从0拆分。

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

如果comm是内部通信程序,则。。。如果comm是一个内部通讯器,那么

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

由于通信错误必须发生在某些上下文中,即在有效的通信器中,请打开MPI替换 在调用错误处理程序时显示MPI_COMM_WORLD,因此在通信器MPI_COMM_WORLD上显示***。这是ompi/mpi/c/bcast.c中的相关代码部分,其中实现了mpi_bcast:

如果ompi_comm_invalidcomm{ 返回OMPI_ERRHANDLER_INVOKEMPI_COMM_WORLD,MPI_ERR_COMM, FUNC_名称; } ... 如果MPI_IN_PLACE==缓冲区{ 返回OMPI\u ERRHANDLER\u INVOKEcomm、MPI\u ERR\u ARG、FUNC\u NAME; }
您的代码在第一次检查中触发错误处理程序。在所有其他错误检查中,将使用comm,因为它被确定为有效的通信器句柄,并且错误消息将在通信器MPI通信器5上显示类似***的内容,从0拆分而来。

+1。Open MPI在所有与提供的无效通信器句柄相关的错误消息中使用MPI_COMM_WORLD-请参阅我的答案。谢谢大家。正如你们所指出的,我已经找到了错误和原因。当我使用if条件调用COMM_NEW中的MPI_BCAST时,它会工作。+1。Open MPI在所有与提供的无效通信器句柄相关的错误消息中使用MPI_COMM_WORLD-请参阅我的答案。谢谢大家。正如你们所指出的,我已经找到了错误和原因。当我使用if条件调用COMM_NEW中的MPI_BCAST时,它会工作。