Пример #1
0
def best_topgraph_z_ini_mapping(L1, C, G, anchor, stop):
    ''' Test a more efficient way for scanning the gates in C than 'y' by using search_bipartite_top_z'''
    g = graph_of_circuit(C)
    test = is_embeddable(g, G, anchor, stop)
    if test[0]:
        #print('The graph of the circuit is embeddable in G')
        return g, test[1]
    #print('The graph of the circuit is very likely NOT embeddable in G')
    L_temp = []  #the index list of first cnot for each edge
    for edge in g.edges():
        p, q = edge[0], edge[1]
        s = min([k for k in L1 if set(C[k]) == {p, q}])
        L_temp.append(s)

    L_temp.sort()
    yes_bound = 0
    no_bound = len(L_temp)
    test_number = no_bound // 2
    exact_bound = search_bipartite_top_z(yes_bound, no_bound, test_number,
                                         L_temp, C, G, anchor, stop)

    g = nx.Graph()
    # add the first edge into g
    for s in L_temp[:exact_bound + 1]:
        g.add_edge(C[s][0], C[s][1])
    test = is_embeddable(g, G, anchor, stop)
    if not test[0]:
        raise Exception('Check why the subgraph is not embeddable!')
    return g, test[1]
Пример #2
0
def best_topgraph_x_ini_mapping(L1, C, G, anchor, stop):  #slow for rochester
    ''' The 'x' version does not use Dump to collect unsolvable gates.'''
    g_of_c = graph_of_circuit(C)
    test = is_embeddable(g_of_c, G, anchor, stop)
    if test[0]:
        #print('The graph of the circuit is embeddable in G')
        return g_of_c, test[1]
    gdg = cx_dependency_graph(L1, C)
    '''Construct the top subgraph g from the circuit '''
    g = nx.Graph()  # the subgraph of G induced by nodes with indices in GATES
    GATES = [
    ]  # the indices of topgates that can be executed (i.e., put in g) in this round
    LX = L1[:]
    result = dict()
    step = 0
    while LX and step < 2000:
        step += 1
        LX0 = LX[:]
        LTG = topgates(LX0, C)
        for i in LTG:
            LX0.remove(i)
            gate = C[i]
            if (gate[0], gate[1]
                ) in g.edges():  # the gate or its inverse has been considered
                GATES.append(i)  # C[i] is to be solved in this round
                continue
            g.add_edge(gate[0], gate[1])
            test = is_embeddable(g, G, anchor, stop)
            if test[0]:
                result = test[1]
                GATES.append(i)
            else:
                '''Remove i's descendants from consideration'''
                LX0 = [x for x in LX0 if x not in nx.descendants(gdg, i)]
                g.remove_edge(gate[0], gate[1])
                if nx.degree(g, gate[0]) == 0: g.remove_node(gate[0])
                if nx.degree(g, gate[1]) == 0: g.remove_node(gate[1])
        LX = LX0[:]
    return g, result, GATES
Пример #3
0
def best_topgraph_y_ini_mapping(L1, C, G, anchor, stop):
    ''' Test a more efficient way for scanning the gates in C, where for each edge
        in g_of_c, we fix the index of the 1st cnot gate which gives the edge 
    '''
    g = graph_of_circuit(C)
    test = is_embeddable(g, G, anchor, stop)
    if test[0]:
        #print('The graph of the circuit is embeddable in G')
        return g, test[1]

    L_temp = []  #the list of the index of the 1st cnot
    for edge in g.edges():
        p, q = edge[0], edge[1]
        s = min([k for k in L1 if set(C[k]) == {p, q}])
        L_temp.append(s)
    # L_temp.sort(reverse=True)
    # for s in L_temp:
    #     p, q = C[s][0], C[s][1]
    #     test = is_embeddable(g, G, True, stop)
    #     if test[0]:
    #         return g, test[1]
    #     g.remove_edge(p,q)
    #     if nx.degree(g, p) == 0: g.remove_node(p)
    #     if nx.degree(g, q) == 0: g.remove_node(q)
    # if g.nodes(): raise Exception('g should be empty here')
    L_temp.sort()
    g = nx.Graph()
    g.add_edge(C[L_temp[0]][0], C[L_temp[0]][1])
    result = dict()
    for s in L_temp[1:]:
        p, q = C[s][0], C[s][1]
        g.add_edge(p, q)
        test = is_embeddable(g, G, True, stop)
        if not test[0]:
            return g, result
        result = test[1]
    return g, result
