From 7e34a0f37e85a9492a8f4752b0dca190ed25ad67 Mon Sep 17 00:00:00 2001 From: JeremyIV Date: Wed, 9 Jun 2021 18:52:05 -0700 Subject: [PATCH 1/2] Improve error message when the graph contains cyclic dependencies --- graphkit/network.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/graphkit/network.py b/graphkit/network.py index 0df3ddf8..a968bdc7 100644 --- a/graphkit/network.py +++ b/graphkit/network.py @@ -27,6 +27,14 @@ class DeleteInstruction(str): def __repr__(self): return 'DeleteInstruction("%s")' % self +def _format_cycle(cycle): + operation_strings = [] + for second, first in reversed(cycle[1:] + [cycle[0]]): + if isinstance(first, DataPlaceholderNode) and operation_strings: + operation_strings[-1] += f' needs "{first}" from {second.name}.' + if isinstance(first, Operation): + operation_strings.append(first.name) + return "\n".join(operation_strings) class Network(object): """ @@ -107,8 +115,15 @@ def compile(self): self.steps = [] # create an execution order such that each layer's needs are provided. - ordered_nodes = list(nx.dag.topological_sort(self.graph)) - + try: + ordered_nodes = list(nx.dag.topological_sort(self.graph)) + except nx.exception.NetworkXUnfeasible as ex: + try: + cycle = nx.find_cycle(self.graph) + except nx.exception.NetworkXNoCycle: + raise ex + + raise Exception(f"Cyclic dependency in graph:\n{_format_cycle(cycle)}") # add Operations evaluation steps, and instructions to free data. for i, node in enumerate(ordered_nodes): From 6e0cdc27b89ee5e013abe5a505b85fd550fea088 Mon Sep 17 00:00:00 2001 From: JeremyIV Date: Tue, 15 Jun 2021 15:38:30 -0700 Subject: [PATCH 2/2] Change cyclic dependency error to a NetworkXUnfeasible error. --- graphkit/network.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/graphkit/network.py b/graphkit/network.py index a968bdc7..4ba36d53 100644 --- a/graphkit/network.py +++ b/graphkit/network.py @@ -122,8 +122,8 @@ def compile(self): cycle = nx.find_cycle(self.graph) except nx.exception.NetworkXNoCycle: raise ex - - raise Exception(f"Cyclic dependency in graph:\n{_format_cycle(cycle)}") + message = f"Cyclic dependency in graph:\n{_format_cycle(cycle)}" + raise nx.exception.NetworkXUnfeasible(message) # add Operations evaluation steps, and instructions to free data. for i, node in enumerate(ordered_nodes):