Esempio n. 1
0
def sapi_refine_modularity(
        graph,
        solver,
        hardware_size,  # max size subproblem
        ptn_variables,  # ptn_variables[node] = 0,1,'free'
        num_reads,
        annealing_time,
        embeddings=False,  # if false, get fast embedding
):
    sub_B_matrix, bias, constant = get_sub_mod_matrix(graph, ptn_variables)
    n = sub_B_matrix.shape[0]
    if n > hardware_size:
        print n, hardware_size
        raise ValueError('Number free variables exceeds hardware size')
    coupler = {}
    # we add negative because we maximize modularity
    bias = [-i for i in bias]
    for i in range(n - 1):
        for j in range(i + 1, n):
            coupler[(i, j)] = -sub_B_matrix.item((i, j))
            coupler[(j, i)] = -sub_B_matrix.item((j, i))
    A = get_hardware_adjacency(solver)
    #print "embedding..."
    if not embeddings:
        print 'finding embedding ....'
        embeddings = find_embedding(coupler, A, verbose=0, fast_embedding=True)
    (h0, j0, jc, new_emb) = embed_problem(bias,
                                          coupler,
                                          embeddings,
                                          A,
                                          clean=True,
                                          smear=True)
    emb_j = j0.copy()
    emb_j.update(jc)
    #print "On DWave..."
    result = solve_ising(solver,
                         h0,
                         emb_j,
                         num_reads=num_reads,
                         annealing_time=annealing_time)
    #print result
    #print "On DWave...COMPLETE"
    energies = result['energies']
    #print energies
    #print result['solutions']
    #print min(energies), max(energies)
    new_answer = unembed_answer(result['solutions'], new_emb,
                                'minimize_energy', bias, coupler)
    min_energy = 10**10
    best_soln = []
    for i, ans in enumerate(new_answer):
        soln = ans[0:n]
        assert 3 not in soln
        en = energies[i]
        if en < min_energy:
            #print 'energy', en
            min_energy = en
            best_soln = copy.deepcopy(soln)
    return get_new_partition(best_soln, ptn_variables)
Esempio n. 2
0
 def __init__(self, solver, network, verbose=0):
     self._verbose = verbose
     # have D-Wave find an embedding of our network into the Chimera
     self._A = dw_util.get_hardware_adjacency(solver)
     self._emb = dw_embedding.find_embedding(network.j(), self._A, \
                                             verbose=verbose, timeout=settings.EMBEDDING_TIMEOUT)
     if verbose:
         print 'embedding:', self._emb
Esempio n. 3
0
    def run_heur_embedding(self, full_adj=True):
        '''Setup and run the Heuristic algorithm'''

        # update embedding type in case direct call
        self.embed_method = 'heur'

        active_cells, qca_adj = self.get_reduced_qca_adj()
        S_size = len(qca_adj)
        A_size = len(self.chimera_adj)

        # construct S, the problem adjacency edge list
        S = set()
        smap = {c: i for i, c in enumerate(active_cells)}
        for c1, adj in qca_adj.items():
            for c2 in adj:
                if c1 < c2:
                    S.add((smap[c1], smap[c2]))

        # construct A, the chimera adjacency edge list
        A = set()
        for qb1 in self.chimera_adj:
            for qb2 in self.chimera_adj[qb1]:
                l1 = tuple_to_linear(qb1,
                                     self.M,
                                     self.N,
                                     L=self.L,
                                     index0=True)
                l2 = tuple_to_linear(qb2,
                                     self.M,
                                     self.N,
                                     L=self.L,
                                     index0=True)
                A.add((l1, l2))

        try:
            print 'Running heuristic embedding'
            #models = find_embedding(S, S_size, A, A_size)
            models = find_embedding(S, A)
        except Exception as e:
            print(e.message())

        print 'Embedding finished'
        self.good = len(models) == S_size

        # map models to standard format
        mapper = lambda ind: linear_to_tuple(
            ind, self.M, self.N, L=self.L, index0=True)
        self.models = {
            active_cells[i]: [mapper(c) for c in model]
            for i, model in enumerate(models)
        }
def embedding_example():

    # formulate k_6 structured graph
    h = [1, 1, 1, 1, 1, 1]
    J = {(i, j): 1 for i in range(6) for j in range(i)}

    solver = local_connection.get_solver("c4-sw_optimize")
    A = get_hardware_adjacency(solver)

    # find and print embeddings for problem graph
    embeddings = find_embedding(J, A, verbose=1)
    print "embeddings are: ", embeddings

    # embed the problem into solver graph
    (h0, j0, jc, new_emb) = embed_problem(h, J, embeddings, A)
    print "embedded problem result:\nj0: ", j0
    print "jc: ", jc

    # find unembedded results for chain strengths -0.5, -1.0, -2.0
    for chain_strength in (-0.5, -1.0, -2.0):
        # set chain strength values
        jc = dict.fromkeys(jc, chain_strength)

        # create new J array concatenating j0 with jc
        emb_j = j0.copy()
        emb_j.update(jc)

        # solve embedded problem
        answer = solve_ising(solver, h0, emb_j, num_reads=10)

        # unembed and print result of the form:
        # solution [solution #]
        # var [var #] : [var value] ([qubit index] : [original qubit value] ...)
        result = unembed_answer(answer['solutions'],
                                new_emb,
                                broken_chains="minimize_energy",
                                h=h,
                                j=J)
        print "result for chain strength = ", chain_strength
        for i, (embsol, sol) in enumerate(zip(answer['solutions'], result)):
            print "solution", i
            for j, emb in enumerate(embeddings):
                print "var %d: %d (" % (j, sol[j]),
                for k in emb:
                    print "%d:%d" % (k, embsol[k]),
                print ")"
