【问题标题】:Batch script for LSF when only one MPI process among the others has 2 or more threadsLSF 的批处理脚本,其中只有一个 MPI 进程有 2 个或更多线程
【发布时间】:2014-12-24 01:33:07
【问题描述】:

我的程序使用 MPI+pthreads,其中 n-1 个 MPI 进程是纯 MPI 代码,而唯一一个 MPI 进程使用 pthreads。最后一个进程仅包含 2 个线程(主线程和 pthread)。假设我要在其上运行此程序的 HPC 集群由计算节点组成,每个计算节点有 12 个核心。我应该如何编写批处理脚本以最大限度地利用硬件?

以下是我编写的批处理脚本。我使用 export OMP_NUM_THREADS=2 因为最后一个 MPI 进程有 2 个线程,并且必须假设其他每个进程也有 2 个线程。

然后我为每个节点分配 6 个 MPI 进程,因此每个节点可以运行 6xOMP_NUM_THREADS = 12(=每个节点上的核心数)线程,尽管所有 MPI 进程都只有一个线程。

#BSUB -J LOOP.N200.L1000_SIMPLE_THREAD
#BSUB -o LOOP.%J
#BSUB -W 00:10
#BSUB -M 1024
#BSUB -N
#BSUB -a openmpi
#BSUB -n 20
#BSUB -m xxx
#BSUB -R "span[ptile=6]"
#BSUB -x

export OMP_NUM_THREADS=2

我怎样才能为此编写更好的脚本?

【问题讨论】:

    标签: mpi cluster-computing batch-processing job-scheduling lsf


    【解决方案1】:

    如果您希望最后一个等级成为混合等级,则以下方法应该有效:

    #BSUB -n 20
    #BSUB -R "span[ptile=12]"
    #BSUB -x
    
    $MPIEXEC $FLAGS_MPI_BATCH -n 19 -x OMP_NUM_THREADS=1 ./program : \
             $FLAGS_MPI_BATCH -n 1  -x OMP_NUM_THREADS=2 ./program
    

    如果您希望 0 级成为混合级,只需切换两行:

    $MPIEXEC $FLAGS_MPI_BATCH -n 1  -x OMP_NUM_THREADS=2 ./program : \
             $FLAGS_MPI_BATCH -n 19 -x OMP_NUM_THREADS=1 ./program
    

    这利用了 Open MPI 的能力来启动 MIMD 程序。

    您提到您的混合等级使用 POSIX 线程,但您正在设置与 OpenMP 相关的环境变量。如果您没有真正使用 OpenMP,则根本不必设置 OMP_NUM_THREADS,这个简单的 mpiexec 命令就足够了:

    $MPIEXEC $FLAGS_MPI_BATCH ./program
    

    (如果我对您学习或工作的教育机构的猜测有误,请删除$FLAGS_MPI_BATCH并将$MPIEXEC替换为mpiexec

    【讨论】:

    • 非常感谢!!!。那么这是否意味着最后一级的两个线程将在第二个计算节点上的任意两个可用内核上运行?如果没有关于这两个线程的额外信息,LSF 是否有可能将这两个线程调度在同一个 cpu 内核上?
    • LSF 通常调度到插槽,而不是核心。绑定(即限制进程调度到某些逻辑 CPU)通常由 MPI 实现或由 OpenMP 运行时完成(或混合程序由两者完成)。
    【解决方案2】:

    我使用 LSF 已经有一段时间了,所以这可能并不完全正确,所以你应该尝试一下。

    我阅读了您的要求

    #BSUB -n 20
    #BSUB -R "span[ptile=6]"
    

    as,一共 20 个任务,每个节点 6 个任务。这意味着您将获得 4 个节点。正如您所说,这似乎是一种浪费,每个节点都有 12 个核心。

    如何使用节点上的所有核心,因为您已请求独占主机 (-x)

    #BSUB -x
    #BSUB -n 20
    #BSUB -R "span[ptile=12]"
    
    export OMP_NUM_THREADS=2
    

    这样你就知道排名了

    • 0..11 在第一台主机上
    • 12..19 在第二台主机上

    第二台主机有备用插槽,以利用等级 19 的 OpenMP。

    当然,如果您要进入更有趣的职位,LSF 可以让您塑造职位。使用LSB_PJL_TASK_GEOMETRY

    假设您有 25 个 MPI 任务,使用 12 个内核,排名为 5

    #BSUB -x
    #BSUB -n 25
    #BSUB -R "span[ptile=12]"
    
    export LSB_PJL_TASK_GEOMETRY="{(0,1,2,3,4,6,7,8,9,10,11,12)\
                                   (13,14,15,16,17,18,19,20,21,22,23,24)\
                                   (5)}"
    

    这样,任务 5 就有了自己的节点。

    【讨论】:

    • 非常感谢。但是我还是不太明白#BSUB -n 的用法。它是用来保留给定数量的硬件计算槽还是用来指示并行进程的数量? #BSUB -n 是否区分线程和 MPI 进程?
    • @cpp_noname, -n 指定 slots 的数量。在您的情况下,每个计算节点提供 12 个插槽,这对应于节点上 CPU 内核的数量(但请注意,插槽不直接映射到内核)。每个作业都可以使用它认为合适的插槽。粗略地说,MPI 作业在每个槽中启动一个进程,而 OpenMP 作业在每个槽中启动一个线程。
    • @HristoIliev,假设我的程序使用 6 个 MPI 进程,每个进程有 3 个线程。所以我总共有 6x3=18 个并行线程。那么 n 应该是什么? #BSUB -n 6 或 #BSUB -n 18
    • -n 6 -R "span[ptile=4]" -x 为了获得 6 个插槽,每个节点有 4 个 MPI 进程并独占节点。这将导致以下分布:4x3+2x3(MPI 处理 x 线程)。请注意,这仅适用于 CPU 密集型线程。在 InfiniBand 集群上,Open MPI 为每个进程生成两个额外的线程。这两个不使用 CPU,因此可以与主线程共享一个内核,您不必为它们请求特殊的插槽。
    猜你喜欢
    • 2013-06-22
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 2018-10-27
    相关资源
    最近更新 更多