【问题标题】:Trouble using MPI_BCAST with MPI_CART_CREATE将 MPI_BCAST 与 MPI_CART_CREATE 一起使用时遇到问题
【发布时间】:2013-06-19 02:49:24
【问题描述】:

我在 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

【问题讨论】:

    标签: fortran mpi


    【解决方案1】:

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

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

    【讨论】:

    • +1。 Open MPI 在与提供的无效通信器句柄相关的所有错误消息中使用MPI_COMM_WORLD - 请参阅我的答案。
    • 谢谢大家。正如你们指出的那样,我已经能够找到错误及其。当我使用 if 条件在 COMM_NEW 中调用 MPI_BCAST 时,它可以工作。
    【解决方案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”的内容。

    【讨论】:

      猜你喜欢
      • 2013-03-20
      • 2021-07-15
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多