Пример #4
0
def best_wtg_o_ini_mapping(C, G, anchor, stop):  #'o' for original
    ''' Return a graph g which is isomorphic to a subgraph of G
            while maximizing the number of CNOTs in C that correspond to edges in g
        Method: sort the edges according to their weights (the number of CNOTs in C corresponding to each edge);
                construct a graph by starting with the edge with the largest weight; then consider the edge with the second large weight, ...
                if in any step the graph is not isomorphic to a subgraph of G, skip this edge and consider the next till all edges are considered.
    
    Args:
        C (list): the input circuit
        G (graph): the architecture graph
        
    Returns:
        g (graph)
        map (dict)
    '''
    g_of_c = graph_of_circuit(C)
    test = is_embeddable(g_of_c, G, anchor, stop)
    if test[0]:
        #print('The graph of the circuit is embeddable in G')
        return g_of_c, test[1]

    edge_wgt_list = list([C.count([e[0], e[1]]) + C.count([e[1], e[0]]), e]
                         for e in g_of_c.edges())
    edge_wgt_list.sort(key=lambda t: t[0],
                       reverse=True)  # q[0] weight, q[1] edge
    '''Sort the edges reversely according to their weights'''
    EdgeList = list(item[1] for item in edge_wgt_list)
    #edge_num = len(EdgeList)
    '''We search backward, remove the first edge that makes g not embeddable, 
            and continue till all edges are evaluated in sequence. '''

    #Hard_Edge_index = 0 # the index of the first hard edge
    g = nx.Graph()
    result = dict()
    # add the first edge into g
    edge = EdgeList[0]
    g.add_edge(edge[0], edge[1])

    # rp = 0
    # for rp in range(edge_num):
    #     # h is the index of the last edge that can be added into g
    #     h = Hard_Edge_index
    #     if h == edge_num - 1:
    #         return g, result

    #     EdgeList_temp = EdgeList[h+1:edge_num]
    #     for edge in EdgeList_temp:
    #         g.add_edge(edge[0], edge[1])
    #         i = EdgeList.index(edge)
    #         # find the largest i such that the first i-1 edges are embeddable
    #         test = is_embeddable(g, G, anchor, stop)
    #         if not test[0]:
    #             Hard_Edge_index = i
    #             g.remove_edge(edge[0], edge[1])
    #             break
    #         result = test[1]
    #         if i == edge_num- 1:
    #             return g, result
    # return g, result

    #EdgeList_temp = EdgeList[:]
    for edge in EdgeList:
        g.add_edge(edge[0], edge[1])
        test = is_embeddable(g, G, anchor, stop)
        if not test[0]:
            g.remove_edge(edge[0], edge[1])
            if nx.degree(g, edge[0]) == 0: g.remove_node(edge[0])
            if nx.degree(g, edge[1]) == 0: g.remove_node(edge[1])
        else:
            result = test[1]
    return g, result
Пример #5
0
def best_topgraph_o_ini_mapping(L1, C, G, anchor,
                                stop):  # 'o': the original version
    ''' Return the topgraph g of the input circuit C
        Method: Consider all gates in the gate dependency graph one by one from the top.
                Let x=C[j] be the current edge. Add it to g and check if g is still embeddable into G.
                Otherwise, remove all gates that are dependent on x from the gate dependency graph
                and check if there are any gate left and continue.
        Args:
            C (list): the input circuit
            G (graph): the architecture graph
            L1: the list of indices of unsolved gates in C           
        Returns:
            g (graph): the topgraph
            map (dict)
    '''
    g_of_c = graph_of_circuit(C)
    test = is_embeddable(g_of_c, G, anchor, stop)
    if test[0]:
        #print('The graph of the circuit is embeddable in G')
        return g_of_c, test[1]
    gdg = cx_dependency_graph(L1, C)
    '''Construct the top subgraph g from the circuit '''
    g = nx.Graph()  # the subgraph of G induced by nodes with indices in GATES
    GATES = [
    ]  # the indices of topgates that can be executed (i.e., put in g) in this round
    result = dict()
    # we consider unsolved gates in C one by one
    Dump = set(
    )  # record all those gates that cannot be put in the solvable graph in this round
    '''To speed up we may consider only L1[0:500] for example.'''
    start = time.time()
    for j in L1:
        if time.time() - start > 100:
            print('Mapping time exceeds 100 seconds!')
            break
        a = L1.index(j)
        gate = C[j]
        '''Update Dump by adding descedents of items in Dump'''
        # CHANGE = True
        # while CHANGE and Dump:
        #     ldump = len(Dump)
        #     Dump_TG = topgates(list(Dump), C)
        #     for s in Dump_TG:
        #         Dump = Dump | set(nx.descendants(gdg, s))
        #     '''Check if Dump changed'''
        #     if ldump == len(Dump):
        #         CHANGE = False
        '''Stop when there are no gates outside Dump '''
        if Dump >= set(L1[a:]):
            return g, result, GATES
        if j in Dump: continue
        if (gate[0],
                gate[1]) in g.edges() and not (gate[1], gate[0]) in g.edges():
            raise Exception('edge error')
        if (gate[0], gate[1]
            ) in g.edges():  # the gate or its inverse has been considered
            GATES.append(j)  # C[i] is to be solved in this round
            continue
        g.add_edge(gate[0], gate[1])
        test = is_embeddable(g, G, anchor, stop)
        if test[0]:
            result = test[1]
            GATES.append(j)
        else:
            # remove the gate from consideration
            Dump.add(j)
            Dump = Dump | set(nx.descendants(gdg, j))  #0908
            g.remove_edge(gate[0], gate[1])
            if nx.degree(g, gate[0]) == 0: g.remove_node(gate[0])
            if nx.degree(g, gate[1]) == 0: g.remove_node(gate[1])
    return g, result, GATES
Пример #6
0
    ### select an initial mapping ###
    #\__/#\#/\#\__/#\#/\__/--\__/#\__/#\#/~\
    _map_ = dict()
    if initial_mapping == 'wgt':  # weighted graph initial mapping
        # _map_ = _tau_bsg_(C, G, anchor, stop)
        imlist = IM[count - 1][1]
        for x in imlist:
            _map_[x[0]] = x[1]
        print(_map_)

        # im = []
        # for key in _map_:
        #     im.append([key, _map_[key]])
        # IM.append([count, im])
    elif initial_mapping == 'empty':  #empty mapping
        g_of_c = graph_of_circuit(C)
        p, q = centre(g_of_c), hub(g_of_c)
        u, v = centre(G), hub(G)
        _map_[q] = v
    elif initial_mapping == 'top':  # topsubgraph mapping
        # _map_ = _tau_bstg_(C, G, anchor, stop)
        imlist = IM[count - 1][1]
        # print(count, IM[count-1])
        for x in imlist:
            _map_[x[0]] = x[1]
        # print(_map_)
        # content = count, file_name, _map_, round(time.time()-timeA, 2)
        # save_result(name2, content)
        # im = []
        # for key in _map_:
        #     im.append([key, _map_[key]])