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

Qiskit Runtime error #2595

Closed
YutoMorohoshi opened this issue Dec 3, 2024 · 3 comments
Closed

Qiskit Runtime error #2595

YutoMorohoshi opened this issue Dec 3, 2024 · 3 comments
Assignees
Labels
bug Something isn't working interface-and-conversions How Mitiq interfaces with quantum software packages.

Comments

@YutoMorohoshi
Copy link

Issue Description

Hi team.

I'd like to calculate p(00...00) (i.e. the probability of getting all zeros) of a circuit.
So I'm using Sampler in Qiskit Runtime.
I also wanted to apply ZNE or other mitigation techniques using Mitiq, so I tried it, but it did not work.
It seems that Mitiq doesn't support Qiskit Runtime (but I could be wrong).

How can I solve this or is there a workaround?

Thanks.

How to Reproduce

I referred to https://mitiq.readthedocs.io/en/stable/examples/ibmq-backends.html

%matplotlib inline

import qiskit
from qiskit_aer import QasmSimulator
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import SamplerV2 as Sampler

from mitiq import zne
from mitiq.interface.mitiq_qiskit.qiskit_utils import initialized_depolarizing_noise
USE_REAL_HARDWARE = False

qreg, creg = qiskit.QuantumRegister(1), qiskit.ClassicalRegister(1)
circuit = qiskit.QuantumCircuit(qreg, creg)
for _ in range(10):
    circuit.x(qreg)
circuit.measure(qreg, creg)
circuit.draw(output="mpl")
if QiskitRuntimeService.saved_accounts() and USE_REAL_HARDWARE:
    service = QiskitRuntimeService()
    backend = service.least_busy(operational=True, simulator=False)
    noise_model = False
else:
    # Simulate the circuit with noise
    noise_model = initialized_depolarizing_noise(noise_level=0.02)
    # Default to a simulator
    backend = QasmSimulator(noise_model=noise_model)


def ibmq_executor(circuit: qiskit.QuantumCircuit, shots: int = 8192) -> float:
    """Returns the expectation value to be mitigated.

    Args:
        circuit: Circuit to run.
        shots: Number of times to execute the circuit to compute the expectation value.
    """
    sampler = Sampler(backend)

    pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
    exec_circuit = pm.run(circuit)

    # Run the circuit
    job = sampler.run([exec_circuit])

    # Convert from raw measurement counts to the expectation value
    result = job.result()
    pub_result = result[0]
    counts = pub_result.data["c0"].get_counts()

    if counts["0"] is None:
        expectation_value = 0.0
    else:
        expectation_value = counts["0"] / shots
    return expectation_value
unmitigated = ibmq_executor(circuit)
mitigated = zne.execute_with_zne(circuit, ibmq_executor)
print(f"Unmitigated result {unmitigated:.3f}")
print(f"Mitigated result {mitigated:.3f}")

Output:

