computation-graph 69__tar.gz → 70__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-69 → computation_graph-70}/PKG-INFO +1 -1
- {computation_graph-69 → computation_graph-70}/computation_graph/composers/__init__.py +37 -29
- {computation_graph-69 → computation_graph-70}/computation_graph/composers/duplication.py +2 -2
- {computation_graph-69 → computation_graph-70}/computation_graph/graph.py +39 -31
- {computation_graph-69 → computation_graph-70}/computation_graph/graph_runners.py +2 -2
- {computation_graph-69 → computation_graph-70}/computation_graph/run.py +4 -6
- {computation_graph-69 → computation_graph-70}/computation_graph/signature.py +1 -36
- {computation_graph-69 → computation_graph-70}/computation_graph.egg-info/PKG-INFO +1 -1
- {computation_graph-69 → computation_graph-70}/setup.py +1 -1
- {computation_graph-69 → computation_graph-70}/LICENSE.md +0 -0
- {computation_graph-69 → computation_graph-70}/README.md +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/__init__.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/base_types.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/composers/composers_test.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/composers/condition.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/composers/condition_test.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/composers/debug.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/composers/lift.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/composers/lift_test.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/composers/logic.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/composers/memory.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/composers/memory_test.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/graph_test.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/infer_sink.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/infer_sink_test.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/legacy.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/trace/__init__.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/trace/ascii.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/trace/graphviz.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/trace/graphviz_test.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/trace/mermaid.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph/trace/trace_utils.py +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph.egg-info/SOURCES.txt +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph.egg-info/dependency_links.txt +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph.egg-info/requires.txt +0 -0
- {computation_graph-69 → computation_graph-70}/computation_graph.egg-info/top_level.txt +0 -0
- {computation_graph-69 → computation_graph-70}/pyproject.toml +0 -0
- {computation_graph-69 → computation_graph-70}/setup.cfg +0 -0
|
@@ -286,36 +286,44 @@ def _infer_composition_edges(
|
|
|
286
286
|
unbound_signature = graph.unbound_signature(
|
|
287
287
|
graph.get_incoming_edges_for_node(destination.edges)
|
|
288
288
|
)
|
|
289
|
-
source_nodes = (
|
|
290
|
-
graph.get_all_nodes(source.edges)
|
|
291
|
-
if isinstance(source, GraphType)
|
|
292
|
-
else frozenset()
|
|
293
|
-
)
|
|
294
|
-
skip_cycle_check = isinstance(source, base_types.ComputationNode)
|
|
295
|
-
new_edges = set()
|
|
296
|
-
# The connectable-node set is order-independent (result is a frozenset), so we
|
|
297
|
-
# can iterate the cached node set instead of rescanning the edges.
|
|
298
|
-
for node in graph.get_all_nodes(destination.edges):
|
|
299
|
-
node_signature = unbound_signature(node)
|
|
300
|
-
if not (
|
|
301
|
-
key in node_signature.kwargs
|
|
302
|
-
or (key is None and signature.is_unary(node_signature))
|
|
303
|
-
):
|
|
304
|
-
continue
|
|
305
|
-
# Do not add edges to nodes from source that are already present in destination (cycle).
|
|
306
|
-
if not skip_cycle_check and node in source_nodes:
|
|
307
|
-
continue
|
|
308
|
-
new_edges.add(
|
|
309
|
-
try_connect(destination=node, unbound_destination_signature=node_signature)
|
|
310
|
-
)
|
|
311
|
-
if not new_edges:
|
|
312
|
-
raise AssertionError(
|
|
313
|
-
f"Cannot compose, destination signature does not contain key '{key}'"
|
|
314
|
-
)
|
|
315
289
|
return graph.merge_graphs(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
290
|
+
gamla.sync.pipe(
|
|
291
|
+
destination,
|
|
292
|
+
gamla.attrgetter("edges"),
|
|
293
|
+
gamla.sync.mapcat(graph.get_edge_nodes),
|
|
294
|
+
gamla.unique,
|
|
295
|
+
gamla.sync.filter(
|
|
296
|
+
gamla.sync.compose_left(
|
|
297
|
+
unbound_signature,
|
|
298
|
+
lambda sig: key in sig.kwargs
|
|
299
|
+
or (key is None and signature.is_unary(sig)),
|
|
300
|
+
)
|
|
301
|
+
),
|
|
302
|
+
# Do not add edges to nodes from source that are already present in destination (cycle).
|
|
303
|
+
gamla.sync.filter(
|
|
304
|
+
lambda node: isinstance(source, base_types.ComputationNode)
|
|
305
|
+
or node
|
|
306
|
+
not in graph.get_all_nodes(
|
|
307
|
+
source.edges if isinstance(source, GraphType) else source
|
|
308
|
+
)
|
|
309
|
+
),
|
|
310
|
+
gamla.sync.map(
|
|
311
|
+
lambda destination_node: try_connect(
|
|
312
|
+
destination=destination_node,
|
|
313
|
+
unbound_destination_signature=unbound_signature(destination_node),
|
|
314
|
+
)
|
|
315
|
+
),
|
|
316
|
+
frozenset,
|
|
317
|
+
gamla.sync.check(
|
|
318
|
+
gamla.identity,
|
|
319
|
+
AssertionError(
|
|
320
|
+
f"Cannot compose, destination signature does not contain key '{key}'"
|
|
321
|
+
),
|
|
322
|
+
),
|
|
323
|
+
# Sink is a placeholder here; `merge_graphs` below sets the real sink
|
|
324
|
+
# via `sink_node_or_graph`.
|
|
325
|
+
lambda edges: GraphType(edges, None), # type: ignore[arg-type]
|
|
326
|
+
),
|
|
319
327
|
_get_edges_from_node_or_graph(source),
|
|
320
328
|
destination,
|
|
321
329
|
sink_node_or_graph=_determine_sink(source, destination, is_future),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import dataclasses
|
|
2
3
|
import functools
|
|
3
|
-
import inspect
|
|
4
4
|
from typing import Dict
|
|
5
5
|
|
|
6
6
|
import gamla
|
|
@@ -10,7 +10,7 @@ from computation_graph.composers import debug
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def duplicate_function(func):
|
|
13
|
-
if
|
|
13
|
+
if asyncio.iscoroutinefunction(func):
|
|
14
14
|
|
|
15
15
|
@functools.wraps(func)
|
|
16
16
|
async def inner(*args, **kwargs):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import dataclasses
|
|
2
2
|
import functools
|
|
3
|
-
from typing import Callable, Dict, FrozenSet,
|
|
3
|
+
from typing import Callable, Dict, FrozenSet, Optional, Tuple
|
|
4
4
|
|
|
5
5
|
import gamla
|
|
6
6
|
from gamla.optimized import sync as opt_gamla
|
|
@@ -64,17 +64,11 @@ def make_computation_node(
|
|
|
64
64
|
)
|
|
65
65
|
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
) -> Callable[[base_types.ComputationNode], FrozenSet[base_types.ComputationEdge]]:
|
|
73
|
-
grouped: Dict[base_types.ComputationNode, list] = {}
|
|
74
|
-
for edge in edges:
|
|
75
|
-
grouped.setdefault(edge.destination, []).append(edge)
|
|
76
|
-
node_to_edges = {node: frozenset(group) for node, group in grouped.items()}
|
|
77
|
-
return lambda node: node_to_edges.get(node, _EMPTY_EDGE_SET)
|
|
67
|
+
get_incoming_edges_for_node = opt_gamla.compose_left(
|
|
68
|
+
opt_gamla.groupby(base_types.edge_destination),
|
|
69
|
+
opt_gamla.valmap(frozenset),
|
|
70
|
+
gamla.dict_to_getter_with_default(frozenset()),
|
|
71
|
+
)
|
|
78
72
|
|
|
79
73
|
|
|
80
74
|
get_terminals = opt_gamla.compose_left(
|
|
@@ -101,24 +95,30 @@ def make_terminal(name: str, func: Callable) -> base_types.ComputationNode:
|
|
|
101
95
|
)
|
|
102
96
|
|
|
103
97
|
|
|
98
|
+
_keep_not_in_bound_kwargs = opt_gamla.compose_left(
|
|
99
|
+
opt_gamla.map(base_types.edge_key),
|
|
100
|
+
gamla.filter(gamla.identity),
|
|
101
|
+
frozenset,
|
|
102
|
+
gamla.contains,
|
|
103
|
+
gamla.remove,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
|
|
104
107
|
@gamla.curry
|
|
105
108
|
def unbound_signature(
|
|
106
109
|
node_to_incoming_edges, node: base_types.ComputationNode
|
|
107
110
|
) -> base_types.NodeSignature:
|
|
108
111
|
"""Computes the new signature of unbound variables after considering internal edges."""
|
|
109
112
|
incoming_edges = node_to_incoming_edges(node)
|
|
110
|
-
|
|
111
|
-
node_signature = node.signature
|
|
113
|
+
keep_not_in_bound_kwargs = _keep_not_in_bound_kwargs(incoming_edges)
|
|
112
114
|
return base_types.NodeSignature(
|
|
113
|
-
is_kwargs=
|
|
114
|
-
and
|
|
115
|
-
and signature.is_unary(
|
|
116
|
-
is_args=
|
|
115
|
+
is_kwargs=node.signature.is_kwargs
|
|
116
|
+
and "**kwargs" not in tuple(opt_gamla.map(base_types.edge_key)(incoming_edges))
|
|
117
|
+
and signature.is_unary(node.signature),
|
|
118
|
+
is_args=node.signature.is_args
|
|
117
119
|
and not any(edge.args for edge in incoming_edges),
|
|
118
|
-
kwargs=tuple(
|
|
119
|
-
optional_kwargs=tuple(
|
|
120
|
-
k for k in node_signature.optional_kwargs if k not in bound_keys
|
|
121
|
-
),
|
|
120
|
+
kwargs=tuple(keep_not_in_bound_kwargs(node.signature.kwargs)),
|
|
121
|
+
optional_kwargs=tuple(keep_not_in_bound_kwargs(node.signature.optional_kwargs)),
|
|
122
122
|
)
|
|
123
123
|
|
|
124
124
|
|
|
@@ -361,20 +361,28 @@ def merge_graphs(
|
|
|
361
361
|
isinstance(x, base_types.GraphType) for x in graphs
|
|
362
362
|
), f"{graphs} not a graph"
|
|
363
363
|
assert (
|
|
364
|
-
not
|
|
365
|
-
or not sink_node_or_graph.edges
|
|
364
|
+
not base_types.is_computation_graph(sink_node_or_graph)
|
|
366
365
|
or sink_node_or_graph in graphs
|
|
367
366
|
), "sink graph must be one of the graphs being merged"
|
|
368
367
|
|
|
369
|
-
new_g =
|
|
370
|
-
|
|
371
|
-
|
|
368
|
+
new_g = gamla.pipe(
|
|
369
|
+
graphs,
|
|
370
|
+
gamla.remove(gamla.equals(base_types.EMPTY_GRAPH)),
|
|
371
|
+
tuple,
|
|
372
|
+
gamla.pair_right(
|
|
373
|
+
gamla.just(
|
|
374
|
+
sink_node_or_graph.sink
|
|
375
|
+
if isinstance(sink_node_or_graph, base_types.GraphType)
|
|
376
|
+
else sink_node_or_graph
|
|
377
|
+
)
|
|
372
378
|
),
|
|
373
|
-
(
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
379
|
+
gamla.packstack(
|
|
380
|
+
gamla.compose_left(
|
|
381
|
+
gamla.map(gamla.attrgetter("edges")), gamla.star(base_types.merge_edges)
|
|
382
|
+
),
|
|
383
|
+
gamla.identity,
|
|
377
384
|
),
|
|
385
|
+
gamla.star(base_types.GraphType),
|
|
378
386
|
)
|
|
379
387
|
|
|
380
388
|
if base_types.is_debug_mode():
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import asyncio
|
|
2
2
|
from typing import Callable, Union
|
|
3
3
|
|
|
4
4
|
import gamla
|
|
@@ -77,7 +77,7 @@ def unary_with_state_and_expectations(
|
|
|
77
77
|
def variadic_with_state_and_expectations(g, sink):
|
|
78
78
|
f = run.to_callable_strict(g)
|
|
79
79
|
|
|
80
|
-
if
|
|
80
|
+
if asyncio.iscoroutinefunction(f):
|
|
81
81
|
|
|
82
82
|
async def inner(turns):
|
|
83
83
|
prev = {}
|
|
@@ -109,7 +109,7 @@ _is_graph_async = opt_gamla.compose_left(
|
|
|
109
109
|
opt_gamla.mapcat(lambda edge: (edge.source, *edge.args)),
|
|
110
110
|
opt_gamla.remove(gamla.equals(None)),
|
|
111
111
|
opt_gamla.map(base_types.node_implementation),
|
|
112
|
-
gamla.anymap(
|
|
112
|
+
gamla.anymap(asyncio.iscoroutinefunction),
|
|
113
113
|
)
|
|
114
114
|
|
|
115
115
|
|
|
@@ -452,7 +452,7 @@ def _make_get_node_executor(
|
|
|
452
452
|
return result
|
|
453
453
|
|
|
454
454
|
all_nodes = graph.get_all_nodes(edges)
|
|
455
|
-
async_nodes = {n for n in all_nodes if
|
|
455
|
+
async_nodes = {n for n in all_nodes if asyncio.iscoroutinefunction(n.func)}
|
|
456
456
|
sync = all_nodes - async_nodes
|
|
457
457
|
tf = graph.traverse_forward(edges)
|
|
458
458
|
downstream_from_async = set(gamla.graph_traverse_many(async_nodes, tf))
|
|
@@ -572,9 +572,7 @@ to_callable = to_callable_with_side_effect(gamla.just(gamla.just(None)))
|
|
|
572
572
|
|
|
573
573
|
|
|
574
574
|
def _node_is_properly_composed(
|
|
575
|
-
node_to_incoming_edges:
|
|
576
|
-
[base_types.ComputationNode], FrozenSet[base_types.ComputationEdge]
|
|
577
|
-
]
|
|
575
|
+
node_to_incoming_edges: base_types.GraphType,
|
|
578
576
|
) -> Callable[[base_types.ComputationNode], bool]:
|
|
579
577
|
return gamla.compose_left(
|
|
580
578
|
graph.unbound_signature(node_to_incoming_edges),
|
|
@@ -583,7 +581,7 @@ def _node_is_properly_composed(
|
|
|
583
581
|
)
|
|
584
582
|
|
|
585
583
|
|
|
586
|
-
def _assert_composition_is_valid(g:
|
|
584
|
+
def _assert_composition_is_valid(g: base_types.GraphType):
|
|
587
585
|
return opt_gamla.pipe(
|
|
588
586
|
g,
|
|
589
587
|
graph.get_all_nodes,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
import inspect
|
|
3
|
-
import types
|
|
4
3
|
from types import MappingProxyType
|
|
5
4
|
from typing import Callable, FrozenSet
|
|
6
5
|
|
|
@@ -40,7 +39,7 @@ _func_parameters = gamla.compose_left(
|
|
|
40
39
|
)
|
|
41
40
|
|
|
42
41
|
|
|
43
|
-
def
|
|
42
|
+
def from_callable(func: Callable) -> base_types.NodeSignature:
|
|
44
43
|
function_parameters = _func_parameters(func)
|
|
45
44
|
return base_types.NodeSignature(
|
|
46
45
|
is_args=gamla.anymap(parameter_is_star)(function_parameters),
|
|
@@ -61,40 +60,6 @@ def _from_callable_via_inspect(func: Callable) -> base_types.NodeSignature:
|
|
|
61
60
|
)
|
|
62
61
|
|
|
63
62
|
|
|
64
|
-
def _as_plain_function(func: Callable):
|
|
65
|
-
"""The `inspect.signature`-equivalent target when it is a plain function whose
|
|
66
|
-
signature is fully described by its code object, else None (wrappers with
|
|
67
|
-
`__signature__`, partials, methods, builtins and classes need `inspect`)."""
|
|
68
|
-
unwrapped = inspect.unwrap(func, stop=lambda f: hasattr(f, "__signature__"))
|
|
69
|
-
if not isinstance(unwrapped, types.FunctionType) or hasattr(
|
|
70
|
-
unwrapped, "__signature__"
|
|
71
|
-
):
|
|
72
|
-
return None
|
|
73
|
-
return unwrapped
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def from_callable(func: Callable) -> base_types.NodeSignature:
|
|
77
|
-
plain_function = _as_plain_function(func)
|
|
78
|
-
if plain_function is None:
|
|
79
|
-
return _from_callable_via_inspect(func)
|
|
80
|
-
code = plain_function.__code__
|
|
81
|
-
positional = code.co_varnames[: code.co_argcount]
|
|
82
|
-
keyword_only = code.co_varnames[
|
|
83
|
-
code.co_argcount : code.co_argcount + code.co_kwonlyargcount
|
|
84
|
-
]
|
|
85
|
-
defaults = plain_function.__defaults__ or ()
|
|
86
|
-
keyword_defaults = plain_function.__kwdefaults__ or {}
|
|
87
|
-
return base_types.NodeSignature(
|
|
88
|
-
is_args=bool(code.co_flags & inspect.CO_VARARGS),
|
|
89
|
-
is_kwargs=bool(code.co_flags & inspect.CO_VARKEYWORDS),
|
|
90
|
-
kwargs=positional + keyword_only,
|
|
91
|
-
optional_kwargs=(
|
|
92
|
-
positional[len(positional) - len(defaults) :]
|
|
93
|
-
+ tuple(name for name in keyword_only if name in keyword_defaults)
|
|
94
|
-
),
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
|
|
98
63
|
def parameters(signature: base_types.NodeSignature) -> FrozenSet[str]:
|
|
99
64
|
return frozenset(
|
|
100
65
|
{
|
|
@@ -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="70",
|
|
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
|
|
File without changes
|
|
File without changes
|
{computation_graph-69 → computation_graph-70}/computation_graph.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|