def spread_out(T, embedding, sheer=None): """ Transform the tile assignment to spread out the embedding starting from tile (0,0) and placing originally adjacent tiles 1 extra tile away. Optional arguments: sheer: {None,0, 1} Perform a translation of every odd column (sheer=0) or row (sheer=1) Example: >>> import embera >>> import networkx as nx >>> import dwave_networkx as dnx >>> S = nx.complete_graph(17) >>> T = dnx.chimera_graph(8) >>> embedding = minorminer.find_embedding(S,T) >>> dnx.draw_chimera_embedding(T,embedding, node_size=10) >>> new_embedding = embera.transform.embedding.spread_out(T,embedding) >>> dnx.draw_chimera_embedding(T,new_embedding,node_size=10) """ tiling = DWaveNetworkXTiling(T) shape = np.array(tiling.shape) # Initialize edges origin = shape end = (0, ) * len(origin) # Find edges for v, chain in embedding.items(): for q in chain: tile = np.array(tiling.get_tile(q)) origin = [min(t, o) for t, o in zip(tile, origin)] end = [max(t, e) for t, e in zip(tile, end)] # Make sure it fits if tuple((np.array(end) - np.array(origin)) * 2) > tiling.shape: raise RuntimeError("Can't spread out") # Spread out all qubits by chain new_embedding = {} if sheer is None: shift = lambda tile, origin: (tile - origin) * 2 elif sheer == 0: shift = lambda tile, origin: (tile - origin) * 2 + np.flip( (tile - origin) % [2, 1]) elif sheer == 1: shift = lambda tile, origin: (tile - origin) * 2 + np.flip( (tile - origin) % [1, 2]) for v, chain in embedding.items(): new_chain = [] for q in chain: tile = np.array(tiling.get_tile(q)) new_tile = tuple(shift(tile, origin)) new_q = tiling.set_tile(q, new_tile) new_chain.append(new_q) new_embedding[v] = new_chain return new_embedding
def open_seam(T, embedding, seam, direction): """ Arguments (continued): seam: (int) If direction is 'left' or 'right', seam corresponds to the column number. If direction is 'up' or 'down', seam corresponds to the row number. direction: (None or str:{'left','right','up','down'}) Given a seam index, that column/row is cleared and all utilized qubits in the embedding are shifted in this direction. Example: >>> import embera >>> import networkx as nx >>> import dwave_networkx as dnx >>> S = nx.complete_graph(10) >>> T = dnx.chimera_graph(8) >>> embedding = minorminer.find_embedding(S,T,random_seed=10) >>> dnx.draw_chimera_embedding(T,embedding,node_size=10) >>> seam = 2 >>> direction = 'right' >>> new_embedding = embera.transform.embedding.open_seam(T,embedding,seam,direction) >>> dnx.draw_chimera_embedding(T,new_embedding,node_size=10) """ tiling = DWaveNetworkXTiling(T) if direction is 'left': shift = lambda tile: tile[1] <= seam offset = np.array([0, -1]) elif direction is 'right': shift = lambda tile: tile[1] >= seam offset = np.array([0, +1]) elif direction is 'up': shift = lambda tile: tile[0] <= seam offset = np.array([-1, 0]) elif direction is 'down': shift = lambda tile: tile[0] >= seam offset = np.array([+1, 0]) else: raise ValueError("Direction not in {'left','right','up','down'}") new_embedding = {} for v, chain in embedding.items(): new_chain = [] for q in chain: tile = np.array(tiling.get_tile(q)) new_tile = tuple(tile + offset) if shift(tile) else tuple(tile) new_q = tiling.set_tile(q, new_tile) new_chain.append(new_q) new_embedding[v] = new_chain return new_embedding
def test_pegasus(self): T_linear = dnx.pegasus_graph(2) linear_tiling = DWaveNetworkXTiling(T_linear) T_coord = dnx.pegasus_graph(2, coordinates=True) coord_tiling = DWaveNetworkXTiling(T_coord) T_nice = dnx.pegasus_graph(2, nice_coordinates=True) nice_tiling = DWaveNetworkXTiling(T_nice) self.assertEqual(linear_tiling.get_tile(10), coord_tiling.get_tile((0, 0, 10, 0)), nice_tiling.get_tile((1, 0, 0, 0, 2)))
def __init__(self, S, T, **params): DWaveNetworkXTiling.__init__(self, Tg) self.tries = params.pop('tries', 1) self.verbose = params.pop('verbose', 0) # Choice of vicinity. See below. self.vicinity = params.pop('vicinity', 0) # Check if all parameters have been parsed. for name in params: raise ValueError("%s is not a valid parameter." % name) # Mapping of source nodes to tile self.mapping = {}
def iter_sliding_window(T, embedding): """ Use a sliding window approach to iteratively transport the embedding from one region of the Chimera graph to another. Example: >>> import embera >>> import networkx as nx >>> import dwave_networkx as dnx >>> import matplotlib.pyplot as plt >>> S = nx.complete_graph(11) >>> T = dnx.chimera_graph(7) >>> embedding = minorminer.find_embedding(S,T) >>> dnx.draw_chimera_embedding(T,embedding,node_size=10) >>> slide = embera.transform.embedding.sliding_window(T,embedding) >>> for new_embedding in slide: ... dnx.draw_chimera_embedding(T,new_embedding,node_size=10) ... plt.pause(0.2) """ tiling = DWaveNetworkXTiling(T) shape = np.array(tiling.shape) # Initialize edges origin = shape end = (0, ) * len(origin) # Find edges for v, chain in embedding.items(): for q in chain: tile = np.array(tiling.get_tile(q)) origin = [min(t, o) for t, o in zip(tile, origin)] end = [max(t, e) for t, e in zip(tile, end)] # Move tiles to origin and translate to try and find valid embedding size = np.array(end) - np.array(origin) interactions = lambda u, v, E: ((s, t) for s in E[u] for t in E[v]) is_connected = lambda edges: any(T.has_edge(s, t) for s, t in edges) for x in range(shape[1] - size[1]): for y in range(shape[0] - size[0]): slide = {} offset = np.array([x, y]) # Translate all qubits for v, chain in embedding.items(): new_chain = [] for q in chain: tile = np.array(tiling.get_tile(q)) new_tile = tuple(tile - np.array(origin) + offset) new_q = tiling.set_tile(q, new_tile) new_chain.append(new_q) slide[v] = new_chain yield slide
def test_chimera(self): T_linear = dnx.chimera_graph(2) linear_tiling = DWaveNetworkXTiling(T_linear) T_coord = dnx.chimera_graph(2, coordinates=True) coord_tiling = DWaveNetworkXTiling(T_coord) self.assertEqual(linear_tiling.get_tile(1), coord_tiling.get_tile((0, 0, 0, 1)))
def rotate(T, embedding, theta=90): """ Rotate the embedding on the same graph to re-distribute qubit assignments. If a perfect fit isn't found, due to disabled qubits, the invalid embedding is still returned. Optional arguments: theta: ({0,90,180,270,360,-90,-180,-270}) Rotation angle. Example: >>> import embera >>> import networkx as nx >>> import dwave_networkx as dnx >>> S = nx.complete_graph(11) >>> T = dnx.chimera_graph(7) >>> embedding = minorminer.find_embedding(S,T) >>> dnx.draw_chimera_embedding(T,embedding,node_size=10) >>> theta = 270 >>> new_embedding = embera.transform.embedding.rotate(T,embedding,theta) >>> dnx.draw_chimera_embedding(T,new_embedding,node_size=10) """ tiling = DWaveNetworkXTiling(T) shape = np.array(tiling.shape) # Define rotations m, n = tiling.shape t = tiling.graph['tile'] if theta in [90, -270]: new_tile = lambda i, j: (j, m - i - 1) new_shore = lambda shore: 0 if shore else 1 new_k = lambda k, shore: t - k - 1 if shore else k elif theta in [180, -180]: new_tile = lambda i, j: (m - i - 1, n - j - 1) new_shore = lambda shore: shore new_k = lambda k, shore: t - k - 1 elif theta in [-90, 270]: new_tile = lambda i, j: (n - j - 1, i) new_shore = lambda shore: 0 if shore else 1 new_k = lambda k, shore: k if shore else t - k - 1 elif theta in [0, 360]: return embedding else: raise ValueError("Value of theta not supported") # Rotate all qubits by chain new_embedding = {} for v, chain in embedding.items(): new_chain = [] for q in chain: k = tiling.get_k(q) tile = tiling.get_tile(q) shore = tiling.get_shore(q) new_coordinates = (new_tile(*tile), new_shore(shore), new_k(k, shore)) new_chain.append(next(tiling.get_qubits(*new_coordinates))) new_embedding[v] = new_chain return new_embedding
def translate(T, embedding, origin=(0, 0)): """ Transport the embedding on the same graph to re-distribute qubit assignments. Optional arguments: origin: (tuple) A tuple of tile coordinates pointing to where the left-uppermost occupied tile in the embedding should move to. All other tiles are moved relative to the origin. Example: >>> import embera >>> import networkx as nx >>> import dwave_networkx as dnx >>> S = nx.complete_graph(11) >>> T = dnx.chimera_graph(7) >>> embedding = minorminer.find_embedding(S,T) >>> dnx.draw_chimera_embedding(T,embedding,node_size=10) >>> origin = (2,3) >>> new_embedding = embera.transform.embedding.translate(T,embedding,origin) >>> dnx.draw_chimera_embedding(T,new_embedding,node_size=10) """ tiling = DWaveNetworkXTiling(T) shape = tiling.shape # Initialize offset offset = shape # Find margins for v, chain in embedding.items(): for q in chain: tile = np.array(tiling.get_tile(q)) offset = [min(t, o) for t, o in zip(tile, offset)] # Define flips m, n = tiling.shape t = tiling.graph['tile'] new_embedding = {} for v, chain in embedding.items(): new_chain = [] for q in chain: k = tiling.get_k(q) tile = tiling.get_tile(q) shore = tiling.get_shore(q) new_tile = tuple( np.array(tile) - np.array(offset) + np.array(origin)) new_q = tiling.set_tile(q, new_tile) new_chain.append(new_q) new_embedding[v] = new_chain return new_embedding
def mirror(T, embedding, axis=0): """ Flip the embedding on the same graph to re-distribute qubit assignments. Optional arguments: axis: {0,1} 0 toflip on horizontal and 1 to flip on vertical Example: >>> import embera >>> import networkx as nx >>> import dwave_networkx as dnx >>> S = nx.complete_graph(11) >>> T = dnx.chimera_graph(7) >>> embedding = minorminer.find_embedding(S,T) >>> dnx.draw_chimera_embedding(T,embedding,node_size=10) >>> axis = 1 >>> new_embedding = embera.transform.embedding.mirror(T,embedding,axis) >>> dnx.draw_chimera_embedding(T,new_embedding,node_size=10) """ tiling = DWaveNetworkXTiling(T) shape = np.array(tiling.shape) # Define flips m, n = tiling.shape t = tiling.graph['tile'] if axis is 0: new_tile = lambda i, j: (i, n - j - 1) new_k = lambda k, shore: k if shore else t - k - 1 elif axis is 1: new_tile = lambda i, j: (m - i - 1, j) new_k = lambda k, shore: t - k - 1 if shore else k else: raise ValueError("Value of axis not supported") # Mirror all qubits by chain new_embedding = {} for v, chain in embedding.items(): new_chain = [] for q in chain: k = tiling.get_k(q) tile = tiling.get_tile(q) shore = tiling.get_shore(q) new_coordinates = (new_tile(*tile), shore, new_k(k, shore)) new_chain.append(next(tiling.get_qubits(*new_coordinates))) new_embedding[v] = new_chain return new_embedding
""" Example of tiling a Pegasus architecture graph. """ import dwave_networkx as dnx import matplotlib.pyplot as plt from embera.architectures import drawing, generators from embera.preprocess.tiling_parser import DWaveNetworkXTiling colours = { 'u': {}, 'w': {}, 'k': {}, 'z': {}, 't': {}, 'ij': {}, 'k2': {}, 'tij': {} } Tg = dnx.pegasus_graph(3, coordinates=True) colours = {} for index, tile in DWaveNetworkXTiling(Tg).items(): if tile.qubits: colours[index] = list(tile.qubits) drawing.draw_architecture_embedding(Tg, colours, show_labels=True, node_size=10) plt.show()