Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

D-Wave QPU

SolverDWaveQPU submits the model to a physical D-Wave Advantage quantum annealer over the D-Wave Leap cloud API. This page is derived from xqsa/dwave_qpu.py and spec/xqsa/*; no D-Wave Leap account was available while writing it, so nothing on this page was run.

Credentials

Requires the [dwave] extra:

pip install xqsa[dwave]

SolverDWaveQPU() resolves an API token from the token= constructor argument first, then the DWAVE_API_TOKEN environment variable; with neither set, construction raises ValueError. An optional endpoint= or DWAVE_API_ENDPOINT overrides the default Leap API URL.

import os
os.environ["DWAVE_API_TOKEN"] = "your-leap-token"

from xqsa import SolverDWaveQPU
from xqvm_py.xqmx import XQMX

model = XQMX.binary_model(4)
model.set_linear(0, -1)
model.set_quadratic(0, 1, 2)

solver = SolverDWaveQPU()              # auto-selects a Pegasus-topology Advantage system
result = solver.solve(model)
print(result.metadata["solver"])       # e.g. "Advantage_system5.4"
print(result.metadata["qpu_timing"])   # QPU timing breakdown from Leap

Pass solver="Advantage_system5.4" to target a specific system instead of the default Pegasus-topology filter.

What Embedding Means

A D-Wave Advantage chip is not fully connected: each physical qubit couples only to a fixed, small set of neighbours defined by its Pegasus topology. Your model’s coupling graph is almost never a subgraph of that hardware graph directly. SolverDWaveQPU wraps the sampler in dwave.system.EmbeddingComposite, which finds a minor embedding: each logical variable maps to a chain of one or more physical qubits, wired together so the chain acts as a single variable by strongly coupling its members (chain_strength).

Problem size on real hardware is not simply “how many variables.” A densely coupled model needs longer chains to embed, chains compete for the chip’s limited qubits, and a model that does not embed at all raises rather than silently degrading. EmbeddingComposite handles the search automatically; there is no separate embedding step to call in xqsa. Contrast this with Quip Network, where SolverQuip requires an exact subgraph match onto a fixed topology and refuses to do this chain-based embedding at all.

Parameters

ParameterConstructor defaultMeaning
tokenNone (env fallback)Leap API token
endpointNone (env fallback)Leap API endpoint override
solverNone (Pegasus filter)Specific Advantage system name
num_reads100Annealing runs read back from the chip
annealing_time20Microseconds per anneal

Both num_reads and annealing_time are overridable per call: solver.solve(model, annealing_time=100, chain_strength=2.0). chain_strength and other EmbeddingComposite options pass straight through **kwargs to the underlying sampler call.

How a QPU Result Differs

The result shape is the same SolverResult every backend returns, but two things are specific to this backend. result.energy is still recomputed by xqsa in exact integer arithmetic from the returned sample – the chip’s own reported energy is never trusted directly – but the sample search itself ran on physical hardware subject to analog noise and the embedding above, not an exact digital simulation. And result.metadata carries QPU-specific detail that the local backends do not report at all: metadata["solver"] names the physical Advantage system that ran the job, and metadata["qpu_timing"] is the timing breakdown Leap returns – a dict when present, with keys that come from Leap and are not fixed by xqsa, or None when the sampler response carries no timing info at all. solver, qpu_timing, and reads sit at the top level of metadata, alongside a params dict structured the same way it is for the three simulated-annealing backends (params["annealing_time"], params["raw_energy"]) – only solver and qpu_timing sit outside params, and this call does not set metadata["seed"] at all (there is no seed on physical hardware). See Solving Overview for the full, per-backend split. If you write code against result.metadata for more than one backend, do not assume its shape is identical across all five; check the backend you are calling.