【问题标题】:Wait for set of qsub jobs to complete等待一组 qsub 作业完成
【发布时间】:2012-07-17 14:52:10
【问题描述】:

我有一个批处理脚本,它启动了几个 qsub 作业,我想在它们全部完成时进行陷阱。

我不想使用 -sync 选项,因为我希望它们同时运行。每个作业都有一组不同的命令行参数。

我希望我的脚本等到所有工作都完成后,然后再做一些事情。我不想使用睡眠功能,例如检查是否在每 30 秒后生成了某些文件,因为这会消耗资源。

我相信 Torque 可能有一些选择,但我正在运行 SGE。

请问有什么想法可以实现吗?

谢谢 附: 我确实找到了另一个线程 Link

有回应

您可以使用 wait 来停止执行,直到您完成所有作业。如果您循环等待特定的 id,您甚至可以收集所有退出状态和其他运行统计信息(花费的时间、当时完成的作业数等)。

但我不确定如何在不轮询某些值的情况下使用它。可以使用 bash 陷阱,但是我将如何使用 qsub?

【问题讨论】:

  • 您说得对,在 TORQUE 中有一种方法可以做到这一点。我不知道 SGE 是否可以选择这样做。

标签: qsub


【解决方案1】:

启动您的 qsub 作业,使用 -N 选项为它们指定任意名称(job1、job2 等):

qsub -N job1 -cwd ./job1_script
qsub -N job2 -cwd ./job2_script
qsub -N job3 -cwd ./job3_script

启动您的脚本并告诉它等到名为 job1、job2 和 job3 的作业完成后再开始:

qsub -hold_jid job1,job2,job3 -cwd ./results_script

【讨论】:

  • 如果工作列表太长,这似乎不起作用(我有 40 个工作,命令最终是 940 个字符......)
  • Hrm.. 不,这不是问题。就是 PBS Pro 使用了不同的格式。你需要使用-W depend=afterok:<job_id>[:<job_id>:...]
  • 有没有办法将参数传递给results_script
【解决方案2】:

如果所有作业的名称都有一个共同的模式,您可以在提交作业时提供该模式。 https://linux.die.net/man/1/sge_types 向您展示可以使用的模式。示例:

-hold_jid "job_name_pattern*"

