Skip to content

Commit

Permalink
Documentation: advanced concepts of workchain design
Browse files Browse the repository at this point in the history
Wrote extensive documentation on all the features of the WorkChain
and how to write robust, maintainable and modular workchains. Described
all the features of the ProcessSpec with the newly added Ports and
PortNamespaces, the context and how to add futures, the reporting system
and how to abort workchains and set their finish status.
  • Loading branch information
sphuber committed May 2, 2018
1 parent def862f commit ff66885
Show file tree
Hide file tree
Showing 11 changed files with 508 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,14 @@ class ChildWorkChain(WorkChain):
@classmethod
def define(cls, spec):
super(ChildWorkChain, cls).define(spec)

spec.input('a', valid_type=Int)
spec.input('b', valid_type=Float)
spec.input('c', valid_type=Bool)

spec.outline(cls.do_run)
spec.output('d', valid_type=Int)
spec.output('e', valid_type=Float)
spec.output('f', valid_type=Bool)

spec.outline(cls.do_run)

def do_run(self):
self.out('d', self.inputs.a)
self.out('e', self.inputs.b)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,52 +6,21 @@ class ComplexParentWorkChain(WorkChain):
@classmethod
def define(cls, spec):
super(ComplexParentWorkChain, cls).define(spec)

spec.expose_inputs(ChildWorkChain, include=['a'])
spec.expose_inputs(
ChildWorkChain,
namespace='child_1',
exclude=['a']
)
spec.expose_inputs(
ChildWorkChain,
namespace='child_2',
exclude=['a']
)

spec.expose_inputs(ChildWorkChain, namespace='child_1', exclude=['a'])
spec.expose_inputs(ChildWorkChain, namespace='child_2', exclude=['a'])
spec.outline(cls.run_children, cls.finalize)
spec.expose_outputs(ChildWorkChain, include=['e'])
spec.expose_outputs(
ChildWorkChain,
namespace='child_1',
exclude=['e'],
)
spec.expose_outputs(
ChildWorkChain,
namespace='child_2',
exclude=['e'],
)
spec.expose_outputs(ChildWorkChain, namespace='child_1', exclude=['e'])
spec.expose_outputs(ChildWorkChain, namespace='child_2', exclude=['e'])

spec.outline(cls.run_children, cls.finalize)

def run_children(self):
return ToContext(
child_1=self.submit(
ChildWorkChain,
**self.exposed_inputs(
ChildWorkChain,
namespace='child_1'
)
),
child_2=self.submit(
ChildWorkChain,
a=self.inputs.a,
**self.exposed_inputs(
ChildWorkChain,
namespace='child_2',
agglomerate=False
)
)
)
child_1_inputs = self.exposed_inputs(ChildWorkChain, namespace='child_1')
child_2_inputs = self.exposed_inputs(ChildWorkChain, namespace='child_1', agglomerate=False)
child_1 = self.submit(ChildWorkChain, **child_1_inputs)
child_2 = self.submit(ChildWorkChain, **child_2_inputs, a=self.inputs.a)
return ToContext(child_1=child_1, child_2=child_2)

def finalize(self):
self.out_many(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
#!/usr/bin/env runaiida

from __future__ import print_function

from aiida.orm.data.bool import Bool
from aiida.orm.data.float import Float
from aiida.orm.data.int import Int
from aiida.work import run

from complex_parent import ComplexParentWorkChain

if __name__ == '__main__':
print(run(
result = run(
ComplexParentWorkChain,
a=Int(1),
child_1=dict(b=Float(1.2), c=Bool(True)),
child_2=dict(b=Float(2.3), c=Bool(False))
))
# Result:
)
print(result)
# {
# u'e': 1.2,
# u'child_1.d': 1, u'child_1.f': True,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
#!/usr/bin/env runaiida

from __future__ import print_function

from aiida.orm.data.bool import Bool
from aiida.orm.data.float import Float
from aiida.orm.data.int import Int
from aiida.work import run

from simple_parent import SimpleParentWorkChain

if __name__ == '__main__':
print(run(
SimpleParentWorkChain,
a=Int(1), b=Float(1.2), c=Bool(True)
))
# Result: {u'e': 1.2, u'd': 1, u'f': True}
result = run(SimpleParentWorkChain, a=Int(1), b=Float(1.2), c=Bool(True))
print(result)
# {u'e': 1.2, u'd': 1, u'f': True}
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
from aiida.work import ToContext, WorkChain, run

from child import ChildWorkChain


class SimpleParentWorkChain(WorkChain):

@classmethod
def define(cls, spec):
super(SimpleParentWorkChain, cls).define(spec)

spec.expose_inputs(ChildWorkChain)
spec.expose_outputs(ChildWorkChain)

spec.outline(cls.run_child, cls.finalize)

def run_child(self):
return ToContext(child=self.submit(
ChildWorkChain,
**self.exposed_inputs(ChildWorkChain)
))
child = self.submit(ChildWorkChain, **self.exposed_inputs(ChildWorkChain))
return ToContext(child=child)

def finalize(self):
self.out_many(
self.exposed_outputs(
self.ctx.child,
ChildWorkChain
)
self.exposed_outputs(self.ctx.child, ChildWorkChain)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from aiida.orm.data.int import Int
from aiida.work.workchain import WorkChain, ToContext, append_

class SomeWorkChain(WorkChain):

@classmethod
def define(cls, spec):
super(SomeWorkChain, cls).define(spec)
spec.outline(
cls.submit_workchains,
cls.inspect_workchains,
)

def submit_workchains(self)
for i in range(3):
future = self.submit(SomeWorkChain)
self.to_context(workchains=append_(future))

def inspect_workchains(self)
for workchain in self.ctx.workchains:
assert workchain.is_finished_ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from aiida.orm.data.int import Int
from aiida.work.workchain import WorkChain, ToContext

class SomeWorkChain(WorkChain):

@classmethod
def define(cls, spec):
super(SomeWorkChain, cls).define(spec)
spec.outline(
cls.submit_workchain,
cls.inspect_workchain,
)

def submit_workchain(self)
future = self.submit(SomeWorkChain)
return ToContext(workchain=future)

def inspect_workchain(self)
assert self.ctx.workchain.is_finished_ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from aiida.orm.data.int import Int
from aiida.work.workchain import WorkChain, ToContext

class SomeWorkChain(WorkChain):

@classmethod
def define(cls, spec):
super(SomeWorkChain, cls).define(spec)
spec.outline(
cls.submit_workchains,
cls.inspect_workchains,
)

def submit_workchains(self)
for i in range(3):
future = self.submit(SomeWorkChain)
key = 'workchain_{}'.format(i)
self.to_context(key=future)

def inspect_workchains(self)
for i in range(3):
key = 'workchain_{}'.format(i)
assert self.ctx[key].is_finished_ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from aiida.work.launch import run_get_node, run_get_pid
from aiida.work.workfunctions import workfunction

a = 1
b = 2

@workfunction
def add(a, b):
return a + b

# Passing inputs as arguments
result, node = run_get_node(add, a, b)
result, pid = run_get_pid(add, a, b)

# Passing inputs as keyword arguments
result, node = run_get_node(add, a=a, b=b)
result, pid = run_get_pid(add, a=a, b=b)
Loading

0 comments on commit ff66885

Please sign in to comment.