提交具有亲缘关系资源需求的作业
通过在 bsub -R 命令中指定 affinity [] 部分,向 lsb.queues 文件中定义的队列或向具有 RES_REQ 参数 (包含和 affinity [] 部分) 的应用程序概要文件提交作业以进行 CPU 和内存亲缘关系调度。
"affinity[core(1)]" 资源需求字符串添加到 bsub -R 命令中。亲缘关系 [] 资源需求字符串控制主机中的作业插槽和处理器单元分配和分发。
有关亲和力[]资源需求字符串的详细语法,请参阅亲和字符串。
如果在 lsb.params 文件中设置了 JOB_INCLUDE_POSTPROC=Y 参数,或者在作业环境中设置了 LSB_JOB_INCLUDE_POSTPROC=Y 环境变量,那么在执行后处理完成之前, LSF 不会释放亲缘关系资源,因为在执行后处理期间作业仍会占用插槽。 对于交互式作业,将在执行后完成之前完成交互式作业。
示例: 处理器单元分配请求
以下示例说明了请求特定处理器单元分配和任务分发的亲缘关系作业。
以下作业要求 6 个插槽并在单个主机中运行。 每个插槽映射到一个核心。 LSF 尝试在单个 NUMA 或套接字上尽可能近地打包 6 个核心。 如果无法满足任务分发,那么无法启动作业。
bsub -n 6 –R "span[hosts=1] affinity[core(1):distribute=pack]" myjob
以下作业要求 6 个插槽并在单个主机中运行。 每个插槽映射到一个核心,但在这种情况下,必须将其打包到单个套接字中,否则,作业将保持暂挂状态:
bsub -n 6 –R "span[hosts=1] affinity[core(1):distribute=pack(socket=1)]" myjob
以下作业要求在单个主机上提供两个插槽。 每个插槽映射到两个核心。 单个插槽 (任务) 的两个核心必须来自同一个套接字; 但是,第二个插槽 (任务) 的其他两个核心必须位于不同的套接字上:
bsub -n 2 –R "span[hosts=1] affinity[core(2, same=socket, exclusive=(socket, injob))]" myjob
以下作业指定作业中的每个任务都需要来自同一套接字的两个核心。 对于所有其他作业,分配的套接字将被标记为互斥。 该任务将被 CPU 绑定到套接字级别。 LSF 尝试分发作业的任务,以便在所有核心之间均衡这些任务:
bsub -n 4 -R "affinity[core(2, same=socket, exclusive=(socket, alljobs)): cpubind=socket:distribute=balance]" myjob
示例 :CPU 和内存绑定请求
您可以提交具有 CPU 各种绑定和内存绑定选项的亲缘关系作业。 以下示例对此进行了说明。
在以下作业中,这两个任务都需要同一 NUMA 节点中的 5 个核心,并使用内存强制绑定来绑定 NUMA 节点上的任务:
bsub -n 2 -R "affinity[core(5,same=numa):cpubind=numa:membind=localonly]" myjob
以下作业在单个 NUMA 节点上绑定多线程作业:
bsub -n 2 -R "affinity[core(3,same=numa):cpubind=numa:membind=localprefer]" myjob
以下作业跨套接字分发任务。 每个任务都需要来自同一套接字的两个核心,并在套接字级别绑定每个任务。 分配的套接字是互斥的,因此没有其他任务可以使用它:
bsub -n 2 -R "affinity[core(2,same=socket,exclusive=(socket,injob|alljobs)): cpubind=socket]" myjob
以下作业将作业任务打包在一个 NUMA 节点中:
bsub -n 2 -R "affinity[core(1,exclusive=(socket,injob)):distribute=pack(numa= 1)]" myjob
每个任务都需要一个核心,而同一作业中的任何其他任务都不会从同一套接字中分配 CPU。 LSF 尝试将同一作业中的所有任务打包到一个 NUMA 节点。
亲缘关系作业的作业执行环境
LSF 在每个作业和任务的执行环境中设置多个环境变量。 这些设计用于集成和使用 IBM Parallel Environment和 IBM Spectrum LSF MPI。 但是,这些环境变量可供所有亲缘关系作业使用,并且可能由其他应用程序使用。 由于 LSF 提供了 IBM Parallel Environment 和 LSF MPI所期望的变量,因此存在一些冗余: 以 RM_ 为前缀的环境变量是为了与 IBM Parallel Environment兼容而实现的,尽管 LSF MPI 也使用这些变量,而以 LSB_ 为前缀的环境变量仅由 LSF MPI使用。 这两种类型的变量提供了类似的信息,但格式不同。
- LSB_BIND_CPU_LIST
- LSB_BIND_MEM_LIST
- LSB_BIND_MEM_POLICY
- RM_CPUTASK n
- RM_MEM_AFFINITY
- OMP_NUM_THREADS
应用集成
对于 单主机应用程序 ,应用程序本身不需要执行任何操作,仅 OMP_NUM_THREADS 变量相关。
对于在 LSF 下运行的 多主机并行应用程序 LSF MPI 的第一个执行主机,将为每个任务选择 CPU 资源,启动 LSF MPI 代理程序 (mpid) 以将 mpid 绑定到所有已分配的 CPU 和内存策略。 设置了相应的环境变量,包括 RM_CPUTASKn。 LSF MPI 在每个主机上读取 RM_CPUTASKn ,并执行任务级别绑定。 LSF MPI 遵循 RM_CPUTASKn 设置,并将每个任务绑定到每个任务的所选 CPU 列表。 这是 LSF MPI 在 LSF 下运行时的缺省行为。
为支持 IBM Parallel Operating Environment 作业, LSF 会启动 PMD 程序,将 PMD 进程绑定到主机上已分配的 CPU 和内存节点,并设置 RM_CPUTASKn, RM_MEM_AFFINITY 和 OMP_NUM_THREADS。 然后, IBM Parallel Operating Environment 将对各个任务执行绑定。
Rank 0=Host1 slot=0,1,2,3
Rank 1=Host1 slot=4,5,6,7
Rank 2=Host2 slot=0,1,2,3
Rank 3=Host2 slot=4,5,6,7
Rank 4=Host3 slot=0,1,2,3
Rank 5=Host4 slot=0,1,2,3脚本 (openmpi_rankfile.sh) 位于 $LSF_BINDIR中。 在 lsb.applications 中的应用程序概要文件中使用 DJOB_ENV_SCRIPT 参数来配置脚本的路径。
对于缺省情况下直接使用 blaunch 来启动每个插槽 (而不是每个主机) 的任务或代理程序的 分布式应用程序 , LSF 会将该任务绑定到主机上所有已分配的 CPU 和内存节点。 即,在主机级别生成 CPU 和内存节点列表。 某些分布式应用程序可能需要逐个任务地生成绑定列表。 此行为可作为名为 LSB_DJOB_TASK_BIND=Y | N的环境变量在作业提交环境或应用程序概要文件中进行配置。 N 是缺省值。 设置此环境变量时,将根据每个任务生成绑定列表。
示例
Host[64.0G] HostN
NUMA[0: 0M / 32.0G] NUMA[1: 0M / 32.0G]
Socket0 Socket0
core0(0 22) core0(1 23)
core1(2 20) core1(3 21)
core2(4 18) core2(5 19)
core3(6 16) core3(7 17)
core4(8 14) core4(9 15)
core5(10 12) core5(11 13)
Socket1 Socket1
core0(24 46) core0(25 47)
core1(26 44) core1(27 45)
core2(28 42) core2(29 43)
core3(30 40) core3(31 41)
core4(32 38) core4(33 39)
core5(34 36) core5(35 37)- 具有亲缘关系需求的 bsub 命令行
- 结果作业的分配显示为如 bjobs 中所示
- 显示的分配与 bhosts 中的分配相同
- 分派作业后以上作业环境变量的值
bsub -R "affinity[core(1)]" 是要求使用单个核心的串行作业。
bjobs中显示的分配:... CPU BINDING MEMORY BINDING ------------------------ -------------------- HOST TYPE LEVEL EXCL IDS POL NUMA SIZE Host1 core - - /0/0/0 - - - ...在 bhosts 中 (假定主机上没有其他作业):... Host[64.0G] Host1 NUMA[0: 0M / 32.0G] NUMA[1: 0M / 32.0G] Socket0 Socket0 core0(*0 *22) core0(1 23) core1(2 20) core1(3 21) core2(4 18) core2(5 19) core3(6 16) core3(7 17) core4(8 14) core4(9 15) core5(10 12) core5(11 13) Socket1 Socket1 core0(24 46) core0(25 47) core1(26 44) core1(27 45) core2(28 42) core2(29 43) core3(30 40) core3(31 41) core4(32 38) core4(33 39) core5(34 36) core5(35 37) ...亲缘关系主机文件的内容:Host1 0,22作业环境变量:LSB_BIND_CPU_LIST=0,22 RM_CPUTASK1=0,22bsub -R "affinity[socket(1)]" 是要求提供整个套接字的串行作业。
bjobs中显示的分配:... CPU BINDING MEMORY BINDING ------------------------ -------------------- HOST TYPE LEVEL EXCL IDS POL NUMA SIZE Host1 socket - - /0/0 - - - ...在 bhosts 中 (假定主机上没有其他作业):... Host[64.0G] Host1 NUMA[0: 0M / 32.0G] NUMA[1: 0M / 32.0G] Socket0 Socket0 core0(*0 *22) core0(1 23) core1(*2 *20) core1(3 21) core2(*4 *18) core2(5 19) core3(*6 *16) core3(7 17) core4(*8 *14) core4(9 15) core5(*10 *12) core5(11 13) Socket1 Socket1 core0(24 46) core0(25 47) core1(26 44) core1(27 45) core2(28 42) core2(29 43) core3(30 40) core3(31 41) core4(32 38) core4(33 39) core5(34 36) core5(35 37) ...亲缘关系主机文件的内容:Host1 0,2,4,6,8,10,12,14,16,18,20,22作业环境变量:LSB_BIND_CPU_LIST=0,2,4,6,8,10,12,14,16,18,20,22 RM_CPUTASK1=0,2,4,6,8,10,12,14,16,18,20,22bsub -R “affinity[core(4):membind=localonly] rusage[mem=2048]” 是需要 4 个核心和 2 GB 内存的多线程单任务作业。
bjobs中显示的分配:... CPU BINDING MEMORY BINDING ------------------------ -------------------- HOST TYPE LEVEL EXCL IDS POL NUMA SIZE Host1 core - - /0/0/0 local 0 2.0GB /0/0/1 /0/0/2 /0/0/3 ...在 bhosts 中 (假定主机上没有其他作业):... Host[64.0G] Host1 NUMA[0: 2.0G / 32.0G] NUMA[1: 0M / 32.0G] Socket0 Socket0 core0(*0 *22) core0(1 23) core1(*2 *20) core1(3 21) core2(*4 *18) core2(5 19) core3(*6 *16) core3(7 17) core4(8 14) core4(9 15) core5(10 12) core5(11 13) Socket1 Socket1 core0(24 46) core0(25 47) core1(26 44) core1(27 45) core2(28 42) core2(29 43) core3(30 40) core3(31 41) core4(32 38) core4(33 39) core5(34 36) core5(35 37) ...亲缘关系主机文件的内容:Host1 0,2,4,6,16,18,20,22 0 1作业环境变量:LSB_BIND_CPU_LIST=0,2,4,6,16,18,20,22 LSB_BIND_MEM_LIST=0 LSB_BIND_MEM_POLICY=localonly RM_MEM_AFFINITY=yes RM_CPUTASK1=0,2,4,6,16,18,20,22 OMP_NUM_THREADS=4注: 现在存在 OMP_NUM_THREADS ,因为作业中唯一需要 4 个核心的任务。bsub -n 2 -R "affinity[core(2)] span[hosts=1]" 是一个多线程并行作业,用于请求 2 任务,其中 2 个核心在同一主机上运行。
bjobs中显示的分配:... CPU BINDING MEMORY BINDING ------------------------ -------------------- HOST TYPE LEVEL EXCL IDS POL NUMA SIZE Host1 core - - /0/0/0 - - - /0/0/1 Host1 core - - /0/0/2 - - - /0/0/3 ...在 bhosts 中 (假定主机上没有其他作业):... Host[64.0G] Host1 NUMA[0: 0M / 32.0G] NUMA[1: 0M / 32.0G] Socket0 Socket0 core0(*0 *22) core0(1 23) core1(*2 *20) core1(3 21) core2(*4 *18) core2(5 19) core3(*6 *16) core3(7 17) core4(8 14) core4(9 15) core5(10 12) core5(11 13) Socket1 Socket1 core0(24 46) core0(25 47) core1(26 44) core1(27 45) core2(28 42) core2(29 43) core3(30 40) core3(31 41) core4(32 38) core4(33 39) core5(34 36) core5(35 37) ...亲缘关系主机文件的内容:Host1 0,2,4,6 Host1 16,18,20,22为 两个任务中的每个任务设置的作业环境变量:LSB_BIND_CPU_LIST=0,2,4,6,16,18,20,22 RM_CPUTASK1=0,2,4,6 RM_CPUTASK2=16,18,20,22 OMP_NUM_THREADS=2注: 每个任务都看到 RM_CPU_TASK1 和 RM_CPU_TASK2 ,并且 LSB_BIND_CPU_LIST 是分配给此主机上的作业的所有 CPU 的组合列表。如果通过 blaunch 命令运行作业并设置 LSB_DJOB_TASK_BIND 参数,那么除了这两个任务的作业环境变量对于每个任务都不同外,所有内容都相同:- 任务 1:
LSB_BIND_CPU_LIST=0,2,20,22 RM_CPUTASK1=0,2,20,22 OMP_NUM_THREADS=2 - 任务 2:
LSB_BIND_CPU_LIST=4,6,16,18 RM_CPUTASK1=4,6,16,18 OMP_NUM_THREADS=2
- 任务 1:
bsub -n 2 -R "affinity[core(2)] span[ptile=1]" 是一个多线程并行作业,用于请求 2 任务,其中 2 个核心在不同的主机上运行。 这几乎与上一个示例相同,只是分配在两个主机上。
bjobs中显示的分配:... CPU BINDING MEMORY BINDING ------------------------ -------------------- HOST TYPE LEVEL EXCL IDS POL NUMA SIZE Host1 core - - /0/0/0 - - - /0/0/1 Host2 core - - /0/0/0 - - - /0/0/1 ...在 bhosts (假定主机上没有其他作业) 中,将按以下方式分配每个 Host1 和 Host2 :... Host[64.0G] Host{1,2} NUMA[0: 0M / 32.0G] NUMA[1: 0M / 32.0G] Socket0 Socket0 core0(*0 *22) core0(1 23) core1(*2 *20) core1(3 21) core2(4 18) core2(5 19) core3(6 16) core3(7 17) core4(8 14) core4(9 15) core5(10 12) core5(11 13) Socket1 Socket1 core0(24 46) core0(25 47) core1(26 44) core1(27 45) core2(28 42) core2(29 43) core3(30 40) core3(31 41) core4(32 38) core4(33 39) core5(34 36) core5(35 37) ...亲缘关系主机文件的内容:Host1 0,2,20,22 Host2 0,2,20,22为两个任务中的每个任务设置的作业环境变量:LSB_BIND_CPU_LIST=0,2,20,22 RM_CPUTASK1=0,2,20,22 OMP_NUM_THREADS=2注: 每个任务只能看到 RM_CPU_TASK1。 这与 LSB_BIND_CPU_LIST 相同,因为每个主机上仅运行一个任务。 在这种情况下,设置 DJOB_TASK_BIND=Y 将不起作用。bsub -R "affinity[core(1,exclusive=(socket,alljobs))]" 是一个单线程串行作业的示例,该作业要求提供它希望在所有作业中独占使用套接字的核心。 将此与以上仅要求核心或套接字的作业的示例 (1) 和 (2) 进行比较。
bjobs 中显示的分配与要求核心 (EXCL 列除外) 的作业相同:... CPU BINDING MEMORY BINDING ------------------------ -------------------- HOST TYPE LEVEL EXCL IDS POL NUMA SIZE Host1 core - socket /0/0/0 - - - ...但是,在 bhosts中,分配与要求套接字的作业相同,因为它需要保留所有套接字:... Host[64.0G] Host1 NUMA[0: 0M / 32.0G] NUMA[1: 0M / 32.0G] Socket0 Socket0 core0(*0 *22) core0(1 23) core1(*2 *20) core1(3 21) core2(*4 *18) core2(5 19) core3(*6 *16) core3(7 17) core4(*8 *14) core4(9 15) core5(*10 *12) core5(11 13) Socket1 Socket1 core0(24 46) core0(25 47) core1(26 44) core1(27 45) core2(28 42) core2(29 43) core3(30 40) core3(31 41) core4(32 38) core4(33 39) core5(34 36) core5(35 37) ...但是,亲缘关系主机文件显示作业仅在运行时绑定到分配的核心Host1 0,22这也体现在作业环境中:LSB_BIND_CPU_LIST=0,22 RM_CPUTASK1=0,22从其他作业可用的内容 (即,针对主机计数的分配) 的角度来看,该作业已使用了整个套接字。 但是,在所有其他方面,作业仅与单个核心绑定。
bsub -R "affinity[core(1):cpubind=socket]" 要求核心,但要求在套接字级别完成绑定。 将此与先前的情况进行对比,即核心希望独占使用套接字。
同样, bjobs 分配与示例 (1) 相同,但这次 LEVEL 列不同:... CPU BINDING MEMORY BINDING ------------------------ -------------------- HOST TYPE LEVEL EXCL IDS POL NUMA SIZE Host1 core socket - /0/0/0 - - - ...在 bhosts中,作业只占用单个核心,而不是像独占作业一样占用整个套接字:... Host[64.0G] Host1 NUMA[0: 0M / 32.0G] NUMA[1: 0M / 32.0G] Socket0 Socket0 core0(*0 *22) core0(1 23) core1(2 20) core1(3 21) core2(4 18) core2(5 19) core3(6 16) core3(7 17) core4(8 14) core4(9 15) core5(10 12) core5(11 13) Socket1 Socket1 core0(24 46) core0(25 47) core1(26 44) core1(27 45) core2(28 42) core2(29 43) core3(30 40) core3(31 41) core4(32 38) core4(33 39) core5(34 36) core5(35 37) ...但是,来自执行端的视图有很大不同: 从这里开始,在主机上填充作业的绑定列表的 CPU 列表是整个套接字。
亲缘关系主机文件的内容:Host1 0,2,4,6,8,10,12,14,16,18,20,22作业环境:LSB_BIND_CPU_LIST=0,2,4,6,8,10,12,14,16,18,20,22 RM_CPUTASK1=0,2,4,6,8,10,12,14,16,18,20,22与上一个示例相比,从其他作业可用的内容 (即针对主机计数的分配) 的角度来看,该作业使用了单个核心。 但是,就绑定列表而言,作业进程在运行时可以自由使用套接字中的任何 CPU。