Commit 05592ac0 authored by Wout De Nolf's avatar Wout De Nolf
Browse files

esrftaskgraph: rename TaskGraph.run and Task.run to TaskGraph.execute and Task.execute

parent 628b8ac1
......@@ -15,7 +15,7 @@ def execute_task(node_name, *inputs):
info = inputs[0]
esrfgraph = load_graph(info["esrfgraph"])
task = esrfgraph.instantiate_task_static(node_name, varinfo=info["varinfo"])
task.run()
task.execute()
return info
......
......@@ -49,7 +49,7 @@ class TaskRunner(luigi.Task):
return EsrfTarget(self.esrftask)
def run(self):
self.esrftask.run()
self.esrftask.execute()
return dict(self.esrftask.output_uhashes)
......
......@@ -37,7 +37,7 @@ class TaskCommand(mpdag.BaseCommand):
logger.info(self.prefix + "instantiate tasks ...")
task = self.taskgraph.instantiate_task_static(self.node, varinfo=self.varinfo)
logger.info(self.prefix + "run ...")
task.run()
task.execute()
logger.info(self.prefix + f"output = {task.output_values}")
......
......@@ -144,7 +144,7 @@ class OWESRFWidget(OWWidget, metaclass=ESRFWidgetMetaClass, openclass=True):
def run(self):
task = self.esrftaskclass(**self.input_variables, varinfo=self.varinfo)
try:
task.run()
task.execute()
except TaskInputError:
self.clear_downstream()
return
......
......@@ -11,11 +11,11 @@ def convert_graph(esrfgraph, varinfo):
tasks = dict()
for node in esrfgraph.graph.nodes:
task = esrfgraph.instantiate_task_static(node, tasks=tasks, varinfo=varinfo)
pdgraph.add_vertex(task.run)
pdgraph.add_vertex(task.execute)
for node in esrfgraph.graph.nodes:
task = tasks[node]
for upstream in esrfgraph.predecessors(node):
pdgraph.add_edge(tasks[upstream].run, task.run)
pdgraph.add_edge(tasks[upstream].execute, task.execute)
return pdgraph
......
......@@ -25,7 +25,7 @@ def run(**inputs):
task = instantiate_task(info["node_attrs"], varinfo=varinfo, inputs=inputs)
try:
task.run()
task.execute()
except Exception as e:
if log:
logger.error(
......
......@@ -189,7 +189,7 @@ class TaskGraph:
.. code-block:: python
taskgraph.run()
taskgraph.execute()
"""
GraphRepresentation = enum.Enum(
......@@ -553,11 +553,11 @@ class TaskGraph:
raise RuntimeError("Sorting nodes is not possible for cyclic graphs")
yield from networkx.topological_sort(self.graph)
def run(self, varinfo=None):
def execute(self, varinfo=None):
"""Sequential execution of DAGs"""
tasks = dict()
if self.has_conditional_links:
raise RuntimeError("Cannot execute graphs with conditional links")
for node in self.topological_sort():
task = self.instantiate_task_static(node, tasks=tasks, varinfo=varinfo)
task.run()
task.execute()
......@@ -6,7 +6,7 @@ from esrftaskgraph.variable import ReadOnlyVariableContainerNamespace
from esrftaskgraph.registration import Registered
class TaskInputError(RuntimeError):
class TaskInputError(AssertionError):
pass
......@@ -173,33 +173,35 @@ class Task(Registered, hashing.UniversalHashable, register=False):
def failed(self):
return self._exception is not None
@property
def can_run(self):
def _unavailable_inputs(self):
for iname in self._INPUT_NAMES:
ivar = self._inputs.get(iname)
if ivar is None or not ivar.available:
return False
return True
yield iname
def check_can_run(self):
unavailable = list()
for iname in self._INPUT_NAMES:
ivar = self._inputs.get(iname)
if ivar is None or not ivar.available:
unavailable.append(iname)
@property
def is_ready_to_execute(self):
try:
next(iter(self._unavailable_inputs()))
except StopIteration:
return True
return False
def assert_ready_to_execute(self):
unavailable = list(self._unavailable_inputs())
if unavailable:
raise TaskInputError(
"The following inputs could not be loaded: " + str(unavailable)
)
def run(self, force_rerun=False, raise_on_error=True):
def execute(self, force_rerun=False, raise_on_error=True):
try:
if force_rerun:
# Rerun a task which is already done
self._outputs.force_non_existing()
if self.done:
return
self.check_can_run()
self.assert_ready_to_execute()
self.process()
self._outputs.dump()
except Exception as e:
......
......@@ -21,7 +21,7 @@ def test_acyclic_execution(tmpdir):
g, expected = taskgraphs.acyclic_graph1()
taskgraph = load_graph(g)
varinfo = {"root_uri": str(tmpdir)}
taskgraph.run(varinfo=varinfo)
taskgraph.execute(varinfo=varinfo)
assert_taskgraph_result(taskgraph, expected, varinfo)
......@@ -30,7 +30,7 @@ def test_cyclic_execution(tmpdir):
taskgraph = load_graph(g)
varinfo = {"root_uri": str(tmpdir)}
with pytest.raises(RuntimeError):
taskgraph.run(varinfo=varinfo)
taskgraph.execute(varinfo=varinfo)
def test_start_nodes(tmpdir):
......
......@@ -45,7 +45,7 @@ def test_task_readonly_input(variable_kwargs):
def test_task_optional_input(tmpdir, variable_kwargs):
task = SumTask(a=10, **variable_kwargs)
assert not task.done
task.run()
task.execute()
assert task.done
assert task.outputs.result == 10
expected = [{"result": str(task.output_variables["result"].uhash)}, 10]
......@@ -55,7 +55,7 @@ def test_task_optional_input(tmpdir, variable_kwargs):
def test_task_done(variable_kwargs):
task = SumTask(a=10, **variable_kwargs)
assert not task.done
task.run()
task.execute()
assert task.done
task = SumTask(a=10, **variable_kwargs)
......@@ -63,7 +63,7 @@ def test_task_done(variable_kwargs):
task = SumTask(a=10)
assert not task.done
task.run()
task.execute()
assert task.done
task = SumTask(a=10)
......@@ -85,7 +85,7 @@ def test_task_uhash(variable_kwargs):
def test_task_storage(tmpdir, variable_kwargs):
task = SumTask(a=10, b=2, **variable_kwargs)
assert not task.done
task.run()
task.execute()
assert task.done
assert task.outputs.result == 12
expected = [{"result": str(task.output_variables["result"].uhash)}, 12]
......@@ -98,7 +98,7 @@ def test_task_storage(tmpdir, variable_kwargs):
task = SumTask(a=2, b=10, **variable_kwargs)
assert not task.done
task.run()
task.execute()
assert task.done
assert task.outputs.result == 12
expected += [{"result": str(task.output_variables["result"].uhash)}, 12]
......@@ -106,7 +106,7 @@ def test_task_storage(tmpdir, variable_kwargs):
task = SumTask(a=task.output_variables["result"], b=0, **variable_kwargs)
assert not task.done
task.run()
task.execute()
assert task.done
assert task.outputs.result == 12
expected += [{"result": str(task.output_variables["result"].uhash)}, 12]
......@@ -114,7 +114,7 @@ def test_task_storage(tmpdir, variable_kwargs):
task = SumTask(a=1, b=task.output_variables["result"].uhash, **variable_kwargs)
assert not task.done
task.run()
task.execute()
assert task.done
assert task.outputs.result == 13
expected += [{"result": str(task.output_variables["result"].uhash)}, 13]
......@@ -125,7 +125,7 @@ def test_method_task(variable_kwargs):
task = Task.instantiate(
"MethodExecutorTask", method=qualname(mymethod), a=3, b=5, **variable_kwargs
)
task.run()
task.execute()
assert task.done
assert task.output_values == {"return_value": {"result": 8}}
......@@ -138,7 +138,7 @@ def test_ppfmethod_task(variable_kwargs):
b=5,
**variable_kwargs,
)
task.run()
task.execute()
assert task.done
assert task.output_values == {"ppfdict": {"a": 8, "b": 5}}
......@@ -179,7 +179,7 @@ def test_python_script_task(tmpdir, variable_kwargs, capsys):
task = Task.instantiate(
"ScriptExecutorTask", script=str(pyscriptname), a=10, **variable_kwargs
)
task.run()
task.execute()
assert task.done
assert task.outputs.returncode == 0
captured = capsys.readouterr()
......@@ -196,7 +196,7 @@ def test_shell_script_task(tmpdir, variable_kwargs, capsys):
task = Task.instantiate(
"ScriptExecutorTask", script=str(shellscriptname), a=10, **variable_kwargs
)
task.run()
task.execute()
assert task.done
assert task.outputs.returncode == 0
captured = capsys.readouterr()
......
%% Cell type:markdown id:lucky-florist tags:
# Prepare for persistent storage of results
%% Cell type:code id:automotive-bulgaria tags:
``` python
import os
import shutil
varinfo = {"root_uri": "/tmp/myresults"}
def prepare_results(clean=True):
if clean:
shutil.rmtree(varinfo["root_uri"], ignore_errors=True)
os.makedirs(varinfo["root_uri"], exist_ok=True)
```
%% Cell type:markdown id:hindu-practice tags:
# Bindings for task schedulers
%% Cell type:code id:falling-trace tags:
``` python
schedulers = {}
```
%% Cell type:code id:small-reputation tags:
``` python
def sequential_execution(taskgraph, varinfo):
# runs in a single thread
from esrftaskgraph import load_graph
runtime_taskgraph = load_graph(taskgraph)
runtime_taskgraph.run(varinfo=varinfo)
runtime_taskgraph.execute(varinfo=varinfo)
schedulers[None] = sequential_execution
```
%% Cell type:code id:latin-width tags:
``` python
def multithreading_scheduler(taskgraph, varinfo):
# tasks are distributed over threads
import esrf2paradag
esrf2paradag.job(taskgraph, varinfo=varinfo)
schedulers["multithreading"] = multithreading_scheduler
```
%% Cell type:code id:operational-school tags:
``` python
def multiprocessing_scheduler(taskgraph, varinfo):
# tasks are distributed over processes
import esrf2multiprocessing
esrf2multiprocessing.job(taskgraph, varinfo=varinfo)
schedulers["multiprocessing"] = multiprocessing_scheduler
```
%% Cell type:code id:stunning-object tags:
``` python
def pypushflow_scheduler(taskgraph, varinfo):
# tasks are distributed over processes
import esrf2pypushflow
esrf2pypushflow.job(taskgraph, varinfo=varinfo)
schedulers["pypushflow"] = pypushflow_scheduler
```
%% Cell type:code id:sexual-beauty tags:
``` python
def luigi_scheduler(taskgraph, varinfo, **kw):
# tasks are distributed by local or centralized scheduler
import esrf2luigi
esrf2luigi.job(taskgraph, varinfo=varinfo, **kw)
schedulers["luigi"] = luigi_scheduler
```
%% Cell type:code id:accredited-basin tags:
``` python
def dask_scheduler(taskgraph, varinfo, **kw):
# tasks are distributed by local or centralized scheduler
import esrf2dask
esrf2dask.job(taskgraph, varinfo=varinfo, **kw)
schedulers["dask"] = dask_scheduler
```
%% Cell type:markdown id:requested-township tags:
### Load a task graph
%% Cell type:code id:communist-disco tags:
``` python
from taskgraphlib import acyclic_graph1
persistent_taskgraph, expected_results = acyclic_graph1()
```
%% Cell type:markdown id:indoor-drink tags:
### Show the task graph
%% Cell type:code id:legal-marking tags:
``` python
import networkx
from pprint import pprint
import matplotlib.pyplot as plt
from esrftaskgraph import load_graph
pprint(persistent_taskgraph)
runtime_taskgraph = load_graph(persistent_taskgraph)
networkx.draw(runtime_taskgraph.graph, with_labels=True)
plt.show()
```
%%%% Output: stream
{'directed': True,
'graph': {'name': 'taskgraphlib.taskgraphs.acyclic_graph1'},
'links': [{'arguments': {'a': 'result'}, 'source': 'task1', 'target': 'task3'},
{'arguments': {'a': 'result'}, 'source': 'task2', 'target': 'task4'},
{'arguments': {'a': 'result'}, 'source': 'task3', 'target': 'task5'},
{'arguments': {'b': 'result'}, 'source': 'task4', 'target': 'task5'},
{'arguments': {'a': 'result'},
'source': 'task5',
'target': 'task6'}],
'multigraph': False,
'nodes': [{'class': 'tasklib.tasks.SumTask',
'id': 'task1',
'inputs': {'a': 1}},
{'class': 'tasklib.tasks.SumTask',
'id': 'task2',
'inputs': {'a': 2}},
{'class': 'tasklib.tasks.SumTask',
'id': 'task3',
'inputs': {'b': 3}},
{'class': 'tasklib.tasks.SumTask',
'id': 'task4',
'inputs': {'b': 4}},
{'class': 'tasklib.tasks.SumTask',
'id': 'task5',
'inputs': {'b': 5}},
{'class': 'tasklib.tasks.SumTask',
'id': 'task6',
'inputs': {'b': 6}}]}
%%%% Output: display_data
![](data:image/png;base64,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)
%% Cell type:markdown id:original-buddy tags:
### Execute the task graph
%% Cell type:code id:acknowledged-sodium tags:
``` python
# Select scheduler
local_scheduler = True
scheduler = schedulers["dask"]
# Schedulers options
scheduler_options = dict()
if local_scheduler:
varinfo["root_uri"] = "/tmp/myresults"
if scheduler is dask_scheduler:
scheduler_options["scheduler"] = "multithreading"
else:
varinfo["root_uri"] = "/data/id21/tmp/myresults"
if scheduler is luigi_scheduler:
# Run "luigid" on any host
scheduler_options["scheduler"] = {"local_scheduler": local_scheduler,
"scheduler_host": "localhost",
"scheduler_port":8082,
"workers": 10}
elif scheduler is dask_scheduler:
# Run this on any host:
# >>> from esrf2dask import local_scheduler
# >>> scheduler = local_scheduler(n_workers=5)
#
# Or run this on slurm-access or any slurm node:
# >>> from esrf2dask import slurm_scheduler
# >>> scheduler = slurm_scheduler(maximum_jobs=5)
scheduler_options["scheduler"] = {"address": "160.103.228.113:35881"}
# Prepare location for results
prepare_results(clean=True)
%timeit -n 1 -r 1 scheduler(persistent_taskgraph, varinfo, **scheduler_options)
```
%%%% Output: stream
210 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
%% Cell type:markdown id:indoor-bangladesh tags:
### Show the results of each task
%% Cell type:code id:antique-moderator tags:
``` python
tasks = dict()
print(f"Task graph results {repr(runtime_taskgraph)}:")
for node, value in expected_results.items():
task = runtime_taskgraph.instantiate_task_static(node, tasks=tasks, varinfo=varinfo)
assert task.done, str(task)
assert task.output_values == value, str(task)
print(f"\ntask {repr(node)}:\n Result: {value}\n Storage: {task.outputs}")
```
%%%% Output: stream
Task graph results taskgraphlib.taskgraphs.acyclic_graph1:
task 'task1':
Result: {'result': 1}
Storage: <esrftaskgraph.variable.VariableContainerNamespace object at 0x7fc90ef89340>
task 'task2':
Result: {'result': 2}
Storage: <esrftaskgraph.variable.VariableContainerNamespace object at 0x7fc911007e80>
task 'task3':
Result: {'result': 4}
Storage: <esrftaskgraph.variable.VariableContainerNamespace object at 0x7fc95b7ec460>
task 'task4':
Result: {'result': 6}
Storage: <esrftaskgraph.variable.VariableContainerNamespace object at 0x7fc90eb6ea60>
task 'task5':
Result: {'result': 10}
Storage: <esrftaskgraph.variable.VariableContainerNamespace object at 0x7fc90eb6e550>
task 'task6':
Result: {'result': 16}
Storage: <esrftaskgraph.variable.VariableContainerNamespace object at 0x7fc90eb6e5e0>
......
......@@ -22,7 +22,7 @@ def multiprocess_scheduler(taskgraph, varinfo):
def singlethread_scheduler(taskgraph, varinfo):
# runs in a single thread
taskgraph.run(varinfo)
taskgraph.execute(varinfo)
if __name__ == "__main__":
......
%% Cell type:markdown id:dominican-grave tags:
# Load an run a task graph
%% Cell type:code id:explicit-stake tags:
``` python
import networkx
import matplotlib.pyplot as plt
from esrftaskgraph import load_graph
from taskgraphlib import acyclic_graph1
varinfo = {"root_uri": "/tmp/myresults"}
persistent_taskgraph, expected_results = acyclic_graph1()
runtime_taskgraph = load_graph(persistent_taskgraph)
runtime_taskgraph.run(varinfo=varinfo)
runtime_taskgraph.execute(varinfo=varinfo)
networkx.draw(runtime_taskgraph.graph, with_labels=True)
plt.show()
```
%%%% Output: display_data
![](data:image/png;base64,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)
%% Cell type:markdown id:academic-rebound tags:
# Instantiating a task
A task can always be instantiated and executed from the runtime representation of a task graph. No results from upstream tasks need to be provided explicitely. The runtime representation can be instantiated from the persistent representation with `load_graph`.
%% Cell type:code id:liked-belly tags:
``` python
import inspect
def print_task_sourcecode(task):
lines, line_nb = inspect.getsourcelines(type(task))
print(" \nSource code:\n" + " ".join(lines))
def print_task_info(name, task):
print(f"{name}: ")
print(f" attributes = {runtime_taskgraph.graph.nodes[name]}")
print(f" uhash = {task.uhash}")
print(f" done = {task.done}")
if task.done:
print(f" result = {task.outputs.result}")
else:
print(" result = <not available>")
def instantiate_task(name):
task = runtime_taskgraph.instantiate_task_static(name, varinfo=varinfo)
print_task_info(name, task)
return task
task = instantiate_task("task6")
print_task_sourcecode(task)
```
%%%% Output: stream
task6:
attributes = {'inputs': {'b': 6}, 'class': 'tasklib.tasks.SumTask'}