如何让优先级更高的 Slurm 作业通过,同时不在任务之间共享单独的 CPU?

问题描述 投票:0回答:1

我的 IT 部门善意地为我设置了一个带有 Slurm 的 Linux 虚拟机,我正在学习命令。我稍微改变了数字,但假设有 2 个节点,每个节点有 5 个核心/CPU(我认为它们在这里是相同的?)。我想运行一个函数 6 次独立迭代,每次迭代 3 个子任务。前 2 个子任务 (a, b) 可以并行运行,但最后一个 (c) 需要前 2 个子任务完成。为简单起见,我们可以说每个子任务需要 1 分钟。

我们还可以说我开始设置 A 并进行迭代 1-6。但后来我意识到我想以更高的优先级运行集合 B 迭代 7-14,并立即开始下一步。在这种情况下,我希望在第 1 分钟内完成集合 A 中 5 次迭代的子任务 a 和 b。对于第 2 分钟,我希望在集合 B 中完成 5 次迭代的子任务 a 和 b。第 3 分钟我希望完成 B 的最后 8 个子任务以及 A 中的 2 个子任务。第 4 分钟将是 A 的最后 6 个子任务。

这可能吗?我该怎么办?

下面是

A MWE,但是当我运行 top 命令时,刚开始

A
,我看到某些进程的 CPU 使用率为 100%,而其他进程则为 50%。对于 50% 的进程,总运行数量多于核心数量。我希望脚本完成任务并等待 CPU 空闲后再开始下一个任务,因为我认为这样可以更快地完成迭代。但在此示例中,即使在 50% 的情况下,运行时间也始终为 2 分钟,这可能是由于
stress
命令的性质所致?由于某种原因,所有迭代也同时开始和结束。

我运行的命令

./test_main.sh

test_main.sh

的内容
#!/bin/bash

rm -rf 'out'
mkdir -p 'out/'

for i1 in {1..6}; do #Changed to 7..14 for B
 printf -v i_str "%03d" $i1 #add zero-padding
 sbatch ./test_sub.sh "$i_str"
done

以下

test_sub.sh
的内容。我尝试过使用
--hint=nomultithread
--cpus-per-task=1
--ntasks-per-node=5
。在
srun
命令中,我尝试过使用和不使用
--exclusive

#!/bin/bash
#
#SBATCH --job-name setA   ## name that will show up in the queue. Change for set B
#SBATCH --output slurm-%j.out   ## filename of the output; the %j is equal to jobID
#SBATCH --nodes=2              ## Number of nodes
#SBATCH --oversubscribe    ## Letting multiple jobs run concurrently
#SBATCH --partition=mypartition     ## the partitions to run in (comma separated). 
#SBATCH --nice=10000  ## Change to a smaller value for set B

in_dir=$1

run_s="$SECONDS" #start a timer

work_dir=$PWD
mkdir -p 'out/'$in_dir
cd 'out/'$in_dir

# Save some tracking info
hostname > example.out #always the name of the primary node. Not important to my task though
echo '('`date`')' >> example.out

srun -N1 -n1 --exclusive "$work_dir"/test_sub2.sh 'alpha' &
srun -N1 -n1 --exclusive "$work_dir"/test_sub2.sh 'beta' &
wait #wait for subprocess alpha and beta to finish

echo '('`date`')' >> example.out

# Can now run gamma
srun -N1 -n1 --exclusive "$work_dir"/test_sub2.sh 'gamma' &
wait

# Save additional tracking info after gamma finishes
echo '('`date`')' >> example.out
loop_rt=$( echo " scale = 2; ( "$SECONDS"- "run_s" ) / 60 " | bc )
echo "$loop_rt" >> example.out  #Runtime

内容

test_sub2.sh

#!/bin/bash

greekLtr=$1

hostname > "$greekLtr".out
echo '('`date`')' >> "$greekLtr".out

stress --cpu 1 --timeout 60

echo '('`date`')' >> "$greekLtr".out

在我的调度下的 slurm.conf 文件中,我有

# SCHEDULING
SchedulerType=sched/backfill
SelectType=select/cons_tres
SelectTypeParameters=CR_CPU

对类似问题的指出也将不胜感激!谢谢!

concurrency slurm hpc stress
1个回答
0
投票

我在这上面花了太多时间,我想我已经明白了。我没有尝试在一个作业中依赖 3 个 srun 任务,而是启动多个 sbatch 作业,每个作业有 1 个 srun 任务,并使它们相互依赖。下面的一些组合有效。

在我的 slurm.conf 文件中,我从 CR_CPU 更改为 CR_CPU_Memory。对于每个节点,我还添加了 RealMemory=16000(实际值来自在头节点上运行

slurm -C
)。然后我以root身份运行

systemctl restart slurmctld
scontrol reconfigure

我修改了

test_main.sh
并添加了对其他作业 ID 的依赖关系。

#!/bin/bash

# Set nice level
n_main=1000 #Decrease this for set B
n_dep=$(($n_main - 10))

mkdir -p 'out/'

ltr_ary=('alpha' 'beta' 'gamma')


for i1 in {1..6}; do #Changed to 7..14 for B
 printf -v i_str "%03d" $i1 #add zero-padding
 J_IDS='' #Previous job IDs in format ':42:43'
 i2=0
 for greekLtr in "${ltr_ary[@]}"; do
  i2=$(($i2+1))
  if [ "$i2" -lt "${#ltr_ary[@]}" ]; then
   # Not the last one
   out_txt=`sbatch --nice="$n_main" ./test_sub.sh "$i_str" "$greekLtr"`
  else
   out_txt=`sbatch --nice="$n_dep" --dependency=afterok"$J_IDS" ./test_sub.sh "$i_str" "$greekLtr"`
  fi
  job_ID=${out_txt##* } #get the job ID number after the final space
  J_IDS="$J_IDS"':'"$job_ID"
 done #end loop over greek letters
done #end loop over number iterations

修改为

test_sub.sh

#!/bin/bash
#
#SBATCH --job-name setA   ## name that will show up in the queue. Change for set B
#SBATCH --output /home/username/slurmlogs/slurm-%j.out   ## filename of the output; the %j is equal to jobID
#SBATCH --nodes=1              ## Number of nodes
#SBATCH --ntasks-per-node=1   ## Limiting number of tasks and hence CPU per node
#SBATCH --mem=3000M   ## Don't give all memory to just 1 CPU
#SBATCH --cpus-per-task=1      ## Each task only needs 1 CPU
#SBATCH --partition=mypartition     ## the partitions to run in (comma separated). 

in_dir=$1
greekLtr=$2

work_dir=$PWD
mkdir -p 'out/'$in_dir
cd 'out/'$in_dir

# Could not figure out how to get SBATCH to not overload CPUs without srun and --exclusive...
srun -N1 -n1 --exclusive --mem-per-cpu=3000M "$work_dir"/test_sub2.sh "$greekLtr" &
wait

我保持

test_sub2.sh
不变。

我通过在设置A后立即开始设置B来验证这是否按预期工作。第一分钟后,我在

squeue
中观察到 B 作业已启动,而其余 A 作业则处于待处理状态。 CPU 使用率似乎最大化,而没有在任务之间分配。

这似乎有效,但请稍等一下接受我自己的答案,以防有更优雅的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.