Запустите миллион списка в PBS с помощью параллельного инструмента - PullRequest
1 голос
/ 29 сентября 2019

У меня огромный список заданий (несколько миллионов), и я хочу запустить написанный на Java инструмент для сравнения функций. Этот инструмент завершает вычисление в

real    0m0.179s
user    0m0.005s
sys 0m0.000s sec

Запуск 5 узлов (каждый имеет 72 процессора) с планировщиком крутящего момента pbs в параллельной GNU, инструмент работает нормально и выдает результаты, но, как я установил 72 задания для узла, ондолжен выполнять 72 x 5 заданий одновременно, но я вижу только 25-35 заданий! Проверка загрузки процессора на каждом узле также показывает низкую загрузку.

Я хочу запускать 72 X 5 или более заданий одновременно и получать результаты, используя весь доступный источник (72 X 5 процессоров).

Как я уже говорил, у меня есть ~ 200 миллионов заданий, которые я хочу выполнить, я хочу выполнить их быстрее (1-2 часа), используя / увеличивая количество узлов / процессоров.

Текущий код, ввод исостояние задания:

example.lst (в нем ~ 300 миллионов строк)

ZNF512-xxxx_2_N-THRA-xxtx_2_N
ZNF512-xxxx_2_N-THRA-xxtx_3_N
ZNF512-xxxx_2_N-THRA-xxtx_4_N
.......

cat 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 {}

cat run_script.sh

#!/bin/bash 
# parallel command options
i=$1
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-параллельный кластер содержит 5 узлов (каждый по 72 процессора) с планировщиком крутящего момента и GNU Parallel 2018, март 2018


Обновление

Вводя новую функцию, которая принимает ввод на стандартный ввод и запускаетПараллельный режим cript прекрасно работает и использует все ресурсы процессора на локальной машине.

Однако, когда он запускается на удаленных машинах, он выдает

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 script

#!/bin/bash 
i=$1
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

Ответы [ 2 ]

0 голосов
/ 03 октября 2019

По вашему времени:

real    0m0.179s
user    0m0.005s
sys 0m0.000s sec

кажется, что инструмент потребляет очень мало ресурсов процессора. Когда GNU Parallel запускает локальные задания, его загрузка ЦП составляет 10 мс на одно задание. Ваши задания используют 179 мс времени и 5 мс времени ЦП. Таким образом, GNU Parallel будет использовать довольно много времени.

Слишком большие издержки при удаленном выполнении заданий. Здесь мы говорим 10 мс + запуск команды ssh. Это может быть порядка 100 мс.

Итак, как мы можем минимизировать количество команд ssh и как распределить накладные расходы по нескольким ядрам?

Сначала давайте сделаем функцию, котораяможет принять входные данные в stdin и запустить скрипт - одно задание на каждый поток ЦП параллельно:

dowork() {
  [...set variables here. that becomes particularly important we when run remotely...]
  parallel sh run_script.sh {}
}
export -f dowork

Проверьте, что это действительно работает, запустив:

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 на 10 блоков на каждый поток ЦП. Таким образом, на машине с 72 потоками процессора это составит 720 блоков. Это будет начало 72 doworks, и когда один будет сделан, он получит другой из 720 блоков. Причина, по которой я выбираю 10 вместо 1, заключается в том, что если одно из заданий какое-то время «застревает», вы вряд ли это заметите.

Это должно обеспечить 100% процессоров на локальном компьютере. Занят.

Если это работает, нам нужно распространить эту работу на удаленные машины:

parallel -j1 -a example.lst --env dowork --pipepart --slf $PBS_NODEFILE --block -10 dowork

Это должно в общей сложности запустить 10 ssh на каждый поток ЦП (т.е. 5 * 72 * 10) - а именно по одному на каждый блок. Если 1 сервер запущен параллельно в $PBS_NODEFILE.

К сожалению, это означает, что --joblog и --resume не будут работать. В настоящее время нет способа заставить это работать, но если это будет полезно для вас, свяжитесь со мной по адресу parallel@gnu.org.

0 голосов
/ 30 сентября 2019

Я не уверен, что делает tool. Но если копирование занимает большую часть времени и если tool только читает файлы, то вы можете просто использовать символическую ссылку на файлы $TMP_DIR вместо копирования.

Хорошее указание на то, можете ли вы сделатьбыстрее взглянуть на top из 5 машин в кластере. Если все они используют все ядра на> 90%, то вы не можете ожидать, что получите его быстрее.

...