我希望能够轻松地在群集的每台计算机上执行集体通信。假设我有4台机器,每台机器有8个核心,我的mpi程序将运行32个MPI任务。对于给定的函数,我想要的是:
从概念上讲,我理解我必须为每个主机创建一个通信器。我四处搜索,发现没有明确这样做。我对MPI小组和传播者感到不舒服。这是我的两个问题:
答案 0 :(得分:6)
规范说MPI_Get_processor_name
返回“实际(而不是虚拟)节点的唯一说明符”,所以我认为你可以这样做。我想你会聚集在一起收集所有的主机名,然后指定一组处理器来制作他们的通信器;或者复制MPI_COMM_WORLD,将名称转换为整数哈希值,并使用mpi_comm_split对集合进行分区。
您还可以采用janneb建议的方法并使用特定于实现的选项来确保MPI实现以这种方式分配任务; OpenMPI使用--byslot生成此排序;使用mpich2,您可以使用-print-rank-map查看映射。
但这真的是你想要做的吗?如果其他进程在一个处理器工作时处于空闲状态,那么这比每个人冗余地进行计算更好吗? (或者这是内存还是I / O密集型,你担心争用吗?)如果你要做很多这样的事情 - 处理节点内并行化与节点外并行化有很大不同 - 那么您可能需要考虑混合编程模型 - 每个节点运行一个MPI任务和MPI_spawning子任务或使用OpenMP进行节点间通信,这两者都是HPM建议的。
答案 1 :(得分:2)
我不认为(受过教育的思想,不是决定性的)你将能够在你的MPI计划中完全做你想做的事。
系统对MPI_Get_processor_name
的调用的响应取决于系统;在您的系统上,它可能会根据需要返回node00
,node01
,node02
,node03
,或者对于您实际运行的处理器,它可能会返回my_big_computer
。前者更有可能,但不能保证。
一种策略是启动32个进程,如果您可以确定每个进程运行的节点,请将通信器划分为4个组,每个节点一个。这样您就可以根据需要自行管理内部和内部通信。
另一种策略是启动4个进程并将它们固定到不同的节点。如何将进程固定到节点(或处理器)将取决于您的MPI运行时和您可能拥有的任何作业管理系统,例如Grid Engine。这可能涉及设置环境变量 - 但是您没有告诉我们您的运行时系统的任何信息,因此我们无法猜测它们可能是什么。然后,您可以让4个进程中的每个进程动态生成另外7个(或8个)进程,并将这些进程固定到与初始进程相同的节点。为此,请阅读有关intercommunicators和运行时系统文档的主题。
第三种策略,现在变得有点疯狂了,就是启动4个独立的MPI程序(每个程序8个进程),一个在集群的每个节点上,并在它们执行时加入它们。有关详细信息,请阅读MPI_Comm_connect
和MPI_Open_port
。
最后,为了获得额外的乐趣,您可以考虑混合您的程序,在每个节点上运行一个MPI进程,并让每个进程执行OpenMP共享内存(子)程序。
答案 2 :(得分:1)
通常可以控制MPI运行时环境,例如:通过环境变量如何在节点上分配任务。默认情况往往是顺序分配,也就是说,对于您的示例,分配了4台8核计算机上的32个任务
是的,MPI_Get_processor_name应该为您提供主机名,以便您可以找出主机之间的边界。