如何运行多步骤 workflows#
启动预定义的 workflow#
启动预定义 workflow 的第一步是加载定义要运行的 workflow 的工作函数或工作链类。加载 workflow 的推荐方法是使用 WorkflowFactory
等:
from aiida.plugins import WorkflowFactory
add_and_multiply = WorkflowFactory('core.arithmetic.add_multiply')
MultiplyAddWorkChain = WorkflowFactory('core.arithmetic.multiply_add')
这与从各自模块中提取 workflow 的 import 基本相同,但使用 WorkflowFactory
的好处是,当软件包或插件重组时,所谓的 entry point (例如 'core.arithmetic.multiply_add'
)不会改变。这意味着在更新 AiiDA 或提供 workflow 的插件时,你的代码不太可能被破坏。
可通过 verdi CLI 轻松访问已安装插件的列表:
$ verdi plugin list
要查看 workflow entry point 列表,只需使用:
$ verdi plugin list aiida.workflows
通过进一步指定 workflow 的 entry point,可以查看其描述、输入、输出和退出代码:
$ verdi plugin list aiida.workflows core.arithmetic.multiply_add
工作职能#
运行工作函数就像调用典型的 Python 函数一样简单:只需使用所需的输入参数调用即可:
from aiida.plugins import WorkflowFactory, DataFactory
add_and_multiply = WorkflowFactory('core.arithmetic.add_multiply')
Int = DataFactory('core.int')
result = add_and_multiply(Int(2), Int(3), Int(5))
在这里, add_and_multiply
工作函数返回输出 Int
node,我们将其赋值给变量 result
。请注意,work 函数的输入参数必须是 Data
node 或其子类的实例。如果使用普通整数调用 add_and_multiply
函数,结果将是 ValueError
,因为这些整数无法存储在 provenance graph 中。
Added in version 2.1: Function argument casting
如果函数参数是一个 Python 基本类型 (即一个 bool
、 dict
、 Enum
、 float
、 int
、 list
或 str
类型的值),它可以直接传递给函数,而不需要先用相应的 AiiDA 数据类型包装它。也就是说,你也可以以下列方式运行上面的示例:
result = add_and_multiply(2, 3, 5)
而 AiiDA 会识别出参数的类型是 int
,并自动用 Int
node 包起来。参数默认值也是如此;如果参数接受 Python 基本类型,它可以指定一个默认值。当函数被调用时,它将自动转换为相应的 AiiDA 数据类型:
@calcfunction
def add(a, b: int = 10):
return a + b
add(10)
结果将是数值为 20
的 Int
node。
备注
虽然上面的示例展示了运行 add_and_multiply
工作函数的最直接方法,但还有其他几种运行进程的方 法,它们返回的不仅仅是结果。例如,AiiDA engine 的 run_get_node
函数同时返回 workflow 和工作函数 node 的结果。参见 corresponding topics section for more details 。
工作链#
要启动工作链,可以使用 run
或 submit
函数。对于这两个函数,都需要将工作链的类作为第一个参数,然后将输入作为关键字参数。当使用 ``running the work chain`` (使用 run
函数)时,它将在与启动它的解释器相同的系统进程中执行:
from aiida.engine import run
from aiida.plugins import WorkflowFactory, DataFactory
Int = DataFactory('core.int')
MultiplyAddWorkChain = WorkflowFactory('core.arithmetic.multiply_add')
add_code = load_code(label='add')
results = run(MultiplyAddWorkChain, x=Int(2), y=Int(3), z=Int(5), code=add_code)
或者,您也可以先创建一个输入字典,然后将其传递给 run
函数, 通过利用 Python关键字展开:
inputs = {'x': Int(1), 'y': Int(2), 'z': Int(3), 'code': add_code}
results = run(MultiplyAddWorkChain, **inputs)
如果您的 workflow 有大量输入,这一点尤其有用。在这两种情况下,运行 MultiplyAddWorkChain
workflow 都会返回 workflow 的 结果 ,即输出 node 的字典,字典的键与每个输出的标签相对应。
备注
与其他流程类似,启动工作链也有多种功能。请参见 launching processes for more details 部分。
由于 * 运行 * workflow 会阻塞解释器,因此必须等到 workflow 结束后才能重新获得控制权。此外,在 workflow 完全结束之前,您无法关闭计算机,甚至无法关闭终端,而且很难并行运行多个 workflow。因此,建议将更复杂或更长的工作链提交给守护进程:
from aiida.engine import submit
from aiida.plugins import WorkflowFactory, DataFactory
Int = DataFactory('core.int')
MultiplyAddWorkChain = WorkflowFactory('core.arithmetic.multiply_add')
add_code = load_code(label='add')
inputs = {'x': Int(1), 'y': Int(2), 'z': Int(3), 'code': add_code}
workchain_node = submit(MultiplyAddWorkChain, **inputs)
请注意,使用 submit
时,工作链不会在本地解释器中运行,而是发送给守护进程,您将立即重新获得控制权。这样,您就可以同时提交多个工作链,守护进程将开始并行处理这些工作链。一旦 submit
调用返回,您将不会得到与 run
相同的结果,但会得到代表工作链的 node 。提交工作链而不是直接运行工作链,不仅可以更方便地并行执行多个工作链,还能确保重启计算机时工作链的进度不会丢失。
备注
从AiiDA v1.5.0开始,工作链 和工作函数 都可以提交给守护进程。旧版本只允许提交工作链 ,而工作函数 不能提交给守护进程,因此只能 运行 。
如果您不熟悉特定 WorkChain
的输入, process builder 是设置工作链的便捷工具。可以通过 get_builder()
方法获得,该方法适用于所有 CalcJob
和 WorkChain
:
In [1]: from aiida.plugins import WorkflowFactory, DataFactory
...: Int = DataFactory('core.int')
...: MultiplyAddWorkChain = WorkflowFactory('core.arithmetic.multiply_add')
...: builder = MultiplyAddWorkChain.get_builder()
要查看工作链的输入,可以使用制表符自动完成功能,输入 builder.
,然后点击 TAB
。如果想了解特定输入的详细信息,只需添加 ?
并按回车键即可:
In [2]: builder.x?
Type: property
String form: <property object at 0x119ad2dd0>
Docstring: {"name": "x", "required": "True", "valid_type": "<class 'aiida.orm.nodes.data.int.Int'>", "non_db": "False"}
在这里,您可以看到 x
input is required, needs to be of the Int
类型已存储在数据库 ( \``non_db\
: ``False```` )。
WorkChain
的输入端可以通过构建器逐个提供:
In [3]: builder.code = load_code(label='add')
...: builder.x = Int(2)
...: builder.y = Int(3)
...: builder.z = Int(5)
向生成器提供 workflow 的 必要 输入后,就可以运行工作链或将其提交给守护进程:
In [4]: from aiida.engine import submit
...: workchain_node = submit(builder)
备注
有关流程生成器的更多详情,请参阅 corresponding topics section 。
现在你已经知道如何运行预定义的 workflow,你可能想启动 writing your own 。