简介
我想编写一个混合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。我当然不是第一个遇到此问题的人,但是以某种方式搜索网络并没有为我指明正确的方向。除了找到自己的同质集群之外,是否有解决该问题的标准方法?
最佳答案
使用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);
关于multithreading - MPI和pthreads : nodes with different numbers of cores,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25755687/