computation-graph 51__tar.gz → 53__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {computation-graph-51 → computation-graph-53}/PKG-INFO +1 -1
- {computation-graph-51 → computation-graph-53}/computation_graph/base_types.py +1 -1
- {computation-graph-51 → computation-graph-53}/computation_graph/composers/duplication.py +39 -2
- {computation-graph-51 → computation-graph-53}/computation_graph/graph.py +21 -2
- {computation-graph-51 → computation-graph-53}/computation_graph/graph_test.py +104 -2
- {computation-graph-51 → computation-graph-53}/computation_graph/run.py +9 -3
- {computation-graph-51 → computation-graph-53}/computation_graph.egg-info/PKG-INFO +1 -1
- {computation-graph-51 → computation-graph-53}/setup.py +1 -1
- {computation-graph-51 → computation-graph-53}/LICENSE.md +0 -0
- {computation-graph-51 → computation-graph-53}/README.md +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/__init__.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/composers/__init__.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/composers/composers_test.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/composers/condition.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/composers/condition_test.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/composers/debug.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/composers/lift.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/composers/logic.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/composers/memory.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/composers/memory_test.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/graph_runners.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/legacy.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/signature.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/trace/__init__.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/trace/ascii.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/trace/graphviz.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/trace/graphviz_test.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/trace/mermaid.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph/trace/trace_utils.py +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph.egg-info/SOURCES.txt +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph.egg-info/dependency_links.txt +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph.egg-info/requires.txt +0 -0
- {computation-graph-51 → computation-graph-53}/computation_graph.egg-info/top_level.txt +0 -0
- {computation-graph-51 → computation-graph-53}/pyproject.toml +0 -0
- {computation-graph-51 → computation-graph-53}/setup.cfg +0 -0
|
@@ -152,7 +152,7 @@ assert_no_unwanted_ambiguity = gamla.side_effect(
|
|
|
152
152
|
|
|
153
153
|
@gamla.side_effect
|
|
154
154
|
def _assert_no_unwanted_ambiguity_when_debug_set(graph):
|
|
155
|
-
if os.getenv(COMPUTATION_GRAPH_DEBUG_ENV_KEY):
|
|
155
|
+
if os.getenv(COMPUTATION_GRAPH_DEBUG_ENV_KEY) is not None:
|
|
156
156
|
assert_no_unwanted_ambiguity(graph)
|
|
157
157
|
|
|
158
158
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import functools
|
|
3
3
|
import inspect
|
|
4
|
+
from typing import Dict
|
|
4
5
|
|
|
5
6
|
import gamla
|
|
6
7
|
|
|
@@ -20,6 +21,7 @@ def duplicate_function(func):
|
|
|
20
21
|
def inner(*args, **kwargs):
|
|
21
22
|
return func(*args, **kwargs)
|
|
22
23
|
|
|
24
|
+
inner.__name__ = f"duplicate of {inner.__name__}"
|
|
23
25
|
return inner
|
|
24
26
|
|
|
25
27
|
|
|
@@ -42,8 +44,8 @@ _duplicate_node = gamla.compose_left(
|
|
|
42
44
|
graph.make_computation_node,
|
|
43
45
|
)
|
|
44
46
|
|
|
47
|
+
|
|
45
48
|
_node_to_duplicated_node = gamla.compose_left(
|
|
46
|
-
graph.get_all_nodes,
|
|
47
49
|
gamla.remove(base_types.node_is_terminal),
|
|
48
50
|
gamla.map(gamla.pair_right(_duplicate_node)),
|
|
49
51
|
dict,
|
|
@@ -51,7 +53,7 @@ _node_to_duplicated_node = gamla.compose_left(
|
|
|
51
53
|
)
|
|
52
54
|
|
|
53
55
|
duplicate_graph = gamla.compose_left(
|
|
54
|
-
gamla.pair_with(_node_to_duplicated_node),
|
|
56
|
+
gamla.pair_with(gamla.compose_left(graph.get_all_nodes, _node_to_duplicated_node)),
|
|
55
57
|
gamla.star(
|
|
56
58
|
lambda get_duplicated_node, graph: gamla.pipe(
|
|
57
59
|
graph,
|
|
@@ -68,3 +70,38 @@ duplicate_graph = gamla.compose_left(
|
|
|
68
70
|
duplicate_function_or_graph = gamla.ternary(
|
|
69
71
|
gamla.is_instance(tuple), duplicate_graph, duplicate_function
|
|
70
72
|
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def safe_replace_sources(
|
|
76
|
+
source_to_replacement_dict: Dict[
|
|
77
|
+
base_types.CallableOrNode, base_types.CallableOrNodeOrGraph
|
|
78
|
+
],
|
|
79
|
+
cg: base_types.GraphType,
|
|
80
|
+
) -> base_types.GraphType:
|
|
81
|
+
source_to_replacement_dict = gamla.keymap(graph.make_computation_node)(
|
|
82
|
+
source_to_replacement_dict
|
|
83
|
+
)
|
|
84
|
+
reachable_to_duplicate_map = gamla.pipe(
|
|
85
|
+
gamla.graph_traverse_many(
|
|
86
|
+
source_to_replacement_dict.keys(), graph.traverse_forward(cg)
|
|
87
|
+
),
|
|
88
|
+
gamla.remove(gamla.contains(source_to_replacement_dict.keys())),
|
|
89
|
+
_node_to_duplicated_node,
|
|
90
|
+
)
|
|
91
|
+
get_node_replacement = gamla.compose_left(
|
|
92
|
+
gamla.lazyjuxt(
|
|
93
|
+
gamla.dict_to_getter_with_default(None)(source_to_replacement_dict),
|
|
94
|
+
reachable_to_duplicate_map,
|
|
95
|
+
gamla.identity,
|
|
96
|
+
),
|
|
97
|
+
gamla.find(gamla.identity),
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
def update_edge(e: base_types.ComputationEdge) -> base_types.GraphType:
|
|
101
|
+
dest = base_types.edge_destination(e)
|
|
102
|
+
g = graph.replace_node(dest, get_node_replacement(dest))((e,))
|
|
103
|
+
for source in base_types.edge_sources(e):
|
|
104
|
+
g = graph.replace_source(source, get_node_replacement(source), g)
|
|
105
|
+
return g
|
|
106
|
+
|
|
107
|
+
return gamla.reduce(lambda updated_cg, e: updated_cg + update_edge(e), (), cg)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import dataclasses
|
|
2
|
-
from typing import Callable, FrozenSet
|
|
2
|
+
from typing import Callable, FrozenSet, Tuple
|
|
3
3
|
|
|
4
4
|
import gamla
|
|
5
5
|
from gamla.optimized import sync as opt_gamla
|
|
@@ -148,6 +148,25 @@ def _replace_source_in_edges(
|
|
|
148
148
|
)
|
|
149
149
|
|
|
150
150
|
|
|
151
|
+
traverse_forward: Callable[
|
|
152
|
+
[base_types.GraphType],
|
|
153
|
+
Callable[[base_types.CallableOrNode], Tuple[base_types.ComputationNode, ...]],
|
|
154
|
+
] = gamla.compose_left(
|
|
155
|
+
gamla.mapcat(
|
|
156
|
+
gamla.compose_left(
|
|
157
|
+
gamla.juxt(base_types.edge_sources, base_types.edge_destination),
|
|
158
|
+
gamla.explode(0),
|
|
159
|
+
)
|
|
160
|
+
),
|
|
161
|
+
gamla.groupby_many_reduce(
|
|
162
|
+
gamla.compose_left(gamla.head, gamla.wrap_tuple),
|
|
163
|
+
lambda destinations, e: (*(destinations if destinations else ()), e[1]),
|
|
164
|
+
),
|
|
165
|
+
gamla.dict_to_getter_with_default(()),
|
|
166
|
+
gamla.before(make_computation_node),
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
|
|
151
170
|
@gamla.curry
|
|
152
171
|
def replace_source(
|
|
153
172
|
original: base_types.CallableOrNode,
|
|
@@ -158,7 +177,7 @@ def replace_source(
|
|
|
158
177
|
return current_graph
|
|
159
178
|
|
|
160
179
|
if gamla.is_instance(base_types.CallableOrNode)(replacement):
|
|
161
|
-
return _replace_source_in_edges(original, replacement)(current_graph)
|
|
180
|
+
return _replace_source_in_edges(original, replacement)(current_graph) # type: ignore
|
|
162
181
|
|
|
163
182
|
if base_types.is_computation_graph(replacement):
|
|
164
183
|
return gamla.pipe(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
from typing import Dict
|
|
2
3
|
|
|
3
4
|
import gamla
|
|
4
5
|
import pytest
|
|
@@ -445,7 +446,9 @@ def test_double_star_signature_considered_unary():
|
|
|
445
446
|
)
|
|
446
447
|
|
|
447
448
|
|
|
448
|
-
def test_type_safety_messages(caplog):
|
|
449
|
+
def test_type_safety_messages(caplog, monkeypatch):
|
|
450
|
+
monkeypatch.setenv(base_types.COMPUTATION_GRAPH_DEBUG_ENV_KEY, "j")
|
|
451
|
+
|
|
449
452
|
def f(x) -> int: # Bad typing!
|
|
450
453
|
return "hello " + x
|
|
451
454
|
|
|
@@ -456,7 +459,9 @@ def test_type_safety_messages(caplog):
|
|
|
456
459
|
assert "TypeError" in caplog.text
|
|
457
460
|
|
|
458
461
|
|
|
459
|
-
def test_type_safety_messages_no_overtrigger(caplog):
|
|
462
|
+
def test_type_safety_messages_no_overtrigger(caplog, monkeypatch):
|
|
463
|
+
monkeypatch.setenv(base_types.COMPUTATION_GRAPH_DEBUG_ENV_KEY, "h")
|
|
464
|
+
|
|
460
465
|
def f(x) -> str:
|
|
461
466
|
return "hello " + x
|
|
462
467
|
|
|
@@ -798,3 +803,100 @@ def test_ambig_edges_assertion_in_merge_graphs_active_only_when_env_var_is_activ
|
|
|
798
803
|
composers.compose_left_unary(lambda: 1, a),
|
|
799
804
|
composers.compose_left_unary(lambda: 1, a),
|
|
800
805
|
)
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
def a():
|
|
809
|
+
pass
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
def b(x):
|
|
813
|
+
pass
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
def c(x):
|
|
817
|
+
pass
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
def d(x, y):
|
|
821
|
+
pass
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
def kuky():
|
|
825
|
+
pass
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
def kuku():
|
|
829
|
+
pass
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
t = graph.make_terminal("t", lambda x: x)
|
|
833
|
+
|
|
834
|
+
g = (
|
|
835
|
+
composers.compose_left(a, c)
|
|
836
|
+
+ composers.compose_left(c, d, key="x")
|
|
837
|
+
+ composers.compose_left(b, d, key="y")
|
|
838
|
+
+ composers.compose_left_future(d, b, "x", "bla")
|
|
839
|
+
+ composers.compose_left(a, t)
|
|
840
|
+
)
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
@pytest.mark.parametrize(
|
|
844
|
+
"to_replace,expected_edges_strs",
|
|
845
|
+
[
|
|
846
|
+
pytest.param(
|
|
847
|
+
{a: kuky},
|
|
848
|
+
{
|
|
849
|
+
"kuky----x---->duplicate of c",
|
|
850
|
+
"kuky----x---->t",
|
|
851
|
+
"duplicate of c----x---->duplicate of d",
|
|
852
|
+
"when_memory_unavailable----x---->duplicate of b",
|
|
853
|
+
"duplicate of d....x....>duplicate of b",
|
|
854
|
+
"duplicate of b----y---->duplicate of d",
|
|
855
|
+
},
|
|
856
|
+
id="replace source node",
|
|
857
|
+
),
|
|
858
|
+
pytest.param(
|
|
859
|
+
{c: kuky},
|
|
860
|
+
{
|
|
861
|
+
"a----x---->kuky",
|
|
862
|
+
"a----x---->t",
|
|
863
|
+
"kuky----x---->duplicate of d",
|
|
864
|
+
"when_memory_unavailable----x---->duplicate of b",
|
|
865
|
+
"duplicate of d....x....>duplicate of b",
|
|
866
|
+
"duplicate of b----y---->duplicate of d",
|
|
867
|
+
},
|
|
868
|
+
id="replace node not in cycle",
|
|
869
|
+
),
|
|
870
|
+
pytest.param(
|
|
871
|
+
{b: kuky},
|
|
872
|
+
{
|
|
873
|
+
"a----x---->c",
|
|
874
|
+
"a----x---->t",
|
|
875
|
+
"c----x---->duplicate of d",
|
|
876
|
+
"when_memory_unavailable----x---->kuky",
|
|
877
|
+
"duplicate of d....x....>kuky",
|
|
878
|
+
"kuky----y---->duplicate of d",
|
|
879
|
+
},
|
|
880
|
+
id="replace node in cycle",
|
|
881
|
+
),
|
|
882
|
+
pytest.param(
|
|
883
|
+
{a: kuku, b: kuky},
|
|
884
|
+
{
|
|
885
|
+
"duplicate of c----x---->duplicate of d",
|
|
886
|
+
"duplicate of d....x....>kuky",
|
|
887
|
+
"kuku----x---->duplicate of c",
|
|
888
|
+
"kuku----x---->t",
|
|
889
|
+
"kuky----y---->duplicate of d",
|
|
890
|
+
"when_memory_unavailable----x---->kuky",
|
|
891
|
+
},
|
|
892
|
+
id="replace multiple nodes - duplicate reachables once",
|
|
893
|
+
),
|
|
894
|
+
],
|
|
895
|
+
)
|
|
896
|
+
def test_safe_replace_node(
|
|
897
|
+
to_replace: Dict[base_types.CallableOrNode, base_types.CallableOrNodeOrGraph],
|
|
898
|
+
expected_edges_strs: str,
|
|
899
|
+
):
|
|
900
|
+
assert expected_edges_strs == {
|
|
901
|
+
str(e) for e in duplication.safe_replace_sources(to_replace, g)
|
|
902
|
+
}
|
|
@@ -3,6 +3,7 @@ import dataclasses
|
|
|
3
3
|
import functools
|
|
4
4
|
import itertools
|
|
5
5
|
import logging
|
|
6
|
+
import os
|
|
6
7
|
import time
|
|
7
8
|
import typing
|
|
8
9
|
from typing import Any, Callable, Dict, FrozenSet, Set, Tuple, Type
|
|
@@ -41,7 +42,7 @@ def _transpose_graph(
|
|
|
41
42
|
|
|
42
43
|
|
|
43
44
|
_toposort_nodes: Callable[
|
|
44
|
-
[base_types.GraphType], Tuple[FrozenSet[base_types.ComputationNode], ...]
|
|
45
|
+
[base_types.GraphType], Tuple[FrozenSet[base_types.ComputationNode], ...]
|
|
45
46
|
] = opt_gamla.compose_left(
|
|
46
47
|
opt_gamla.groupby_many(base_types.edge_sources),
|
|
47
48
|
opt_gamla.valmap(
|
|
@@ -76,7 +77,6 @@ def _profile(node, time_started: float):
|
|
|
76
77
|
def _make_get_node_input_and_apply(
|
|
77
78
|
is_async: bool, side_effect: _SingleNodeSideEffect
|
|
78
79
|
) -> Callable[..., base_types.Result]:
|
|
79
|
-
|
|
80
80
|
if is_async:
|
|
81
81
|
|
|
82
82
|
@opt_async_gamla.star
|
|
@@ -149,6 +149,12 @@ def _to_callable_with_side_effect_for_single_and_multiple(
|
|
|
149
149
|
edges: base_types.GraphType,
|
|
150
150
|
handled_exceptions: Tuple[Type[Exception], ...],
|
|
151
151
|
) -> Callable[[_NodeToResults, _NodeToResults], _NodeToResults]:
|
|
152
|
+
single_node_side_effect = (
|
|
153
|
+
(lambda node, result: result)
|
|
154
|
+
if os.getenv(base_types.COMPUTATION_GRAPH_DEBUG_ENV_KEY) is None
|
|
155
|
+
else single_node_side_effect
|
|
156
|
+
)
|
|
157
|
+
|
|
152
158
|
future_sources = _graph_to_future_sources(edges)
|
|
153
159
|
future_source_to_placeholder = _map_future_source_to_placeholder(future_sources)
|
|
154
160
|
edges = gamla.pipe(
|
|
@@ -247,7 +253,7 @@ def _node_incoming_edges_to_input_spec(
|
|
|
247
253
|
|
|
248
254
|
def _edges_to_accumulated_results_to_node_to_first_possible_input(
|
|
249
255
|
edges,
|
|
250
|
-
) -> Callable[[_NodeToResults], _NodeToComputationInput
|
|
256
|
+
) -> Callable[[_NodeToResults], _NodeToComputationInput]:
|
|
251
257
|
node_to_incoming_edges = graph.get_incoming_edges_for_node(edges)
|
|
252
258
|
node_to_computation_input_spec_options: Callable[
|
|
253
259
|
[base_types.ComputationNode], Tuple[_ComputaionInputSpec]
|
|
@@ -7,7 +7,7 @@ with open("README.md", "r") as fh:
|
|
|
7
7
|
setuptools.setup(
|
|
8
8
|
name="computation-graph",
|
|
9
9
|
python_requires=">=3",
|
|
10
|
-
version="
|
|
10
|
+
version="53",
|
|
11
11
|
long_description=_LONG_DESCRIPTION,
|
|
12
12
|
long_description_content_type="text/markdown",
|
|
13
13
|
packages=setuptools.find_namespace_packages(),
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{computation-graph-51 → computation-graph-53}/computation_graph.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|