Skip to content
Closed
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
3 changes: 2 additions & 1 deletion dace/sdfg/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from dace.dtypes import deduplicate
import dace.serialize
from typing import Any, Callable, Generic, Iterable, List, Optional, Sequence, TypeVar, Union
from ordered_set import OrderedSet


class NodeNotFoundError(Exception):
Expand Down Expand Up @@ -215,7 +216,7 @@ def __getitem__(self, node: NodeT) -> Iterable[NodeT]:

def all_edges(self, *nodes: NodeT) -> Iterable[Edge[EdgeT]]:
"""Returns an iterable to incoming and outgoing Edge objects."""
result = set()
result = OrderedSet()
for node in nodes:
result.update(self.in_edges(node))
result.update(self.out_edges(node))
Expand Down
7 changes: 4 additions & 3 deletions dace/sdfg/scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from dace.config import Config
from dace.sdfg import nodes as nd
from dace.sdfg.state import StateSubgraphView
from ordered_set import OrderedSet

ScopeDictType = Dict[nd.Node, List[nd.Node]]

Expand Down Expand Up @@ -62,16 +63,16 @@ def _scope_subgraph(graph, entry_node, include_entry, include_exit) -> ScopeSubg
raise TypeError("Received {}: should be dace.nodes.EntryNode".format(type(entry_node).__name__))
node_to_children = graph.scope_children()
if include_exit:
children_nodes = set(node_to_children[entry_node])
children_nodes = OrderedSet(node_to_children[entry_node])
else:
children_nodes = set(n for n in node_to_children[entry_node] if not isinstance(n, nd.ExitNode))
children_nodes = OrderedSet(n for n in node_to_children[entry_node] if not isinstance(n, nd.ExitNode))
map_nodes = [node for node in children_nodes if isinstance(node, nd.EntryNode)]
while len(map_nodes) > 0:
next_map_nodes = []
# Traverse children map nodes
for map_node in map_nodes:
# Get child map subgraph (1 level)
more_nodes = set(node_to_children[map_node])
more_nodes = OrderedSet(node_to_children[map_node])
# Unionize children_nodes with new nodes
children_nodes |= more_nodes
# Add nodes of the next level to next_map_nodes
Expand Down
8 changes: 6 additions & 2 deletions dace/sdfg/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -1790,9 +1790,13 @@ def add_nested_sdfg(
sdfg.update_cfg_list([])

# Make dictionary of autodetect connector types from set
if isinstance(inputs, (set, collections.abc.KeysView)):
# TODO(tehrengruber): Using sets here leads to a situation where self._nodes has a different
# ordering, but to_json from_json restores the order again. Investigate.
if isinstance(inputs, set) or isinstance(outputs, set):
warnings.warn("Using sets as inputs is discouraged as it leads to indeterministic behavior.")
Comment thread
edopao marked this conversation as resolved.
if isinstance(inputs, (set, collections.abc.KeysView, collections.abc.Set)):
inputs = {k: None for k in inputs}
if isinstance(outputs, (set, collections.abc.KeysView)):
if isinstance(outputs, (set, collections.abc.KeysView, collections.abc.Set)):
outputs = {k: None for k in outputs}

s = nd.NestedSDFG(
Expand Down
17 changes: 9 additions & 8 deletions dace/transformation/dataflow/map_fusion_vertical.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from dace.sdfg import SDFG, SDFGState, graph, nodes, propagation
from dace.transformation.dataflow import map_fusion_helper as mfhelper
from dace.sdfg.type_inference import infer_expr_type
from ordered_set import OrderedSet


@properties.make_properties
Expand Down Expand Up @@ -405,9 +406,9 @@ def partition_first_outputs(
param_repl: Dict[str, str],
) -> Union[
Tuple[
Set[graph.MultiConnectorEdge[dace.Memlet]],
Set[graph.MultiConnectorEdge[dace.Memlet]],
Set[graph.MultiConnectorEdge[dace.Memlet]],
OrderedSet[graph.MultiConnectorEdge[dace.Memlet]],
OrderedSet[graph.MultiConnectorEdge[dace.Memlet]],
OrderedSet[graph.MultiConnectorEdge[dace.Memlet]],
],
None,
]:
Expand Down Expand Up @@ -447,9 +448,9 @@ def partition_first_outputs(
`require_all_intermediates` and by `self.require_exclusive_intermediates`.
"""
# The three outputs set.
pure_outputs: Set[graph.MultiConnectorEdge[dace.Memlet]] = set()
exclusive_outputs: Set[graph.MultiConnectorEdge[dace.Memlet]] = set()
shared_outputs: Set[graph.MultiConnectorEdge[dace.Memlet]] = set()
pure_outputs: Set[graph.MultiConnectorEdge[dace.Memlet]] = OrderedSet()
exclusive_outputs: Set[graph.MultiConnectorEdge[dace.Memlet]] = OrderedSet()
shared_outputs: Set[graph.MultiConnectorEdge[dace.Memlet]] = OrderedSet()

# Set of intermediate nodes that we have already processed.
processed_inter_nodes: Set[nodes.Node] = set()
Expand Down Expand Up @@ -703,7 +704,7 @@ def partition_first_outputs(

def handle_intermediate_set(
self,
intermediate_outputs: Set[graph.MultiConnectorEdge[dace.Memlet]],
intermediate_outputs: OrderedSet[graph.MultiConnectorEdge[dace.Memlet]],
state: dace.SDFGState,
sdfg: SDFG,
first_map_exit: nodes.MapExit,
Expand Down Expand Up @@ -870,7 +871,7 @@ def handle_intermediate_set(
# the input connectors on the MapEntry, such that we know where we
# have to reroute inside the Map.
# NOTE: Assumes that Map (if connected is the direct neighbour).
conn_names: Set[str] = set()
conn_names: OrderedSet[str] = OrderedSet()
for inter_node_out_edge in state.out_edges(inter_node):
if inter_node_out_edge.dst == second_map_entry:
assert inter_node_out_edge.dst_conn.startswith("IN_")
Expand Down
9 changes: 4 additions & 5 deletions dace/transformation/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -865,10 +865,9 @@ def isolate_nested_sdfg(
# These are the nodes that belongs to the Post State. There are two reasons why a
# node belongs to the set of post nodes.
# The first is that the node does not belong to any other set.
post_nodes: Set[nodes.Node] = {
node
for node in state.nodes() if (node not in pre_nodes) and (node not in middle_nodes)
}
post_nodes: list[nodes.Node] = [
node for node in state.nodes() if (node not in pre_nodes) and (node not in middle_nodes)
]

# The second reason, are read dependencies, for this we have to look at the incoming
# edges and add any node that we need.
Expand All @@ -881,7 +880,7 @@ def isolate_nested_sdfg(
if test_if_applicable:
return False
raise ValueError("Can not replicate non non-View AccessNodes into the post state.")
post_nodes.add(node)
post_nodes.append(node)

if test_if_applicable:
return True
Expand Down
13 changes: 5 additions & 8 deletions dace/transformation/pass_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ class Pass:

CATEGORY: str = 'Helper'

def depends_on(self) -> Set[Union[Type['Pass'], 'Pass']]:
def depends_on(self) -> List[Union[Type['Pass'], 'Pass']]:
"""
If in the context of a ``Pipeline``, which other Passes need to run first.

:return: A set of Pass subclasses or objects that need to run prior to this Pass.
"""
return set()
return []
Comment on lines +58 to +64

def modifies(self) -> Modifies:
"""
Expand Down Expand Up @@ -412,7 +412,7 @@ class Pipeline(Pass):

def __init__(self, passes: List[Pass]):
self.passes = []
self._pass_names = set(type(p).__name__ for p in passes)
self._pass_names = set(type(p).__name__ for p in passes) # todo sort this?
self.passes.extend(passes)

# Add missing Pass dependencies
Expand Down Expand Up @@ -482,11 +482,8 @@ def modifies(self) -> Modifies:
def should_reapply(self, modified: Modifies) -> bool:
return any(p.should_reapply(modified) for p in self.passes)

def depends_on(self) -> Set[Type[Pass]]:
result = set()
for p in self.passes:
result.update(p.depends_on())
return result
def depends_on(self) -> List[Type[Pass]]:
return list(dict.fromkeys([p.depends_on() for p in self.passes]))
Comment on lines +485 to +486

def _make_dependency_graph(self) -> gr.OrderedDiGraph:
"""
Expand Down
Loading