运行 使用并行工具在 PBS 中包含数百万个列表
Run million of list in PBS with parallel tool
我有一个巨大的(几百万)作业包含列表并且想要 运行 java 编写工具来执行功能比较。此工具在
内完成计算
real 0m0.179s
user 0m0.005s
sys 0m0.000s sec
运行 5 个节点(每个节点有 72 个 cpus)在 GNU 并行中使用 pbs 扭矩调度程序,工具 运行s 很好并产生结果但是当我设置 72 个作业时每个节点,一次应该 运行 72 x 5 个作业,但我只能看到 运行 25-35 个作业!
检查每个节点上的 cpu 利用率也显示利用率低。
我希望一次 运行 72 X 5 个工作或更多,并利用所有可用资源 (72 X 5 cpus) 产生结果。
正如我提到的,运行 有约 2 亿份工作,我希望以 using/increasing nodes/cpus 的数量更快地完成它(1-2 小时)。
当前代码、输入和作业状态:
example.lst(大约有 3 亿行)
ZNF512-xxxx_2_N-THRA-xxtx_2_N
ZNF512-xxxx_2_N-THRA-xxtx_3_N
ZNF512-xxxx_2_N-THRA-xxtx_4_N
.......
猫job_script.sh
#!/bin/bash
#PBS -l nodes=5:ppn=72
#PBS -N job01
#PBS -j oe
#work dir
export WDIR=/shared/data/work_dir
cd $WDIR;
# use available 72 cpu in each node
export JOBS_PER_NODE=72
#gnu parallel command
parallelrun="parallel -j $JOBS_PER_NODE --slf $PBS_NODEFILE --wd $WDIR --joblog process.log --resume"
$parallelrun -a example.lst sh run_script.sh {}
猫run_script.sh
#!/bin/bash
# parallel command options
i=
data=/shared/TF_data
# create tmp dir and work in
TMP_DIR=/shared/data/work_dir/$i
mkdir -p $TMP_DIR
cd $TMP_DIR/
# get file name
mk=$(echo "$i" | cut -d- -f1-2)
nk=$(echo "$i" | cut -d- -f3-6)
#run a tool to compare the features of pair files
/shared/software/tool_v2.1/tool -s1 $data/inf_tf/$mk -s1cf $data/features/$mk-cf -s1ss $data/features/$mk-ss -s2 $data/inf_tf/$nk.pdb -s2cf $data/features/$nk-cf.pdb -s2ss $data/features/$nk-ss.pdb > $data/$i.out
# move output files
mv matrix.txt $data/glosa_tf/matrix/$mk"_"$nk.txt
mv ali_struct.pdb $data/glosa_tf/aligned/$nk"_"$mk.pdb
# move back and remove tmp dir
cd $TMP_DIR/../
rm -rf $TMP_DIR
exit 0
PBS 投稿
qsub job_script.sh
登录到其中一个节点:ssh ip-172-31-9-208
top - 09:28:03 up 15 min, 1 user, load average: 14.77, 13.44, 8.08
Tasks: 928 total, 1 running, 434 sleeping, 0 stopped, 166 zombie
Cpu(s): 0.1%us, 0.1%sy, 0.0%ni, 98.4%id, 1.4%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 193694612k total, 1811200k used, 191883412k free, 94680k buffers
Swap: 0k total, 0k used, 0k free, 707960k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
15348 ec2-user 20 0 16028 2820 1820 R 0.3 0.0 0:00.10 top
15621 ec2-user 20 0 169m 7584 6684 S 0.3 0.0 0:00.01 ssh
15625 ec2-user 20 0 171m 7472 6552 S 0.3 0.0 0:00.01 ssh
15626 ec2-user 20 0 126m 3924 3492 S 0.3 0.0 0:00.01 perl
.....
顶部的所有节点都显示相似的状态,并通过 运行一次仅生成 ~26 个结果!
我的 aws-parallelcluster 包含 5 个节点(每个节点有 72 个 cpus),带有扭矩调度程序和 GNU Parallel 2018,2018 年 3 月
更新
通过引入在 stdin 上接受输入的新函数,运行并行运行脚本效果很好,并利用了本地机器中的所有 CPU。
然而,当它在远程机器上的 运行s 时,它会产生一个
parallel: Error: test.lst is neither a file nor a block device
MCVE:
一个简单的代码,回显列表在 运行 在远程机器上运行它时给出相同的错误,但在本地机器上运行良好:
cat test.lst # 包含列表
DNMT3L-5yx2B_1_N-DNMT3L-5yx2B_2_N
DNMT3L-5yx2B_1_N-DNMT3L-6brrC_3_N
DNMT3L-5yx2B_1_N-DNMT3L-6f57B_2_N
DNMT3L-5yx2B_1_N-DNMT3L-6f57C_2_N
DNMT3L-5yx2B_1_N-DUX4-6e8cA_4_N
DNMT3L-5yx2B_1_N-E2F8-4yo2A_3_P
DNMT3L-5yx2B_1_N-E2F8-4yo2A_6_N
DNMT3L-5yx2B_1_N-EBF3-3n50A_2_N
DNMT3L-5yx2B_1_N-ELK4-1k6oA_3_N
DNMT3L-5yx2B_1_N-EPAS1-1p97A_1_N
cat test_job.sh # GNU 并行提交脚本
#!/bin/bash
#PBS -l nodes=1:ppn=72
#PBS -N test
#PBS -k oe
# introduce new function and Run from ~/
dowork() {
parallel sh test_work.sh {}
}
export -f dowork
parallel -a test.lst --env dowork --pipepart --slf $PBS_NODEFILE --block -10 dowork
cat test_work.sh # run/work 脚本
#!/bin/bash
i=
data=pwd
#create temporary folder in current dir
TMP_DIR=$data/$i
mkdir -p $TMP_DIR
cd $TMP_DIR/
# split list
mk=$(echo "$i" | cut -d- -f1-2)
nk=$(echo "$i" | cut -d- -f3-6)
# echo list and save in echo_test.out
echo $mk, $nk >> $data/echo_test.out
cd $TMP_DIR/../
rm -rf $TMP_DIR
我不确定 tool
是做什么的。但是,如果复制花费了大部分时间,并且 tool
仅读取文件,那么您可以将文件符号链接到 $TMP_DIR
而不是复制。
您是否可以更快地完成它的一个很好的指示是查看集群中 5 台机器中的 top
。如果他们都以 >90% 的速度使用所有内核,那么您不能指望它会更快。
根据你的时间:
real 0m0.179s
user 0m0.005s
sys 0m0.000s sec
似乎该工具只使用很少的 CPU 功能。当 GNU Parallel 运行 本地作业时,每个作业的开销为 10 毫秒 CPU 时间。您的作业使用 179 毫秒和 5 毫秒 CPU 时间。因此 GNU Parallel 将使用相当多的时间。
远程 运行 宁作业时,开销要大得多。这里我们说的是 10 毫秒 + 运行 宁一个 ssh 命令。这很容易达到 100 毫秒的数量级。
那么我们如何才能最大限度地减少 ssh 命令的数量以及如何将开销分散到多个内核上?
首先让我们创建一个函数,可以在 stdin 和 运行 脚本上获取输入 - 每个 CPU 并行线程一个作业:
dowork() {
[...set variables here. that becomes particularly important we when run remotely...]
parallel sh run_script.sh {}
}
export -f dowork
通过 运行ning 测试这是否有效:
head -n 1000 example.lst | dowork
然后让我们看看 运行本地的工作。这可以像这里描述的那样完成:https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Running-more-than-250-jobs-workaround
parallel -a example.lst --pipepart --block -10 dowork
这会将 example.lst
拆分为每个 CPU 线程的 10 个块。因此,在具有 72 CPU 个线程的机器上,这将生成 720 个块。它将开始 72 doworks
,当完成一个时,它将获得 720 个块中的另一个。我选择 10 而不是 1 的原因是如果其中一份工作 "get stuck" 有一段时间,那么你不太可能注意到这一点。
这应该确保本地计算机上 100% 的 CPU 处于忙碌状态。
如果可行,我们需要将这项工作分配给远程机器:
parallel -j1 -a example.lst --env dowork --pipepart --slf $PBS_NODEFILE --block -10 dowork
每个 CPU 线程总共应该启动 10 ssh
(即 5*72*10)- 即每个块一个。每个服务器 1 运行ning 在 $PBS_NODEFILE
中并行列出。
不幸的是,这意味着 --joblog
和 --resume
将不起作用。目前没有办法使这项工作,但如果它对你有价值,请通过 parallel@gnu.org.
与我联系
我有一个巨大的(几百万)作业包含列表并且想要 运行 java 编写工具来执行功能比较。此工具在
内完成计算real 0m0.179s
user 0m0.005s
sys 0m0.000s sec
运行 5 个节点(每个节点有 72 个 cpus)在 GNU 并行中使用 pbs 扭矩调度程序,工具 运行s 很好并产生结果但是当我设置 72 个作业时每个节点,一次应该 运行 72 x 5 个作业,但我只能看到 运行 25-35 个作业! 检查每个节点上的 cpu 利用率也显示利用率低。
我希望一次 运行 72 X 5 个工作或更多,并利用所有可用资源 (72 X 5 cpus) 产生结果。
正如我提到的,运行 有约 2 亿份工作,我希望以 using/increasing nodes/cpus 的数量更快地完成它(1-2 小时)。
当前代码、输入和作业状态:
example.lst(大约有 3 亿行)
ZNF512-xxxx_2_N-THRA-xxtx_2_N
ZNF512-xxxx_2_N-THRA-xxtx_3_N
ZNF512-xxxx_2_N-THRA-xxtx_4_N
.......
猫job_script.sh
#!/bin/bash
#PBS -l nodes=5:ppn=72
#PBS -N job01
#PBS -j oe
#work dir
export WDIR=/shared/data/work_dir
cd $WDIR;
# use available 72 cpu in each node
export JOBS_PER_NODE=72
#gnu parallel command
parallelrun="parallel -j $JOBS_PER_NODE --slf $PBS_NODEFILE --wd $WDIR --joblog process.log --resume"
$parallelrun -a example.lst sh run_script.sh {}
猫run_script.sh
#!/bin/bash
# parallel command options
i=
data=/shared/TF_data
# create tmp dir and work in
TMP_DIR=/shared/data/work_dir/$i
mkdir -p $TMP_DIR
cd $TMP_DIR/
# get file name
mk=$(echo "$i" | cut -d- -f1-2)
nk=$(echo "$i" | cut -d- -f3-6)
#run a tool to compare the features of pair files
/shared/software/tool_v2.1/tool -s1 $data/inf_tf/$mk -s1cf $data/features/$mk-cf -s1ss $data/features/$mk-ss -s2 $data/inf_tf/$nk.pdb -s2cf $data/features/$nk-cf.pdb -s2ss $data/features/$nk-ss.pdb > $data/$i.out
# move output files
mv matrix.txt $data/glosa_tf/matrix/$mk"_"$nk.txt
mv ali_struct.pdb $data/glosa_tf/aligned/$nk"_"$mk.pdb
# move back and remove tmp dir
cd $TMP_DIR/../
rm -rf $TMP_DIR
exit 0
PBS 投稿
qsub job_script.sh
登录到其中一个节点:ssh ip-172-31-9-208
top - 09:28:03 up 15 min, 1 user, load average: 14.77, 13.44, 8.08
Tasks: 928 total, 1 running, 434 sleeping, 0 stopped, 166 zombie
Cpu(s): 0.1%us, 0.1%sy, 0.0%ni, 98.4%id, 1.4%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 193694612k total, 1811200k used, 191883412k free, 94680k buffers
Swap: 0k total, 0k used, 0k free, 707960k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
15348 ec2-user 20 0 16028 2820 1820 R 0.3 0.0 0:00.10 top
15621 ec2-user 20 0 169m 7584 6684 S 0.3 0.0 0:00.01 ssh
15625 ec2-user 20 0 171m 7472 6552 S 0.3 0.0 0:00.01 ssh
15626 ec2-user 20 0 126m 3924 3492 S 0.3 0.0 0:00.01 perl
.....
顶部的所有节点都显示相似的状态,并通过 运行一次仅生成 ~26 个结果!
我的 aws-parallelcluster 包含 5 个节点(每个节点有 72 个 cpus),带有扭矩调度程序和 GNU Parallel 2018,2018 年 3 月
更新
通过引入在 stdin 上接受输入的新函数,运行并行运行脚本效果很好,并利用了本地机器中的所有 CPU。
然而,当它在远程机器上的 运行s 时,它会产生一个
parallel: Error: test.lst is neither a file nor a block device
MCVE:
一个简单的代码,回显列表在 运行 在远程机器上运行它时给出相同的错误,但在本地机器上运行良好:
cat test.lst # 包含列表
DNMT3L-5yx2B_1_N-DNMT3L-5yx2B_2_N
DNMT3L-5yx2B_1_N-DNMT3L-6brrC_3_N
DNMT3L-5yx2B_1_N-DNMT3L-6f57B_2_N
DNMT3L-5yx2B_1_N-DNMT3L-6f57C_2_N
DNMT3L-5yx2B_1_N-DUX4-6e8cA_4_N
DNMT3L-5yx2B_1_N-E2F8-4yo2A_3_P
DNMT3L-5yx2B_1_N-E2F8-4yo2A_6_N
DNMT3L-5yx2B_1_N-EBF3-3n50A_2_N
DNMT3L-5yx2B_1_N-ELK4-1k6oA_3_N
DNMT3L-5yx2B_1_N-EPAS1-1p97A_1_N
cat test_job.sh # GNU 并行提交脚本
#!/bin/bash
#PBS -l nodes=1:ppn=72
#PBS -N test
#PBS -k oe
# introduce new function and Run from ~/
dowork() {
parallel sh test_work.sh {}
}
export -f dowork
parallel -a test.lst --env dowork --pipepart --slf $PBS_NODEFILE --block -10 dowork
cat test_work.sh # run/work 脚本
#!/bin/bash
i=
data=pwd
#create temporary folder in current dir
TMP_DIR=$data/$i
mkdir -p $TMP_DIR
cd $TMP_DIR/
# split list
mk=$(echo "$i" | cut -d- -f1-2)
nk=$(echo "$i" | cut -d- -f3-6)
# echo list and save in echo_test.out
echo $mk, $nk >> $data/echo_test.out
cd $TMP_DIR/../
rm -rf $TMP_DIR
我不确定 tool
是做什么的。但是,如果复制花费了大部分时间,并且 tool
仅读取文件,那么您可以将文件符号链接到 $TMP_DIR
而不是复制。
您是否可以更快地完成它的一个很好的指示是查看集群中 5 台机器中的 top
。如果他们都以 >90% 的速度使用所有内核,那么您不能指望它会更快。
根据你的时间:
real 0m0.179s
user 0m0.005s
sys 0m0.000s sec
似乎该工具只使用很少的 CPU 功能。当 GNU Parallel 运行 本地作业时,每个作业的开销为 10 毫秒 CPU 时间。您的作业使用 179 毫秒和 5 毫秒 CPU 时间。因此 GNU Parallel 将使用相当多的时间。
远程 运行 宁作业时,开销要大得多。这里我们说的是 10 毫秒 + 运行 宁一个 ssh 命令。这很容易达到 100 毫秒的数量级。
那么我们如何才能最大限度地减少 ssh 命令的数量以及如何将开销分散到多个内核上?
首先让我们创建一个函数,可以在 stdin 和 运行 脚本上获取输入 - 每个 CPU 并行线程一个作业:
dowork() {
[...set variables here. that becomes particularly important we when run remotely...]
parallel sh run_script.sh {}
}
export -f dowork
通过 运行ning 测试这是否有效:
head -n 1000 example.lst | dowork
然后让我们看看 运行本地的工作。这可以像这里描述的那样完成:https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Running-more-than-250-jobs-workaround
parallel -a example.lst --pipepart --block -10 dowork
这会将 example.lst
拆分为每个 CPU 线程的 10 个块。因此,在具有 72 CPU 个线程的机器上,这将生成 720 个块。它将开始 72 doworks
,当完成一个时,它将获得 720 个块中的另一个。我选择 10 而不是 1 的原因是如果其中一份工作 "get stuck" 有一段时间,那么你不太可能注意到这一点。
这应该确保本地计算机上 100% 的 CPU 处于忙碌状态。
如果可行,我们需要将这项工作分配给远程机器:
parallel -j1 -a example.lst --env dowork --pipepart --slf $PBS_NODEFILE --block -10 dowork
每个 CPU 线程总共应该启动 10 ssh
(即 5*72*10)- 即每个块一个。每个服务器 1 运行ning 在 $PBS_NODEFILE
中并行列出。
不幸的是,这意味着 --joblog
和 --resume
将不起作用。目前没有办法使这项工作,但如果它对你有价值,请通过 parallel@gnu.org.