我正在运行一个物理求解器,该求解器被编写为使用混合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个(2个MPI任务运行16个OMP线程每个)。
[一旦开发人员使用Intel Fortran编译器,而我使用GNU fortran编译器(分别为mpif90和mpifort),我们就已经遇到了问题。
有人知道如何使我的OpenMP线程使用所有可用的内核,而不是仅使用少数几个吗?
某些系统/代码信息:
Linux发行版:OpenSUSE Leap 15.0
编译器:mpif90
代码:FORTRAN90
很少的东西,通过使用:
#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
输出,您是否登录到计算节点?通常不是。关于集群的一个好主意。
我知道这不是一个完整的答案,但是如果没有实际的代码,很难告诉更多,这太长了,无法发布为评论。