Limit

limits 提供简单的负载管理,限制提交到某个 ecflow_server 上的作业数目。

suite 设计者使用两种触发器:

  • data dependency trigger:由 trigger 关键词设置
  • courtesy trigger:由 limit 关键词设置

trigger 是第一种触发器。第二种用于防止同时运行过多的作业,实际上是一种人工的作业排队方法。 因为 ecflow 不区分这两种触发器,不利于后续维护。所以引入 limit。

inlimit

limits 与 inlimit 同时使用。

首先定义 limit: limit NAME N,通常放在 suite 级

接着将定义一组想应用该 limit 的 task,将 inlimit NAME 属性添加到节点。添加到 task 中将该 task 加入到 limit 组;添加到 family 将该 family 下的所有任务添加到 limit 组。

limit 的效果是确保该组中同时运行的任务数不超过 N。一个节点可以被多个 limit 限制。

Ecf脚本

创建有九个 task 的 family f5。

$ECF_HOME/test/f5/ 目录下创建这些 ecf script 脚本,每个内容如下:

  1. %include <head.h>
  2. echo "I will now sleep for %SLEEP% seconds"
  3. sleep %SLEEP%
  4. %include <tail.h>

suite definition

在 suite definition 中添加 limit。

Text

  1. # Definition of the suite test.
  2. suite test
  3. edit ECF_INCLUDE "$ECF_HOME"
  4. edit ECF_HOME "$ECF_HOME"
  5. limit l1 2
  6. family f5
  7. inlimit l1
  8. edit SLEEP 20
  9. task t1
  10. task t2
  11. task t3
  12. task t4
  13. task t5
  14. task t6
  15. task t7
  16. task t8
  17. task t9
  18. endfamily
  19. endsuite

定义语法

  1. limit ::= "limit" >> ( identifier >> unsigned int ) >> +nextline
  2. inlimit ::= "inlimit" >>( (nodePath >> ":“ >> identifier) | identifier )) >> ! unsigned int >> +nextline

Python

  1. import os
  2. from pathlib import Path
  3. from ecflow import Defs, Suite, Task, Family, Edit, Trigger, \
  4. Event, Complete, Meter, Time, Day, Date, Cron, Label, \
  5. RepeatString, RepeatInteger, RepeatDate, Limit, InLimit
  6. # ... skip ...
  7. def create_family_f5():
  8. return Family("f5",
  9. InLimit("l1"),
  10. Edit(SLEEP=20),
  11. [Task('t{}'.format(i)) for i in range(1, 10)])
  12. print("Creating suite definition")
  13. home = os.path.abspath(Path(Path(__file__).parent, "../../../build/course"))
  14. defs = Defs(
  15. Suite('test',
  16. Edit(ECF_INCLUDE=home, ECF_HOME=home),
  17. Limit("l1", 2),
  18. create_family_f1(),
  19. create_family_house_keeping(),
  20. create_family_f3(),
  21. create_family_f4(),
  22. create_family_f5()))
  23. print(defs)
  24. print("Checking job creation: .ecf -> .job0")
  25. print(defs.check_job_creation())
  26. print("Saving definition to file 'test.def'")
  27. defs.save_as_defs(str(Path(home, "test.def")))
  28. # To restore the definition from file 'test.def' we can use:
  29. # restored_defs = ecflow.Defs("test.def")

运行结果:

  1. python test.py
  2. Creating suite definition
  3. # 4.8.0
  4. suite test
  5. edit ECF_INCLUDE '/g3/wangdp/project/study/ecflow/ecflow-tutorial-code/build/course'
  6. edit ECF_HOME '/g3/wangdp/project/study/ecflow/ecflow-tutorial-code/build/course'
  7. limit l1 2
  8. # ... skip ...
  9. family f5
  10. edit SLEEP '20'
  11. inlimit l1
  12. task t1
  13. task t2
  14. task t3
  15. task t4
  16. task t5
  17. task t6
  18. task t7
  19. task t8
  20. task t9
  21. endfamily
  22. endsuite
  23. Checking job creation: .ecf -> .job0
  24. Saving definition to file 'test.def'

Python API

ecflow.InLimit

创建

  1. InLimit(name, optional, optional)
  2. string name : The name of the referenced Limit
  3. string path : The path to the Limit, if this is left out, then Limit of 'name' must be specified
  4. some where up the parent hierarchy
  5. int value : The usage of the Limit. Each job submission will consume 'value' tokens
  6. from the Limit. defaults to 1 if no value specified.

使用

  1. inlimit = InLimit("fast","/x/f", 2)
  2. # ...
  3. family.add_inlimit(inlimit)

ecflow.Limit

创建

  1. Limit(name,value)
  2. string name: the name of the limit
  3. int value: The value of the limit
  1. limit = Limit("fast", 10)
  2. # ...
  3. suite.add_limit(limit)

任务

  1. 修改
  2. 替换 suite definition
  3. 在 ecflow_ui 中观察 limit l1

    Limit - 图1

  4. 修改 limit 的值

    Limit - 图2

  5. 打开 /test/f5 下某个排队 task 的 Why 面板

    Limit - 图3