Esempio n. 5
0
def embedding_example():

    # formulate k_6 structured graph
    h = [1, 1, 1, 1, 1, 1]
    J = {(i, j): 1 for i in range(6) for j in range(i)}

    solver = local_connection.get_solver("c4-sw_optimize")
    A = get_hardware_adjacency(solver)

    # find and print embeddings for problem graph
    embeddings = find_embedding(J, A, verbose=1)
    print "embeddings are: ", embeddings

    # embed the problem into solver graph
    (h0, j0, jc, new_emb) = embed_problem(h, J, embeddings, A)
    print "embedded problem result:\nj0: ", j0
    print "jc: ", jc

    # find unembedded results for chain strengths -0.5, -1.0, -2.0
    for chain_strength in (-0.5, -1.0, -2.0):
        # set chain strength values
        jc = dict.fromkeys(jc, chain_strength)

        # create new J array concatenating j0 with jc
        emb_j = j0.copy()
        emb_j.update(jc)

        # solve embedded problem
        answer = solve_ising(solver, h0, emb_j, num_reads=10)

        # unembed and print result of the form:
        # solution [solution #]
        # var [var #] : [var value] ([qubit index] : [original qubit value] ...)
        result = unembed_answer(answer['solutions'], new_emb, broken_chains="minimize_energy", h=h, j=J)
        print "result for chain strength = ", chain_strength
        for i, (embsol, sol) in enumerate(zip(answer['solutions'], result)):
            print "solution", i
            for j, emb in enumerate(embeddings):
                print "var %d: %d (" % (j, sol[j]),
                for k in emb:
                    print "%d:%d" % (k, embsol[k]),
                print ")"
