def test_sublattice_mappings(self): def check_subgraph_mapping(f, g, h): for v in g: if not h.has_node(f(v)): raise RuntimeError( f"node {v} mapped to {f(v)} is not in {h.graph['name']} ({h.graph['labels']})" ) for u, v in g.edges: if not h.has_edge(f(u), f(v)): raise RuntimeError( f"edge {(u, v)} mapped to {(f(u), f(v))} not present in {h.graph['name']} ({h.graph['labels']})" ) z2l = dnx.zephyr_graph(2) z2c = dnx.zephyr_graph(2, coordinates=True) c2l = dnx.chimera_graph(2) c2c = dnx.chimera_graph(2, coordinates=True) c23l = dnx.chimera_graph(2, 3) c32c = dnx.chimera_graph(3, 2, coordinates=True) c2l8 = dnx.chimera_graph(2, t=8) c2c8 = dnx.chimera_graph(2, t=8, coordinates=True) c23l8 = dnx.chimera_graph(2, 3, t=8) c32c8 = dnx.chimera_graph(3, 2, t=8, coordinates=True) z5l = dnx.zephyr_graph(5) z5c = dnx.zephyr_graph(5, coordinates=True) for target in z5l, z5c: for source in z2l, z2c, c2l, c2c, c2l8, c2c8, c23l, c32c, c23l8, c32c8, target: covered = set() for f in dnx.zephyr_sublattice_mappings(source, target): check_subgraph_mapping(f, source, target) covered.update(map(f, source)) self.assertEqual(covered, set(target))
def test_graph_relabeling(self): def graph_equal(g, h): self.assertEqual(set(g), set(h)) self.assertEqual(set(map(tuple, map(sorted, g.edges))), set(map(tuple, map(sorted, g.edges)))) for v, d in g.nodes(data=True): self.assertEqual(h.nodes[v], d) coords = dnx.zephyr_coordinates(3) for data in True, False: z3l = dnx.zephyr_graph(3, data=data) z3c = dnx.zephyr_graph(3, data=data, coordinates=True) graph_equal(z3l, coords.graph_to_linear(z3l)) graph_equal(z3l, coords.graph_to_linear(z3c)) graph_equal(z3c, coords.graph_to_zephyr(z3c)) graph_equal(z3c, coords.graph_to_zephyr(z3l)) h = dnx.zephyr_graph(2) del h.graph['labels'] with self.assertRaises(ValueError): coords.graph_to_linear(h) with self.assertRaises(ValueError): coords.graph_to_zephyr(h)
def test_not_full_yield(self): edges = [(2, 30), (7, 44), (10, 37), (12, 29), (15, 37), (19, 41)] G = dnx.zephyr_graph(1, 4, edge_list=edges) for e in edges: self.assertIn(e, G.edges()) for (u, v) in G.edges: self.assertTrue((u, v) in edges or (v, u) in edges) nodes = [0, 1, 2] G = dnx.zephyr_graph(1, 2, node_list=nodes) self.assertEqual(len(G), 3) self.assertEqual(len(G.edges()), 1) edges = [(0, 1), (2, 3)] nodes = [0, 1, 2, 3] G = dnx.zephyr_graph(1, 2, node_list=nodes, edge_list=edges) self.assertEqual(len(G), 4) self.assertEqual(len(G.edges()), 2)
def test_coordinate_basics(self): from dwave_networkx.generators.zephyr import zephyr_coordinates G = dnx.zephyr_graph(4) H = dnx.zephyr_graph(4, coordinates=True) coords = zephyr_coordinates(4) Gnodes = G.nodes Hnodes = H.nodes for v in Gnodes: q = Gnodes[v]['zephyr_index'] self.assertIn(q, Hnodes) self.assertEqual(Hnodes[q]['linear_index'], v) self.assertEqual(v, coords.zephyr_to_linear(q)) self.assertEqual(q, coords.linear_to_zephyr(v)) for q in Hnodes: v = Hnodes[q]['linear_index'] self.assertIn(v, Gnodes) self.assertEqual(Gnodes[v]['zephyr_index'], q) self.assertEqual(v, coords.zephyr_to_linear(q)) self.assertEqual(q, coords.linear_to_zephyr(v))
def test_single_tile(self): # fully specified G = dnx.zephyr_graph(1, 4) # should have 8 nodes self.assertEqual(len(G), 48) # nodes 0,...,7 should be in the tile for n in range(48): self.assertIn(n, G)
def test_to_networkx_pegasus(self): sampler = self.sampler sampler.solver.properties.update({'topology': {'type': 'zephyr', 'shape': [4, 4]}}) G = sampler.to_networkx_graph() # Create pegasus graph for comparison zephyrG = dnx.zephyr_graph(4, node_list=sampler.nodelist, edge_list=sampler.edgelist) self.assertEqual(set(G), set(zephyrG)) for u, v in zephyrG.edges: self.assertIn(u, G[v]) del sampler.solver.properties['topology']
def __init__(self, *args, **kwargs): super(TestLayoutPlacement, self).__init__(*args, **kwargs) # Graphs for testing self.S = nx.random_regular_graph(3, 50) self.S_small = nx.random_regular_graph(3, 10) self.S_components = nx.Graph([(2*i, 2*i+1) for i in range(10)]) self.G = nx.Graph() self.H = nx.complete_graph(1) self.C = dnx.chimera_graph(4) self.C_coord = dnx.chimera_graph(4, coordinates=True) self.C_blank = dnx.chimera_graph(4, data=False) self.P = dnx.pegasus_graph(4) self.P_coord = dnx.pegasus_graph(4, coordinates=True) self.P_nice = dnx.pegasus_graph(4, nice_coordinates=True) self.P_blank = dnx.pegasus_graph(4, data=False) self.Z = dnx.zephyr_graph(4) self.Z_coord = dnx.zephyr_graph(4, coordinates=True) self.Z_blank = dnx.pegasus_graph(4, data=False) # Compute some layouts self.S_layout = mml.Layout(self.S) self.S_small_layout = mml.Layout(self.S_small) self.S_components_layout = mml.Layout(self.S_small) self.G_layout = mml.Layout(self.G) self.C_layout = mml.Layout(self.C) self.C_coord_layout = mml.Layout(self.C_coord) self.C_blank_layout = mml.Layout(self.C_blank) self.C_layout_3 = mml.Layout(self.C, dim=3) self.P_layout = mml.Layout(self.P) self.P_coord_layout = mml.Layout(self.P_coord) self.P_nice_layout = mml.Layout(self.P_nice) self.P_blank_layout = mml.Layout(self.P_blank) self.Z_layout = mml.Layout(self.Z) self.Z_coord_layout = mml.Layout(self.Z_coord) self.Z_blank_layout = mml.Layout(self.Z_blank)
def test_float_robustness(self): G = dnx.zephyr_graph(8 / 2) self.assertEqual(set(G.nodes), set(dnx.zephyr_graph(4).nodes)) for u, v in dnx.zephyr_graph(4).edges: self.assertIn(u, G[v]) G = dnx.zephyr_graph(4, 4.) self.assertEqual(set(G.nodes), set(dnx.zephyr_graph(4).nodes)) for u, v in dnx.zephyr_graph(4).edges: self.assertIn(u, G[v])
def test_coordinate_subgraphs(self): from dwave_networkx.generators.zephyr import zephyr_coordinates from random import sample G = dnx.zephyr_graph(4) H = dnx.zephyr_graph(4, coordinates=True) coords = zephyr_coordinates(4) lmask = sample(list(G.nodes()), G.number_of_nodes() // 2) cmask = list(coords.iter_linear_to_zephyr(lmask)) self.assertEqual(lmask, list(coords.iter_zephyr_to_linear(cmask))) Gm = dnx.zephyr_graph(4, node_list=lmask) Hm = dnx.zephyr_graph(4, node_list=cmask, coordinates=True) Gs = G.subgraph(lmask) Hs = H.subgraph(cmask) EG = sorted(map(sorted, Gs.edges())) EH = sorted(map(sorted, Hs.edges())) self.assertEqual(EG, sorted(map(sorted, Gm.edges()))) self.assertEqual(EH, sorted(map(sorted, Hm.edges()))) Gn = dnx.zephyr_graph(4, edge_list=EG) Hn = dnx.zephyr_graph(4, edge_list=EH, coordinates=True) Gnodes = Gn.nodes Hnodes = Hn.nodes for v in Gnodes: q = Gnodes[v]['zephyr_index'] self.assertIn(q, Hnodes) self.assertEqual(Hnodes[q]['linear_index'], v) self.assertEqual(v, coords.zephyr_to_linear(q)) self.assertEqual(q, coords.linear_to_zephyr(v)) for q in Hnodes: v = Hnodes[q]['linear_index'] self.assertIn(v, Gnodes) self.assertEqual(Gnodes[v]['zephyr_index'], q) self.assertEqual(v, coords.zephyr_to_linear(q)) self.assertEqual(q, coords.linear_to_zephyr(v)) self.assertEqual( EG, sorted(map(sorted, coords.iter_zephyr_to_linear_pairs(Hn.edges())))) self.assertEqual( EH, sorted(map(sorted, coords.iter_linear_to_zephyr_pairs(Gn.edges()))))
def to_networkx_graph(self): """Converts DWaveSampler's structure to a Chimera, Pegasus or Zephyr NetworkX graph. Returns: :class:`networkx.Graph`: Either an (m, n, t) Chimera lattice, a Pegasus lattice of size m or a Zephyr lattice of size m. Examples: This example converts a selected D-Wave system solver to a graph and verifies it has over 2000 nodes. >>> from dwave.system import DWaveSampler ... >>> sampler = DWaveSampler() >>> g = sampler.to_networkx_graph() # doctest: +SKIP >>> len(g.nodes) > 2000 # doctest: +SKIP True """ topology_type = self.properties['topology']['type'] shape = self.properties['topology']['shape'] if topology_type == 'chimera': G = dnx.chimera_graph(*shape, node_list=self.nodelist, edge_list=self.edgelist) elif topology_type == 'pegasus': G = dnx.pegasus_graph(shape[0], node_list=self.nodelist, edge_list=self.edgelist) elif topology_type == 'zephyr': G = dnx.zephyr_graph(shape[0], node_list=self.nodelist, edge_list=self.edgelist) return G
def __init__(self, *args, **kwargs): super(TestZephyr, self).__init__(*args, **kwargs) self.z6 = dnx.zephyr_graph(6)
def __init__(self, broken_nodes=None, broken_edges=None, topology_type='chimera', topology_shape=None, **config): if topology_type == 'zephyr': if topology_shape is None: topology_shape = [2, 4] elif len(topology_shape) != 2: raise ValueError('topology_shape must be a 2-value ' 'list for Zephyr') # Z2 for small manageable (but non-trivial) default. # Z15 full scale. solver_graph = dnx.zephyr_graph(topology_shape[0], topology_shape[1]) elif topology_type == 'pegasus': if topology_shape is None: topology_shape = [3] elif len(topology_shape) != 1: raise ValueError('topology_shape must be a single-value ' 'list for Pegasus') # P3 fabric_only for small manageable (but non-trivial) default. # P16 full scale. solver_graph = dnx.pegasus_graph(topology_shape[0], fabric_only=True) elif topology_type == 'chimera': if topology_shape is None: topology_shape = [4, 4, 4] elif len(topology_shape) != 3: raise ValueError('topology_shape must be 3-value list ' 'for Chimera') # solver_graph for small manageable (but non-trivial) default. # C16 full scale. solver_graph = dnx.chimera_graph(topology_shape[0], topology_shape[1], topology_shape[2]) else: raise ValueError("Only 'chimera', 'pegasus' and 'zephyr' " "topologies are supported") if broken_nodes is None and broken_edges is None: self.nodelist = sorted(solver_graph.nodes) self.edgelist = sorted( tuple(sorted(edge)) for edge in solver_graph.edges) else: if broken_nodes is None: broken_nodes = [] self.nodelist = sorted( set(solver_graph.nodes).difference(broken_nodes)) if broken_edges == None: broken_edges = [] self.edgelist = sorted( tuple(sorted((u, v))) for u, v in solver_graph.edges if u not in broken_nodes and v not in broken_nodes and ( u, v) not in broken_edges and (v, u) not in broken_edges) # mark the sample kwargs self.parameters = parameters = {} parameters['num_reads'] = ['num_reads_range'] parameters['flux_biases'] = ['j_range'] parameters['label'] = [] # add the interesting properties manually self.properties = properties = {} properties['j_range'] = [-1.0, 1.0] properties['h_range'] = [-2.0, 2.0] properties['num_reads_range'] = [1, 10000] properties['num_qubits'] = len(solver_graph) properties['category'] = 'qpu' properties['quota_conversion_rate'] = 1 properties['topology'] = { 'type': topology_type, 'shape': topology_shape } properties['chip_id'] = 'MockDWaveSampler' properties['annealing_time_range'] = [1.0, 2000.0] properties['num_qubits'] = len(self.nodelist) properties['extended_j_range'] = [-2.0, 1.0] properties["supported_problem_types"] = ['ising', 'qubo'] # add some occasionally useful properties properties["default_annealing_time"] = 20.0 properties["default_programming_thermalization"] = 1000.0 properties["default_readout_thermalization"] = 0.0 properties["h_gain_schedule_range"] = [-4.0, 4.0] properties["max_anneal_schedule_points"] = 12 properties["max_h_gain_schedule_points"] = 20 properties["per_qubit_coupling_range"] = [-18.0, 15.0] properties["problem_run_duration_range"] = [0.0, 1000000.0] properties["programming_thermalization_range"] = [0.0, 10000.0] properties["readout_thermalization_range"] = [0.0, 10000.0] properties["qubits"] = self.nodelist.copy() properties["couplers"] = self.edgelist.copy()