Fixes #1098: spack graph crashes for large graphs.

- Fixed logic for collapsing backward edges

- Last collapse now depends on whether prior step in left collapse
  sequence alrady did the collapse.
This commit is contained in:
Todd Gamblin 2016-09-27 23:28:51 -04:00
parent 0d3d74e5c2
commit f082d26ddd

View file

@ -128,7 +128,7 @@ def find(seq, predicate):
return -1 return -1
# Names of different graph line states. We Record previous line # Names of different graph line states. We record previous line
# states so that we can easily determine what to do when connecting. # states so that we can easily determine what to do when connecting.
states = ('node', 'collapse', 'merge-right', 'expand-right', 'back-edge') states = ('node', 'collapse', 'merge-right', 'expand-right', 'back-edge')
NODE, COLLAPSE, MERGE_RIGHT, EXPAND_RIGHT, BACK_EDGE = states NODE, COLLAPSE, MERGE_RIGHT, EXPAND_RIGHT, BACK_EDGE = states
@ -161,6 +161,9 @@ def _indent(self):
def _write_edge(self, string, index, sub=0): def _write_edge(self, string, index, sub=0):
"""Write a colored edge to the output stream.""" """Write a colored edge to the output stream."""
# Ignore empty frontier entries (they're just collapsed)
if not self._frontier[index]:
return
name = self._frontier[index][sub] name = self._frontier[index][sub]
edge = "@%s{%s}" % (self._name_to_color[name], string) edge = "@%s{%s}" % (self._name_to_color[name], string)
self._out.write(edge) self._out.write(edge)
@ -419,20 +422,26 @@ def write(self, spec, **kwargs):
if back: if back:
back.sort() back.sort()
prev_ends = [] prev_ends = []
collapse_l1 = False
for j, (b, d) in enumerate(back): for j, (b, d) in enumerate(back):
self._frontier[i].remove(d) self._frontier[i].remove(d)
if i - b > 1: if i - b > 1:
self._back_edge_line(prev_ends, b, i, False, collapse_l1 = any(not e for e in self._frontier)
'left-1') self._back_edge_line(
prev_ends, b, i, collapse_l1, 'left-1')
del prev_ends[:] del prev_ends[:]
prev_ends.append(b) prev_ends.append(b)
# Check whether we did ALL the deps as back edges, # Check whether we did ALL the deps as back edges,
# in which case we're done. # in which case we're done.
collapse = not self._frontier[i] pop = not self._frontier[i]
if collapse: collapse_l2 = pop
if collapse_l1:
collapse_l2 = False
if pop:
self._frontier.pop(i) self._frontier.pop(i)
self._back_edge_line(prev_ends, -1, -1, collapse, 'left-2') self._back_edge_line(
prev_ends, -1, -1, collapse_l2, 'left-2')
elif len(self._frontier[i]) > 1: elif len(self._frontier[i]) > 1:
# Expand forward after doing all back connections # Expand forward after doing all back connections