The error is because the number of qubits in the hardware you are selecting, is less than what your QAOA circuit has (in this case 40). All you have to do is change the backend importing code, and assert that you want a backend with at least this many qubits. You can do this via
least_busy(min_num_qubits=None, instance=None, filters=None, **kwargs)
or in your code, you have to do the following:
service = QiskitRuntimeService(channel="ibm_quantum",token="TOKEN")
backend = service.least_busy(min_num_qubits = 40,operational=True, simulator=False)
For updated QAOA implementation, follow this
The backend is assigned in the sampler
and estimator
using options
, like this:
# To run on local simulator:
# 1. Use the Estimator from qiskit.primitives instead.
# 2. Remove the Session context manager below.
options = Options()
options.transpilation.skip_transpilation = True
options.execution.shots = 10000
session = Session(backend=backend)
estimator = Estimator(session=session, options={"shots": int(1e4)})
sampler = Sampler(session=session, options={"shots": int(1e4)})
Recent Implementation
As per your recent comments, that error can be rectified by doing follows:
I'm following your code till this line:
print(qp.export_as_lp_string())
Selecting the backend and importing
# General imports
import numpy as np
import warnings
warnings.filterwarnings("ignore")
# Pre-defined ansatz circuit, operator class and visualization tools
from qiskit.circuit.library import QAOAAnsatz
from qiskit.quantum_info import SparsePauliOp
from qiskit.visualization import plot_distribution
# Qiskit Runtime
from qiskit_ibm_runtime import QiskitRuntimeService, Session
from qiskit_ibm_runtime import EstimatorV2 as Estimator
from qiskit_ibm_runtime import SamplerV2 as Sampler
# SciPy minimizer routine
from scipy.optimize import minimize
# rustworkx graph library
import rustworkx as rx
from rustworkx.visualization import mpl_draw
# To run on hardware, select the backend with the fewest number of jobs in the queue
service = QiskitRuntimeService(channel="ibm_quantum")
backend = service.least_busy(min_num_qubits=40,operational=True, simulator=False)
backend.name
Since you are using a QAOA function, I'll write how it is done in the updated version:
Convert QUBO to a SparsePauliOp
op,offset = qp.to_ising()
print("offset: {}".format(offset))
print("operator:")
print(op)
Make a QAOA Ansatz
from qiskit.circuit.library import QAOAAnsatz
ansatz = QAOAAnsatz(op, reps=2)
ansatz.decompose(reps=3).draw(output="mpl", style="iqp")
Optimize problem for quantum execution
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
ansatz_isa = pm.run(ansatz)
ansatz_isa.draw(output="mpl", idle_wires=False, style="iqp")
Observables
hamiltonian_isa = op.apply_layout(ansatz_isa.layout)
hamiltonian_isa
Execute
def cost_func(params, ansatz, hamiltonian, estimator):
"""Return estimate of energy from estimator
Parameters:
params (ndarray): Array of ansatz parameters
ansatz (QuantumCircuit): Parameterized ansatz circuit
hamiltonian (SparsePauliOp): Operator representation of Hamiltonian
estimator (EstimatorV2): Estimator primitive instance
Returns:
float: Energy estimate
"""
pub = (ansatz, [hamiltonian], [params])
result = estimator.run(pubs=[pub]).result()
cost = result[0].data.evs[0]
return cost
Quantum Backend
# To run on local simulator:
# 1. Use the StatevectorEstimator from qiskit.primitives instead.
# 2. Remove the Session instantiation below.
session = Session(backend=backend)
# Configure estimator
estimator = Estimator(session=session)
estimator.options.default_shots = 10_000
estimator.options.dynamical_decoupling.enable = True
# Configure sampler
sampler = Sampler(session=session)
sampler.options.default_shots = 10_000
sampler.options.dynamical_decoupling.enable = True
Initial Parameters
x0 = 2 * np.pi * np.random.rand(ansatz_isa.num_parameters)
and minimization
res = minimize(cost_func, x0, args=(ansatz_isa, hamiltonian_isa, estimator), method="COBYLA")
res
Post Process
# Assign solution parameters to ansatz
qc = ansatz.assign_parameters(res.x)
# Add measurements to our circuit
qc.measure_all()
qc_isa = pm.run(qc)
qc_isa.draw(output="mpl", idle_wires=False, style="iqp")
result = sampler.run([qc_isa]).result()
samp_dist = result[0].data.meas.get_counts()
# Close the session since we are now done with it
session.close()
and if your problem instance is small, you can view it as well
plot_distribution(samp_dist, figsize=(15, 5))
System Versions
Python: 3.11.7
Qiskit: 1.0.2
and the all the other Qiskit dependencies in their latest version as of today.