dflow入门4——recursereuseconditional
为了梳理学习dflow时遇到的知识点,我决定开这一个系列记录自己的学习过程。当然了,最好是去看 官方教程 和 文档
本文,我们将阅读教程中recurse、reuse和conditional这三节
文章目录
- 阅读原教程
- recurse
- reuse
- conditional
阅读原教程
recurse
recurse是dflow开发人员针对递归循环设计的模块,我们先来看recurse
首先定义了一个模板
plus1 = ShellOPTemplate(name='plus1',image="alpine:3.15",script="echo 'This is iter {{inputs.parameters.iter}}' && ""echo $(({{inputs.parameters.iter}}+1)) > /tmp/result.txt")plus1.inputs.parameters = {"iter": InputParameter()}plus1.outputs.parameters = {"iter": OutputParameter(value_from_path="/tmp/result.txt")}
该模板是自增1的操作
hello = Step(name="hello", template=plus1, parameters={"iter": steps.inputs.parameters["iter"]})
定义了一个step,该step使用了模板,自增1,输入是其他模板的输出
下面定义一个steps
steps = Steps(name="iter", inputs=Inputs(parameters={"iter": InputParameter(value=0),"limit": InputParameter(value=3)}))
该steps的输入有两个,一个是iter,一个是limit
最后定义一个新的step
next = Step(name="next", template=steps,parameters={"iter": hello.outputs.parameters["iter"]},when="%s < %s" % (hello.outputs.parameters["iter"],steps.inputs.parameters["limit"]))
翻译成普通的python
程序:
def add1(input: int):print(input)return input + 1def loops(input_loop: int, limit_loop: int):if input_loop < limit_loop:input_loop = add1(input_loop)loops(input_loop=input_loop, limit_loop=limit_loop)loops(input_loop=0, limit_loop=3)
我们对比来看,自增1操作即为add1函数
loops函数对应next
我们从上往下看:
- wf 里仅有一个 steps
- 这个 steps add 了两步,add 1 和 loops
- 此外设定了进入函数的条件,也就是 if 的条件
从小往上看是build的过程:
- 首先定义自增1的模板
- 定义steps,设定好条件
- 定义next模板,该模板接收自增1的输出,再调用steps
- 最后steps添加这两个模板,wf 提交任务
调用方法:
- 把自增1替换为我们要循环的模板即可,next 接收自增1的关键输出,steps设定好阈值。这就是一个for循环
reuse
下面我们看reuse
这一节首先将上一节的shelltemplate替换成了python template
import timefrom dflow import InputParameter, Inputs, Step, Steps, Workflow
from dflow.python import OP, OPIO, OPIOSign, PythonOPTemplateclass Plus1(OP):def __init__(self):pass@classmethoddef get_input_sign(cls):return OPIOSign({'iter': int})@classmethoddef get_output_sign(cls):return OPIOSign({'iter': int})@OP.exec_sign_checkdef execute(self,op_in: OPIO,) -> OPIO:return OPIO({'iter': op_in['iter'] + 1})if __name__ == "__main__":steps = Steps(name="iter", inputs=Inputs(parameters={"iter": InputParameter(value=0),"limit": InputParameter(value=5)}))plus1 = Step(name="plus1",template=PythonOPTemplate(Plus1,image="python:3.8"),parameters={"iter": steps.inputs.parameters["iter"]},key="iter-%s" % steps.inputs.parameters["iter"])steps.add(plus1)next = Step(name="next", template=steps,parameters={"iter": plus1.outputs.parameters["iter"]},when="%s < %s" % (plus1.outputs.parameters["iter"],steps.inputs.parameters["limit"]))steps.add(next)wf = Workflow("recurse", steps=steps)wf.submit()
区别在于limit替换成了5
这样的话,自增1步进行了5次
此外,每一个自增1步分配了一个key
重点在后面
while wf.query_status() in ["Pending", "Running"]:time.sleep(1)assert(wf.query_status() == "Succeeded")step0 = wf.query_step(key="iter-0")[0]step1 = wf.query_step(key="iter-1")[0]step1.modify_output_parameter("iter", 3)wf = Workflow("recurse-resubmit", steps=steps)wf.submit(reuse_step=[step0, step1])
这里取出了前两步,修改了第二步的输出(从2修改到了3)
重新提交后,原来5次的循环,重新使用之前的两次,由于修改了第二次的输出,所以在这次相当于从原来的第4步开始,运行两步后结束。
这一feature比较有价值的点在于,我们的输入输出文件都是在minio上存着的,只要我们不删容器(e.g. 重启docker),只要有他们的key,这些东西都是可以查询的,可以重用的。
conditional
首先定义了一个条件template
import random
import timefrom dflow import (OutputArtifact, OutputParameter, Outputs, Step, Steps,Workflow, if_expression)
from dflow.python import (OP, OPIO, Artifact, OPIOSign, PythonOPTemplate,upload_packages)if "__file__" in locals():upload_packages.append(__file__)class Random(OP):@classmethoddef get_input_sign(cls):return OPIOSign()@classmethoddef get_output_sign(cls):return OPIOSign({"is_head": bool,"msg1": str,"msg2": str,"foo": Artifact(str),"bar": Artifact(str)})@OP.exec_sign_checkdef execute(self,op_in: OPIO,) -> OPIO:open("foo.txt", "w").write("head")open("bar.txt", "w").write("tail")if random.random() < 0.5:is_head = Trueelse:is_head = Falsereturn OPIO({"is_head": is_head,"msg1": "head","msg2": "tail","foo": "foo.txt","bar": "bar.txt"})
然后套上壳
steps = Steps("conditional-steps", outputs=Outputs(parameters={"msg": OutputParameter()},artifacts={"res": OutputArtifact()}))random_step = Step(name="random",template=PythonOPTemplate(Random, image="python:3.8"))steps.add(random_step)steps.outputs.parameters["msg"].value_from_expression = if_expression(_if=random_step.outputs.parameters["is_head"],_then=random_step.outputs.parameters["msg1"],_else=random_step.outputs.parameters["msg2"])steps.outputs.artifacts["res"].from_expression = if_expression(_if=random_step.outputs.parameters["is_head"],_then=random_step.outputs.artifacts["foo"],_else=random_step.outputs.artifacts["bar"])wf = Workflow(name="conditional", steps=steps)wf.submit()while wf.query_status() in ["Pending", "Running"]:time.sleep(1)assert(wf.query_status() == "Succeeded")
结构简单
dflow入门4——recursereuseconditional相关推荐
- 用Construct 2制作入门小游戏~
今天在软导课上了解到了Construct 2这个神器,本零基础菜鸟决定尝试做一个简单的小游戏(实际上是入门的教程啊= = 首先呢,肯定是到官网下载软件啊,点击我下载~ 等安装完毕后我便按照新手教程开始 ...
- Docker入门六部曲——Swarm
原文链接:http://www.dubby.cn/detail.html?id=8738 准备工作 安装Docker(版本最低1.13). 安装好Docker Compose,上一篇文章介绍过的. 安 ...
- Docker入门六部曲——Stack
原文链接:http://www.dubby.cn/detail.html?id=8739 准备知识 安装Docker(版本最低1.13). 阅读完Docker入门六部曲--Swarm,并且完成其中介绍 ...
- Docker入门六部曲——服务
原文链接:http://www.dubby.cn/detail.html?id=8735 准备 已经安装好Docker 1.13或者以上的版本. 安装好Docker Compose.如果你是用的是Do ...
- 【springboot】入门
简介: springBoot是spring团队为了整合spring全家桶中的系列框架做研究出来的一个轻量级框架.随着spring4.0推出而推出,springBoot可以説是J2SEE的一站式解决方案 ...
- SpringBoot (一) :入门篇 Hello World
什么是SpringBoot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不 ...
- 入门指南目录页 -PaddlePaddle 飞桨 入门指南 FAQ合集-深度学习问题
入门指南目录页 -PaddlePaddle 飞桨 入门指南 FAQ合集 GT_Zhang关注 0.1012019.08.01 18:43:34字数 1,874阅读 795 Hi,欢迎各位来自Paddl ...
- 5 分钟入门 Google 最强NLP模型:BERT
BERT (Bidirectional Encoder Representations from Transformers) 10月11日,Google AI Language 发布了论文 BERT: ...
- 命名实体识别入门教程(必看)
关于开发自己的命名实体识别先期思路: 虽然网上有很多相关代码,但实际如何入门材料较少,故整理下: CRF:先期可以用人民日报语料库去做,步骤如下: https://blog.csdn.net/hude ...
- Shiro第一个程序:官方快速入门程序Qucickstart详解教程
目录 一.下载解压 二.第一个Shiro程序 1. 导入依赖 2. 配置shiro配置文件 3. Quickstart.java 4. 启动测试 三.shiro.ini分析 四.Quickstart. ...
最新文章
- 数据仓库数据模型之:极限存储--历史拉链表
- 产业互联网受瞩目:互联网主战场从To C转向To B | 企鹅经济学
- bug4 导入新工程时报 Target runtime com.genuitec.runtime.generic.jee60 is not defined
- windows下tomcat自动定时重启方法
- arraylist 初始化_Java二维数组和动态数组ArrayList 类
- 初探奥尔良(Orleans)
- jsp测试mysql_Jsp登陆与MySQL对接验证
- mysql配置两个猪数据库_Linux下安装启动多个Mysql
- java 复制字段_java - 在构造函数中按字段复制字段 - 我需要一个更简洁的形式 - SO中文参考 - www.soinside.com...
- 【转】3个普通IO识别22个按键试验
- 15.explain
- linux离线依赖包一键安装包,【分享】一键离线安装PetaLinux依赖包
- java dump分析工具_java线程dump分析工具
- 00_51入门知识积累__学看电路原理图
- Pascal voc 2012 数据集简介
- 基于STM32的智能小区安保管理系统设计
- html页面加密js,javascript怎么加密?
- 网页游戏外挂资料(转)
- 使用UltraISO从文件还原Linux操作系统ISO
- 使用分布式图计算系统实现研报关键词权重分数计算性能提升百倍以上