【讨论】:

    【解决方案3】:

    另一种选择(来自here)如下:

    FIRST=$(qsub job1.pbs)
    echo $FIRST
    SECOND=$(qsub -W depend=afterany:$FIRST job2.pbs)
    echo $SECOND
    THIRD=$(qsub -W depend=afterany:$SECOND job3.pbs)
    echo $THIRD
    

    洞察力是 qsub 返回 jobid,这通常被转储到标准输出。相反,将其捕获在一个变量($FIRST$SECOND$THIRD)中,并在您将作业排入队列时使用-W depend=afterany:[JOBIDs] 标志来控制它们何时出列时的依赖结构。

    【讨论】:

      【解决方案4】:
      qsub -hold_jid job1,job2,job3 -cwd ./myscript
      

      【讨论】:

      • 为了提高您的帖子质量,请说明您的帖子解决问题的原因/方式。
      【解决方案5】:

      这在 bash 中有效,但这些想法应该是可移植的。使用-terse 来帮助建立一个带有作业ID的字符串以等待;然后提交一个使用-hold_jid 等待之前的作业和-sync y 的虚拟作业,这样 qsub 直到它(以及所有 prereqs)完成后才返回:

      # example where each of three jobs just sleeps for some time:
      job_ids=$(qsub -terse -b y sleep 10)
      job_ids=job_ids,$(qsub -terse -b y sleep 20)
      job_ids=job_ids,$(qsub -terse -b y sleep 30)
      qsub -hold_jid ${job_ids} -sync y -b y echo "DONE"  
      
      • -terse 选项使 qsub 的输出只是作业 id
      • -hold_jid 选项(如其他答案中所述)使作业等待指定的作业 ID
      • -sync y 选项(由 OP 引用)要求 qsub 在提交的作业完成之前不要返回
      • -b y 指定该命令不是脚本文件的路径(例如,我使用sleep 30 作为命令)

      有关详细信息,请参阅man page

      【讨论】:

        【解决方案6】:
        #!/depot/Python-2.4.2/bin/python
        
        import os
        import subprocess
        import shlex
        
        def trackJobs(jobs, waittime=4):
            while len(jobs) != 0:
                for jobid in jobs:
                    x = subprocess.Popen(['qstat', '-j', jobid], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                    std_out, std_err = x.communicate()
                    if std_err :
                        jobs.remove(jobid)
                        break
                os.system("sleep " + str(waittime))
            return
        
        

        这是一个简单的代码,您可以在其中跟踪 qsub 作业的完成状态。 这里函数接受 jobIds 列表(例如 ['84210770', '84210774', '84210776', '84210777', '84210778'] )

        【讨论】:

        • shlex 导入看起来没有必要。此外,您的 shebang 看起来特定于环境; #!/usr/bin/env python 更便携。
        【解决方案7】:

        如果您有 150 个文件需要处理并且每次只能运行 15 个,而其他文件在队列中,您可以设置类似这样的设置。

        # split my list files in a junk of small list having 10 file each
        awk 'NR%10==1 {x="F"++i;}{ print >  "list_part"x".txt" }'  list.txt
        

        qsub 以这样的方式对所有作业进行排序,即每个 list_part*.txt 中的第一个保存第二个 ....第二个保存第三个 .....依此类推。

        for list in $( ls list_part*.txt ) ; do
            PREV_JOB=$(qsub start.sh) # create a dummy script start.sh just for starting
         for file in  $(cat $list )  ; do
           NEXT_JOB=$(qsub -v file=$file  -W depend=afterany:$PREV_JOB  myscript.sh )
           PREV_JOB=$NEXT_JOB
         done
        done
        

        如果您在 myscript.sh 中有一个需要移动或下载许多文件或在集群局域网中创建大量流量的过程,这将非常有用

        【讨论】:

          【解决方案8】:

          您可以启动一个作业数组qsub -N jobname -t 1-"$numofjobs" -tc 20,然后它只有一个作业 id,一次运行 20 个。你给它一个名字,然后一直保持直到使用qsub -hold_jid jidqsub -hold_jid jobname 完成该数组。

          【讨论】:

            【解决方案9】:

            我需要更大的灵活性,因此我为此和其他目的构建了一个 Python 模块here。您可以直接将模块作为脚本 (python qsub.py) 运行以进行演示。

            用法:

            $ git clone https://github.com/stevekm/util.git
            $ cd util
            $ python
            Python 2.7.3 (default, Mar 29 2013, 16:50:34)
            [GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
            Type "help", "copyright", "credits" or "license" for more information.
            >>> import qsub
            >>> job = qsub.submit(command = 'echo foo; sleep 60', print_verbose = True)
            qsub command is:
            
            qsub -j y -N "python" -o :"/home/util/" -e :"/home/util/" <<E0F
            set -x
            echo foo; sleep 60
            set +x
            E0F
            
            >>> qsub.monitor_jobs(jobs = [job], print_verbose = True)
            Monitoring jobs for completion. Number of jobs in queue: 1
            Number of jobs in queue: 0
            No jobs remaining in the job queue
            ([Job(id = 4112505, name = python, log_dir = None)], [])
            

            使用 Python 2.7 和 SGE 设计,因为我们的系统就是这样运行的。唯一需要的非标准 Python 库是包含的 tools.pylog.py 模块,以及 sh.py(也包括在内)

            如果您希望纯粹留在 bash 中,显然没有那么有用,但如果您需要等待 qsub 工作,那么我想您的工作流程正逐渐变得复杂,而使用 Python 会受益。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-09-02
              • 2015-04-17
              • 2020-01-12
              • 1970-01-01
              • 1970-01-01
              • 2015-09-02
              • 2015-10-23
              相关资源
              最近更新 更多