我希望在集群中的每台机器上独立地轻松执行集体通信。假设我有 4 台机器,每台机器有 8 个核心,我的 mpi 程序将运行 32 个 MPI 任务。我想要的是,对于给定的函数:

  • 在每台主机上,只有一个任务执行计算,其他任务在此计算期间不执行任何操作。在我的示例中,4 个 MPI 任务将执行计算,另外 28 个任务正在等待。
  • 一旦计算完成,每个 MPI 任务将仅对本地任务(在同一主机上运行的任务)执行集体通信。

从概念上讲,我知道我必须为每个主机创建一个通信器。我四处搜寻,没有发现任何明确的做法。我对 MPI 团体和沟通者不太满意。这是我的两个问题:

  • 对于这种行为,MPI_Get_processor_name 是否足够独特?
  • 更一般地说,你有一段代码可以做到这一点吗?
有帮助吗?

解决方案

规范说 MPI_Get_processor_name 返回“实际(而不是虚拟)节点的唯一说明符”,所以我认为你会同意的。我猜你会进行一次收集来组合所有主机名,然后分配处理器组来启动它们的通信器;或 dup MPI_COMM_WORLD,将名称转换为整数哈希,并使用 mpi_comm_split 对集合进行分区。

您还可以采用 janneb 建议的方法,并使用 mpirun 的特定于实现的选项,以确保 MPI 实现以这种方式分配任务;OpenMPI 使用 --byslot 来生成此排序;对于 mpich2,您可以使用 -print-rank-map 来查看映射。

但这真的是你想做的吗?如果当一个处理器正在工作时其他进程处于空闲状态,这比每个人都冗余地进行计算更好吗?(或者这是否非常占用内存或 I/O,并且您担心争用?)如果您打算做很多这样的事情——处理节点上并行化与节点外并行化非常不同——那么您可能需要考虑混合编程模型 - 每个节点运行一个 MPI 任务和 MPI_spawning 子任务,或者使用 OpenMP 进行节点上通信,两者均如 HPM 所建议的那样。

其他提示

我不认为(有根据的想法,不是确定的)您将能够完全在 MPI 程序中做您想做的事情。

系统对调用的响应 MPI_Get_processor_name 取决于系统;在你的系统上它可能会返回 node00, node01, node02, node03 视情况而定,否则可能会返回 my_big_computer 对于您实际运行的任何处理器。前者的可能性更大,但不能保证。

一种策略是启动 32 个进程,如果您可以确定每个进程在哪个节点上运行,请将通信器分为 4 组,每个节点上一组。这样您就可以根据需要自行管理内部和内部通信。

另一种策略是启动 4 个进程并将它们固定到不同的节点。如何将进程固定到节点(或处理器)将取决于您的 MPI 运行时以及您可能拥有的任何作业管理系统,例如 Grid Engine。这可能涉及设置环境变量——但是您没有告诉我们有关您的运行时系统的任何信息,因此我们无法猜测它们可能是什么。然后,您可以让 4 个进程中的每一个进程动态生成另外 7 个(或 8 个)进程,并将它们固定到与初始进程相同的节点。为此,请阅读内部通信器主题和运行时系统文档。

第三种策略(现在有点疯狂)是启动 4 个独立的 MPI 程序(每个程序 8 个进程),集群的每个节点上都有一个,并在它们执行时加入它们。阅读 MPI_Comm_connectMPI_Open_port 了解详情。

最后,为了获得额外的乐趣,您可以考虑混合您的程序,在每个节点上运行一个 MPI 进程,并让每个进程执行一个 OpenMP 共享内存(子)程序。

通常,您的 MPI 运行时环境可以被控制,例如通过环境变量如何在节点上分配任务。默认情况下往往是顺序分配,也就是说,对于您的示例,32 个任务分布在 4 台 8 核计算机上

  • 机器1:MPI 排名 0-7
  • 机器2:MPI排名8-15
  • 机器3:MPI排名16-23
  • 机器4:MPI 排名 24-31

是的,MPI_Get_processor_name 应该为您提供主机名,以便您可以找出主机之间的边界在哪里。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top