shell - 等待用户的所有作业完成,然后再将后续作业提交到 PBS 集群

标签 shell cluster-computing wait pbs qsub

我正在尝试调整一些 bash 脚本,使它们在 ( ) 集群上运行。

单个任务由几个脚本执行,这些脚本由一个主脚本启动。
到目前为止,这个主要脚本在后台启动多个脚本(通过附加 & )使它们在一台多核机器上并行运行。
我想用 qsub 代替这些电话s 跨集群节点分配负载。

但是,有些工作需要先完成其他工作才能开始。
到目前为止,这是由 wait 实现的。主脚本中的语句。
但是,使用 Grid Engine 执行此操作的最佳方法是什么?

我已经找到 this question以及 -W after:jobid[:jobid...] qsub 中的文档手册页,但我希望有更好的方法。
我们正在谈论首先并行运行多个 thousend 作业,并在其中最后一个完成后同时运行另一组相同大小的作业。
这意味着我必须根据大量作业对大量作业进行排队。

我可以通过在两者之间使用一个虚拟工作来解决这个问题,除了依赖于第二组可以依赖的第一组工作之外什么都不做。
这会将依赖项的数量从数百万减少到数千,但仍然:感觉不对,我什至不确定 shell 是否会接受这么长的命令行。

  • 有没有办法等待我所有的工作完成(比如 qwait -u <user> )?
  • 或者所有从这个脚本提交的作业(比如 qwait [-p <PID>] )?

  • 当然可以使用 qstat 来写这样的东西和 sleepwhile循环,但我想这个用例很重要,足以有一个内置的解决方案,我只是无法弄清楚。

    在这种情况下,您会推荐/使用什么?

    附录一:

    由于在评论中要求它:

    $ qsub --version
    version: 2.4.8
    

    也许也有助于确定确切的系统:

    $ qsub --help
    usage: qsub [-a date_time] [-A account_string] [-b secs]
          [-c [ none | { enabled | periodic | shutdown |
          depth=<int> | dir=<path> | interval=<minutes>}... ]
          [-C directive_prefix] [-d path] [-D path]
          [-e path] [-h] [-I] [-j oe] [-k {oe}] [-l resource_list] [-m n|{abe}]
          [-M user_list] [-N jobname] [-o path] [-p priority] [-P proxy_user] [-q queue]
          [-r y|n] [-S path] [-t number_to_submit] [-T type] [-u user_list] [-w] path
          [-W otherattributes=value...] [-v variable_list] [-V] [-x] [-X] [-z] [script]
    

    由于到目前为止评论指向作业数组,我搜索了 qsub具有以下结果的手册页:

    [...]
    DESCRIPTION
    [...]
           In addition to the above, the following environment variables will be available to the batch job.
    [...]
           PBS_ARRAYID
                  each member of a job array is assigned a unique identifier (see -t)
    [...]
    OPTIONS
    [...]
           -t array_request
                   Specifies the task ids of a job array. Single task arrays are allowed.
                   The array_request argument is an integer id or a range of integers. Multiple ids or id ranges can be combined in a comman delimeted list. Examples : -t 1-100 or -t 1,10,50-100
    [...]
    

    附录二:

    我试过 Dmitri Chubarov 给出的解决方案,但它不像描述的那样工作。

    如果没有工作数组,它会按预期工作:
    testuser@headnode ~ $ qsub -W depend=afterok:`qsub ./test1.sh` ./test2 && qstat
    2553.testserver.domain
    Job id                  Name             User            Time Use S Queue
    ----------------------- ---------------- --------------- -------- - -----
    2552.testserver         Test1            testuser               0 Q testqueue
    2553.testserver         Test2            testuser               0 H testqueue
    testuser@headnode ~ $ qstat
    Job id                  Name             User            Time Use S Queue
    ----------------------- ---------------- --------------- -------- - -----
    2552.testserver         Test1            testuser               0 R testqueue
    2553.testserver         Test2            testuser               0 H testqueue
    testuser@headnode ~ $ qstat
    Job id                  Name             User            Time Use S Queue
    ----------------------- ---------------- --------------- -------- - -----
    2553.testserver         Test2            testuser               0 R testqueue
    

    但是,使用作业数组不会启动第二个作业:
    testuser@headnode ~ $ qsub -W depend=afterok:`qsub -t 1-2 ./test1.sh` ./test2 && qstat
    2555.testserver.domain
    Job id                  Name             User            Time Use S Queue
    ----------------------- ---------------- --------------- -------- - -----
    2554-1.testserver       Test1-1          testuser               0 Q testqueue
    2554-2.testserver       Test1-1          testuser               0 Q testqueue
    2555.testserver         Test2            testuser               0 H testqueue
    testuser@headnode ~ $ qstat
    Job id                  Name             User            Time Use S Queue
    ----------------------- ---------------- --------------- -------- - -----
    2554-1.testserver       Test1-1          testuser               0 R testqueue
    2554-2.testserver       Test1-2          testuser               0 R testqueue
    2555.testserver         Test2            testuser               0 H testqueue
    testuser@headnode ~ $ qstat
    Job id                  Name             User            Time Use S Queue
    ----------------------- ---------------- --------------- -------- - -----
    2555.testserver         Test2            testuser               0 H testqueue
    

    我想这是由于第一个 qsub 返回的作业 ID 中缺少数组指示。 :
    testuser@headnode ~ $ qsub -t 1-2 ./test1.sh
    2556.testserver.domain
    

    如您所见,没有 ...[]表明这是一个工作数组。
    此外,在 qsub输出没有 ...[] s 但 ...-1...-2表示数组。

    所以剩下的问题是如何格式化-W depend=afterok:...使作业依赖于指定的作业数组。

    最佳答案

    按照 Jonathan 在评论中建议的解决方案填写。

    有几个基于原始可移植批处理系统的资源管理器:OpenPBS、TORQUE 和 PBS Professional。这些系统已经出现了显着差异,并为作业数组等新功能使用了不同的命令语法。

    作业数组是一种基于相同作业脚本提交多个相似作业的便捷方式。引用手册:

    Sometimes users will want to submit large numbers of jobs based on the same job script. Rather than using a script to repeatedly call qsub, a feature known as job arrays now exists to allow the creation of multiple jobs with one qsub command.



    提交作业数组 PBS 提供以下语法:
     qsub -t 0-10,13,15 script.sh
    

    这将提交 ID 为 0,1,2,...,10,13,15 的作业。

    在脚本中,变量 PBS_ARRAYID携带数组中作业的 id,可用于选择必要的配置。

    作业数组有其特定的依赖选项。

    扭矩

    可能在 OP 中使用的 TORQUE 资源管理器。提供了额外的依赖项选项,可以在以下示例中看到:
    $ qsub -t 1-1000 script.sh
    1234[].pbsserver.domainname
    $ qsub -t 1001-2000 -W depend=afterokarray:1234[] script.sh
    1235[].pbsserver.domainname
    

    这将导致以下 qstat输出
    1234[]         script.sh    user          0 R queue
    1235[]         script.sh    user          0 H queue   
    

    在扭矩版本 3.0.4 上测试

    完整的 afterokarray 语法在 qsub(1) 中手动的。

    PBS专业版

    在 PBS Professional 中,依赖项可以在普通作业和阵列作业上统一工作。下面是一个例子:
    $ qsub -J 1-1000 -ry script.sh
    1234[].pbsserver.domainname
    $ qsub -J 1001-2000 -ry -W depend=afterok:1234[] script.sh
    1235[].pbsserver.domainname
    

    这将导致以下 qstat输出
    1234[]         script.sh    user          0 B queue
    1235[]         script.sh    user          0 H queue   
    

    扭矩版本更新

    从 2.5.3 版开始,Torque 中提供了数组依赖项。 2.5 版的作业数组与 2.3 或 2.4 版的作业数组不兼容。特别是[] Torque 从 2.5 版开始引入语法。

    使用分隔符作业的更新

    对于 2.5 之前的扭矩版本,基于在要分离的作业批次之间提交虚拟分隔符作业的不同解决方案可能会起作用。
    它使用三种依赖类型:on , before , 和 after .

    考虑下面的例子
     $ DELIM=`qsub -Wdepend=on:1000 dummy.sh `
     $ qsub -Wdepend=beforeany:$DELIM script.sh
     1001.pbsserver.domainname
     ... another 998 jobs ...
     $ qsub -Wdepend=beforeany:$DELIM script.sh
     2000.pbsserver.domainname
     $ qsub -Wdepend=after:$DELIM script.sh
     2001.pbsserver.domainname
     ...
    

    这将导致像这样的队列状态
    1000         dummy.sh    user          0 H queue
    1001         script.sh   user          0 R queue   
    ...
    2000         script.sh   user          0 R queue   
    2001         script.sh   user          0 H queue
    ...   
    

    也就是说,只有在前 1000 个作业终止后,作业 #2001 才会运行。可能也可以使用 TORQUE 2.4 中可用的基本作业数组工具来提交脚本作业。

    此解决方案也适用于 TORQUE 2.5 版及更高版本。

    关于shell - 等待用户的所有作业完成,然后再将后续作业提交到 PBS 集群,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18442224/

    相关文章:

    shell - Applescript Shell 脚本进度

    android - 从 Android Studio gradle build 访问环境变量

    xml - 将 XML 标签存储到 shell 中的 Perl 变量

    php - 如何在多台服务器上托管一个 MySQL 数据库?

    c++ - 在 C++ 中等待通知

    java - 使用Java命令设置属性文件的路径

    cluster-computing - 将 Kafka 与 zookeeper 一起集群

    windows - Spark EC2 对 Windows 的支持

    Java如何延迟程序执行

    android - 在 Kotlin 中如何告诉函数等待几秒钟?