dwave-networkx icon indicating copy to clipboard operation
dwave-networkx copied to clipboard

Layout overhaul

Open boothby opened this issue 3 years ago • 3 comments

Normalizes node sizes across the board Makes yield plots easier to read Adds qubit-line plots

~needs a little more documentation~

boothby avatar Dec 07 '21 16:12 boothby

~Caught a mistake; will patch later. For now, have a preview.~

yield2z100

A giant run of sample images:

import dwave_networkx as dnx
import networkx as nx
from minorminer import find_embedding
import random
import gc
from matplotlib import pyplot as plt
import os
from itertools import chain
os.system("rm yield*.png")
for dpi in (100,):
    for i,(m, t) in enumerate([(2, 1), (2, 4), (2,8), (4,4), (4,8), (8,6), (6,8), (15,4), (15,8), (2, 2), (2, 1), (4, 1), (8, 1)]):
        z = dnx.zephyr_graph(m,t,coordinates=True)
        z.remove_nodes_from(random.sample([*z], len(z)//10))
        z.remove_edges_from(random.sample([*z.edges], len(z.edges)//10))
        emb = {}
        hits = set()
        for _ in range(10):
            emb_ = find_embedding(nx.complete_graph(8), z.subgraph(z.nodes - hits), tries=1, max_no_improvement=1, chainlength_patience=0)
            for c in emb_.values():
                hits.update(c)
                emb[len(emb)] = c
            if not emb_: break
        fig, ax = plt.subplots(2, 2, figsize=(20,20), dpi=dpi)
        dnx.draw_zephyr(z, node_color = range(len(z)), ax=ax[0][0])
        dnx.draw_zephyr(z, node_color = range(len(z)), edge_color=range(len(z.edges)), ax=ax[0][1], line_plot=True)
        dnx.draw_zephyr_embedding(z, emb, ax=ax[1][0], line_plot=True)
        dnx.draw_zephyr_yield(z, fault_shape='o', ax=ax[1][1], line_plot=True)
        fig.tight_layout()
        plt.savefig(f'yield{i}z{dpi}.png', bbox_inches='tight')
        plt.close()
        gc.collect()
    for i,(m,crosses) in enumerate([(2,0), (2, 1), (4,0), (6,1), (8,0), (16,1)]):
        z = dnx.pegasus_graph(m,coordinates=True)
        z.remove_nodes_from(random.sample([*z], len(z)//10))
        z.remove_edges_from(random.sample([*z.edges], len(z.edges)//10))
        emb = {}
        hits = set()
        for _ in range(10):
            emb_ = find_embedding(nx.complete_graph(8), z.subgraph(z.nodes - hits), tries=1, max_no_improvement=1, chainlength_patience=0)
            for c in emb_.values():
                hits.update(c)
                emb[len(emb)] = c
            if not emb_: break
        fig, ax = plt.subplots(2, 2, figsize=(20,20), dpi=dpi)
        dnx.draw_pegasus(z, ax=ax[0][0], crosses=crosses)
        dnx.draw_pegasus(z, ax=ax[0][1], crosses=not crosses, line_plot=True)
        dnx.draw_pegasus_embedding(z, emb, ax=ax[1][0], crosses=crosses, line_plot=True)
        dnx.draw_pegasus_yield(z, fault_shape='o', ax=ax[1][1], crosses=crosses)
        fig.tight_layout()
        plt.savefig(f'yield{i}p{dpi}.png', bbox_inches='tight')
        plt.close()
        gc.collect()
    for i,(m, n, t) in enumerate([(2, 2, 2), (2,2,4), (2,2,8), (4,4,8), (4,4,4), (8,4,8), (8,8,4), (16,16,4), (16, 16,8)]):
        z = dnx.chimera_graph(m,n,t,coordinates=True)
        z.remove_nodes_from(random.sample([*z], len(z)//10))
        z.remove_edges_from(random.sample([*z.edges], len(z.edges)//10))
        emb = {}
        hits = set()
        for _ in range(1):
            emb_ = find_embedding(nx.complete_graph(8), z.subgraph(z.nodes - hits), tries=1, max_no_improvement=1, chainlength_patience=0)
            for c in emb_.values():
                hits.update(c)
                emb[len(emb)] = c
            if not emb_: break
        fig, ax = plt.subplots(2, 2, figsize=(20*n/m,20), dpi=dpi)
        dnx.draw_chimera(z, ax=ax[0][0])
        dnx.draw_chimera(z, ax=ax[0][1], line_plot=True)
        dnx.draw_chimera_embedding(z, emb, ax=ax[1][0], line_plot=False)
        dnx.draw_chimera_yield(z, fault_shape='o', ax=ax[1][1], line_plot=False)
        fig.tight_layout()
        plt.savefig(f'yield{i}c{dpi}.png', bbox_inches='tight')
        plt.close()
        gc.collect()

boothby avatar Dec 07 '21 17:12 boothby

Codecov Report

Merging #214 (25b0adc) into main (4ade84b) will decrease coverage by 5.21%. The diff coverage is 5.85%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #214      +/-   ##
==========================================
- Coverage   74.42%   69.20%   -5.22%     
==========================================
  Files          29       29              
  Lines        2045     2205     +160     
==========================================
+ Hits         1522     1526       +4     
- Misses        523      679     +156     
Impacted Files Coverage Δ
dwave_networkx/drawing/qubit_layout.py 4.63% <3.22%> (-0.41%) :arrow_down:
dwave_networkx/drawing/zephyr_layout.py 15.71% <7.69%> (-4.66%) :arrow_down:
dwave_networkx/drawing/chimera_layout.py 11.82% <8.10%> (-2.84%) :arrow_down:
dwave_networkx/drawing/pegasus_layout.py 13.63% <8.92%> (-3.76%) :arrow_down:

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 4ade84b...25b0adc. Read the comment docs.

codecov-commenter avatar Dec 10 '21 18:12 codecov-commenter

@boothby, what about updating the requirement on networkx to a minimum of version 2.8.6 to apply this fix there too?

I'm hitting it on the NetworkX draw() function here:

>>> from dwave_networkx.drawing.qubit_layout import draw_embedding
>>> draw_embedding(G, layout, {0:[0, 4, 5]})
...
File ~\pyenv\ocean_repos\dwave_networkx_3_10_2\lib\site-packages\networkx\drawing\nx_pylab.py:117, in draw(G, pos, ax, **kwds)
    115 cf.set_facecolor('w')
    116 if ax is None:
--> 117     if cf._axstack() is None:
    118         ax = cf.add_axes((0, 0, 1, 1))
    119     else:

TypeError: '_AxesStack' object is not callable

JoelPasvolsky avatar Jan 31 '23 21:01 JoelPasvolsky