Skip to content

Commit 906dbc2

Browse files
authored
Test Executorlib (#17)
* Clean up pure python * Add executorlib interface * Add notebooks * fix syntax * get_item() * update notebooks
1 parent 1adbba9 commit 906dbc2

File tree

5 files changed

+91
-16
lines changed

5 files changed

+91
-16
lines changed

.github/workflows/executorlib.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: executorlib
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
8+
jobs:
9+
build:
10+
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: conda-incubator/setup-miniconda@v3
16+
with:
17+
auto-update-conda: true
18+
python-version: "3.12"
19+
environment-file: environment.yml
20+
auto-activate-base: false
21+
- name: Tests
22+
shell: bash -l {0}
23+
run: |
24+
pip install -e adis_tools
25+
pip install -e python_workflow_definition
26+
conda install -c conda-forge jupyter papermill
27+
export ESPRESSO_PSEUDO=$(pwd)/espresso/pseudo
28+
papermill universal_simple_to_executorlib.ipynb universal_simple_to_executorlib_out.ipynb -k "python3"
29+
papermill universal_qe_to_executorlib.ipynb universal_qe_to_executorlib_out.ipynb -k "python3"
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import json
2+
from importlib import import_module
3+
from inspect import isfunction
4+
5+
6+
from python_workflow_definition.shared import get_dict, get_list, get_kwargs, get_source_handles
7+
from python_workflow_definition.purepython import resort_total_lst, group_edges
8+
9+
10+
def get_item(obj, key):
11+
return obj[key]
12+
13+
14+
def _get_value(result_dict, nodes_new_dict, link_dict, exe):
15+
source, source_handle = link_dict["source"], link_dict["sourceHandle"]
16+
if source in result_dict.keys():
17+
result = result_dict[source]
18+
elif source in nodes_new_dict.keys():
19+
result = nodes_new_dict[source]
20+
else:
21+
raise KeyError()
22+
if source_handle is None:
23+
return result
24+
else:
25+
return exe.submit(fn=get_item, obj=result, key=source_handle)
26+
27+
28+
def load_workflow_json(file_name, exe):
29+
with open(file_name, "r") as f:
30+
content = json.load(f)
31+
32+
edges_new_lst = content["edges"]
33+
nodes_new_dict = {}
34+
for k, v in content["nodes"].items():
35+
if isinstance(v, str) and "." in v:
36+
p, m = v.rsplit('.', 1)
37+
mod = import_module(p)
38+
nodes_new_dict[int(k)] = getattr(mod, m)
39+
else:
40+
nodes_new_dict[int(k)] = v
41+
42+
total_lst = group_edges(edges_new_lst)
43+
total_new_lst = resort_total_lst(total_lst=total_lst, nodes_dict=nodes_new_dict)
44+
45+
result_dict = {}
46+
last_key = None
47+
for lst in total_new_lst:
48+
node = nodes_new_dict[lst[0]]
49+
if isfunction(node):
50+
kwargs = {
51+
k: _get_value(result_dict=result_dict, nodes_new_dict=nodes_new_dict, link_dict=v, exe=exe)
52+
for k, v in lst[1].items()
53+
}
54+
result_dict[lst[0]] = exe.submit(node, **kwargs)
55+
last_key = lst[0]
56+
57+
return result_dict[last_key]

python_workflow_definition/src/python_workflow_definition/purepython.py

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from inspect import isfunction
44

55

6-
from python_workflow_definition.shared import get_dict, get_list, get_kwargs
6+
from python_workflow_definition.shared import get_dict, get_list, get_kwargs, get_source_handles
77

88

99
def resort_total_lst(total_lst, nodes_dict):
@@ -35,20 +35,7 @@ def group_edges(edges_lst):
3535
return total_lst
3636

3737

38-
def get_source_handles(edges_lst):
39-
source_handle_dict = {}
40-
for ed in edges_lst:
41-
if ed['source'] not in source_handle_dict.keys():
42-
source_handle_dict[ed['source']] = [ed['sourceHandle']]
43-
else:
44-
source_handle_dict[ed['source']].append(ed['sourceHandle'])
45-
return {
46-
k: list(range(len(v))) if len(v) > 1 and all([el is None for el in v]) else v
47-
for k, v in source_handle_dict.items()
48-
}
49-
50-
51-
def get_value(result_dict, nodes_new_dict, link_dict):
38+
def _get_value(result_dict, nodes_new_dict, link_dict):
5239
source, source_handle = link_dict["source"], link_dict["sourceHandle"]
5340
if source in result_dict.keys():
5441
result = result_dict[source]
@@ -85,7 +72,7 @@ def load_workflow_json(file_name):
8572
node = nodes_new_dict[lst[0]]
8673
if isfunction(node):
8774
kwargs = {
88-
k: get_value(result_dict=result_dict, nodes_new_dict=nodes_new_dict, link_dict=v)
75+
k: _get_value(result_dict=result_dict, nodes_new_dict=nodes_new_dict, link_dict=v)
8976
for k, v in lst[1].items()
9077
}
9178
result_dict[lst[0]] = node(**kwargs)

universal_qe_to_executorlib.ipynb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"metadata":{"kernelspec":{"display_name":"Python 3 (ipykernel)","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.12.8","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":5,"nbformat":4,"cells":[{"id":"ae0b5775-fb9d-4150-be79-d48dfb0b2cf4","cell_type":"code","source":"from executorlib import SingleNodeExecutor","metadata":{"trusted":true},"outputs":[],"execution_count":1},{"id":"b0f920a2-c646-485b-af0f-48251e061163","cell_type":"code","source":"from python_workflow_definition.executorlib import load_workflow_json","metadata":{"trusted":true},"outputs":[],"execution_count":2},{"id":"46559120-d58a-492f-b734-db27424b5659","cell_type":"code","source":"with SingleNodeExecutor(max_workers=1) as exe:\n result = load_workflow_json(file_name=\"workflow_qe.json\", exe=exe).result()","metadata":{"trusted":true},"outputs":[{"name":"stderr","output_type":"stream","text":"[jupyter-pyiron-dev-pyth-flow-definition-4gvxle22:01655] mca_base_component_repository_open: unable to open mca_btl_openib: librdmacm.so.1: cannot open shared object file: No such file or directory (ignored)\nNote: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG\n[jupyter-pyiron-dev-pyth-flow-definition-4gvxle22:01891] mca_base_component_repository_open: unable to open mca_btl_openib: librdmacm.so.1: cannot open shared object file: No such file or directory (ignored)\nNote: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG\n[jupyter-pyiron-dev-pyth-flow-definition-4gvxle22:01962] mca_base_component_repository_open: unable to open mca_btl_openib: librdmacm.so.1: cannot open shared object file: No such file or directory (ignored)\nNote: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG\n[jupyter-pyiron-dev-pyth-flow-definition-4gvxle22:02029] mca_base_component_repository_open: unable to open mca_btl_openib: librdmacm.so.1: cannot open shared object file: No such file or directory (ignored)\nNote: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG\n[jupyter-pyiron-dev-pyth-flow-definition-4gvxle22:02093] mca_base_component_repository_open: unable to open mca_btl_openib: librdmacm.so.1: cannot open shared object file: No such file or directory (ignored)\nNote: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG\n[jupyter-pyiron-dev-pyth-flow-definition-4gvxle22:02159] mca_base_component_repository_open: unable to open mca_btl_openib: librdmacm.so.1: cannot open shared object file: No such file or directory (ignored)\nNote: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG\n"}],"execution_count":3},{"id":"b37f476d-b7f8-4400-8070-83f8f2eb8bf9","cell_type":"code","source":"result","metadata":{"trusted":true},"outputs":[],"execution_count":4},{"id":"336dfbea-7e5c-4950-a0b3-c027a2a8e935","cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"metadata":{"kernelspec":{"display_name":"Python 3 (ipykernel)","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.12.8","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":5,"nbformat":4,"cells":[{"id":"ae0b5775-fb9d-4150-be79-d48dfb0b2cf4","cell_type":"code","source":"from executorlib import SingleNodeExecutor","metadata":{"trusted":true},"outputs":[],"execution_count":1},{"id":"b0f920a2-c646-485b-af0f-48251e061163","cell_type":"code","source":"from python_workflow_definition.executorlib import load_workflow_json","metadata":{"trusted":true},"outputs":[],"execution_count":2},{"id":"46559120-d58a-492f-b734-db27424b5659","cell_type":"code","source":"with SingleNodeExecutor(max_workers=1) as exe:\n result = load_workflow_json(file_name=\"workflow_simple.json\", exe=exe).result()","metadata":{"trusted":true},"outputs":[],"execution_count":3},{"id":"b37f476d-b7f8-4400-8070-83f8f2eb8bf9","cell_type":"code","source":"result","metadata":{"trusted":true},"outputs":[{"execution_count":4,"output_type":"execute_result","data":{"text/plain":"6"},"metadata":{}}],"execution_count":4},{"id":"336dfbea-7e5c-4950-a0b3-c027a2a8e935","cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}

0 commit comments

Comments
 (0)