Esempio n. 6
0
def find_dwave_embedding(logical, optimization, verbosity, hw_adj_file):
    """Find an embedding of a logical problem in the D-Wave's physical topology.
    Store the embedding within the Problem object."""
    # SAPI tends to choke when embed_problem is told to embed a problem
    # containing a zero-weight node whose adjacent couplers all have zero
    # strength.  (Tested with SAPI 2.4.)  To help out SAPI, we simply remove
    # all zero-strength couplers.
    edges = [
        e for e in logical.strengths.keys() if logical.strengths[e] != 0.0
    ]
    edges.sort()
    logical.edges = edges
    if hw_adj_file == None:
        try:
            hw_adj = get_hardware_adjacency(qmasm.solver)
        except KeyError:
            # The Ising heuristic solver is an example of a solver that lacks a
            # fixed hardware representation.  We therefore assert that the
            # hardware is an all-to-all network that connects every node to
            # every other node.
            endpoints = set([a for a, b in edges] + [b for a, b in edges])
            hw_adj = [(a, b) for a in endpoints for b in endpoints if a != b]
    else:
        hw_adj = read_hardware_adjacency(hw_adj_file, verbosity)

    # Tell the user if we have any hope at all of embedding the problem.
    if verbosity >= 2:
        report_embeddability(edges, hw_adj)

    # Determine the edges of a rectangle of cells we want to use.  If we read
    # the topology from a file or otherwise can't prove that we have a Chimera
    # graph, we call this rectangle 0x0 and force the main embedding loop to
    # exit after a single iteration because we don't know the topology is even
    # rectangular.
    edgex = 0
    edgey = 0
    M = 0
    N = 0
    try:
        if hw_adj_file == None:
            L, M, N = qmasm.chimera_topology(qmasm.solver)
            L2 = 2 * L
            ncells = (qmasm.next_sym_num +
                      L2) // L2  # Round up the number of cells.
            if optimization >= 2:
                edgey = max(int(math.sqrt(ncells)), 1)
                edgex = max((ncells + edgey - 1) // edgey, 1)
            else:
                edgey = N
                edgex = M
    except qmasm.NonChimera:
        pass

    # Announce what we're about to do.
    if verbosity >= 2:
        sys.stderr.write(
            "Embedding the logical adjacency within the physical topology.\n\n"
        )

    # Repeatedly expand edgex and edgey until the embedding works.
    while edgex <= M and edgey <= N:
        if edgex == M and edgey == N:
            alt_hw_adj = hw_adj
        else:
            # Retain adjacencies only within the rectangle.
            alt_hw_adj = []
            for q1, q2 in hw_adj:
                c1 = q1 // L2
                if c1 % M >= edgex:
                    continue
                if c1 // M >= edgey:
                    continue
                c2 = q2 // L2
                if c2 % M >= edgex:
                    continue
                if c2 // M >= edgey:
                    continue
                alt_hw_adj.append((q1, q2))
            alt_hw_adj = set(alt_hw_adj)
        logical.hw_adj = alt_hw_adj

        # See if we already have an embedding in the embedding cache.
        ec = EmbeddingCache(edges, alt_hw_adj)
        if verbosity >= 2:
            if ec.cachedir == None:
                sys.stderr.write(
                    "  No embedding cache directory was specified ($QMASMCACHE).\n"
                )
            else:
                sys.stderr.write(
                    "  Using %s as the embedding cache directory ...\n" %
                    ec.cachedir)
        embedding = ec.read()
        if embedding == []:
            # Cache hit, but embedding had failed
            if verbosity >= 2:
                sys.stderr.write(
                    "  Found failed embedding %s in the embedding cache.\n\n" %
                    ec.hash)
        elif embedding != None:
            # Successful cache hit!
            if verbosity >= 2:
                sys.stderr.write(
                    "  Found successful embedding %s in the embedding cache.\n\n"
                    % ec.hash)
            logical.embedding = embedding
            return
        if verbosity >= 2 and ec.cachedir != None:
            sys.stderr.write(
                "  No existing embedding found in the embedding cache.\n")

        # Try to find an embedding, unless we previously determined that it had
        # failed.
        if embedding != []:
            if verbosity >= 2:
                # SAPI's find_embedding is hard-wired to write to stdout.
                # Trick it into writing into a pipe instead.
                if edgex == 0 and edgey == 0:
                    sys.stderr.write("  Trying to embed ... ")
                else:
                    sys.stderr.write(
                        "  Trying a %dx%d unit-cell embedding ...\n\n" %
                        (edgex, edgey))
                sepLine = "=== EMBEDDING ===\n"
                r, w = os.pipe()
                pid = os.fork()
                if pid == 0:
                    # Child -- perform the embedding.
                    os.close(r)
                    os.dup2(w, sys.stdout.fileno())
                    embedding = find_embedding(edges, alt_hw_adj, verbose=1)
                    sys.stdout.flush()
                    os.write(w, sepLine)
                    os.write(w, json.dumps(embedding) + "\n")
                    os.close(w)
                    os._exit(0)
                else:
                    # Parent -- report the embedding's progress.
                    os.close(w)
                    pipe = os.fdopen(r, "r", 10000)
                    while True:
                        try:
                            rstr = pipe.readline()
                            if rstr == sepLine:
                                break
                            if rstr == "":
                                qmasm.abend(
                                    "Embedder failed to terminate properly")
                            sys.stderr.write("      %s" % rstr)
                        except:
                            pass

                    # Receive the embedding from the child.
                    embedding = json.loads(pipe.readline())
                    sys.stderr.write("\n")
            else:
                embedding = find_embedding(edges, alt_hw_adj, verbose=0)
            ec.write(embedding)
            if len(embedding) > 0:
                # Success!
                break

        # Continued failure -- increase edgex or edgey and try again.
        if edgex < edgey:
            edgex += 1
        else:
            edgey += 1
    if not (edgex <= M and edgey <= N):
        qmasm.abend("Failed to embed the problem")
    logical.embedding = embedding
Esempio n. 7
0
def find_dwave_embedding(logical, optimize, verbosity):

    """Find an embedding of a logical problem in the D-Wave's physical topology.
    Store the embedding within the Problem object."""
    # SAPI tends to choke when embed_problem is told to embed a problem
    # containing a zero-weight node whose adjacent couplers all have zero
    # strength.  (Tested with SAPI 2.4.)  To help out SAPI, we simply remove
    # all zero-strength couplers.
    edges = [e for e in list(logical.strengths.keys()) if logical.strengths[e] != 0.0]
    edges.sort()
    logical.edges = edges
    try:
        hw_adj = get_hardware_adjacency(qmasm.solver)
    except KeyError:
        # The Ising heuristic solver is an example of a solver that lacks a
        # fixed hardware representation.  We therefore assert that the hardware
        # is an all-to-all network that connects every node to every other node.
        endpoints = set([a for a, b in edges] + [b for a, b in edges])
        hw_adj = [(a, b) for a in endpoints for b in endpoints if a != b]

    # Tell the user if we have any hope at all of embedding the problem.
    if verbosity >= 2:
        report_embeddability(edges, hw_adj)

    # Determine the edges of a rectangle of cells we want to use.
    L, M, N = qmasm.chimera_topology(qmasm.solver)
    L2 = 2*L
    ncells = (qmasm.next_sym_num + L2) // L2   # Round up the number of cells.
    if optimize:
        edgey = max(int(math.sqrt(ncells)), 1)
        edgex = max((ncells + edgey - 1) // edgey, 1)
    else:
        edgey = N
        edgex = M

    # Announce what we're about to do.
    if verbosity >= 2:
        sys.stderr.write("Embedding the logical adjacency within the physical topology.\n\n")

    # Repeatedly expand edgex and edgey until the embedding works.
    while edgex <= M and edgey <= N:
        # Retain adjacencies only within the rectangle.
        alt_hw_adj = []
        for q1, q2 in hw_adj:
            c1 = q1//L2
            if c1 % M >= edgex:
                continue
            if c1 // M >= edgey:
                continue
            c2 = q2//L2
            if c2 % M >= edgex:
                continue
            if c2 // M >= edgey:
                continue
            alt_hw_adj.append((q1, q2))
        alt_hw_adj = set(alt_hw_adj)
        logical.hw_adj = alt_hw_adj

        # See if we already have an embedding in the embedding cache.
        ec = EmbeddingCache(edges, alt_hw_adj)
        if verbosity >= 2:
            if ec.cachedir == None:
                sys.stderr.write("  No embedding cache directory was specified ($QMASMCACHE).\n")
            else:
                sys.stderr.write("  Using %s as the embedding cache directory ...\n" % ec.cachedir)
        embedding = ec.read()
        if embedding == []:
            # Cache hit, but embedding had failed
            if verbosity >= 2:
                sys.stderr.write("  Found failed embedding %s in the embedding cache.\n\n" % ec.hash)
        elif embedding != None:
            # Successful cache hit!
            if verbosity >= 2:
                sys.stderr.write("  Found successful embedding %s in the embedding cache.\n\n" % ec.hash)
            logical.embedding = embedding
            return
        if verbosity >= 2 and ec.cachedir != None:
            sys.stderr.write("  No existing embedding found in the embedding cache.\n")

        # Try to find an embedding, unless we previously determined that it had
        # failed.
        if embedding != []:
            if verbosity >= 2:
                sys.stderr.write("  Trying a %dx%d unit-cell embedding ... " % (edgex, edgey))
                status_file = tempfile.NamedTemporaryFile(mode="w", delete=False)
                stdout_fd = os.dup(sys.stdout.fileno())
                os.dup2(status_file.fileno(), sys.stdout.fileno())
                embedding = find_embedding(edges, alt_hw_adj, verbose=1)
                sys.stdout.flush()
                os.dup2(stdout_fd, sys.stdout.fileno())
                status_file.close()
                if len(embedding) > 0:
                    sys.stderr.write("succeeded\n\n")
                else:
                    sys.stderr.write("failed\n\n")
                with open(status_file.name, "r") as status:
                    for line in status:
                        sys.stderr.write("    %s" % line)
                sys.stderr.write("\n")
                os.remove(status_file.name)
            else:
                embedding = find_embedding(edges, alt_hw_adj, verbose=0)
            ec.write(embedding)
            if len(embedding) > 0:
                # Success!
                break

        # Continued failure -- increase edgex or edgey and try again.
        if edgex < edgey:
            edgex += 1
        else:
            edgey += 1
    if not(edgex <= M and edgey <= N):
        qmasm.abend("Failed to embed the problem")
    logical.embedding = embedding
Esempio n. 8
0
def anneal(C_i, C_ij, mu, sigma, l, strength_scale, energy_fraction, ngauges,
           max_excited_states):
    url = "https://usci.qcc.isi.edu/sapi"
    token = "your-token"

    h = np.zeros(len(C_i))
    J = {}
    for i in range(len(C_i)):
        h_i = -2 * sigma[i] * C_i[i]
        for j in range(len(C_ij[0])):
            if j > i:
                J[(i, j)] = 2 * C_ij[i][j] * sigma[i] * sigma[j]
            h_i += 2 * (sigma[i] * C_ij[i][j] * mu[j])
        h[i] = h_i

    vals = np.array(J.values())
    cutoff = np.percentile(vals, AUGMENT_CUTOFF_PERCENTILE)
    to_delete = []
    for k, v in J.items():
        if v < cutoff:
            to_delete.append(k)
    for k in to_delete:
        del J[k]

    isingpartial = []

    if FIXING_VARIABLES:
        Q, _ = ising_to_qubo(h, J)
        simple = fix_variables(Q, method='standard')
        new_Q = simple['new_Q']
        print('new length', len(new_Q))
        isingpartial = simple['fixed_variables']
    if (not FIXING_VARIABLES) or len(new_Q) > 0:
        cant_connect = True
        while cant_connect:
            try:
                print('about to call remote')
                conn = dwave_sapi2.remote.RemoteConnection(url, token)
                solver = conn.get_solver("DW2X")
                print('called remote', conn)
                cant_connect = False
            except IOError:
                print('Network error, trying again', datetime.datetime.now())
                time.sleep(10)
                cant_connect = True

        A = get_hardware_adjacency(solver)

        mapping = []
        offset = 0
        for i in range(len(C_i)):
            if i in isingpartial:
                mapping.append(None)
                offset += 1
            else:
                mapping.append(i - offset)
        if FIXING_VARIABLES:
            new_Q_mapped = {}
            for (first, second), val in new_Q.items():
                new_Q_mapped[(mapping[first], mapping[second])] = val
            h, J, _ = qubo_to_ising(new_Q_mapped)

        # run gauges
        nreads = 200
        qaresults = np.zeros((ngauges * nreads, len(h)))
        for g in range(ngauges):
            embedded = False
            for attempt in range(5):
                a = np.sign(np.random.rand(len(h)) - 0.5)
                h_gauge = h * a
                J_gauge = {}
                for i in range(len(h)):
                    for j in range(len(h)):
                        if (i, j) in J:
                            J_gauge[(i, j)] = J[(i, j)] * a[i] * a[j]

                embeddings = find_embedding(J.keys(), A)
                try:
                    (h0, j0, jc,
                     new_emb) = embed_problem(h_gauge, J_gauge, embeddings, A,
                                              True, True)
                    embedded = True
                    break
                except ValueError:  # no embedding found
                    print('no embedding found')
                    embedded = False
                    continue

            if not embedded:
                continue

            # adjust chain strength
            rescale_couplers = strength_scale * max(
                np.amax(np.abs(np.array(h0))),
                np.amax(np.abs(np.array(list(j0.values())))))
            #         print('scaling by', rescale_couplers)
            for k, v in j0.items():
                j0[k] /= strength_scale
            for i in range(len(h0)):
                h0[i] /= strength_scale

            emb_j = j0.copy()
            emb_j.update(jc)

            print("Quantum annealing")
            try_again = True
            while try_again:
                try:
                    qaresult = solve_ising(solver,
                                           h0,
                                           emb_j,
                                           num_reads=nreads,
                                           annealing_time=a_time,
                                           answer_mode='raw')
                    try_again = False
                except:
                    print('runtime or ioerror, trying again')
                    time.sleep(10)
                    try_again = True
            print("Quantum done")

            qaresult = np.array(
                unembed_answer(qaresult["solutions"], new_emb, 'vote', h_gauge,
                               J_gauge))
            qaresult = qaresult * a
            qaresults[g * nreads:(g + 1) * nreads] = qaresult

        if FIXING_VARIABLES:
            j = 0
            for i in range(len(C_i)):
                if i in isingpartial:
                    full_strings[:, i] = 2 * isingpartial[i] - 1
                else:
                    full_strings[:, i] = qaresults[:, j]
                    j += 1
        else:
            full_strings = qaresults

        s = full_strings
        energies = np.zeros(len(qaresults))
        s[np.where(s > 1)] = 1.0
        s[np.where(s < -1)] = -1.0
        bits = len(s[0])
        for i in range(bits):
            energies += 2 * s[:, i] * (-sigma[i] * C_i[i])
            for j in range(bits):
                if j > i:
                    energies += 2 * s[:, i] * s[:, j] * sigma[i] * sigma[
                        j] * C_ij[i][j]
                energies += 2 * s[:, i] * sigma[i] * C_ij[i][j] * mu[j]

        unique_energies, unique_indices = np.unique(energies,
                                                    return_index=True)
        ground_energy = np.amin(unique_energies)
        #         print('ground energy', ground_energy)
        if ground_energy < 0:
            threshold_energy = (1 - energy_fraction) * ground_energy
        else:
            threshold_energy = (1 + energy_fraction) * ground_energy
        lowest = np.where(unique_energies < threshold_energy)
        unique_indices = unique_indices[lowest]
        if len(unique_indices) > max_excited_states:
            sorted_indices = np.argsort(
                energies[unique_indices])[-max_excited_states:]
            unique_indices = unique_indices[sorted_indices]
        final_answers = full_strings[unique_indices]
        print('number of selected excited states', len(final_answers))

        return final_answers

    else:
        final_answer = []
        for i in range(len(C_i)):
            if i in isingpartial:
                final_answer.append(2 * isingpartial[i] - 1)
        final_answer = np.array(final_answer)
        return np.array([final_answer])
Esempio n. 9
0
# Heuristic embedding
# suppose we can't manually embed our 2D checkerboard example. J and h then remain unchanged from our initial definitions:
J = {(0,1): 1, (0,2): 1, (1,3): 1, (2,3): 1}
h = [-1,0,0,0]

connection = RemoteConnection(DWAVE_SAPI_URL, DWAVE_TOKEN)
solver = connection.get_solver(DWAVE_SOLVER)

# first get the adjacency matrix of the current hardware graph:

adjacency = get_hardware_adjacency(solver)

# Now let's try to find an embedding of our problem:

embedding = find_embedding(J.keys(), adjacency)

# We are now ready to embed our problem onto the graph:

[h, j0, jc, embeddings] = embed_problem(h, J, embedding, adjacency)

# j0 contains the original couplings that we defined and jc contains the couplings that enforce the integrity of the chains (they correlate the qubits within the chains). Thus, we need to combine them again into one big J dictionary:

J = j0.copy()
J.update(jc)

# Now, we're ready to solve the embedded problem:

params = {"answer_mode": 'histogram', "num_reads": 10000}
raw_results = solve_ising(solver, h, J, **params)
Esempio n. 10
0
    def sample_ising(self, h, J, embedding_tag=None, **sapi_kwargs):
        """Embeds the given problem using sapi's find_embedding then invokes
        the given sampler to solve it.

        Args:
            h (dict/list): The linear terms in the Ising problem. If a
                dict, should be of the form {v: bias, ...} where v is
                a variable in the Ising problem, and bias is the linear
                bias associated with v. If a list, should be of the form
                [bias, ...] where the indices of the biases are the
                variables in the Ising problem.
            J (dict): A dictionary of the quadratic terms in the Ising
                problem. Should be of the form {(u, v): bias} where u,
                v are variables in the Ising problem and bias is the
                quadratic bias associated with u, v.
            embedding_tag: Allows the user to specify a tag for the generated
                embedding. Useful for when the user wishes to submit multiple
                problems with the same logical structure.
            Additional keyword parameters are the same as for
            SAPI's solve_ising function, see QUBIST documentation.

        Returns:
            :class:`dimod.SpinResponse`: The unembedded samples.

        Examples:
            >>> sampler = sapi.EmbeddingComposite(sapi.SAPILocalSampler('c4-sw_optimize'))
            >>> response = sampler.sample_ising({}, {(0, 1): 1, (0, 2): 1, (1, 2): 1})

            Using the embedding_tag, the embedding is generated only once.
            >>> h = {0: .1, 1: 1.3, 2: -1.}
            >>> J = {(0, 1): 1, (1, 2): 1, (0, 2): 1}
            >>> sampler = sapi.EmbeddingComposite(sapi.SAPILocalSampler('c4-sw_optimize'))
            >>> response0 = sampler.sample_ising(h, J, embedding_tag='K3')
            >>> response1 = sampler.sample_ising(h, J, embedding_tag='K3')

        """
        # get the sampler that is used by the composite
        sampler = self._child

        # the ising_index_labels decorator converted the keys of h to be indices 0, n-1
        # sapi wants h to be a list, so let's make that conversion, using the keys as
        # the indices.
        h_list = [h[v] for v in range(len(h))]

        # get the structure of the child sampler. The first value are the nodes which
        # we don't need, the second is the set of edges available.
        (__, edgeset) = sampler.structure

        if embedding_tag is None or embedding_tag not in self.cached_embeddings:
            # we have not previously cached an embedding so we need to determine it

            # get the adjacency structure of our problem
            S = set(J)
            S.update({(v, v) for v in h})

            # embed our adjacency structure, S, into the edgeset of the sampler.
            embeddings = find_embedding(S, edgeset)

            # sometimes it fails, often because the problem is too large
            if J and not embeddings:
                raise Exception('No embedding found')

            # now it is possible that h_list might include nodes not in embedding, so let's
            # handle that case here
            if len(h_list) > len(embeddings):
                emb_qubits = set().union(*embeddings)
                while len(h_list) > len(embeddings):
                    for v in sampler.solver.properties['qubits']:
                        if v not in emb_qubits:
                            embeddings.append([v])
                            emb_qubits.add(v)
                            break

            if embedding_tag is not None:
                # save the embedding for posterity
                self.cached_embeddings[embedding_tag] = embeddings
        else:
            # the user has asserted that we can reuse a previously created embedding
            embeddings = self.cached_embeddings[embedding_tag]

        # embed the problem
        h0, j0, jc, new_emb = embed_problem(h_list, J, embeddings, edgeset)

        # combine jc and j0
        emb_j = j0.copy()
        emb_j.update(jc)

        # pass the chains we made into the sampler if it wants them
        if 'chains' in sampler.solver.properties['parameters'] and 'chains' not in sapi_kwargs:
            sapi_kwargs['chains'] = new_emb

        # invoke the child sampler
        emb_response = sampler.sample_ising(h0, emb_j, **sapi_kwargs)

        # we need the samples back into lists for the unembed_answer function
        answers = [[sample[i] for i in range(len(sample))] for sample in emb_response]

        # unemnbed
        solutions = unembed_answer(answers, new_emb, 'minimize_energy', h_list, J)

        # and back once again into dicts for dimod...
        samples = ({v: sample[v] for v in h} for sample in solutions)
        sample_data = (data for __, data in emb_response.samples(data=True))
        response = dimod.SpinResponse()
        response.add_samples_from(samples, sample_data=sample_data, h=h, J=J)

        return response
Esempio n. 11
0
File: dwave.py Progetto: rizkg/qasm
def find_dwave_embedding(logical, optimize, verbosity):
    """Find an embedding of a logical problem in the D-Wave's physical topology.
    Store the embedding within the Problem object."""
    edges = logical.strengths.keys()
    edges.sort()
    try:
        hw_adj = get_hardware_adjacency(qasm.solver)
    except KeyError:
        # The Ising heuristic solver is an example of a solver that lacks a
        # fixed hardware representation.  We therefore assert that the hardware
        # exactly matches the problem'input graph.
        hw_adj = edges

    # Determine the edges of a rectangle of cells we want to use.
    L, M, N = qasm.chimera_topology(qasm.solver)
    L2 = 2 * L
    ncells = (qasm.next_sym_num + 1) // L2
    if optimize:
        edgey = max(int(math.sqrt(ncells)), 1)
        edgex = max((ncells + edgey - 1) // edgey, 1)
    else:
        edgey = N
        edgex = M

    # Announce what we're about to do.
    if verbosity >= 2:
        sys.stderr.write(
            "Embedding the logical adjacency within the physical topology.\n\n"
        )

    # Repeatedly expand edgex and edgey until the embedding works.
    while edgex <= M and edgey <= N:
        # Retain adjacencies only within the rectangle.
        alt_hw_adj = []
        for q1, q2 in hw_adj:
            c1 = q1 // L2
            if c1 % M >= edgex:
                continue
            if c1 // M >= edgey:
                continue
            c2 = q2 // L2
            if c2 % M >= edgex:
                continue
            if c2 // M >= edgey:
                continue
            alt_hw_adj.append((q1, q2))
        alt_hw_adj = set(alt_hw_adj)

        # Try to find an embedding.
        if verbosity >= 2:
            sys.stderr.write("  Trying a %dx%d unit-cell embedding ... " %
                             (edgex, edgey))
            status_file = tempfile.NamedTemporaryFile(mode="w", delete=False)
            stdout_fd = os.dup(sys.stdout.fileno())
            os.dup2(status_file.fileno(), sys.stdout.fileno())
            embedding = find_embedding(edges, alt_hw_adj, verbose=1)
            sys.stdout.flush()
            os.dup2(stdout_fd, sys.stdout.fileno())
            status_file.close()
            if len(embedding) > 0:
                sys.stderr.write("succeeded\n\n")
            else:
                sys.stderr.write("failed\n\n")
            with open(status_file.name, "r") as status:
                for line in status:
                    sys.stderr.write("    %s" % line)
            sys.stderr.write("\n")
            os.remove(status_file.name)
        else:
            embedding = find_embedding(edges, alt_hw_adj, verbose=0)
        if len(embedding) > 0:
            # Success!
            break

        # Failure -- increase edgex or edgey and try again.
        if edgex < edgey:
            edgex += 1
        else:
            edgey += 1
    if not (edgex <= M and edgey <= N):
        qasm.abend("Failed to embed the problem")

    # Store in the logical problem additional information about the embedding.
    logical.embedding = embedding
    logical.hw_adj = alt_hw_adj
    logical.edges = edges
Esempio n. 12
0
    def solvequbo(self):
        # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        # EMBEDDING:
        # gets the hardware adjacency for the solver in use.
        self.Adjacency = get_hardware_adjacency(self.solver)
        # gets the embedding for the D-Wave hardware
        self.Embedding = find_embedding(self.qubo_dict, self.Adjacency)
        # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        # CONVERSIONS AND RESCALING:
        # convert qubo to ising
        (self.h, self.J, self.ising_offset) = qubo_to_ising(self.qubo_dict)
        # Even though auto_scale = TRUE, we are rescaling values
        # Normalize h and J to be between +/-1
        self.h_max = max(map(abs, self.h))

        if len(self.J.values()) > 0:
            j_max = max([abs(x) for x in self.J.values()])
        else:
            j_max = 1
        # In [0,1], this scales down J values to be less than jc
        j_scale = 0.8

        # Use the largest large value
        if self.h_max > j_max:
            j_max = self.h_max

        # This is the actual scaling
        rescale = j_scale / j_max
        self.h1 = map(lambda x: rescale * x, self.h)

        if len(self.J.values()) > 0:
            self.J1 = {key: rescale * val for key, val in self.J.items()}
        else:
            self.J1 = self.J
        # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        # EMBEDDING:
        # gets the hardware adjacency for the solver in use.
        self.Adjacency = get_hardware_adjacency(self.solver)
        # gets the embedding for the D-Wave hardware
        self.Embedding = find_embedding(self.qubo_dict, self.Adjacency)
        # Embed the rescale values into the hardware graph
        [self.h0, self.j0, self.jc, self.Embedding
         ] = embed_problem(self.h1, self.J1, self.Embedding, self.Adjacency,
                           self.clean, self.smear, self.h_range, self.J_range)
        # embed_problem returns two J's, one for the biases from your problem, one for the chains.
        self.j0.update(self.jc)
        # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        # SOLVE PROBLEM ON D-WAVE:
        # generate the embedded solution to the ising problem.
        self.dwave_return = solve_ising(self.solver, self.h0, self.j0,
                                        **self.params)
        #print("dwave_return")
        #print(self.dwave_return['solutions'])
        # the unembedded answer to the ising problem.
        unembed = np.array(
            unembed_answer(self.dwave_return['solutions'],
                           self.Embedding,
                           broken_chains="minimize_energy",
                           h=self.h,
                           j=self.J))  #[0]
        # convert ising string to qubo string
        ising_ans = [
            list(filter(lambda a: a != 3, unembed[i]))
            for i in range(len(unembed))
        ]
        #print(ising_ans)
        #print("ISING ANS")
        # Because the problem is unembedded, the energy will be different for the embedded, and unembedded problem.
        # ising_energies = dwave_return['energies']
        self.h_energy = [
            sum(self.h1[v] * val for v, val in enumerate(unembed[i]))
            for i in range(len(unembed))
        ]
        self.J_energy = [
            sum(self.J1[(u, v)] * unembed[i, u] * unembed[i, v]
                for u, v in self.J1) for i in range(len(unembed))
        ]
        self.ising_energies = np.array(self.h_energy) + np.array(self.J_energy)
        #print(self.h_energy)
        #print(self.J_energy)
        #print(self.ising_energies)
        #print("ENERGIES")
        # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        # CONVERT ANSWER WITH ENERGY TO QUBO FORM:
        # Rescale and add back in the ising_offset and another constant
        self.dwave_energies = self.ising_energies / rescale + self.ising_offset  #[map(lambda x: (x / rescale + self.ising_offset), self.ising_energies[i]) for i in range(len(self.ising_energies))]
        # QUBO RESULTS:
        self.qubo_ans = (
            np.array(ising_ans) + 1
        ) / 2  #[map(lambda x: (x + 1) / 2, ising_ans[i]) for i in range(len(ising_ans))]
Esempio n. 13
0
def find_dwave_embedding(logical, optimization, verbosity, hw_adj_file):
    """Find an embedding of a logical problem in the D-Wave's physical topology.
    Store the embedding within the Problem object."""
    # SAPI tends to choke when embed_problem is told to embed a problem
    # containing a zero-weight node whose adjacent couplers all have zero
    # strength.  (Tested with SAPI 2.4.)  To help out SAPI, we simply remove
    # all zero-strength couplers.
    edges = [e for e in logical.strengths.keys() if logical.strengths[e] != 0.0]
    edges.sort()
    logical.edges = edges
    if hw_adj_file == None:
        try:
            hw_adj = get_hardware_adjacency(qmasm.solver)
        except KeyError:
            # The Ising heuristic solver is an example of a solver that lacks a
            # fixed hardware representation.  We therefore assert that the
            # hardware is an all-to-all network that connects every node to
            # every other node.
            endpoints = set([a for a, b in edges] + [b for a, b in edges])
            hw_adj = [(a, b) for a in endpoints for b in endpoints if a != b]
    else:
        hw_adj = read_hardware_adjacency(hw_adj_file, verbosity)

    # Tell the user if we have any hope at all of embedding the problem.
    if verbosity >= 2:
        report_embeddability(edges, hw_adj)

    # Determine the edges of a rectangle of cells we want to use.  If we read
    # the topology from a file or otherwise can't prove that we have a Chimera
    # graph, we call this rectangle 0x0 and force the main embedding loop to
    # exit after a single iteration because we don't know the topology is even
    # rectangular.
    edgex = 0
    edgey = 0
    M = 0
    N = 0
    num_vars = len(qmasm.sym_map.all_numbers())
    try:
        if hw_adj_file == None:
            L, M, N = qmasm.chimera_topology(qmasm.solver)
            L2 = 2*L
            ncells = (num_vars + L2) // L2   # Round up the number of cells.
            if optimization >= 2:
                edgey = max(int(math.sqrt(ncells)), 1)
                edgex = max((ncells + edgey - 1) // edgey, 1)
            else:
                edgey = N
                edgex = M
    except qmasm.NonChimera:
        pass

    # Announce what we're about to do.
    if verbosity >= 2:
        sys.stderr.write("Embedding the logical adjacency within the physical topology.\n\n")

    # Repeatedly expand edgex and edgey until the embedding works.
    while edgex <= M and edgey <= N:
        if edgex == M and edgey == N:
            alt_hw_adj = hw_adj
        else:
            # Retain adjacencies only within the rectangle.
            alt_hw_adj = []
            for q1, q2 in hw_adj:
                c1 = q1//L2
                if c1 % M >= edgex:
                    continue
                if c1 // M >= edgey:
                    continue
                c2 = q2//L2
                if c2 % M >= edgex:
                    continue
                if c2 // M >= edgey:
                    continue
                alt_hw_adj.append((q1, q2))
            alt_hw_adj = set(alt_hw_adj)
        logical.hw_adj = alt_hw_adj

        # See if we already have an embedding in the embedding cache.
        ec = EmbeddingCache(edges, alt_hw_adj)
        if verbosity >= 2:
            if ec.cachedir == None:
                sys.stderr.write("  No embedding cache directory was specified ($QMASMCACHE).\n")
            else:
                sys.stderr.write("  Using %s as the embedding cache directory ...\n" % ec.cachedir)
        embedding = ec.read()
        if embedding == []:
            # Cache hit, but embedding had failed
            if verbosity >= 2:
                sys.stderr.write("  Found failed embedding %s in the embedding cache.\n\n" % ec.hash)
        elif embedding != None:
            # Successful cache hit!
            if verbosity >= 2:
                sys.stderr.write("  Found successful embedding %s in the embedding cache.\n\n" % ec.hash)
            logical.embedding = embedding
            return
        if verbosity >= 2 and ec.cachedir != None:
            sys.stderr.write("  No existing embedding found in the embedding cache.\n")

        # Try to find an embedding, unless we previously determined that it had
        # failed.
        if embedding != []:
            if verbosity >= 2:
                # SAPI's find_embedding is hard-wired to write to stdout.
                # Trick it into writing into a pipe instead.
                if edgex == 0 and edgey == 0:
                    sys.stderr.write("  Trying to embed ... ")
                else:
                    sys.stderr.write("  Trying a %dx%d unit-cell embedding ...\n\n" % (edgex, edgey))
                sepLine = "=== EMBEDDING ===\n"
                r, w = os.pipe()
                pid = os.fork()
                if pid == 0:
                    # Child -- perform the embedding.
                    os.close(r)
                    os.dup2(w, sys.stdout.fileno())
                    embedding = find_embedding(edges, alt_hw_adj, verbose=1)
                    sys.stdout.flush()
                    os.write(w, sepLine)
                    os.write(w, json.dumps(embedding) + "\n")
                    os.close(w)
                    os._exit(0)
                else:
                    # Parent -- report the embedding's progress.
                    os.close(w)
                    pipe = os.fdopen(r, "r", 10000)
                    while True:
                        try:
                            rstr = pipe.readline()
                            if rstr == sepLine:
                                break
                            if rstr == "":
                                qmasm.abend("Embedder failed to terminate properly")
                            sys.stderr.write("      %s" % rstr)
                        except:
                            pass

                    # Receive the embedding from the child.
                    embedding = json.loads(pipe.readline())
                    sys.stderr.write("\n")
            else:
                embedding = find_embedding(edges, alt_hw_adj, verbose=0)
            ec.write(embedding)
            if len(embedding) > 0:
                # Success!
                break

        # Continued failure -- increase edgex or edgey and try again.
        if edgex < edgey:
            edgex += 1
        else:
            edgey += 1
    if not(edgex <= M and edgey <= N):
        qmasm.abend("Failed to embed the problem")
    logical.embedding = embedding
Esempio n. 14
0
#A = util.get_chimera_adjacency(1,1,4)

S_size = 3
#S = {}
# A list should work as well as a dictionary.
# Only required to be an iterable specifying pairs of nodes.
S = []

for i in range(S_size):
    for j in range(S_size):
        #        S[(i,j)] = 1
        S.append((i, j))

print S

emb = embedding.find_embedding(S, A, verbose=1)
print emb

Q = {(0, 0): 1, (1, 1): 1, (2, 2): 1, (0, 1): 1, (0, 2): -2, (1, 2): -2}

(h, j, ising_offset) = util.qubo_to_ising(Q)

print "h:", h
print "j:", j
print "ising_offset:", ising_offset

(h0, j0, jc, new_emb) = embedding.embed_problem(h, j, emb, A)

print "h0:", h0
print "j0:", j0
print "jc:", jc