我想向SGE提交一个多线程MPI作业,我运行的集群有不同的节点,每个节点都有不同数量的内核。假设每个进程的线程数是M(对于OpenMP,M==OMP_NUM_THREADS
)我如何请求提交到SGE队列的作业以这样的方式运行,即在每个节点中,为我的作业分配M的整数倍?
假设M=8,MPI任务的数量为5(因此总共请求了40个内核)。在这个集群中,有4个、8个、12个和16个核心节点。那么这个组合是可以的:
2*(8-core nodes) + 1*(16-core nodes) + 0.5*(16-core nodes)
但当然不是这些:
2*(4-core nodes) + 2*(8-core nodes) + 1*(16-core node)
2*(12-core nodes) + 1*(16-core node)
(3/8)*(8-core nodes) + (5/8)*(8-core nodes) + 2*(16-core node)
PS:还有另一个类似的问题,比如这个:(MPI&pthreads:具有不同核数的节点),但我的问题不同,因为我每个MPI进程必须运行M个线程(想想混合MPI+OpenMP)。
最好的方案是在相同类型的节点上独占运行此作业。但为了加快启动时间,我希望允许此作业在不同类型的节点上运行,前提是每个节点都有分配给该作业的整数*M个内核。
SGE中的分配策略是在每个并行环境(PE)的基础上指定的。每个PE可以被配置为以特定的方式填充集群节点上可用的插槽。一个请求具有-pe pe_name num_slots
参数的特定PE,然后SGE试图按照pe_name
PE的分配策略找到num_slots
插槽。不幸的是,没有简单的方法来请求每个节点整数倍的插槽。
为了能够为每个主机准确地请求M
个插槽(而不是M
的倍数),您的SGE管理员(或者您,如果您是SGE管理员)必须首先创建一个新的PE,称之为mpi8ppn
,将其allocation_rule
设置为8
,然后将PE分配给每个集群队列。然后,您必须使用-pe mpi8ppn 40
将作业提交给该PE,并指示MPI运行时每个主机仅启动一个进程,例如,使用-npernode 1
for Open MPI。
如果上述情况不太可能发生,那么您的另一个(不可靠的)解决方案将是每个插槽请求非常高的内存量,接近每个节点的内存量(例如-l h_vmem=23.5G
)。假设节点配置有24GiB的h_vmem
,则此请求将确保SGE无法在每个主机上容纳一个以上的插槽。因此,如果您想在5个节点上启动混合作业,只需向SGE请求5个插槽,并向每个插槽请求23.5G vmem
,其中:
qsub -pe whatever 5 -l h_vmem=23.5G <other args> jobscript
或
#$ -pe whatever 5
#$ -l h_vmem=23.5G
此方法不可靠,因为它不允许您选择具有特定核数的群集节点,并且只有在所有节点都配置了小于47 GB的h_vmem
时才有效。h_vmem
只是一个例子-任何其他每个插槽的可消耗属性都应该这样做。以下命令应该让您了解定义了哪些主机复合体,以及它们在集群节点上的值:
qhost -F | egrep '(^[^ ])|(hc:)'
该方法最适用于node_mem = k * #cores
和k
在所有节点上恒定的集群。如果一个节点提供两倍的核心数量,但内存也是两倍,例如48GiB,那么上述请求将在这些节点上为您提供两个插槽。
我并不声称完全理解SGE,我的知识可以追溯到SGE 6.2u5时代,所以现在可能存在更简单的解决方案。