简介
我想编写一个混合的MPI / pthreads代码。我的目标是在每个节点上启动一个MPI进程,并将每个进程拆分为多个线程,这些线程实际上将完成这项工作,但通信只发生在单独的MPI进程之间。
有很多教程描述了这种情况,称为混合编程,但它们通常假设是一个同类群集。但是,我使用的是异构节点:它们具有不同的处理器和不同数量的核心,即节点是4/8/12/16核心机器的组合。
我知道在这个集群中运行MPI进程会使我的代码速度降低到使用的最慢CPU的速度;我接受这个事实。有了这个,我想谈谈我的问题。
有没有办法启动N个MPI进程 - 每个节点有一个MPI进程 - 并让每个进程知道该节点有多少个可用的物理内核?
我可以访问的MPI实现是OpenMPI。节点是Intel和AMD CPU的混合体。我想到使用一个机器文件,每个节点被指定为有一个插槽,然后在本地计算核心数量。但是,there seem to be problems with doing that。我肯定不是第一个遇到这个问题的人,但不知何故在网上搜索并没有指出我正确的方向。除了找到一个同质的集群之外,还有一种解决这个问题的标准方法吗?
答案 0 :(得分:4)
使用Open MPI,每个节点只启动一个进程非常简单:
mpiexec -pernode ./mympiprogram
-pernode
参数等同于-npernode 1
,它指示ORTE启动程序为主机列表中的每个节点启动一个进程。这种方法的优点是无论实际主机列表是如何提供的,它都可以工作,即当它来自与某些资源管理器(例如Torque / PBS,SGE,LSF,SLURM等)的紧密耦合并且手动提供时主机。即使主机列表包含具有多个插槽的节点,它也可以工作。
了解内核数量有点棘手且非常特定于操作系统。但Open MPI附带hwloc library,它提供了一个抽象API来查询系统组件,包括核心数量:
hwloc_topology_t topology;
/* Allocate and initialize topology object. */
hwloc_topology_init(&topology);
/* Perform the topology detection. */
hwloc_topology_load(topology);
/* Get the number of cores */
unsigned nbcores = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_CORE);
/* Destroy topology object. */
hwloc_topology_destroy(topology);
如果您希望在作业中为每个MPI流程提供整个群集的核心数量,那么您需要一个简单的MPI_Allgather
:
/* Obtain the number or MPI processes in the job */
int nranks;
MPI_Comm_size(MPI_COMM_WORLD, &nranks);
unsigned cores[nranks];
MPI_Allgather(&nbcores, 1, MPI_UNSIGNED,
cores, 1, MPI_UNSIGNED, MPI_COMM_WORLD);