Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Use the cached graph analysis of `ewokscore` (`TaskGraph.analysis`), which makes building
a workflow from a large graph faster.

## [3.1.0rc1] - 2026-08-04

### Added
Expand Down
21 changes: 11 additions & 10 deletions src/ewoksppf/bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from ewokscore import load_graph
from ewokscore import ppftasks
from ewokscore.graph import TaskGraph
from ewokscore.graph import analysis
from ewokscore.graph import graph_io
from ewokscore.inittask import task_executable
from ewokscore.inittask import task_executable_info
Expand Down Expand Up @@ -467,9 +466,7 @@ def _create_task_actors(self, taskgraph: TaskGraph):
script=ppfrunscript.__name__ + ".dummy",
**self._actor_arguments,
)
if not analysis.node_has_successors(
taskgraph.graph, node_id, link_has_on_error=True
):
if not taskgraph.analysis.node_has_error_handlers(node_id):
self._connect_actors(actor, error_actor)
taskactors[node_id] = actor

Expand Down Expand Up @@ -526,7 +523,7 @@ def _create_source_actor(
source_actor = taskactors[source_id]
if conditions:
conditions = {c["source_output"]: c["value"] for c in conditions}
all_conditions = analysis.node_condition_values(taskgraph.graph, source_id)
all_conditions = taskgraph.analysis.node_condition_values(source_id)
conditions_else_value = taskgraph.graph.nodes[source_id].get(
"conditions_else_value", None
)
Expand Down Expand Up @@ -583,7 +580,7 @@ def _create_name_mapper(
cache_if_optional = link_attrs.get("cache_if_optional", False)

# Required link
required = analysis.link_is_required(taskgraph.graph, source_id, target_id)
required = taskgraph.analysis.link_is_required(source_id, target_id)

source_label = ppfname(source_id)
target_label = ppfname(target_id)
Expand Down Expand Up @@ -612,7 +609,7 @@ def _compile_target_actors(self, taskgraph: TaskGraph):
# task_name -> EwoksPythonActor
taskactors = self._taskactors
for target_id in taskgraph.graph.nodes:
predecessors = list(analysis.node_predecessors(taskgraph.graph, target_id))
predecessors = list(taskgraph.analysis.node_predecessors(target_id))
npredecessors = len(predecessors)
if npredecessors == 0:
targetactor = None
Expand Down Expand Up @@ -642,7 +639,7 @@ def _connect_start_actor(self, taskgraph: TaskGraph):
targetactors = self._targetactors
start_actor = self.startActor
has_start_node = False
for target_id in analysis.start_nodes(taskgraph.graph):
for target_id in taskgraph.analysis.start_nodes():
has_start_node = True
target_actor = targetactors.get(target_id)
if target_actor is None:
Expand All @@ -656,7 +653,7 @@ def _connect_stop_actor(self, taskgraph: TaskGraph):
taskactors = self._taskactors
stop_actor = self.stopActor
has_end_node = False
for source_id in analysis.end_nodes(taskgraph.graph):
for source_id in taskgraph.analysis.end_nodes():
has_end_node = True
source_actor = taskactors[source_id]
self._connect_actors(source_actor, stop_actor)
Expand Down Expand Up @@ -748,7 +745,11 @@ def _actor_outputs(
) -> Dict[EwoksPythonActor, List[OutputSelection]]:
"""Tell pypushflow which actor results need to be stored and how."""
actor_outputs: Dict[EwoksPythonActor, List[OutputSelection]] = dict()
for output_item in graph_io.parse_outputs(self.__ewoksgraph.graph, outputs):
for output_item in graph_io.parse_outputs(
self.__ewoksgraph.graph,
outputs,
graph_analysis=self.__ewoksgraph.analysis,
):
actor = self._taskactors.get(output_item["id"])
if actor is None:
# The output item refers to a node that is not in the graph
Expand Down
Loading