Constraints Example: Submitting to a QPU Solver

This section shows how you submit a problem to a D-Wave quantum computer. It uses D-Wave’s open-source Ocean SDK to submit the exactly-one-true problem formulated in the previous chapters.

Before you can submit a problem to D-Wave solvers, you must have an account and an API token; visit Leap to sign up for an account and get your token.

Note

To run the following steps yourself requires prior configuration of some requisite information for problem submission through SAPI. If you have installed the Ocean SDK, this is typically done as a first step; in D-Wave’s Leap IDE, the default workspace meets these requirements.

For more information, including on Ocean SDK installation instructions and detailed examples, see the Ocean software documentation.

The section below submits the problem that the Constraints Example: Minor-Embedding chapter manually minor-embedded; the next section uses Ocean tools to minor-embed automatically when submitting the original objective function.

Manually Minor-Embedded Problem

The Chimera embedding found in the Constraints Example: Minor-Embedding chapter can be used only on a D-Wave 2000Q system, and only on a QPU that has the selected qubits and couplers on its working graph.1

1

The yield of a working graph is typically less than the total number of qubits and couplers that are fabricated and physically present on a QPU.

First, select a D-Wave 2000Q system.

from dwave.system import DWaveSampler
sampler_manual = DWaveSampler(solver={'topology__type': 'chimera'})

The following checks that the qubits and couplers selected in the Constraints Example: Minor-Embedding chapter are available. If not, use others (for example, add 8 to shift to the next Chimera unit cell and try qubits 8, 9, 12, 13).

>>> all(qubit in sampler_manual.nodelist for qubit in [0, 1, 4, 5])
True
>>> all(coupler in sampler_manual.edgelist for coupler in [(0, 4), (0, 5), (1, 4), (1, 5)])
True

Set values of the minor-embedded QUBO and submit to the selected QPU.

qubit_biases = {(0, 0): 1, (1, 1): -1, (4, 4): -1, (5, 5): 1}
coupler_strengths = {(0, 4): 2, (0, 5): -3, (1, 4): 2, (1, 5): 2}
Q = {**qubit_biases, **coupler_strengths}

sampleset = sampler_manual.sample_qubo(Q, num_reads=5000)

Below are results from running this problem on a D-Wave 2000Q system:

>>> print(sampleset)                    
   0  1  4  5 energy num_oc.
0  0  0  1  0   -1.0    1274
1  0  1  0  0   -1.0    1726
2  1  0  0  1   -1.0    1997
3  1  1  0  1    0.0       1
4  0  1  1  0    0.0       2
['BINARY', 5 rows, 5000 samples, 4 variables]

The solutions returned from the QPU express the states of qubits at the end of each of 5000 anneals (num_reads=5000), with the num_oc column showing the number of occurrences of a returned state. The results above unembed to:

  • Row 0: Solution \((a, b, c) = (1, 0, 0)\) with energy \(-1\) was found 1274 times.

  • Row 1: Solution \((a, b, c) = (0, 0, 1)\) with energy \(-1\) was found 1726 times.

  • Row 2: Solution \((a, b, c) = (0, 1, 0)\) with energy \(-1\) was found 1997 times.

Although five unique states are returned, the lowest energy occurs for the valid solutions, which are the most frequent solution. Three anneals ended with incorrect solutions, which have higher energy than the correct solutions.

Automated Minor-Embedded Problem

The Ocean software can heuristically find minor-embeddings for your QUBO or Ising objective functions, as shown here.

First, select a D-Wave 2000Q system.

from dwave.system import DWaveSampler, EmbeddingComposite
sampler_auto = EmbeddingComposite(DWaveSampler(solver={'topology__type': 'chimera'}))

Unlike the previous section, here you do not need to check pre-selected qubits and couplers.

Set values of the original QUBO (i.e., variables, such as \(a\), rather than qubit indices, such as 0, and coefficients without modifications for chains) and submit to the selected QPU.

linear = {('a', 'a'): -1, ('b', 'b'): -1, ('c', 'c'): -1}
quadratic = {('a', 'b'): 2, ('b', 'c'): 2, ('a', 'c'): 2}
Q = {**linear, **quadratic}

sampleset = sampler_auto.sample_qubo(Q, num_reads=5000)

Below are results from running this problem on a D-Wave 2000Q system:

>>> print(sampleset)                        
   a  b  c energy num_oc. chain_b.
0  0  1  0   -1.0    1465      0.0
1  1  0  0   -1.0    1838      0.0
2  0  0  1   -1.0    1695      0.0
3  0  1  1    0.0       1      0.0
4  1  0  1    0.0       1 0.333333
['BINARY', 5 rows, 5000 samples, 3 variables]

The results show values for the objective function’s variables, not the qubits they were mapped to, so there is no need for unembedding this time. Again in the results of 5000 reads, you see that the lowest energy occurs for the three valid solutions to the problem.

Note for row 4 that the value in the chain_b column, which shows the percentage of variable values that are based on broken chains, is not zero. For this anneal, the qubits in the chain of qubits representing variable \(b\) ended in different states. Ocean software chose the value \(b=0\) by fixing the broken chain; it has different methods for dealing with broken chains, for example, selecting the value a majority of the chain’s qubits were in at the end of the anneal. This is one of a number of techniques, called postprocessing, which are often part of solving problems on quantum computers.