{
	"name": "AttributeError",
	"message": "'qiskit._accelerate.circuit.DAGCircuit' object has no attribute '_global_phase'",
	"stack": "---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[6], line 2
      1 unmitigated = ibmq_executor(circuit)
----> 2 mitigated = zne.execute_with_zne(circuit, ibmq_executor)
      3 print(f\"Unmitigated result {unmitigated:.3f}\")
      4 print(f\"Mitigated result {mitigated:.3f}\")

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/mitiq/zne/zne.py:109, in execute_with_zne(circuit, executor, observable, factory, scale_noise, num_to_average)
    106 if num_to_average < 1:
    107     raise ValueError(\"Argument `num_to_average` must be a positive int.\")
--> 109 return factory.run(
    110     circuit, executor, observable, scale_noise, int(num_to_average)
    111 ).reduce()

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/mitiq/zne/inference.py:541, in BatchedFactory.run(self, qp, executor, observable, scale_noise, num_to_average)
    538 _check_circuit_length(qp)
    540 # Get all noise-scaled circuits to run.
--> 541 to_run = self._generate_circuits(qp, scale_noise, num_to_average)
    543 # Run all circuits.
    544 if not isinstance(executor, Executor):

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/mitiq/zne/inference.py:617, in BatchedFactory._generate_circuits(self, circuit, scale_noise, num_to_average)
    615 for scale_factor in self.get_scale_factors():
    616     for _ in range(num_to_average):
--> 617         to_run.append(scale_noise(circuit, scale_factor))
    618 return to_run

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/mitiq/interface/conversions.py:395, in accept_qprogram_and_validate.<locals>.new_function(circuit, *args, **kwargs)
    388 from mitiq.interface.mitiq_qiskit.conversions import (
    389     _measurement_order,
    390     _remove_identity_from_idle,
    391     _transform_registers,
    392 )
    394 out_circuit.remove_final_measurements()
--> 395 out_circuit = _transform_registers(
    396     out_circuit, new_qregs=circuit.qregs
    397 )
    398 _remove_identity_from_idle(out_circuit, idle_qubits)
    399 if circuit.cregs and not out_circuit.cregs:

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/mitiq/interface/mitiq_qiskit/conversions.py:212, in _transform_registers(circuit, new_qregs)
    208 circuit_layout = Layout.from_qubit_list(circuit.qubits)
    209 pass_manager = PassManager(
    210     [SetLayout(circuit_layout), ApplyMitiqLayout(new_qregs), ClearLayout()]
    211 )
--> 212 return pass_manager.run(circuit)

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/qiskit/transpiler/passmanager.py:464, in _replace_error.<locals>.wrapper(*meth_args, **meth_kwargs)
    461 @wraps(meth)
    462 def wrapper(*meth_args, **meth_kwargs):
    463     try:
--> 464         return meth(*meth_args, **meth_kwargs)
    465     except PassManagerError as ex:
    466         raise TranspilerError(ex.message) from ex

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/qiskit/transpiler/passmanager.py:226, in PassManager.run(self, circuits, output_name, callback, num_processes)
    223 if callback is not None:
    224     callback = _legacy_style_callback(callback)
--> 226 return super().run(
    227     in_programs=circuits,
    228     callback=callback,
    229     output_name=output_name,
    230     num_processes=num_processes,
    231 )

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/qiskit/passmanager/passmanager.py:231, in BasePassManager.run(self, in_programs, callback, num_processes, **kwargs)
    228 # If we're not going to run in parallel, we want to avoid spending time `dill` serializing
    229 # ourselves, since that can be quite expensive.
    230 if len(in_programs) == 1 or not should_run_in_parallel(num_processes):
--> 231     out = [
    232         _run_workflow(program=program, pass_manager=self, callback=callback, **kwargs)
    233         for program in in_programs
    234     ]
    235     if len(in_programs) == 1 and not is_list:
    236         return out[0]

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/qiskit/passmanager/passmanager.py:232, in <listcomp>(.0)
    228 # If we're not going to run in parallel, we want to avoid spending time `dill` serializing
    229 # ourselves, since that can be quite expensive.
    230 if len(in_programs) == 1 or not should_run_in_parallel(num_processes):
    231     out = [
--> 232         _run_workflow(program=program, pass_manager=self, callback=callback, **kwargs)
    233         for program in in_programs
    234     ]
    235     if len(in_programs) == 1 and not is_list:
    236         return out[0]

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/qiskit/passmanager/passmanager.py:292, in _run_workflow(program, pass_manager, **kwargs)
    286 initial_status = WorkflowStatus()
    288 passmanager_ir = pass_manager._passmanager_frontend(
    289     input_program=program,
    290     **kwargs,
    291 )
--> 292 passmanager_ir, final_state = flow_controller.execute(
    293     passmanager_ir=passmanager_ir,
    294     state=PassManagerState(
    295         workflow_status=initial_status,
    296         property_set=PropertySet(),
    297     ),
    298     callback=kwargs.get(\"callback\", None),
    299 )
    300 # The `property_set` has historically been returned as a mutable attribute on `PassManager`
    301 # This makes us non-reentrant (though `PassManager` would be dependent on its internal tasks to
    302 # be re-entrant if that was required), but is consistent with previous interfaces.  We're still
    303 # safe to be called in a serial loop, again assuming internal tasks are re-runnable.  The
    304 # conversion to the backend language is also allowed to use the property set, so it must be set
    305 # before calling it.
    306 pass_manager.property_set = final_state.property_set

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/qiskit/passmanager/base_tasks.py:218, in BaseController.execute(self, passmanager_ir, state, callback)
    216     return passmanager_ir, state
    217 while True:
--> 218     passmanager_ir, state = next_task.execute(
    219         passmanager_ir=passmanager_ir,
    220         state=state,
    221         callback=callback,
    222     )
    223     try:
    224         # Sending the object through the generator implies the custom controllers
    225         # can always rely on the latest data to choose the next task to run.
    226         next_task = task_generator.send(state)

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/qiskit/transpiler/basepasses.py:195, in TransformationPass.execute(self, passmanager_ir, state, callback)
    189 def execute(
    190     self,
    191     passmanager_ir: PassManagerIR,
    192     state: PassManagerState,
    193     callback: Callable = None,
    194 ) -> tuple[PassManagerIR, PassManagerState]:
--> 195     new_dag, state = super().execute(
    196         passmanager_ir=passmanager_ir,
    197         state=state,
    198         callback=callback,
    199     )
    201     if state.workflow_status.previous_run == RunState.SUCCESS:
    202         if isinstance(new_dag, DAGCircuit):
    203             # Copy calibration data from the original program

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/qiskit/passmanager/base_tasks.py:98, in GenericPass.execute(self, passmanager_ir, state, callback)
     96 try:
     97     if self not in state.workflow_status.completed_passes:
---> 98         ret = self.run(passmanager_ir)
     99         run_state = RunState.SUCCESS
    100     else:

File ~/Desktop/test_mitiq/.venv/lib/python3.10/site-packages/mitiq/interface/mitiq_qiskit/transpiler.py:96, in ApplyMitiqLayout.run(self, dag)
     91     qargs = [q[virtual_physical_map[qarg]] for qarg in node.qargs]
     92     new_dag.apply_operation_back(
     93         node.op, qargs, node.cargs, check=False
     94     )
---> 96 new_dag._global_phase = dag._global_phase
     98 return new_dag

AttributeError: 'qiskit._accelerate.circuit.DAGCircuit' object has no attribute '_global_phase'"
}

Expected behavior


Unmitigated result xxx
Mitigated result yyy

Environment Context

Use the about() function to summarize information on operating system, python version and dependencies.

from mitiq import about
about()

Mitiq: A Python toolkit for implementing error mitigation on quantum computers
==============================================================================
Authored by: Mitiq team, 2020 & later (https://github.com/unitaryfund/mitiq)

Mitiq Version:	0.41.0

Core Dependencies
-----------------
Cirq Version:	1.4.1
NumPy Version:	1.26.4
SciPy Version:	1.14.1

Optional Dependencies
---------------------
PyQuil Version:	Not installed
Qiskit Version:	Not installed
Braket Version:	Not installed

Python Version:	3.10.14
Platform Info:	Darwin (arm64)

Additional Python Environment Details (pip freeze or conda list):

Copy and paste the output of `pip freeze` or `conda list` here.

%pip freeze

annotated-types==0.7.0
anyio==4.6.2.post1
appnope==0.1.4
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
arrow==1.3.0
asttokens==3.0.0
async-lru==2.0.4
attrs==24.2.0
babel==2.16.0
beautifulsoup4==4.12.3
bleach==6.2.0
certifi==2024.8.30
cffi==1.17.1
charset-normalizer==3.4.0
cirq-core==1.4.1
comm==0.2.2
contourpy==1.3.1
cryptography==44.0.0
cycler==0.12.1
debugpy==1.8.9
decorator==5.1.1
defusedxml==0.7.1
dill==0.3.9
duet==0.2.9
exceptiongroup==1.2.2
executing==2.1.0
fastjsonschema==2.21.1
fonttools==4.55.0
fqdn==1.5.1
h11==0.14.0
httpcore==1.0.7
httpx==0.28.0
ibm-cloud-sdk-core==3.22.0
ibm-platform-services==0.59.0
idna==3.10
ipykernel==6.29.5
ipython==8.30.0
isoduration==20.11.0
jedi==0.19.2
Jinja2==3.1.4
json5==0.10.0
jsonpointer==3.0.0
jsonschema==4.23.0
jsonschema-specifications==2024.10.1
jupyter-events==0.10.0
jupyter-lsp==2.2.5
jupyter_client==8.6.3
jupyter_core==5.7.2
jupyter_server==2.14.2
jupyter_server_terminals==0.5.3
jupyterlab==4.3.1
jupyterlab_pygments==0.3.0
jupyterlab_server==2.27.3
kiwisolver==1.4.7
MarkupSafe==3.0.2
matplotlib==3.9.3
matplotlib-inline==0.1.7
mistune==3.0.2
mitiq==0.41.0
mpmath==1.3.0
nbclient==0.10.1
nbconvert==7.16.4
nbformat==5.10.4
nest-asyncio==1.6.0
networkx==3.4.2
notebook_shim==0.2.4
numpy==1.26.4
overrides==7.7.0
packaging==24.2
pandas==2.2.3
pandocfilters==1.5.1
parso==0.8.4
pbr==6.1.0
pexpect==4.9.0
pillow==11.0.0
platformdirs==4.3.6
ply==3.11
prometheus_client==0.21.0
prompt_toolkit==3.0.48
psutil==6.1.0
ptyprocess==0.7.0
pure_eval==0.2.3
pycparser==2.22
pydantic==2.10.2
pydantic_core==2.27.1
Pygments==2.18.0
PyJWT==2.10.1
pylatexenc==2.10
pyparsing==3.2.0
pyspnego==0.11.2
python-dateutil==2.9.0.post0
python-json-logger==2.0.7
pytz==2024.2
PyYAML==6.0.2
pyzmq==26.2.0
qiskit==1.3.0
qiskit-aer==0.15.1
qiskit-ibm-runtime==0.33.2
referencing==0.35.1
requests==2.32.3
requests_ntlm==1.3.0
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
rpds-py==0.22.0
rustworkx==0.15.1
scipy==1.14.1
Send2Trash==1.8.3
six==1.16.0
sniffio==1.3.1
sortedcontainers==2.4.0
soupsieve==2.6
stack-data==0.6.3
stevedore==5.4.0
symengine==0.13.0
sympy==1.13.3
tabulate==0.9.0
terminado==0.18.1
tinycss2==1.4.0
tomli==2.2.1
tornado==6.4.2
tqdm==4.67.1
traitlets==5.14.3
types-python-dateutil==2.9.0.20241003
typing_extensions==4.12.2
tzdata==2024.2
uri-template==1.3.0
urllib3==2.2.3
wcwidth==0.2.13
webcolors==24.11.1
webencodings==0.5.1
websocket-client==1.8.0
Note: you may need to restart the kernel to use updated packages.
@YutoMorohoshi YutoMorohoshi added the bug Something isn't working label Dec 3, 2024
@cosenal
Copy link
Contributor

cosenal commented Dec 3, 2024

Hi @YutoMorohoshi, qiskit==1.3.0 is not yet supported by Mitiq.
I have just made a fix to the dependabot PR that introduces support for it. See https://github.com/unitaryfund/mitiq/pull/2588/files
It's going to be merged today, but will be released at the end of the month.
In the meantime, you can use qiskit~=1.2.x, as per requirements

@cosenal cosenal self-assigned this Dec 3, 2024
@cosenal cosenal added the interface-and-conversions How Mitiq interfaces with quantum software packages. label Dec 3, 2024
@YutoMorohoshi
Copy link
Author

Thanks @cosenal . It was a version problem.
I downgraded qiskit to 1.2.4 like you said, and it works!
Thank you very much.

@cosenal
Copy link
Contributor

cosenal commented Dec 3, 2024

Thanks for checking (and for using Mitiq 👍).
I am closing this as it's going to be fixed by #2588.

@cosenal cosenal closed this as completed Dec 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working interface-and-conversions How Mitiq interfaces with quantum software packages.
Projects
None yet
Development

No branches or pull requests

2 participants