From 21439e3595e13d984f63d2e4c73aebd1580a22be Mon Sep 17 00:00:00 2001 From: Stefan Holst Date: Fri, 31 Oct 2025 17:12:50 +0900 Subject: [PATCH] circuit objects and nodes/lines of different circuits are not quivalent. --- src/kyupy/circuit.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/kyupy/circuit.py b/src/kyupy/circuit.py index 0191d26..ee49275 100644 --- a/src/kyupy/circuit.py +++ b/src/kyupy/circuit.py @@ -134,10 +134,10 @@ class Node: This is ok, because (name, kind) is unique within a circuit. """ - return self.name == other.name and self.kind == other.kind + return self.name == other.name and self.kind == other.kind and self.circuit == other.circuit def __hash__(self): - return hash((self.name, self.kind)) + return hash((self.name, self.kind, id(self.circuit))) class Line: @@ -539,9 +539,6 @@ class Circuit: for n in state['io_nodes']: self.io_nodes.append(self.nodes[n]) - def __eq__(self, other): - return self.nodes == other.nodes and self.lines == other.lines and self.io_nodes == other.io_nodes - def __repr__(self): return f'{{name: "{self.name}", cells: {len(self.cells)}, forks: {len(self.forks)}, lines: {len(self.lines)}, io_nodes: {len(self.io_nodes)}}}' @@ -651,9 +648,9 @@ class Circuit: region.append(n) yield stem, region - def dot(self, format='svg'): + def dot(self, format='svg', graph_attr={}, line_labels={}): from graphviz import Digraph - dot = Digraph(format=format, graph_attr={'rankdir': 'LR', 'splines': 'true'}) + dot = Digraph(format=format, graph_attr={'rankdir': 'LR', 'splines': 'true', 'size': '10', 'ranksep': '0.1'} | graph_attr) s_dict = dict((n, i) for i, n in enumerate(self.s_nodes)) node_level = np.zeros(len(self.nodes), dtype=np.uint32) @@ -666,20 +663,24 @@ class Circuit: with dot.subgraph() as s: s.attr(rank='same') for n in level_nodes[lv]: - ins = '|'.join([f'{i}' for i in range(len(n.ins))]) - outs = '|'.join([f'{i}' for i in range(len(n.outs))]) + ins = '{' + '|'.join([f'{i}' for i in range(len(n.ins))]) + '}|' if len(n.ins) > 1 else '' + outs = '|{' + '|'.join([f'{i}' for i in range(len(n.outs))]) + '}' if len(n.outs) > 1 else '' io = f' [{s_dict[n]}]' if n in s_dict else '' - s.node(name=str(n.index), label = fr'{{{{{ins}}}|{n.index}{io}\n{n.kind}\n{n.name}|{{{outs}}}}}', shape='record') + color = '#f5f5f5' if n.kind == '__fork__' else '#cccccc' + kind = '' if n.kind == '__fork__' else fr'\n{n.kind}' + s.node(name=str(n.index), label = fr'{{{ins}{n.index}{io}{kind}\n{n.name}{outs}}}', shape='record', style='filled', fillcolor=color) for l in self.lines: - driver, reader = f'{l.driver.index}:o{l.driver_pin}', f'{l.reader.index}:i{l.reader_pin}' + driver = f'{l.driver.index}:o{l.driver_pin}' if len(l.driver.outs)>1 else f'{l.driver.index}' + reader = f'{l.reader.index}:i{l.reader_pin}' if len(l.reader.ins)>1 else f'{l.reader.index}' + label = str(line_labels.get(l, l.index)) if node_level[l.driver] == node_level[l.reader]: s.node(f'_{l.index}_') - dot.edge(driver, f'_{l.index}_', style='dotted', label=str(l.index)) - dot.edge(f'_{l.index}_', reader, style='dotted', label=str(l.index)) + dot.edge(driver, f'_{l.index}_', style='dotted', label=label) + dot.edge(f'_{l.index}_', reader, style='dotted', label=label) elif node_level[l.driver] > node_level[l.reader]: - dot.edge(driver, reader, style='dotted', label=str(l.index)) + dot.edge(driver, reader, style='dotted', label=label) else: - dot.edge(driver, reader, label=str(l.index)) + dot.edge(driver, reader, label=label) return dot