【问题标题】:Group MPI tasks by host按主机对 MPI 任务进行分组
【发布时间】:2021-02-16 13:18:40
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: mpi communicator


    【解决方案1】:

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

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

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

    【讨论】:

    • MPI_Comm_split 对我来说似乎是最好的解决方案。我正在测试它,但我想知道 OpenMPI 是如何处理它的。如果通信器中的任务都属于同一个主机,那么 OpenMPI 是否足够智能以仅使用共享内存执行 Bcast?是否可以将策略分配给传播者或广播?
    • 关于你的最后一个问题:为什么这样更好?我正在研究一个大型 HPC 程序的一小部分。混合方法 MPI + OpenMP 已经过测试,但我正在使用的版本是纯 MPI。在这个阶段,1 个核心 = 1 个 MPI 任务。在程序的某个时刻,MPI 任务调用 Lapack 函数。所有内核对相同的数据执行相同的功能。想法是在每个主机上执行此功能,但仅通过 1 个 MPI 任务,使用此功能的并行实现。我只是在跳跃(Lapack_fc / nb_core + Bcast_time)
    • 市场上的所有 MPI 都足够智能,可以将共享内存用于仅本地通信,实际上通常会先通过本地操作然后全局操作来实现全局集合。基本上,任何明显的东西都已经实现了(除非有一个不明显的原因很难)。至于为什么混合(可以)更好——如果在整个代码中,您在节点上和节点外并行之间存在这种区别,那么您的并行模型也可能会反映这一点。另一方面,如果这只是较大代码中的一个小“一次性”,那么扁平 MPI 可能是最好的。
    • 感谢您对这个(从我个人的观点)重要问题的出色回答。我正在尝试做同样的事情,但是I'd like to implement it in mpi4py as explained there。你知道这种使用 mpi4py 实现的例子吗?
    【解决方案2】:

    我不认为(受过教育的想法,不是确定的)你能够完全在你的 MPI 程序中做你想做的事情。

    系统对MPI_Get_processor_name 的调用的响应取决于系统;在您的系统上,它可能会根据需要返回node00node01node02node03,或者对于您实际运行的任何处理器,它可能会返回my_big_computer。前者的可能性更大,但不能保证。

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

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

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

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

    【讨论】:

    • 你的三个方法都很有趣,但我不能用。我正在开发一个真正的大型应用程序,并且无法更改那样的内容。
    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2019-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-14
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多