Slurm作业数组提交失败 运行Rscript处理shapefile问题排查
问题背景
- 计划在HPC集群通过Slurm提交作业数组,完成单圆形shapefile与人口普查区块大shapefile的相交计算,单任务计算完成后保存独立的相交结果shapefile,最后在本地机器上将所有单个结果合并为完整大文件,以此规避之前碰到的sf空间对象并行计算时的mapply报错问题。
- 提交作业数组时直接返回报错:
sbatch: error: Batch job submission failed: Invalid job array specification - 本次使用的R脚本、Slurm提交脚本、文件名映射csv文件已同步在代码仓库,可复现示例仅保留最小测试数据集。
任务依赖文件说明
作业运行共依赖三类文件:
- buffer文件:圆形多边形文件。原包含3086个圆形的大shapefile已拆分为3086个仅含单个圆形的独立shapefile,存储在/lustre路径下的
lihtc_bites文件夹中。R脚本每次运行时读取1个圆形与人口普查区块做相交计算,输出结果shapefile,最终3086份结果将在本地笔记本上合并为统一dataframe。可复现示例中仅提供2个示例圆形shapefile。 - lihtc文件:R函数中作为索引使用的shapefile,共3个版本,每个圆形shapefile对应其中一个lihtc文件。可复现示例中仅提供与2个示例圆形匹配的1个lihtc shapefile。
- blocks文件:包含71万条人口普查区块记录的shapefile,所有圆形相交计算任务运行时该文件固定不变。可复现示例中仅提供旧金山县范围内的7386个区块shapefile。
当前排查进展
- 已针对单个buffer、单个lihtc shapefile完成R脚本测试,单任务运行逻辑完全正常,因此初步判断问题出在Slurm作业数组启动脚本
lihtc_array_example.sh上。 - 设计的任务传参逻辑:通过Slurm数组任务ID匹配
master_example.csv(可复现示例已提供)中对应行的文件名,指定R脚本每次需要加载的文件,例如ID为1的任务加载csv第1行列出的buffer和lihtc文件。参考的文件名提取shell命令如下:
shp_filename=$( echo "$line_N" | cut -d "," -f 2 ) lihtc_filename=$( echo "$line_N" | cut -d "," -f 3 )
- 目前需要排查.sh提交脚本、文件名映射csv、R脚本三者的衔接流程是否存在明显问题,可根据排查需要补充其他信息。
现有Slurm提交脚本完整内容
#SBATCH -t 2:00:00 #SBATCH -p defq #SBATCH -N 1 #SBATCH -o jobArrayScript_%A_%a.out #SBATCH -e jobArrayScript_%A_%a.err #SBATCH -a 1-3086%1000 line_N=$( awk "NR==$SLURM_ARRAY_TASK_ID" master_example.csv ) # NR为Awk语法中的行号标识 shp_filename=$( echo "$line_N" | cut -d "," -f 2 ) lihtc_filename=$( echo "$line_N" | cut -d "," -f 3 ) module load R/4.1.1 module load libudunits2/2.2.28 module load gdal/3.5.0 module load proj/6.3.0 module load geos/3.10.3 Rscript slurm_job_array.R $shp_filename $lihtc_filename
本地R环境参考信息
> sessionInfo() R version 4.1.0 (2021-05-18) Platform: x86_64-apple-darwin17.0 (64-bit) Running under: macOS Catalina 10.15.7 Matrix products: default BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib locale: [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8 attached base packages: [1] parallel stats graphics grDevices utils datasets methods base other attached packages: [1] dplyr_1.0.9 ggmap_3.0.0 ggplot2_3.3.6 sf_1.0-7 loaded via a namespace (and not attached): [1] xfun0.28 tidyselect_1.1.2 purrr_0.3.4 lattice_0.20-45 colorspace_2.0-3 vctrs_0.4.1 generics_0.1.2 [8] htmltools_0.5.2 s2_1.0.7 utf8_1.2.2 rlang_1.0.2 e1071_1.7-9 pillar_1.7.0 glue_1.6.2 [15] withr_2.5.0 DBI_1.1.1 sp_1.4-6 wk_0.5.0 jpeg_0.1-9 lifecycle_1.0.1 plyr_1.8.7 [22] stringr_1.4.0 munsell_0.5.0 gtable_0.3.0 RgoogleMaps_1.4.5.3 evaluate_0.15 knitr_1.36 fastmap_1.1.0 [29] curl_4.3.2 class_7.3-19 fansi_1.0.3 highr_0.9 Rcpp_1.0.8.3 KernSmooth_2.23-20 scales_1.2.0 [36] classInt_0.4-3 farver_2.1.0 rjson_0.2.20 png_0.1-7 digest_0.6.29 stringi_1.7.6 grid_4.1.0 [43] cli_3.3.0 tools_4.1.0 bitops_1.0-7 magrittr_2.0.3 proxy_0.4-26 tibble_3.1.7 crayon_1.5.1 [50] tidyr_1.2.0 pkgconfig_2.0.3 ellipsis_0.3.2 assertthat_0.2.1 rmarkdown_2.11 httr_1.4.2 rstudioapi_0.13 [57] R6_2.5.1 units_0.7-2 compiler_4.1.0
问题排查结果与修复方案
该报错为提交脚本的基础配置问题,和R逻辑、csv映射逻辑无关,核心问题点及修复方式如下:
- 脚本缺少shebang解释器声明
Slurm提交脚本第一行必须指定运行解释器,当前脚本直接以#SBATCH开头,部分版本的sbatch无法正确识别后续的#SBATCH参数,会将数组参数判定为无效输入。在脚本最顶部添加一行即可:
#!/bin/bash
- 作业数组范围超出集群配置上限
配置项#SBATCH -a 1-3086%1000中,%1000的作用是限制同时运行的任务数为1000,但绝大多数HPC集群默认配置的MaxArraySize(作业数组最大索引上限)为1000,即数组任务ID最大不能超过1000,当前设置的数组范围到3086,会直接触发参数无效报错。
可以先在集群执行scontrol show config | grep MaxArraySize确认上限值:
- 如果上限确实为1000,可联系集群管理员调整MaxArraySize参数到3086以上
- 不想改集群配置的话,可将3086个任务拆分为4个独立作业数组提交,范围分别为1-1000、1001-2000、2001-3000、3001-3086,每个数组的并发数按需设置即可
- 相对路径存在文件找不到的风险
脚本中读取master_example.csv、调用slurm_job_array.R使用的是相对路径,作业提交后Slurm会将工作目录设置为执行sbatch命令时所在的目录,如果提交命令时不在脚本和csv存放路径,会出现文件不存在的错误。建议在#SBATCH参数块中添加一行指定工作目录,替换为实际的脚本存放绝对路径:
#SBATCH -D /lustre/your/project/path/
- 文件名传参存在边界兼容问题
使用cut按逗号分割csv提取文件名的写法,如果csv是Windows格式带\r换行符、或者文件名包含空格,会导致传参错误。建议将读取csv提取参数的逻辑替换为更稳妥的写法,自动跳过表头、处理特殊换行符:
# 跳过csv第一行表头,取对应任务ID行的第2、3列,自动清除Windows格式换行符 line_N=$( awk -v nid="$SLURM_ARRAY_TASK_ID" 'NR==nid+1{gsub(/\r/,"");print $0}' master_example.csv ) shp_filename=$( echo "$line_N" | cut -d "," -f 2 ) lihtc_filename=$( echo "$line_N" | cut -d "," -f 3 )
修复完成后,可先用测试数组范围提交验证,比如临时设置#SBATCH -a 1-2%2(对应可复现示例里的2个测试文件,同时跑2个任务),确认单任务逻辑正常、输出结果正确后,再提交全量3086个任务即可。
内容的提问来源于stack exchange,提问作者mhankinson
相关产品推荐
相关产品推荐

