How to write an advanced while loop?
See how to write a while loop how to for a simplest possible while loop. Here, we will consider a more complicated case with possible initialization.
We begin from empty repo.
$ tb init
Created repository using module "taskblaster.repository" in "/home/myuser/tmprepo".
Create a following workflow.py
import taskblaster as tb
@tb.workflow
class WhileLoopWorkflow:
number = tb.var()
@tb.jump('whilebranch')
# @tb.branch('entry') is automatic, so skipped here
@tb.task
def initialize(self):
return tb.node('initialize', number=self.number)
@tb.branch('whilebranch', loop=True)
@tb.task
def iterate(self):
return tb.node(
'iterate_task',
number=tb.Phi(entry=self.initialize, whilebranch=self.iterate),
)
@tb.branch('whilebranch', loop=True)
@tb._if(false='whilebranch', true='final')
@tb.task
def converged(self):
return tb.node('converged_task', number=self.iterate)
@tb.branch('final')
@tb.fixedpoint
@tb.task
def result(self):
return tb.node('define', obj=self.iterate)
def workflow(rn):
rn.run_workflow(WhileLoopWorkflow(number=3))
and a following tasks.py
def initialize(number):
# Preprocessing of possible inputs
return number
def converged_task(number):
# This task could determine whether atoms wave been relaxed?
return number < 1
def iterate_task(number):
# This could relax atoms, and return the relaxed atoms
return number - 1
def depend_on_result(number):
# This task depends on the final result of the while loop
return number
We note, that we will start with entry branch, and then we will immediately make a non-conditional jump to the whilebranch
.
Now, we have an _if
task, which either jumps back to this branch, or to final
branch.
We have defined the final
branch task as fixedpoint, which allows us to reference it from outside of this workflow,
even the branch has now been executed yet.
We can iterate the workflow few times and observe the results. We iterate the workflow 4 times, run the created tasks, and observe the outputs.
$ tb workflow workflow.py && tb run . >/dev/null && tb ls --sort=topo -c sirITfo entry: add new 0/? tree/result add new 0/0 tree/initialize jump: whilebranch whilebranch: add new 0/1 tree/iterate-001 if: add new 0/1 tree/converged-001 T=final F=whilebranch state deps tags worker time folder output ──────────────────────────────────────────────────────────────────────────────────────────────────────── done 0/0 N/A-0/1 00:00:00 tree/initialize 3 done 1/1 N/A-0/1 00:00:00 tree/iterate-001 2 done 1/1 N/A-0/1 00:00:00 tree/converged-001 False new 0/? tree/result ø
$ tb workflow workflow.py && tb run . >/dev/null && tb ls --sort=topo -c sirITfo entry: have done 0/0 tree/initialize jump: whilebranch whilebranch: have done 1/1 tree/iterate-001 if: have done 1/1 tree/converged-001 T=final F=whilebranch jump: whilebranch whilebranch: add new 2/2 tree/iterate-002 if: add new 1/2 tree/converged-002 T=final F=whilebranch state deps tags worker time folder output ──────────────────────────────────────────────────────────────────────────────────────────────────────── done 0/0 N/A-0/1 00:00:00 tree/initialize 3 done 1/1 N/A-0/1 00:00:00 tree/iterate-001 2 done 1/1 N/A-0/1 00:00:00 tree/converged-001 False done 2/2 N/A-0/1 00:00:00 tree/iterate-002 1 done 2/2 N/A-0/1 00:00:00 tree/converged-002 False new 0/? tree/result ø
$ tb workflow workflow.py && tb run . >/dev/null && tb ls --sort=topo -c sirITfo entry: have done 0/0 tree/initialize jump: whilebranch whilebranch: have done 1/1 tree/iterate-001 if: have done 1/1 tree/converged-001 T=final F=whilebranch jump: whilebranch whilebranch: have done 2/2 tree/iterate-002 if: have done 2/2 tree/converged-002 T=final F=whilebranch jump: whilebranch whilebranch: add new 3/3 tree/iterate-003 if: add new 2/3 tree/converged-003 T=final F=whilebranch state deps tags worker time folder output ──────────────────────────────────────────────────────────────────────────────────────────────────────── done 0/0 N/A-0/1 00:00:00 tree/initialize 3 done 1/1 N/A-0/1 00:00:00 tree/iterate-001 2 done 1/1 N/A-0/1 00:00:00 tree/converged-001 False done 2/2 N/A-0/1 00:00:00 tree/iterate-002 1 done 2/2 N/A-0/1 00:00:00 tree/converged-002 False done 3/3 N/A-0/1 00:00:00 tree/iterate-003 0 done 3/3 N/A-0/1 00:00:00 tree/converged-003 True new 0/? tree/result ø
$ tb workflow workflow.py && tb run . >/dev/null && tb ls --sort=topo -c sirITfo entry: have done 0/0 tree/initialize jump: whilebranch whilebranch: have done 1/1 tree/iterate-001 if: have done 1/1 tree/converged-001 T=final F=whilebranch jump: whilebranch whilebranch: have done 2/2 tree/iterate-002 if: have done 2/2 tree/converged-002 T=final F=whilebranch jump: whilebranch whilebranch: have done 3/3 tree/iterate-003 if: have done 3/3 tree/converged-003 T=final F=whilebranch jump: final final: update new 4/4 tree/result state deps tags worker time folder output ──────────────────────────────────────────────────────────────────────────────────────────────────────── done 0/0 N/A-0/1 00:00:00 tree/initialize 3 done 1/1 N/A-0/1 00:00:00 tree/iterate-001 2 done 1/1 N/A-0/1 00:00:00 tree/converged-001 False done 2/2 N/A-0/1 00:00:00 tree/iterate-002 1 done 2/2 N/A-0/1 00:00:00 tree/converged-002 False done 3/3 N/A-0/1 00:00:00 tree/iterate-003 0 done 3/3 N/A-0/1 00:00:00 tree/converged-003 True done 4/4 N/A-0/1 00:00:00 tree/result 0
To view an experimental automatically generated workflow diagram of the workflow here, click here
.
This structure is an example of a more advanced for loop.