Example #1
0
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
Example #2
0
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
Example #3
0
 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 = {}
Example #5
0
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
Example #6
0
 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)))
Example #7
0
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
Example #8
0
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
Example #9
0
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 #10
0
""" 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()