qiskit-extensions / mthree Goto Github PK
View Code? Open in Web Editor NEWMatrix-free Measurement Mitigation
Home Page: https://qiskit-extensions.github.io/mthree/
License: Apache License 2.0
Matrix-free Measurement Mitigation
Home Page: https://qiskit-extensions.github.io/mthree/
License: Apache License 2.0
They allow you to compute the error rates up to a given precision with a number of shots that scales inversely with number of qubits
Right now the built-in expvals just looks at Z on every qubit. We need to be able to pass an array that says which qubits should be I rather than Z. Then all Pauli's would be covered if input circuits have proper post-rotations.
Here is a snippet from the docs:
backend = FakeCasablanca()
mit = mthree.M3Mitigation(backend)
mit.cals_from_system(range(6))
The call to mit.cals_from_system
sends a job to the backend and stores the results. However, there doesn't seem to be a way to find out the properties of the job that was run. This is important because presumably, the error mitigation computed by mthree is only valid for the backend calibration used for the job, and the hardware is periodically calibrated without notice. Subsequent experimental results can only be corrected with the mthree error mitigation if it is run during the same calibration cycle.
I think mthree should support a 2-step workflow:
IBMQJob
objectExample:
job = mthree.run_calibration(backend, qubits)
mit = mthree.M3Mitigation.from_job(job)
This way, the user can tell which calibration cycle the error mitigation is valid for by looking at job.properties().last_update_date
. This has the added advantage that creating the job is not a blocking operation, so the job can be run in the background and its results retrieved later.
The GPU cals need to be an array so that I can pass a pointer to the kernel. Thus I need to refactor the standard cals to be of the same type. This needs to be done before #70
mthree seems to be broken on the development version of Qiskit.
import mthree
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
Input In [1], in <cell line: 1>()
----> 1 import mthree
File /usr/local/venvs/qiskit-research-4492DR1p/lib/python3.9/site-packages/mthree-0.23.0-py3.9-linux-x86_64.egg/mthree/__init__.py:31, in <module>
28 __version__ = '0.0.0'
29 openmp = False
---> 31 from .mitigation import M3Mitigation
34 def about():
35 """The M3 version info function.
36 """
File /usr/local/venvs/qiskit-research-4492DR1p/lib/python3.9/site-packages/mthree-0.23.0-py3.9-linux-x86_64.egg/mthree/mitigation.py:26, in <module>
24 import orjson
25 from qiskit import transpile, execute
---> 26 from qiskit.providers import BaseBackend
28 from mthree.circuits import (_tensor_meas_states, _marg_meas_states,
29 balanced_cal_strings, balanced_cal_circuits)
30 from mthree.matrix import _reduced_cal_matrix, sdd_check
ImportError: cannot import name 'BaseBackend' from 'qiskit.providers' (/home/kjs/projects/qiskit-terra/qiskit/providers/__init__.py)
Qiskit version: 04807a13a7ba53d97c37bb092324e419296e3fba
mthree version: 581514b
backend.run()
is being removed in favor of the Sampler
interface. We will therefore need to move to that
QuasiDistribution supports computing the expectation and standard deviation of diagonal operators. In practice, the covariance is also needed to estimate errors in observables. This can be supported by adding a cov
method to QuasiDistribution which takes two diagonal operators as input and outputs their covariance.
I am trying to use the mthree package for measurement error mitigation. When I am using the backend "Qasm simulator" the code is running smoothly, but when using "BraketLocalBackend" a backend of qiskit_braket_provider, getting an error in the line "mit.cals_from_system(mappings)" and the error is "ValueError: Circuit must have instructions to run on a device". How can I fix this issue?
<
trans_circ = transpile(circuit, backend=device)
mappings = mthree.utils.final_measurement_mapping(trans_circ)
result = device.run(trans_circ, shots=5000).result()
results=result.get_counts()
r1 = list(results.keys())
r2 = list(results.values())
print(r1)
print(r2)
mit = mthree.M3Mitigation(device)
mit.cals_from_system(mappings)
The core routine is unchanged since the paper came out and everything else has been added for usability. I think we are pretty much on top of all the possible features that one could want in a 1.0
release. However before doing so we should:
Doing a 1.0
release would also allow us to add things that are non-trivial, eg GPU support and / or better support for dealing with operators, by making a clean partition in the versioning
The fake backends only work for 0.18+, when calling backend.run()
so we need to bump the version so that people can actually run the examples
Exception checking is causing performance issues now, and that needs to be explicitly turned off in Cython.
Problem - when using async_cals
and cals_file
together, asynchronous threading no longer works.
Solution - Speaking with @nonhermitian , he recommended to move the saving function into the jobs thread.
It seems there is an error related to the recent mapping changes (#133). The CI passed for that PR, so not sure what is going on. Will take a look.
The project now has the workflows to deploy the documentation to a branch called gh-pages, but we need to perform the first deployment and set up the repo to use GitHub Pages by following these instructions. Once the GitHub Pages is set up please update the repo's About section to display the new link.
gh-pages
branchWarning
Before starting with the process, you need to add a new branch called gh-pages
. This branch needs to have that name to ensure the workflows can deploy successfully. You can create it manually, or, in case you have the new workflows, it will be created automatically after the first deployment (Better option).
Once you have the branch gh-pages
created, you can follow the following steps:
Settings
Pages
Deploy from a branch
, under the Source
section on Build and deployment
gh-pages
branch and the / (root)
folder in the Branch
section on Build and deployment
The default URL where you can find your site is https://qiskit-extensions.github.io/mthree
For further information, you can see the GitHub Pages Quickstart and Qiskit/ecosystem#578.
It is often useful to evaluate grouped Pauli operators where the grouping is done via graph coloring, or the like. Current doing this is supported, but not in an optimal fashion. Should clean this up for version 1.0
cut.
Add here for ease of use.
According to Qiskit/qiskit#7644 (comment) this is a bug in mthree because mthree should not assume that the job result has a date attribute.
import numpy as np
import mthree
from qiskit import BasicAer, QuantumCircuit
backend = backend = BasicAer.get_backend("statevector_simulator")
mit = mthree.M3Mitigation(backend)
mit.cals_from_system(range(2))
circuit = QuantumCircuit(2)
circuit.rx(np.pi / 4, 0)
circuit.rx(np.pi / 2, 1)
circuit.measure_all()
counts = backend.run(circuit, shots=1000).result().get_counts()
quasis = mit.apply_correction(counts, range(2))
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
~/projects/qiskit-terra/qiskit/result/result.py in __getattr__(self, name)
125 try:
--> 126 return self._metadata[name]
127 except KeyError as ex:
KeyError: 'date'
The above exception was the direct cause of the following exception:
AttributeError Traceback (most recent call last)
<ipython-input-1-ae55a076da9e> in <module>
5 backend = backend = BasicAer.get_backend("statevector_simulator")
6 mit = mthree.M3Mitigation(backend)
----> 7 mit.cals_from_system(range(2))
8
9 circuit = QuantumCircuit(2)
~/.local/share/virtualenvs/qiskit-research-4492DR1p/lib/python3.9/site-packages/mthree-0.21.0-py3.9-linux-x86_64.egg/mthree/mitigation.py in cals_from_system(self, qubits, shots, method, initial_reset, rep_delay, cals_file, async_cal)
157 self.rep_delay = rep_delay
158 self.cal_timestamp = None
--> 159 self._grab_additional_cals(qubits, shots=shots, method=method,
160 rep_delay=rep_delay, initial_reset=initial_reset,
161 async_cal=async_cal)
~/.local/share/virtualenvs/qiskit-research-4492DR1p/lib/python3.9/site-packages/mthree-0.21.0-py3.9-linux-x86_64.egg/mthree/mitigation.py in _grab_additional_cals(self, qubits, shots, method, rep_delay, initial_reset, async_cal)
319 self._thread.start()
320 else:
--> 321 _job_thread(job, self, method, qubits, num_cal_qubits, cal_strings)
322
323 def apply_correction(self, counts, qubits, distance=None,
~/.local/share/virtualenvs/qiskit-research-4492DR1p/lib/python3.9/site-packages/mthree-0.21.0-py3.9-linux-x86_64.egg/mthree/mitigation.py in _job_thread(job, mit, method, qubits, num_cal_qubits, cal_strings)
657 counts = res.get_counts()
658 # attach timestamp
--> 659 timestamp = res.date
660 # Needed since Aer result date is str but IBMQ job is datetime
661 if isinstance(timestamp, datetime.datetime):
~/projects/qiskit-terra/qiskit/result/result.py in __getattr__(self, name)
126 return self._metadata[name]
127 except KeyError as ex:
--> 128 raise AttributeError(f"Attribute {name} is not defined") from ex
129
130 @classmethod
AttributeError: Attribute date is not defined
Currently one can only save calibrations when doing the calibration itself. It should be possible to save them after the fact.
Seems to happen when return_mitigation_overhead=True
is set and there is only one bitstring with nonzero count.
Code:
from qiskit import Aer, QuantumCircuit, transpile
import mthree
qc = QuantumCircuit(6)
qc.measure_all()
backend = Aer.get_backend("statevector_simulator")
mit = mthree.M3Mitigation(backend)
mit.cals_from_system(range(6))
trans_qc = transpile(qc, backend)
raw_counts = backend.run(trans_qc, shots=100).result().get_counts()
quasis = mit.apply_correction(raw_counts, range(6), return_mitigation_overhead=True)
Output:
/home/kevinsung/.local/share/virtualenvs/qiskit-terra-rZn7sWYf/lib64/python3.9/site-packages/mthree/norms.py:76: RuntimeWarning: invalid value encountered in true_divide
x = (-1)**(x+1)*(1+(x-1)/(dims-1))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Input In [1], in <module>
11 trans_qc = transpile(qc, backend)
12 raw_counts = backend.run(trans_qc, shots=100).result().get_counts()
---> 14 quasis = mit.apply_correction(raw_counts, range(6), return_mitigation_overhead=True)
File ~/.local/share/virtualenvs/qiskit-terra-rZn7sWYf/lib64/python3.9/site-packages/mthree/mitigation.py:366, in M3Mitigation.apply_correction(self, counts, qubits, distance, method, max_iter, tol, return_mitigation_overhead, details)
362 quasi_out = []
363 for idx, cnts in enumerate(counts):
365 quasi_out.append(
--> 366 self._apply_correction(cnts, qubits=qubits[idx],
367 distance=distance,
368 method=method,
369 max_iter=max_iter, tol=tol,
370 return_mitigation_overhead=return_mitigation_overhead,
371 details=details)
372 )
374 if not given_list:
375 return quasi_out[0]
File ~/.local/share/virtualenvs/qiskit-terra-rZn7sWYf/lib64/python3.9/site-packages/mthree/mitigation.py:439, in M3Mitigation._apply_correction(self, counts, qubits, distance, method, max_iter, tol, return_mitigation_overhead, details)
437 if method == 'direct':
438 st = perf_counter()
--> 439 mit_counts, col_norms, gamma = self._direct_solver(counts, qubits, distance,
440 return_mitigation_overhead)
441 dur = perf_counter()-st
442 mit_counts.shots = shots
File ~/.local/share/virtualenvs/qiskit-terra-rZn7sWYf/lib64/python3.9/site-packages/mthree/mitigation.py:540, in M3Mitigation._direct_solver(self, counts, qubits, distance, return_mitigation_overhead)
538 gamma = None
539 if return_mitigation_overhead:
--> 540 gamma = ainv_onenorm_est_lu(A, LU)
541 out = vector_to_quasiprobs(x, sorted_counts)
542 return out, col_norms, gamma
File ~/.local/share/virtualenvs/qiskit-terra-rZn7sWYf/lib64/python3.9/site-packages/mthree/norms.py:80, in ainv_onenorm_est_lu(A, LU)
76 x = (-1)**(x+1)*(1+(x-1)/(dims-1))
78 x = la.lu_solve(LU, x, check_finite=False)
---> 80 temp = 2*la.norm(x, 1)/(3*dims)
82 if temp > gamma:
83 gamma = temp
File ~/.local/share/virtualenvs/qiskit-terra-rZn7sWYf/lib64/python3.9/site-packages/scipy/linalg/_misc.py:145, in norm(a, ord, axis, keepdims, check_finite)
143 # Differs from numpy only in non-finite handling and the use of blas.
144 if check_finite:
--> 145 a = np.asarray_chkfinite(a)
146 else:
147 a = np.asarray(a)
File ~/.local/share/virtualenvs/qiskit-terra-rZn7sWYf/lib64/python3.9/site-packages/numpy/lib/function_base.py:603, in asarray_chkfinite(a, dtype, order)
601 a = asarray(a, dtype=dtype, order=order)
602 if a.dtype.char in typecodes['AllFloat'] and not np.isfinite(a).all():
--> 603 raise ValueError(
604 "array must not contain infs or NaNs")
605 return a
ValueError: array must not contain infs or NaNs
mthree version: 0.19.0
qiskit-ibmq-provider
is unmaintained since July 2023. Considering migrating to qiskit-ibm-provider
and remove the unmaintained dependency.
The docs are a bit out of date, and should be revised before version 2.0 goes out.
M3 can mitigate mid-circuit measurements, provided that the results are not used until the end, e.g. no controlling gates based on the measured outcomes. Those cases need per-shot correction.
I think we are already setup for this, but we need a new routine that looks for correctable mid-circuit measurements. Something like a generic measurement_mapping
to go with final_measurement_mapping
?
We have noticed that state prep errors from incomplete unconditional reset tend to make life difficult, masking as correlated errors when in fact they are not. We have been using rep_delay
to go around that, but it is slow. Instead, we should use resets on all the cal circuits, and ideally, on the executed circuits as well to help make sure state prep is as good as it can be.
Setup:
import numpy as np
import mthree
from qiskit import Aer, QuantumCircuit
backend = backend = Aer.get_backend("statevector_simulator")
mit = mthree.M3Mitigation(backend)
mit.cals_from_system(range(2))
circuit = QuantumCircuit(2)
circuit.rx(np.pi / 4, 0)
circuit.rx(np.pi / 2, 1)
circuit.measure_all()
counts = backend.run(circuit, shots=1000).result().get_counts()
quasis = mit.apply_correction(counts, range(2))
Passing strings works:
print(quasis.expval('00'))
print(quasis.expval('ZI'))
0.419
0.7020000000000001
Passing dictionary fails for second example:
print(quasis.expval({'00': 1}))
print(quasis.expval({'ZI': 1}))
0.419
0.0
Passing float fails:
print(quasis.expval({'00': 0.5}))
0.0
mthree version: 13b941f
Python version: 3.8.12
Operating system: Arch Linux
Qiskit does not have a easy way of getting exp vals. We should expose the functionality here so that users can use our tools on generic Counts
objects. I find myself needing these all the time for exploring the non-mitigated values.
Now that Python 3.12 has been released https://docs.python.org/3/whatsnew/3.12.html we should add support to mthree for using Python 3.12. This is going to be blocked on qiskit's support in: Qiskit/qiskit#10887 but once qiskit has a release with 3.12 support we should add it to mthree and publish a new release that adds precompiled wheels for 3.12.
The other thing we'll need to check is whether #188 is a blocker for this. I expect that cython only supports 3.12 on Cython 3.0, but I have to check the documentation to confirm.
There is no configuration file for V2 fake backends (but it does exist for V2 real backends), which is causing M3 to fail because we rely on backend.configuration()
being there. Things that need to be resolved
backend2.name
backend.name()
backend2.num_qubits
backend.configuration().num_qubits
backend.configuration().simulator
backend2
?
backend.configuration().max_shots
backend2
?
I am done with the code for direct solutions using GPUs via CuPy. Now need to integrate. Not sure how to do the unit testing in CI though.
Counts is not really the correct name since it is a bunch of probabilities. However people already using counts_file
so just add both, check if passing two different files, and then just use cals_file
in the docs.
I have a local version of https://github.com/iccmr-quantum/QuSing that suddenly stopped working. I apologize for not copying down the exact error message, but there was an import error that was resolved by running a pip update. But, now the error is:
~\AppData\Local\Temp/ipykernel_17056/431539747.py in generate_note(transition_matrix, qubits, dictionary_key, backend, unique_notes, shots)
117 mit.cals_from_system(qubits=assignment, shots=shots)
118 raw_counts = result.get_counts(qc)
--> 119 m3_quasi = mit.apply_correction(raw_counts, assignment)
120 counts = str(max(m3_quasi, key=m3_quasi.get)) # In case of shots > 1, find the result with the highest count.
121 #counts = str(max(result.get_counts(qc)))
~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\mthree\mitigation.py in apply_correction(self, counts, qubits, distance, method, max_iter, tol, return_mitigation_overhead, details)
377
378 quasi_out.append(
--> 379 self._apply_correction(cnts, qubits=qubits[idx],
380 distance=distance,
381 method=method,
~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\mthree\mitigation.py in _apply_correction(self, counts, qubits, distance, method, max_iter, tol, return_mitigation_overhead, details)
429
430 # Check if no cals done yet
--> 431 if self.single_qubit_cals is None:
432 warnings.warn('No calibration data. Calibrating: {}'.format(qubits))
433 self._grab_additional_cals(qubits, method=self.cal_method)
~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\mthree\mitigation.py in getattribute(self, attr)
70 if attr in dict:
71 if attr in ['single_qubit_cals']:
---> 72 self._thread_check()
73 return super().getattribute(attr)
74
~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\mthree\mitigation.py in _thread_check(self)
642 self._thread = None
643 if self._job_error:
--> 644 raise self._job_error # pylint: disable=raising-bad-type
645
646
~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\mthree\mitigation.py in _job_thread(job, mit, method, qubits, num_cal_qubits, cal_strings)
656 """
657 try:
--> 658 res = job.result()
659 # pylint: disable=broad-except
660 except Exception as error:
~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\qiskit\providers\ibmq\job\ibmqjob.py in result(self, timeout, wait, partial, refresh)
288 else:
289 error_message = ": " + error_message
--> 290 raise IBMQJobFailureError(
291 'Unable to retrieve result for job {}. Job has failed{}'.format(
292 self.job_id(), error_message))
IBMQJobFailureError: 'Unable to retrieve result for job 631882bd89d4a56f5aa2c52f. Job has failed: QObj does not conform to the schema. Error code: 1101.'
Cython 3.0 was a major release [1] so we'll have to evaluate compatibility in mthree with it.
[1] https://cython.readthedocs.io/en/latest/src/changes.html#unified-release-notes
Originally posted by @mtreinish in #187 (review)
As reported in #187 there is noticeable performance regression when building mthree from source with Cython >= 3.0. Before we say we support building with cython 3.0 we should get to the bottom of that.
This would save a loop in user code
It would be good to document expvals and Collections
qiskit-ibm-runtime
builds started failing after the latest mthree release 0.21.0.
pip install mthree
nows throws below error:
(qiskit-ibm-runtime) rathish@Rathishs-MacBook-Pro qiskit-ibm-runtime % pip install -I mthree
Collecting mthree
Using cached mthree-0.21.0.tar.gz (730 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... error
ERROR: Command errored out with exit status 1:
command: /Users/rathish/opt/anaconda3/envs/qiskit-ibm-runtime/bin/python /Users/rathish/opt/anaconda3/envs/qiskit-ibm-runtime/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/_in_process.py get_requires_for_build_wheel /var/folders/jt/2qwx0rx17tl94gnll6wjftjc0000gn/T/tmp6kxr64xk
cwd: /private/var/folders/jt/2qwx0rx17tl94gnll6wjftjc0000gn/T/pip-install-spm6gvgs/mthree_86c865a23ace4bf7934fd7dcf00c7c40
Complete output (16 lines):
Traceback (most recent call last):
File "/Users/rathish/opt/anaconda3/envs/qiskit-ibm-runtime/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 349, in <module>
main()
File "/Users/rathish/opt/anaconda3/envs/qiskit-ibm-runtime/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 331, in main
json_out['return_val'] = hook(**hook_input['kwargs'])
File "/Users/rathish/opt/anaconda3/envs/qiskit-ibm-runtime/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 117, in get_requires_for_build_wheel
return hook(config_settings)
File "/private/var/folders/jt/2qwx0rx17tl94gnll6wjftjc0000gn/T/pip-build-env-9osqm8ic/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 177, in get_requires_for_build_wheel
return self._get_build_requires(
File "/private/var/folders/jt/2qwx0rx17tl94gnll6wjftjc0000gn/T/pip-build-env-9osqm8ic/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 159, in _get_build_requires
self.run_setup()
File "/private/var/folders/jt/2qwx0rx17tl94gnll6wjftjc0000gn/T/pip-build-env-9osqm8ic/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 174, in run_setup
exec(compile(code, __file__, 'exec'), locals())
File "setup.py", line 130, in <module>
File "setup.py", line 114, in write_version_py
FileNotFoundError: [Errno 2] No such file or directory: 'mthree/version.py'
----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/2a/c0/984e28773f84c3b60a9eede448a7f1e350593f9c70c757242f8a2e5cbe2b/mthree-0.21.0.tar.gz#sha256=a0daa86b88111c03cba1070797ac8dc316a2618fa227ebc08638c767477f9b82 (from https://pypi.org/simple/mthree/). Command errored out with exit status 1: /Users/rathish/opt/anaconda3/envs/qiskit-ibm-runtime/bin/python /Users/rathish/opt/anaconda3/envs/qiskit-ibm-runtime/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/_in_process.py get_requires_for_build_wheel /var/folders/jt/2qwx0rx17tl94gnll6wjftjc0000gn/T/tmp6kxr64xk Check the logs for full command output.
Make doing custom expval operators easy within the current framework.
Many Hamiltonians are sparse in that the Pauli weight of all the operators is low. Thus there will be a lot of 'I'
terms in the strings. thus we should add a sparse representation of the strings so that iterating over them in expval
routines is more efficient.
let default be min(backend.max_shots, 10000)
Users should be able to do QuasiCollection.mitigation_overhead
and return an array of values, just like they can on individual quasi-probs.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.