如何将混合OpenMP / OpenMPI并行化与GNU编译器一起使用?

时间:2020-03-23 11:28:59

标签: mpi openmp openmpi slurm

我正在运行一个物理求解器,该求解器被编写为使用混合OpenMP / MPI并行化。我们集群上的工作经理是SLURM。当我以纯MPI模式运行时,一切都按预期进行。但是,一旦我尝试使用混合并行化,就会发生奇怪的事情:

1)首先,我尝试了以下SLURM块:

#SBATCH --ntasks=8
#SBATCH --ntasks-per-node=2
#SBATCH --cpus-per-task=16

(提示:16是集群中处理器的物理核心数)

但是,发生的情况是模拟运行在4个节点上,在那里我看到4个用过的内核(在htop中)。此外,求解器告诉我它是从16个内核启动的,我对此并不了解。我想应该是8 * 16 = 128。

2)由于上述操作不成功,因此我在SLURM脚本中添加了以下循环:

if [ -n "$SLURM_CPUS_PER_TASK" ]; then
  omp_threads=$SLURM_CPUS_PER_TASK
else
  omp_threads=1
fi
export OMP_NUM_THREADS=$omp_threads

发生的事情是,求解器现在告诉我它是在128个内核上启动的。但是,当在各个节点上使用htop时,很明显这些OpenMP线程使用相同的内核,因此求解器非常慢。代码的开发人员告诉我,他从未使用过添加的循环,因此可能存在问题,但是我并不理解为什么OpenMP线程使用相同的内核。但是,在htop中,线程似乎在那里。另一个奇怪的事情是,htop向我显示了每个集群4个活动核心...我本来希望有2个(每个节点2个MPI任务),或者,如果一切按计划进行,那么我希望有32个(运行16个OMP线程的2个MPI任务)每个)。

开发人员使用Intel Fortran编译器,而我使用GNU fortran编译器(分别为mpif90和mpifort),我们已经遇到了一个问题。

有人知道如何使我的OpenMP线程使用所有可用的内核,而不是仅使用几个内核吗?

某些系统/代码信息:

Linux发行版:OpenSUSE Leap 15.0

编译器:mpif90

代码:FORTRAN90

1 个答案:

答案 0 :(得分:0)

使用以下方法可以使事情变得很少

#SBATCH --ntasks=8
#SBATCH --ntasks-per-node=2
#SBATCH --cpus-per-task=16

您告诉您要执行8个任务(即MPI工作程序),并且每个节点有两个任务,因此将代码从4个节点开始是正常的。

然后,您告诉每个MPI工作者使用16个OMP线程。你说:

此外,求解器告诉我它是在16个内核上启动的

求解器可能会查看OMP线程,因此他通常表示16。我不知道您的代码的详细信息,但是通常,如果您在网格上解决问题,则会将网格划分为子域(每个MPI 1个),并在此子域上使用OMP求解。因此,您有8个并行运行的求解器,每个求解器使用16个核。

命令export OMP_NUM_THREADS=$omp_threads和您添加的if块是正确的(顺便说这不是循环)。

如果群集上每个节点有16个核心,则配置应为:

#SBATCH --ntasks=8
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=16

因此,每个节点一个MPI,然后每个核心1个OMP,而不是现在的两个,这可能只会降低代码的速度。

最后,您如何获得htop输出,您是否登录到计算节点?通常不是。关于集群的好主意。

我知道这不是一个完整的答案,但是如果没有实际的代码,很难告诉更多,而且太长了,无法发布为评论。