HPC集群入门指南
先决条件
本教程页面需要先完成以下前置教程:
目标
在本教程结束时,您将完成Cromwell与HPC集群的对接配置。我们将以SGE为例进行说明,但这些步骤同样适用于LSF等其他调度系统。
让我们开始吧!
告知 Cromwell 后端类型
首先在backend部分定义您的新后端配置。目前,我们将您的后端命名为SGE,但您可以使用任何喜欢的名称。
backend {
providers {
SGE {
actor-factory = "cromwell.backend.impl.sfs.config.ConfigBackendLifecycleActorFactory"
config {
# to be filled in
}
}
}
}
上面的actor-factory告诉cromwell,你将使用config部分来告诉cromwell如何提交作业、中止作业等。
您可能还想通过设置以下配置值,将默认后端更改为您的新后端:
backend.default = SGE
为您的HPC任务指定运行时属性
在后端配置部分,您可以定义HPC任务将支持的不同运行时属性。此处配置的任何运行时属性都将从WDL任务中读取,然后传递到用于向HPC集群提交作业的命令行中。
所有运行时属性必须在一个多行代码块中定义。该代码块的语法与定义WDL任务的输入相同。
backend.providers.SGE.config {
runtime-attributes = """
Int cpu = 1
Float? memory_gb
String? sge_queue
String? sge_project
"""
}
在上面的示例中,我们定义了四个不同的WDL变量:cpu、memory_gb、sge_queue和sge_project。下面您将找到关于cpu和memory的更多信息,以及添加自定义运行时属性(如sge_queue和sge_project)的功能。
CPU
当你声明一个名为cpu的运行时属性时,它必须是一个Int类型。这个整数值会被验证确保始终>= 1。
backend.providers.SGE.config {
runtime-attributes = """
Int cpu = 1
# ...
"""
}
内存
运行工作流时,任务中的内存运行时属性将指定内存的单位。例如,此作业指定运行时仅需要512兆字节的内存。
task hello {
command { echo hello }
runtime { memory: "512 MB" }
}
然而,在向HPC集群提交作业时,您可能希望以GB为单位进行指定。
要指定提交命令应使用的内存单位,请将单位附加到内存运行时属性。例如:
backend.providers.SGE.config {
runtime-attributes = """
Float? memory_gb
# ...
"""
}
现在,无论任务中使用何种内存单位,该值都会在传递给您的提交命令之前转换为千兆字节。
自定义属性
您还可以声明WDL任务可能使用的其他运行时属性。例如,假设您希望允许WDL在任务中指定一个sge队列,如下所示:
task hello {
command { echo hello }
runtime { sqe_queue: "short" }
}
您可以在配置文件中声明运行时属性,只需将其他自定义值添加到runtime-attributes部分:
backend.providers.SGE.config {
runtime-attributes = """
String? sge_queue
# ...
"""
}
在这种情况下,我们声明sge_queue是可选的。这允许我们重用其他可能没有设置sge_queue的流程作者编写的WDL。
或者,您也可以为声明的运行时属性设置默认值。
backend.providers.SGE.config {
runtime-attributes = """
String sge_queue = "short"
# ...
"""
}
基于运行时属性的调用缓存
HPC后端调用缓存的规则如下:
* docker: 调用缓存时会被考虑。
* 内存选项:调用缓存时不会被考虑。
* CPU选项:调用缓存时不会被考虑。
* 自定义属性:默认情况下调用缓存时不会被考虑。
虽然默认情况下调用缓存时不会考虑自定义属性,但你可以在runtime-attributes-for-caching部分覆盖此设置。例如:
backend.providers.SGE.config {
runtime-attributes = """
String sge_queue = "short"
String singularity_image
# ...
"""
runtime-attributes-for-caching {
sge_queue: false
singularity_image: true
}
}
- 注意:只有自定义属性可以通过这种方式修改。内存、CPU和docker将始终保持其默认的缓存考虑行为。
- Note: Unlike memory, cpu and docker attributes which inherit validation and hash-lookup behavior, any custom attributes will be simple primitive comparisons.
- 例如,
docker属性会通过查询docker仓库中的哈希值进行缓存,而自定义的singularity属性则采用原始字符串匹配方式。
- 例如,
Cromwell如何启动HPC作业
当Cromwell运行任务时,它会使用声明的运行时属性填充作业模板。这个具体模板会根据您HPC集群的要求而变化。例如,假设您通常使用以下命令向SGE提交作业:
qsub -terse -V -b y -N my_job_name \
-wd /path/to/working_directory \
-o /path/to/stdout.qsub \
-e /path/to/stderr.qsub \
-pe smp 1 -l mem_free=0.5g -q short \
/usr/bin/env bash myScript.bash
对于这个特定的SGE集群,上述配置设置了工作目录、标准输出和错误输出路径,将CPU数量设为1,内存设为0.5GB,并在短队列中运行。
使用我们的运行时属性将其转换为模板需要像定义WDL任务command那样定义submit:
backend.providers.SGE.config {
submit = """
qsub \
-terse \
-V \
-b y \
-N ${job_name} \
-wd ${cwd} \
-o ${out}.qsub \
-e ${err}.qsub \
-pe smp ${cpu} \
${"-l mem_free=" + memory_gb + "g"} \
${"-q " + sge_queue} \
${"-P " + sge_project} \
/usr/bin/env bash ${script}
"""
}
当任务提交完成后,Cromwell需要获取作业ID,以便在必要时中止该作业。提交后,该作业ID应写入标准输出(stdout),Cromwell随后会读取这个ID。由于作业ID可能被其他文本包围,需要使用自定义正则表达式来捕获实际的作业ID。由于上述提交使用了-terse参数,作业ID将是标准输出的全部内容,但应该全由数字组成:
backend.providers.SGE.config {
job-id-regex = "(\\d+)"
}
Cromwell如何中止HPC作业
当中止HPC作业时,Cromwell将运行在kill键下配置的命令,并传入WDL变量job_id:
backend.providers.SGE.config {
kill = "qdel ${job_id}"
}
Cromwell如何检查HPC作业是否存活
每当Cromwell重启时,它会通过在一个名为rc的文件中搜索返回码来检查作业是否已完成。如果该文件不可用,在这种情况下Cromwell会运行额外检查以确保作业仍在运行。您可以通过以下方式配置用于此检查的命令:
backend.providers.SGE.config {
check-alive = "qstat -j ${job_id}"
}
其他后端设置
在某些系统中,管理员可能会限制用户同时运行的HPC作业数量。要配置此限制,您可以使用concurrent-job-limit值来限制作业数量。
backend.providers.SGE.config {
concurrent-job-limit = 100
}
整合配置部分
通过以上章节,我们可以将它们全部整合在一起,创建一个完全可用的HPC后端。
backend {
default = SGE
providers {
SGE {
actor-factory = "cromwell.backend.impl.sfs.config.ConfigBackendLifecycleActorFactory"
config {
concurrent-job-limit = 100
runtime-attributes = """
Int cpu = 1
Float? memory_gb
String? sge_queue
String? sge_project
"""
submit = """
qsub \
-terse \
-V \
-b y \
-N ${job_name} \
-wd ${cwd} \
-o ${out} \
-e ${err} \
-pe smp ${cpu} \
${"-l mem_free=" + memory_gb + "g"} \
${"-q " + sge_queue} \
${"-P " + sge_project} \
/usr/bin/env bash ${script}
"""
job-id-regex = "(\\d+)"
kill = "qdel ${job_id}"
check-alive = "qstat -j ${job_id}"
}
}
}
}
在配置文件中使用Cromwell运行此设置后,现在可以将作业提交到SGE!
后续步骤
你可能会对接下来要学习的以下教程感兴趣:
- 重启间数据持久化
- 服务器模式
- 如需配置Cromwell使用本地临时存储设备,请参阅此处的说明 HPCSlurmWithLocalScratch.md