Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failure when running QAOA on AQT-Simulator #46

Closed
lasys opened this issue Jul 27, 2021 · 6 comments · Fixed by #47
Closed

Failure when running QAOA on AQT-Simulator #46

lasys opened this issue Jul 27, 2021 · 6 comments · Fixed by #47
Labels
bug Something isn't working

Comments

@lasys
Copy link
Contributor

lasys commented Jul 27, 2021

Informations

  • Qiskit AQT Provider version: 0.4.2
  • Qiskit version: 0.28 and 0.27
  • Python version: 3.8.0
  • Operating system: Linux

What is the current behavior?

I wanted to execute QAOA on the AQT-Simulator, but unfortunately I have this error several times in a row:

FAILURE: Can not get job id, Resubmit the qobj to get job id.Error: 'list' object has no attribute 'qubits'

Steps to reproduce the problem

import networkx as nx
import numpy as np
from qiskit.algorithms.optimizers import SPSA
from qiskit.utils import QuantumInstance
from qiskit_optimization.algorithms import MinimumEigenOptimizer
from qiskit.algorithms import QAOA
from qiskit_aqt_provider import AQTProvider
from qiskit_optimization.applications import Maxcut

# create graph
n = 4
graph = nx.Graph()
graph.add_nodes_from(np.arange(0, n, 1))
elist = [(0, 1, 1), (1, 2, 1), (2, 3, 1), (3, 0, 1)]
graph.add_weighted_edges_from(elist)

# create Maxcut
max_cut = Maxcut(graph)
max_cut_qubo = max_cut.to_quadratic_program()

# connection to AQT
aqt = AQTProvider('<token>')
print(aqt.backends)
simulator_backend = aqt.backends.aqt_qasm_simulator
quantum_instance = QuantumInstance(backend=simulator_backend,shots=200)
qaoa = QAOA(optimizer=SPSA(maxiter=1), quantum_instance=quantum_instance)

# execute qaoa
MinimumEigenOptimizer(qaoa).solve(max_cut_qubo)

What is the expected behavior?

Running without failure.

Suggested solutions

@lasys lasys added the bug Something isn't working label Jul 27, 2021
@nonhermitian
Copy link
Collaborator

I can reproduce this, however I do not understand the error as the AQT jobs have a job_id that is returned by the API (explicitly verified this). I would open an issue in the qiskit-terra repo as the issue is likely in the quantum_instance job submission code.

@mtreinish
Copy link
Collaborator

I took a look at this and after adding a bunch of raises and prints to the QuantumInstance code the underlying issue is in the aqt provider: https://github.com/Qiskit-Partners/qiskit-aqt-provider/blob/master/qiskit_aqt_provider/aqt_job.py#L80 does not account for a list of circuits. backend.run() can take a QuantumCircuit or a list of QuantumCircuit objects and while the aqt provider only supports a single circuit we still should accept a list of 1 as input and test that path. It should be simple enough to fix (probably just converting a single entry list to a QuantumCircuit in the job).

@woodsp-ibm
Copy link
Member

What could be tried, to check that out, is to set this environment variable that allows the circuits per job to be limited and see if that works - of course it may turn out to be a lot of jobs dependent on the algo in question. (I notice the name never got changed though!)

MAX_CIRCUITS_PER_JOB = os.environ.get("QISKIT_AQUA_MAX_CIRCUITS_PER_JOB", None)

@lasys
Copy link
Contributor Author

lasys commented Aug 5, 2021

I took a look at this and after adding a bunch of raises and prints to the QuantumInstance code the underlying issue is in the aqt provider: https://github.com/Qiskit-Partners/qiskit-aqt-provider/blob/master/qiskit_aqt_provider/aqt_job.py#L80 does not account for a list of circuits. backend.run() can take a QuantumCircuit or a list of QuantumCircuit objects and while the aqt provider only supports a single circuit we still should accept a list of 1 as input and test that path. It should be simple enough to fix (probably just converting a single entry list to a QuantumCircuit in the job).

Yes, you're right.
I set self.qobj to the given QuantumCircuit and it's working.

def _build_memory_mapping(self):
    qu2cl = {}
    if isinstance(self.qobj, QasmQobj):
        for instruction in self.qobj.experiments[0].instructions:
            if instruction.name == 'measure':
                qu2cl[instruction.qubits[0]] = instruction.memory[0]
        return qu2cl
    qubit_map = {}
    count = 0
    
    # NEW # 

    # check if self.qobj is list
    if isinstance(self.qobj, list) and len(self.qobj) != 0:
        # check if first element of self.qobj is QuantumCircuit
        if isinstance(self.qobj[0], QuantumCircuit):
            # set self.qobj to QuantumCircuit object
            self.qobj = self.qobj[0]
  
    for bit in self.qobj.qubits:
        qubit_map[bit] = count
        count += 1
    clbit_map = {}
    count = 0
    for bit in self.qobj.clbits:
        clbit_map[bit] = count
        count += 1
    for instruction in self.qobj.data:
        if instruction[0].name == 'measure':
            for index, qubit in enumerate(instruction[1]):
                qu2cl[qubit_map[qubit]] = clbit_map[instruction[2][index]]
    return qu2cl

@mtreinish
Copy link
Collaborator

@lasys please feel free to open a PR with your modification (I meant to last week but clearly forgot about it) to fix this issue. The one thing I'd say though is that the list will only have a single entry. The AQTBackend's configuration set the max_experiments attribute to 1: https://github.com/Qiskit-Partners/qiskit-aqt-provider/blob/master/qiskit_aqt_provider/aqt_backend.py#L49 so it should raise an exception if there is more than 1 circuit in the list: https://github.com/Qiskit-Partners/qiskit-aqt-provider/blob/056b203e97bb5eabcc77b08c359f711628c11efe/qiskit_aqt_provider/circuit_to_aqt.py#L77

@lasys
Copy link
Contributor Author

lasys commented Aug 6, 2021

@mtreinish all right. Then a simple fix like:

...
qubit_map = {}
count = 0

self.qobj = self.qobj[0]

for bit in self.qobj.qubits:
    qubit_map[bit] = count
    count += 1
clbit_map = {}
...

should be okay, shouldn't it?
I will open a PR.

wilfried-huss pushed a commit that referenced this issue Sep 26, 2023
* resource: expose the result polling parameters as backend options

* mypy: enable disallow_untyped_defs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants