[英]Process group of files in parallel then compute in series using slurm
我需要转换特定目录中的每个文件,然后在使用Slurm的系统上将结果编译为单个计算。 每个单独文件上的工作大约需要其余集体计算时间。 因此,我希望各个转换同时发生。 因此,这是我需要做的:
main.sh
#!/bin/bash
#SBATCH --account=millironx
#SBATCH --time=1-00:00:00
#SBATCH --ntasks=32
#SBATCH --cpus-per-task=4
find . -maxdepth 1 -name "*.input.txt" \
-exec ./convert-files.sh {} \;
./compile-results.sh *.output.txt
./compute.sh
echo "All Done!"
转换文件
#!/bin/bash
# Simulate a time-intensive process
INPUT=${1%}
OUTPUT="${$INPUT/input.txt/output.txt}"
sleep 10
date > $OUTPUT
在该系统正常运行的同时,我通常处理30多个文件的批处理,并且计算时间超出了管理员仅使用一个节点时设置的时间限制。 如何并行处理文件,然后在文件全部处理完毕后对其进行编译和计算?
find -exec
find . -maxdepth 1 -name "*.input.txt" \
-exec srun -n1 -N1 --exclusive ./convert-files.sh {} \;
find -exec
等待阻塞的进程 ,而srun在阻塞 ,因此这与时间上的基本代码完全相同。
find . -maxdepth 1 -name "*.input.txt" \
-exec sbatch ./convert-files.sh {} \;
这不会在开始计算之前等待转换完成,因此会失败。
find . -maxdepth 1 -name "*.input.txt" | \
parallel ./convert-files.sh
要么
find . -maxdepth 1 -name "*.input.txt" | \
parallel srun -n1 -N1 --exclusive ./convert-files.sh
并行只能“查看”当前节点上的CPU数量,因此它一次只能处理四个文件。 更好,但仍然不是我想要的。
这种方法听起来很有希望 ,但由于要处理的文件名称中没有序号,因此我无法找到一种使之起作用的方法。
在航站楼:
$ find . -maxdepth 1 -name "*.input.txt" \
> -exec sbatch --account=millironx --time=05:00:00 --cpus-per-task=4 \
> ./convert-files.sh {} \;
五小时后:
$ srun --account=millironx --time=30:00 --cpus-per-task=4 \
> ./compile-results.sh *.output.txt & \
> sbatch --account=millironx --time=05:00:00 --cpus-per-task=4 \
> ./compute.sh
到目前为止,这是我提出的最佳策略,但这意味着我必须记住检查转换批处理的进度,并在完成转换后立即开始计算。
在航站楼:
$ find . -maxdepth 1 -name "*.input.txt" \
> -exec sbatch --account=millironx --time=05:00:00 --cpus-per-task=4 \
> ./convert-files.sh {} \;
Submitted job xxxx01
Submitted job xxxx02
...
Submitted job xxxx45
$ sbatch --account=millironx --time=30:00 --cpus-per-task=4 \
> --dependency=after:xxxx45 --job-name=compile_results \
> ./compile-results.sh *.output.txt & \
> sbatch --account=millironx --time=05:00:00 --cpus-per-task=4 \
> --dependency=after:compile_results \
> ./compute.sh
我还不敢尝试,因为我知道最后的工作并不能保证最后完成。
似乎应该很容易做到,但是我还没有弄清楚。
如果您的$SLURM_NODELIST
包含类似于node1,node2,node34
,则可能可行:
find ... | parallel -S $SLURM_NODELIST convert_files
find . -maxdepth 1 -name "*.input.txt" | parallel srun -n1 -N1 --exclusive ./convert-files.sh
find . -maxdepth 1 -name "*.input.txt" | parallel srun -n1 -N1 --exclusive ./convert-files.sh
find . -maxdepth 1 -name "*.input.txt" | parallel srun -n1 -N1 --exclusive ./convert-files.sh
可能是遵循的方式。 但是似乎./convert-files.sh
希望将文件名作为参数,并且您正尝试通过管道将其推入stdin
。 您需要使用xargs
,并且由于xargs
可以并行工作,因此不需要parallel
命令。
尝试:
find . -maxdepth 1 -name "*.input.txt" | xargs -L1 -P$SLURM_NTASKS srun -n1 -N1 --exclusive ./convert-files.sh
-L1
将按行分割find
结果,并将其馈送到convert.sh
,一次生成最大$SLURM_NTASKS
进程,并通过srun -n1 -N1 --exclusive
将每个进程“发送”到Slurm分配的节点上的CPU中srun -n1 -N1 --exclusive
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.