1
$\begingroup$

I'm trying to run the QAOA code from Qiskit (https://qiskit.org/textbook/ch-applications/qaoa.html) on a real quantum computer. However, it doesn't work.

Here starts my code:

import networkx as nx
import matplotlib.pyplot as plt
from qiskit import Aer, IBMQ
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit

from qiskit.providers.ibmq import least_busy
from qiskit.tools.monitor import job_monitor
from qiskit.visualization import plot_histogram

from qiskit.compiler import assemble

from qiskit.visualization import plot_circuit_layout

from qiskit import execute, transpile
from qiskit.circuit import Parameter

from qiskit.tools import parallel_map
provider = IBMQ.load_account()
backend = provider.get_backend('ibmq_manila')

shots = 2048
import networkx as nx

G = nx.Graph()
G.add_nodes_from([0, 1, 2, 3])
G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 0)])
nx.draw(G, with_labels=True, alpha=0.8, node_size=500)
# Adjacency is essentially a matrix which tells you which nodes are connected. This matrix is given as a sparse matrix, so
# we need to convert it to a dense matrix
adjacency = nx.adjacency_matrix(G).todense()

nqubits = 4

beta = Parameter("$\\beta$")
gamma = Parameter("$\\gamma$")

qc_mix = QuantumCircuit(nqubits)
for i in range(0, nqubits):
    qc_mix.rx(2 * beta, i)

qc_p = QuantumCircuit(nqubits)
for pair in list(G.edges()):  # pairs of nodes
    qc_p.rzz(2 * gamma, pair[0], pair[1])
    qc_p.barrier()
    
qc_0 = QuantumCircuit(nqubits)
for i in range(0, nqubits):
    qc_0.h(i)
    
qc_qaoa = QuantumCircuit(nqubits)

qc_qaoa.append(qc_0, [i for i in range(0, nqubits)])
qc_qaoa.append(qc_p, [i for i in range(0, nqubits)])
qc_qaoa.append(qc_mix, [i for i in range(0, nqubits)])

qc_qaoa.decompose().decompose().draw(output='mpl')

Until here, the code is the same as from Qiskit. However, I found out, that the basis gates used in the Qiskit circuit are not the ones that are used in a real quantum computer (her: ibm_manila).

This is seen in

backend.configuration().basis_gates

So, what I did, I transpiled the circuit and maximized the optimization level.

from qiskit import transpile

qc_basis = transpile(qc_qaoa, backend)
qc_basis.draw(output='mpl')
new_circ_lv3 = transpile(qc_basis, backend=backend, optimization_level=3)
plot_circuit_layout(new_circ_lv3, backend)

After that, the Qiskit code doesn't work anymore and I don't know how to solve it.

def maxcut_obj(x, G):
    """
    Given a bitstring as a solution, this function returns
    the number of edges shared between the two partitions
    of the graph.
    
    Args:
        x: str
           solution bitstring
           
        G: networkx graph
        
    Returns:
        obj: float
             Objective
    """
    obj = 0
    for i, j in G.edges():
        if x[i] != x[j]:
            obj -= 1
            
    return obj


def compute_expectation(counts, G):
    
    """
    Computes expectation value based on measurement results
    
    Args:
        counts: dict
                key as bitstring, val as count
           
        G: networkx graph
        
    Returns:
        avg: float
             expectation value
    """
    
    avg = 0
    sum_count = 0
    for bitstring, count in counts.items():
        
        obj = maxcut_obj(bitstring, G)
        avg += obj * count
        sum_count += count
        
    return avg/sum_count


# We will also bring the different circuit components that
# build the qaoa circuit under a single function
def create_qaoa_circ(G, theta):
    
    """
    Creates a parametrized qaoa circuit
    
    Args:  
        G: networkx graph
        theta: list
               unitary parameters
                     
    Returns:
        qc: qiskit circuit
    """
    
      
    nqubits = len(G.nodes())
    p = len(theta)//2  # number of alternating unitaries
    qc = QuantumCircuit(nqubits)
          
    beta = theta[:p]
    gamma = theta[p:]
        
    # initial_state
    for i in range(0, nqubits):
        qc.h(i)
    
    for irep in range(0, p):
        
        # problem unitary
        for pair in list(G.edges()):
            qc.rzz(2 * gamma[irep], pair[0], pair[1])

        # mixer unitary
        for i in range(0, nqubits):
            qc.rx(2 * beta[irep], i)
            
    qc.measure_all()
           
        
    return qc

# Finally we write a function that executes the circuit on the chosen backend
def get_expectation(G, p, shots=2048):
    
    """
    Runs parametrized circuit
    
    Args:
        G: networkx graph
        p: int,
           Number of repetitions of unitaries
    """
            
    backend.shots = shots
    
    def execute_circ(theta):
        
        qc = create_qaoa_circ(G, theta)
        
        compiled_circuits = transpile(qc_basis, backend)
        qobj = assemble(compiled_circuits, backend)
                    
       
        return compute_expectation(counts, G)
    
        
    return execute_circ
from scipy.optimize import minimize

expectation = get_expectation(G, p=1)


res = minimize(expectation, 
                      [1.0, 1.0], 
                      method='COBYLA')

res

And I get this error:

---------------------------------------------------------------------------
QiskitError                               Traceback (most recent call last)
Input In [20], in <cell line: 8>()
      3 #qc_basis.assign_parameters(create_qaoa_circ, inplace = True)
      5 expectation = get_expectation(G, p=1)
----> 8 res = minimize(expectation, 
      9                       [1.0, 1.0], 
     10                       method='COBYLA')
     12 res

File ~\anaconda3\lib\site-packages\scipy\optimize\_minimize.py:698, in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    695     res = _minimize_tnc(fun, x0, args, jac, bounds, callback=callback,
    696                         **options)
    697 elif meth == 'cobyla':
--> 698     res = _minimize_cobyla(fun, x0, args, constraints, callback=callback,
    699                             **options)
    700 elif meth == 'slsqp':
    701     res = _minimize_slsqp(fun, x0, args, jac, bounds,
    702                           constraints, callback=callback, **options)

File ~\anaconda3\lib\site-packages\scipy\optimize\_cobyla_py.py:34, in synchronized.<locals>.wrapper(*args, **kwargs)
     31 @functools.wraps(func)
     32 def wrapper(*args, **kwargs):
     33     with _module_lock:
---> 34         return func(*args, **kwargs)

File ~\anaconda3\lib\site-packages\scipy\optimize\_cobyla_py.py:273, in _minimize_cobyla(fun, x0, args, constraints, rhobeg, tol, maxiter, disp, catol, callback, **unknown_options)
    270         callback(np.copy(x))
    272 info = np.zeros(4, np.float64)
--> 273 xopt, info = cobyla.minimize(calcfc, m=m, x=np.copy(x0), rhobeg=rhobeg,
    274                               rhoend=rhoend, iprint=iprint, maxfun=maxfun,
    275                               dinfo=info, callback=wrapped_callback)
    277 if info[3] > catol:
    278     # Check constraint violation
    279     info[0] = 4

File ~\anaconda3\lib\site-packages\scipy\optimize\_cobyla_py.py:261, in _minimize_cobyla.<locals>.calcfc(x, con)
    260 def calcfc(x, con):
--> 261     f = fun(np.copy(x), *args)
    262     i = 0
    263     for size, c in izip(cons_lengths, constraints):

Input In [18], in get_expectation.<locals>.execute_circ(theta)
    111 qc = create_qaoa_circ(G, theta)
    113 compiled_circuits = transpile(qc_basis, backend)
--> 114 qobj = assemble(compiled_circuits, backend)
    116 #execute_circ.run_config.parameter_binds('gamma', 'beta')
    117 
    118 # qobj = assemble(qc_basis).result().get_counts()
    119 # counts = transpile.run(qc_basis).result().get_counts()
    122 return compute_expectation(counts, G)

File ~\anaconda3\lib\site-packages\qiskit\compiler\assembler.py:205, in assemble(experiments, backend, qobj_id, qobj_header, shots, memory, max_credits, seed_simulator, qubit_lo_freq, meas_lo_freq, qubit_lo_range, meas_lo_range, schedule_los, meas_level, meas_return, meas_map, memory_slot_size, rep_time, rep_delay, parameter_binds, parametric_pulses, init_qubits, **run_config)
    195 run_config = _parse_circuit_args(
    196     parameter_binds,
    197     backend,
   (...)
    201     **run_config_common_dict,
    202 )
    204 # If circuits are parameterized, bind parameters and remove from run_config
--> 205 bound_experiments, run_config = _expand_parameters(
    206     circuits=experiments, run_config=run_config
    207 )
    208 end_time = time()
    209 _log_assembly_time(start_time, end_time)

File ~\anaconda3\lib\site-packages\qiskit\compiler\assembler.py:596, in _expand_parameters(circuits, run_config)
    589 # Check that all parameters are common to all circuits and binds
    590 if (
    591     not all_bind_parameters
    592     or not all_circuit_parameters
    593     or any(unique_parameters != bind_params for bind_params in all_bind_parameters)
    594     or any(unique_parameters != parameters for parameters in all_circuit_parameters)
    595 ):
--> 596     raise QiskitError(
    597         (
    598             "Mismatch between run_config.parameter_binds and all circuit parameters. "
    599             + "Parameter binds: {} "
    600             + "Circuit parameters: {}"
    601         ).format(all_bind_parameters, all_circuit_parameters)
    602     )
    604 circuits = [
    605     circuit.bind_parameters(binds) for circuit in circuits for binds in parameter_binds
    606 ]
    608 # All parameters have been expanded and bound, so remove from run_config

QiskitError: 'Mismatch between run_config.parameter_binds and all circuit parameters. Parameter binds: [] Circuit parameters: [ParameterView([Parameter($\\beta$), Parameter($\\gamma$)])]'

I'll be very grateful if someone could help me out to get rid of the 'Mismatch'-error! (I'm pretty new to coding with Qiskit and Python, so a detailed answer would be even more appreciated. Thanks!)

$\endgroup$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.