forked from Qiskit/qiskit
-
Notifications
You must be signed in to change notification settings - Fork 1
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
clean up Bit._register and Bit._index #44
Open
1ucian0
wants to merge
596
commits into
fixes/10744/1
Choose a base branch
from
fixes/10744/2
base: fixes/10744/1
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* add _evolve_ecr() - Adds support for Pauli (and related classes) to evolve through ECR gates encountered in a quantum circuit. - Also moved the dicts of special-case gates (`basis_1q`, `basis_2q`, `non-clifford`) outside the subroutine definition. They are now just after the `_evolve_*()` functions they reference. * fix pauli.evolve bug for certain circuit names - Should fix qiskit issue Qiskit#12093 - Bug happened after converting circuit to instruction, which AFAICT was not necessary. Now if input is a QuantumCircuit, that part of the code is bypassed. - Removed creation of a look-up dict of bit locations, since `QuantumCircuit.find_bit` already provides one. * add ECRGate to `evolve()` tests * mark gate-dicts as private * add test evolving by circuit named 'cx' Test showing issue Qiskit#12093 is solved. * add release note for pauli-evolve fixes * Update test_pauli_list.py
Qiskit#12214) This commit updates the documentation for the generate_preset_pass_manager() function to clearly indicate that the function will accept a integer list for the initial_layout field. This already was supported but it wasn't documented. As it's now a documented part of the API a unittest is added to ensure we don't regress this functionality in the future. Fixes Qiskit#11690
`num_custom_gates` is not actually part of the `CIRCUIT_HEADER` structs in any version of QPY. The number of custom-instruction objects is instead stored as a `uint64_t` inline in the `CUSTOM_DEFINITIONS` part of the file, so separately to the rest of the header.
This commit removes the use of intermediate DAGCircuit objects and calling substitute_node_with_dag() in the Optimize1qGatesDecomposition pass. Since everything is 1q it's very easy to just directly insert the nodes on the DAG prior to the run and then remove the old nodes. This avoids a lot of extra operations and overhead to create a second dagcircuit for each identified run and then substiting that dag in place of the run.
* fix docstring * import * exposing additional plugin arguments * tests * lint * release notes
* add mapping features to data_bin * Update qiskit/primitives/containers/data_bin.py Co-authored-by: Ian Hincks <[email protected]> * add values * change iterable with list * Update qiskit/primitives/containers/data_bin.py Co-authored-by: Ian Hincks <[email protected]> * Apply suggestions from code review Co-authored-by: Christopher J. Wood <[email protected]> * reno * change return types --------- Co-authored-by: Ian Hincks <[email protected]> Co-authored-by: Christopher J. Wood <[email protected]>
* Increase heuristic effort for optimization level 2 This commit tweaks the heuristic effort in optimization level 2 to be more of a middle ground between level 1 and 3; with a better balance between output quality and runtime. This places it to be a better default for a pass manager we use if one isn't specified. The tradeoff here is that the vf2layout and vf2postlayout search space is reduced to be the same as level 1. There are diminishing margins of return on the vf2 layout search especially for cases when there are a large number of qubit permutations for the mapping found. Then the number of sabre trials is brought up to the same level as optimization level 3. As this can have a significant impact on output and the extra runtime cost is minimal. The larger change is that the optimization passes from level 3. This ends up mainly being 2q peephole optimization. With the performance improvements from Qiskit#12010 and Qiskit#11946 and all the follow-on PRs this is now fast enough to rely on in optimization level 2. * Add test workaround from level 3 to level 2 too * Expand vf2 call limit on VF2Layout For the initial VF2Layout call this commit expands the vf2 call limit back to the previous level instead of reducing it to the same as level 1. The idea behind making this change is that spending up to 10s to find a perfect layout is a worthwhile tradeoff as that will greatly improve the result from execution. But scoring multiple layouts to find the lowest error rate subgraph has a diminishing margin of return in most cases as there typically aren't thousands of unique subgraphs and often when we hit the scoring limit it's just permuting the qubits inside a subgraph which doesn't provide the most value. For VF2PostLayout the lower call limits from level 1 is still used. This is because both the search for isomorphic subgraphs is typically much shorter with the vf2++ node ordering heuristic so we don't need to spend as much time looking for alternative subgraphs. * Move 2q peephole outside of optimization loop in O2 Due to potential instability in the 2q peephole optimization we run we were using the `MinimumPoint` pass to provide backtracking when we reach a local minimum. However, this pass adds a significant amount of overhead because it deep copies the circuit at every iteration of the optimization loop that improves the output quality. This commit tweaks the O2 pass manager construction to only run 2q peephole once, and then updates the optimization loop to be what the previous O2 optimization loop was.
* Remove FakeBackendV2 * Fix lint
…2145) * Provider abstraction is not very useful * udpate docs * ignore deprecations * not triggered on CI * deprecation warnings in visual tests * set up * set up without warning? * setUpClass * more test adjust * raise at setUpClass * warms * test_circuit_matplotlib_drawer.py * skip Aer warning * Apply suggestions from code review Co-authored-by: Matthew Treinish <[email protected]> * reno * Run black * Update release note * linter --------- Co-authored-by: Matthew Treinish <[email protected]>
* adding annotated argument to power methods * release notes * Apply suggestions from code review --------- Co-authored-by: Matthew Treinish <[email protected]>
This class is hard to make the most efficient, due to how abstract the base class is, with many different options and many private methods that subclasses override. Still, in cases where, _at the point of build_, we can detect that rotation or entanglement layers are simple applications of a single standard-library gate, we can skip the entire `copy` + `assign` + `compose` pipeline and simply construct the gates in-place with the correct parameters. This skips huge tracts of overhead that using the high-level, abstract interfaces (which are somewhat necessarily more optimised to work with large operands) in tight inner loops adds, culminating in about a 10x improvement in build time. `NLocal` is so abstract that it's hard to hit similar performance to an idiomatic direct construction of the relevant structure, but to be fair, the concept of a circuit library is not necessarily to make the absolute fastest constructors for tight loops, but to make it much simpler to just get a circuit that works as intended.
…t_barriers`` (Qiskit#11878) * deprecate args show_idle and show_barrier * reno * Update qiskit/visualization/timeline/interface.py Co-authored-by: Matthew Treinish <[email protected]> * pending=True --------- Co-authored-by: Matthew Treinish <[email protected]>
* fix mid-circuit measure problem * Update qiskit/transpiler/passes/scheduling/base_scheduler.py Co-authored-by: Naoki Kanazawa <[email protected]> * Update releasenotes/notes/add-scheduler-warnings-da6968a39fd8e6e7.yaml Co-authored-by: Naoki Kanazawa <[email protected]> * Update qiskit/transpiler/passes/scheduling/base_scheduler.py Co-authored-by: Naoki Kanazawa <[email protected]> * Move runtime warning about reset and measurement durations outside of calibration if statement * Replace raise with warn * Switch import orders --------- Co-authored-by: Naoki Kanazawa <[email protected]>
* consolidate circuits with the same number of shots * update BackendEstimatorV2 * add job size limit tests * Apply suggestions from code review Co-authored-by: Ian Hincks <[email protected]> * fix errors * refactor * revise comments * reno * fix an error --------- Co-authored-by: Ian Hincks <[email protected]>
* adding note for nested-min-max for linting * updating note for nested-min-max for linting
…skit#12109) * Add support for returning a DAGCircuit to TwoQubitBasisDecomposer This commit adds a new flag, use_dag, to the constructor for the TwoQubitBasisDecomposer. When set to True, the __call__ method will return a DAGCircuit instead of a QuantumCircuit. This is useful when the two qubit basis decomposer is called from within a transpiler context, as with the UnitarySynthesis pass, to avoid an extra conversion step. * Pivot to argument on __call__ and add to XXDecomposer too This commit moves the use_dag flag to the __call__ method directly instead of storing it as an instance variable. To make the interface consistent between the 2 built-in decomposers the flag is also added to the XXDecomposer class's __call__ method too. This was needed because the unitary synthesis pass calls the decomposers interchangeably and to be able to use them without type checking they both will need the flag.
…h `BackendV2Converter` (Qiskit#11996) * Convert to V2 inside transpile, deal with small changes in tests. * Fix lint * Add reno and apply comment from Ray's review
* Finalise support for Numpy 2.0 This commit brings the Qiskit test suite to a passing state (with all optionals installed) with Numpy 2.0.0b1, building on previous commits that handled much of the rest of the changing requirements: - Qiskitgh-10890 - Qiskitgh-10891 - Qiskitgh-10892 - Qiskitgh-10897 - Qiskitgh-11023 Notably, this commit did not actually require a rebuild of Qiskit, despite us compiling against Numpy; it seems to happen that the C API stuff we use via `rust-numpy` (which loads the Numpy C extensions dynamically during module initialisation) hasn't changed. The main changes are: - adapting to the changed `copy=None` and `copy=False` semantics in `array` and `asarray`. - making sure all our implementers of `__array__` accept both `dtype` and `copy` arguments. Co-authored-by: Lev S. Bishop <[email protected]> * Update `__array__` methods for Numpy 2.0 compatibility As of Numpy 2.0, implementers of `__array__` are expected and required to have a signature def __array__(self, dtype=None, copy=None): ... In Numpys before 2.0, the `copy` argument will never be passed, and the expected signature was def __array__(self, dtype=None): ... Because of this, we have latitude to set `copy` in our implementations to anything we like if we're running against Numpy 1.x, but we should default to `copy=None` if we're running against Numpy 2.0. The semantics of the `copy` argument to `np.array` changed in Numpy 2.0. Now, `copy=False` means "raise a `ValueError` if a copy is required" and `copy=None` means "copy only if required". In Numpy 1.x, `copy=False` meant "copy only if required". In _both_ Numpy 1.x and 2.0, `ndarray.astype` takes a `copy` argument, and in both, `copy=False` means "copy only if required". In Numpy 2.0 only, `np.asarray` gained a `copy` argument with the same semantics as the `np.array` copy argument from Numpy 2.0. Further, the semantics of the `__array__` method changed in Numpy 2.0, particularly around copying. Now, Numpy will assume that it can pass `copy=True` and the implementer will handle this. If `copy=False` is given and a copy or calculation is required, then the implementer is required to raise `ValueError`. We have a few places where the `__array__` method may (or always does) calculate the array, so in all these, we must forbid `copy=False`. With all this in mind: this PR sets up all our implementers of `__array__` to either default to `copy=None` if they will never actually need to _use_ the `copy` argument within themselves (except perhaps to test if it was set by Numpy 2.0 to `False`, as Numpy 1.x will never set it), or to a compatibility shim `_numpy_compat.COPY_ONLY_IF_NEEDED` if they do naturally want to use it with those semantics. The pattern def __array__(self, dtype=None, copy=_numpy_compat.COPY_ONLY_IF_NEEDED): dtype = self._array.dtype if dtype is None else dtype return np.array(self._array, dtype=dtype, copy=copy) using `array` instead of `asarray` lets us achieve all the desired behaviour between the interactions of `dtype` and `copy` in a way that is compatible with both Numpy 1.x and 2.x. * fixing numerical issues on mac-arm * Change error to match Numpy --------- Co-authored-by: Lev S. Bishop <[email protected]> Co-authored-by: Sebastian Brandhofer <[email protected]>
Previously the module of this was set incorrectly (stemming from its move in Qiskitgh-9064), at which point the `__getstate__`/`__setstate__` pickling wouldn't work correctly any more. Also, however, there was no `__getnewargs__` and `new` didn't have a zero-argument form, so this wouldn't have worked either.
* extend clifford docs * mimor fix * minor fix * update docs following comment * update following review
* Add QPY format version table to the docs This commit adds a new table to the QPY module docs that outlines all the supported QPY format versions for every qiskit/qiskit-terra release that had qpy. This information is potentially useful when trying to navigate generating QPY files across versions. Fixes Qiskit#12283 * Update qiskit/qpy/__init__.py
* Add Rust-based `SparsePauliOp.to_matrix` This rewrites the numerical version of `SparsePauliOp.to_matrix` to be written in parallelised Rust, building up the matrices row-by-row rather than converting each contained operator to a matrix individually and summing them. The new algorithms are complete row-based, which is embarrassingly parallel for dense matrices, and parallelisable with additional copies and cumulative sums in the CSR case. The two new algorithms are an asymptotic complexity improvement for both dense and sparse matrices over the "sum the individual matrices" version. In the dense case, the cost goes from O(4 ** num_qubits * num_ops) to O(4 ** num_qubits + (2 ** num_qubits) * reduced_num_ops) where the first term is from the zeroing of the matrix, and the second is from updating the elements in-place. `reduced_num_ops` is the number of explicitly stored operations after Pauli-operator uniqueness compaction, so is upper-bounded as `4 ** num_qubits`. (The Pauli compaction goes as `O(num_ops)`, so is irrelevant to the complexity discussion.) The CSR form of the algorithm goes as O(2 ** num_qubits * reduced_num_ops * lg(reduced_num_ops)) which (I think! - I didn't fully calculate it) is asymptotically the same as before, but in practice the constant factors and intermediate memory use are *dramatically* reduced, and the new algorithm is threadable with an additional `O(2 ** num_qubits * reduced_num_ops)` intermediate memory overhead (the serial form has only `O(reduced_num_ops)` memory overhead). The `object`-coefficients form is left as-is to avoid exploding the complexity in Rust space; these objects are already slow and unsuited for high-performance code, so the effects should be minimal. * Add non-blocking Miri to CI As we begin to include more `unsafe` code in the Rust-accelerated components, it is becoming more important for us to test these in an undefined-behaviour sanitiser. This is done in a separate CI job because: - we do not yet know how stable Miri will be, so we don't want to block on it. - some dependencies need their version-resolution patching to Miri-compatible versions, but we want to run our regular test suites with the same versions of packages we will be building against. * Parallelise cumulative nnz sum This parallelises the previously serial-only cumulative sum of the `indptr` array of number of non-zero entries at the end. In practice, I didn't actually see any change in performance from this, but philosophically it feels like the right thing to do. * Update Miri pin to later version of crossbeam-epohc * Improve error handling and messages * Simplify unnecessary match * Add link to environment variable configuration * Add link to Rayon plumbing README * Add explicit test of serial and parallel modes
* add permutation reverse lnn function * update init files * update other synthesis functions * add tests * add release notes * add helper function _append_reverse_permutation_lnn_kms * add more cases to test
) This commit updates the minimum rustworkx version to 0.15.0 to pull in the new PyDiGraph.remove_node_retain_edges_by_id() method introduced in that release. This new function is used for the DAGCircuit.remove_op_node() method instead of the PyDiGraph.remove_node_retain_edges() function. This new method has much better scaling characteristics and should improve the performance characteristics of removing very wide operations from a DAGCircuit. Fixes Qiskit#11677 Part of Qiskit#12156
* Update generic_backend_v2.py * reno * Update barebone-backend-option-675c86df4382a443.yaml * ... * suggestions from code review * Update barebone-backend-option-675c86df4382a443.yaml * tests, typo
* add clifford gates to collect_cliffords * replace hard coded clifford names by clifford_circuit names * move import * replace hard coded clifford names in random_clifford_circuit * add release notes * add permutation to collect_clifford gate list
* remove some of the entries * fixing obscure expcetion handleing for comparison * remove all the modules * ignore "Treating CircuitInstruction as an iterable is deprecated" in Aer * remove allow_DeprecationWarning_module and revert ignore/default * revert
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.61 to 1.0.62. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](dtolnay/thiserror@1.0.61...1.0.62) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Add: `iter()` method to `CircuitData` - Make `PackedInstruction` public. * Docs: Remove "rust-native method" from docstring.
* Add missing gate definitions * Reorder gates, following number of qubits and a sort of alphabetical order. Make definitions and matrices consistent with new gate order. Remove C4XGate (second mcx) from list.
* Oxidize two qubit local invariance functions This commit migrates the two functions in the private module `qiskit.synthesis.two_qubit.local_invariance` to primarily be implemented in rust. Since the two_qubit_local_invariants() function is being used in Qiskit#12727 premptively porting these functions to rust will both potentially speed up the new transpiler pass in that PR and also facilitate a future porting of that pass to rust. The two python space functions continue to exist as a small wrapper to do input type checking/conversion and rounding of the result (since the python API for rounding is simpler). There is no release note included for these functions as they are internal utilities in Qiskit and not exposed as a public interface. * Add docstring to rust function with citation * Store adjoint magic array statically * Use arraview1 instead of slice for local_equivalence() * Fix rustfmt
* Fix pass-manager drawing tests for pydot 3.0 Two changes in pydot 3 changed the reference output: 1. previously, attributes were sorted before being output. Pydot 3 stores them in declaration order. Here, we sort our attributes to maintain the closest behaviour between the two versions. 2. Text fields (like `label`) that contain special characters now have their values enclosed in quote marks. This is a difference between the two versions, and we update the reference files to the new version since that's what we'll be using in CI. Qiskit is still compatible with pydot 2 in general usage, it's just our tests that are a little more tied to the current version. * Add test-only constraint on pydot
…iskit#12772) * Optimization for the MCX Recursive Gate Change the recursive method for the Lemma 9 of arXiv:1501.06911, first shown in Lemma 7.3 of https://link.aps.org/doi/10.1103/PhysRevA.52.3457 Co-Authored-By: Rafaella Vale <[email protected]> Co-Authored-By: Jefferson Deyvis <[email protected]> * Revert "Optimization for the MCX Recursive Gate" This reverts commit 507d5b3. Co-Authored-By: Rafaella Vale <[email protected]> Co-Authored-By: Jefferson Deyvis <[email protected]> * Revert "Revert "Optimization for the MCX Recursive Gate"" This reverts commit 4671b7e. * Optimization for MCX Recursive Fixing co-authors Co-Authored-By: Rafaella Vale <[email protected]> Co-Authored-By: Jefferson Deyvis <[email protected]> Co-Authored-By: Adenilton Silva <[email protected]> * Optimization of MCX Recursive Now with fixed co-authors Co-Authored-By: Rafaella Vale <[email protected]> Co-Authored-By: Jefferson Deyvis <[email protected]> Co-Authored-By: Adenilton Silva <[email protected]> * refactored MCXRecursive and unused method deleted * fixed qasm string for mcx test with variants * remove draw * fix qasm file in test_circuit_qasm_with_mcx_gate_variants * update the MCXRecursive class docstring * add a test of the upper bound limit of the number of CX gates * fix failing qasm test * fix qasm file in test_export in qasm2 tests * fix format lint errors in qasm strings * add release notes * update references format * update release notes after review --------- Co-authored-by: Thiago Melo <[email protected]> Co-authored-by: Rafaella Vale <[email protected]> Co-authored-by: Jefferson Deyvis <[email protected]> Co-authored-by: Adenilton Silva <[email protected]>
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.62 to 1.0.63. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](dtolnay/thiserror@1.0.62...1.0.63) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
) * riverlane paper * docs * improvement * empty * fix linting and add abs * Update qiskit/primitives/backend_estimator_v2.py Co-authored-by: Takashi Imamichi <[email protected]> * CR * Update qiskit/primitives/backend_estimator_v2.py Co-authored-by: Ian Hincks <[email protected]> * CR * indent * Update releasenotes/notes/backend-estimator-v2-variance-905c953415ad0e29.yaml Co-authored-by: Takashi Imamichi <[email protected]> --------- Co-authored-by: Takashi Imamichi <[email protected]> Co-authored-by: Ian Hincks <[email protected]>
* added circuit functions * updated circuits functions * added qasm files * added benchmarking metrics * cleaning up circuits * updated tests * updated tests * formatting * removed unused import * clifford synthesis circ test * lint test
* initial commit * release notes * fixing synthesis plugin options * finalize merge conflicts * fixing default option values for qft plugins' * additional tests for qft plugins * starting to experiment * porting code * messy code porting * printing statements to enable debugging * fixes * fixing phase * removing some of the printing statements * fixing inaccuracy for cost computation * Moving some of the functionality to SymplecticMatrix class * reducing the number of warnings * formatting * replacing expensive adjoint and compose operations for symplectic matrices by significantly cheaper in-place prepend operations * resolving merge conflicts * cleanup * code cleanup * cleanup * cleanup * cleanup * cleanup * cleanup * cleanup * cleanup * using fast lookup * cleanup * clippy * including params in gate_seq to avoid mapping * removing unnecessary inner function * cleanup * renaming * changes on the python side * reno * adding error handling * improved error handling * removing redundant Ok(Some(...)) * using random_clifford in tests * reorganizing clifford code * fixes * formatting * improved error handling * do not panic * formatting * Applying refactoring suggestions d/utils.rs from code review * release notes update * starting to port code * continuing to port code * porting + fixing * polishing * changes on the python side; modifying tests to include missing testcases and to use random_clifford instead of random_clifford_circuit since the former provides better randomness guarantees * release notes (last but not least) * Correct reported speedups * applying suggestion from code review * resolving even more merge conflicts
* Rewrite OpenQASM 3 exporter symbol table This rewrites the symbol handling of the OpenQASM 3 exporter to decouple object identities from the necessary object identifiers. As part of this, we use the same trick of standard-gate reparametrisation to produce gate-definition sources for Qiskit built-ins, which fixes many cases of bad parametrisation of gates like `rzx`. This kind of rewrite was necessary to fix the now-bad assumption within the OQ3 exporter that "gate identity" is always static within a circuit. Since standard gate `Gate` instances are now only generated on demand, there is no guarantee of stability of them. The fix to the definition source for these makes them independent of object identity. User-defined gates can still use the identity, as these are still guaranteed static. This commit fixes almost all of the "bad parametrisation" tests in the test suite. There are several other changes in the test suite necessary: * since the uniqueness of the identifier is now independent of how the lookup of a Qiskit object works, there is no need to include the highly non-deterministic `id` in the generated symbols for user gates. Several tests changed to use the new, simple count-based unique names. * the escaping and uniqueness rules now apply uniformly to all gate definitions, fixing several bad test cases that previously were testing invalid OpenQASM 3. * the escaping rules changed slightly for naming collisions with keywords, making them slightly more consistent with how other renaming rules worked. * Add test for bug fix for issue Qiskit#7335 * Rename qiskit gates whose names are OQ3 hardware qubit identifiers If a custom qiskit gate is given a name that is a valid identifer for a hardware qubit in OQ3, then, before this commit, the name would not be escaped when writing the OQ3 gate definition. This commit fixes this by escaping the leading dollar sign as it would be in any other position in the name. That is, the dollar sign is replaced by underscore. Co-authored-by: Jake Lishman <[email protected]> * Reduce overloading of word "definition" Much of what we're doing with the "definition source" is actually a form of object canonicalisation for comparison purposes. It's clearer to use this terminology. * Remove unnecessary getattr * Fix isinstance/issubclass naming --------- Co-authored-by: John Lapeyre <[email protected]>
* Validate order kwarg in BitArray * Added releasenotes for bugfix * Added pytest to check order * Reformatted files * Update releasenotes/notes/fix-kwarg-validation-BitArray-1bf542a1fb5c15c6.yaml Co-authored-by: Takashi Imamichi <[email protected]> --------- Co-authored-by: Takashi Imamichi <[email protected]>
* added functionality for porting * updated functionality * formatting * lint changes * resolved error * updated docstring * formatting * formatting
* Update version of OpenQASM 3.0 standard library This is just a file vendored from the OpenQASM project, but it's been updated since the last time we vendored it to fix a couple of problems. This one is vendored from openqasm/openqasm@4ca1d793833b24a1. * Clarify git link
* Add troubleshooting section to docs-build dev docs There are a couple of known failure modes for the documentation build that require additional setup. This documents these, to consolidate the knowledge. * Update CONTRIBUTING.md Co-authored-by: Elena Peña Tapia <[email protected]> --------- Co-authored-by: Elena Peña Tapia <[email protected]>
* Rebalance `CircuitInstruction` and `PackedInstruction` This is a large overhaul of how circuit instructions are both stored in Rust (`PackedInstruction`) and how they are presented to Python (`CircuitInstruction`). In summary: * The old `OperationType` enum is now collapsed into a manually managed `PackedOperation`. This is logically equivalent, but stores a `PyGate`/`PyInstruction`/`PyOperation` indirectly through a boxed pointer, and stores a `StandardGate` inline. As we expect the vast majority of gates to be standard, this hugely reduces the memory usage. The enumeration is manually compressed to a single pointer, hiding the discriminant in the low, alignment-required bytes of the pointer. * `PackedOperation::view()` unpacks the operation into a proper reference-like enumeration `OperationRef<'a>`, which implements `Operation` (though there is also a `try_standard_gate` method to get the gate without unpacking the whole enumeration). * Both `PackedInstruction` and `CircuitInstruction` use this `PackedOperation` as the operation storage. * `PackedInstruction` is now completely the Rust-space format for data, and `CircuitInstruction` is purely for communication with Python. On my machine, this commit brings the utility-scale benchmarks to within 10% of the runtime of 1.1.0 (and some to parity), despite all the additional overhead. Changes to accepting and building Python objects ------------------------------------------------ * A `PackedInstruction` is created by copy constructor from a `CircuitInstruction` by `CircuitData::pack`. There is no `pack_owned` (really, there never was - the previous method didn't take ownership) because there's never owned `CircuitInstruction`s coming in; they're Python-space interop, so we never own them (unless we clone them) other than when we're unpacking them. * `PackedInstruction` is currently just created manually when not coming from a `CircuitInstruction`. It's not hard, and makes it easier to re-use known intern indices than to waste time re-interning them. There is no need to go via `CircuitInstruction`. * `CircuitInstruction` now has two separated Python-space constructors: the old one, which is the default and takes `(operation, qubits, clbits)` (and extracts the information), and a new fast-path `from_standard` which asks only for the standard gate, qubits and params, avoiding operator construction. * To accept a Python-space operation, extract a Python object to `OperationFromPython`. This extracts the components that are separate in Rust space, but joined in Python space (the operation, params and extra attributes). This replaces `OperationInput` and `OperationTypeConstruct`, being more efficient at the extraction, including providing the data in the formats needed for `PackedInstruction` or `CircuitInstruction`. * To retrieve the Python-space operation, use `CircuitInstruction::get_operation` or `PackedInstruction::unpack_py_op` as appropriate. Both will cache and reuse the op, if `cache_pygates` is active. (Though note that if the op is created by `CircuitInstruction`, it will not propagate back to a `PackedInstruction`.) Avoiding operation creation --------------------------- The `_raw_op` field of `CircuitInstruction` is gone, because `PyGate`, `PyInstruction` and `PyOperation` are no longer pyclasses and no longer exposed to Python. Instead, we avoid operation creation by: * having an internal `DAGNode::_to_circuit_instruction`, which returns a copy of the internal `CircuitInstruction`, which can then be used with `CircuitInstruction.replace`, etc. * having `CircuitInstruction::is_standard_gate` to query from Python space if we should bother to create the operator. * changing `CircuitData::map_ops` to `map_nonstandard_ops`, and having it only call the Python callback function if the operation is not an unconditional standard gate. Memory usage ------------ Given the very simple example construction script: ```python from qiskit.circuit import QuantumCircuit qc = QuantumCircuit(1_000) for _ in range(3_000): for q in qc.qubits: qc.rz(0.0, q) for q in qc.qubits: qc.rx(0.0, q) for q in qc.qubits: qc.rz(0.0, q) for a, b in zip(qc.qubits[:-1], qc.qubits[1:]): qc.cx(a, b) ``` This uses 1.5GB in max resident set size on my Macbook (note that it's about 12 million gates) on both 1.1.0 and with this commit, so we've undone our memory losses. The parent of this commit uses 2GB. However, we're in a strong position to beat 1.1.0 in the future now; there are two obvious large remaining costs: * There are 16 bytes per `PackedInstruction` for the Python-operation caching (worth about 180MB in this benchmark, since no Python operations are actually created). * There is also significant memory wastage in the current `SmallVec<[Param; 3]>` storage of the parameters; for all standard gates, we know statically how many parameters are / should be stored, and we never need to increase the capacity. Further, the `Param` enum is 16 bytes wide per parameter, of which nearly 8 bytes is padding, but for all our current use cases, we only care if _all_ the parameters or floats (for everything else, we're going to have to defer to Python). We could move the discriminant out to the level of the parameters structure, and save a large amount of padding. Further work ------------ There's still performance left on the table here: * We still copy-in and copy-out of `CircuitInstruction` too much right now; we might want to make all the `CircuitInstruction` fields nullable and have `CircuitData::append` take them by _move_ rather than by copy. * The qubits/clbits interner requires owned arrays going in, but most interning should return an existing entry. We probably want to switch to have the interner take references/iterators by default, and clone when necessary. We could have a small circuit optimisation where the intern contexts reserve the first n entries to use for an all-to-all connectivity interning for up to (say) 8 qubits, since the transpiler will want to create a lot of ephemeral small circuits. * The `Param` vectors are too heavy at the moment; `SmallVec<[Param; 3]>` is 56 bytes wide, despite the vast majority of gates we care about having at most one single float (8 bytes). Dead padding is a large chunk of the memory use currently. * Fix clippy in no-gate-cache mode * Fix pylint unused-import complaints * Fix broken assumptions around the gate model The `compose` test had a now-broken assumption, because the Python-space `is` check is no longer expected to return an identical object when a standard gate is moved from one circuit to another and has its components remapped as part of the `compose` operation. This doesn't constitute the unpleasant deep-copy that that test is preventing. A custom gate still satisfies that, however, so we can just change the test. `DAGNode::set_name` could cause problems if it was called for the first time on a `CircuitInstruction` that was for a standard gate; these would be created as immutable instances. Given the changes in operator extraction to Rust space, it can now be the case that a standard gate that comes in as mutable is unpacked into Rust space, the cache is some time later invalidated, and then the operation is recreated immutably. * Fix lint * Fix minor documentation
* Use Rust gates for 2q unitary synthesis This commit builds off of what Qiskit#12650 did for the 1q decomposer and moves to using rust gates for the 2q decomposer too. This means that the circuit sequence generation is using rust's StandardGate representation directly instead of relying on mapping strings. For places where circuits are generated (calling `TwoQubitWeylDecomposition.circuit()` or or `TwoQubitBasisDecomposer.__call__` without the `use_dag` flag) the entire circuit is generated in Rust and returned to Python. * Run cargo fmt and black post rebase
* Move generate_preset_pass_manager to generate_preset_pass_manager.py * Add top-level import and reno * Apply suggestions from Matt's code review Co-authored-by: Matthew Treinish <[email protected]> * Add import path from qiskit.transpiler too * Fix cyclic import issue * Fix cyclic import issue in tools/pgo_scripts * Address cyclic import issues. Reorder imports alphabetically when relevant. * Fix docstring issue * Update releasenotes/notes/add-generate-preset-pm-global-import-efb12f185f3f738b.yaml Co-authored-by: Matthew Treinish <[email protected]> --------- Co-authored-by: Matthew Treinish <[email protected]>
…it (Qiskit#12785) * Deprecate accidentally public qc helper methods * Fix lint * Complete reno and add removal timeline * Update qiskit/circuit/quantumcircuit.py Co-authored-by: Julien Gacon <[email protected]> * Update remaining docstrings and removal timeline. * Trailing whitespace --------- Co-authored-by: Julien Gacon <[email protected]>
* Oxidize TwoQubitDecomposeUpToDiagonal This commit ports the TwoQubitDecomposeUpToDiagonal class from Python to rust. This internal private class is used internally by the quantum shannon decomposition code, and while not performance critical was simple to port. One difference is while the original Python implementation was a class, it acted more like a function in practice. So the new rust version is exposed as a function. Co-authored-by: Luciano Bello <[email protected]> Co-authored-by: Elena Peña Tapia <[email protected]> Co-authored-by: Sebastian Brandhofer <[email protected]> Co-authored-by: Jake Lishman <[email protected]> Co-authored-by: John Lapeyre <[email protected]> Co-authored-by: Julien Gacon <[email protected]> Co-authored-by: Eli Arbel <[email protected]> Co-authored-by: Raynel Sanchez <[email protected]> Co-authored-by: Henry Zou <[email protected]> Co-authored-by: Shelly Garion <[email protected]> Co-authored-by: Alexander Ivrii <[email protected]> * Build circuit from rust Since Qiskit#12459 recently merged we now have a mechanism to build a circuit from rust. This commit updates the synthesis function to build the circuit directly in rust instead of returning a circuit sequence and building the circuit from Python. This should speed up the construction substantially. * Remove unused private Python class This commit removes the Python implementation of the function. This is now unused in Qiskit and was never a public class so nothing external should be depending on it. Since it's not used we should just remove it. * Remove unused import * Calculate best_nbasis in unwrap_or_else() --------- Co-authored-by: Luciano Bello <[email protected]> Co-authored-by: Elena Peña Tapia <[email protected]> Co-authored-by: Sebastian Brandhofer <[email protected]> Co-authored-by: Jake Lishman <[email protected]> Co-authored-by: John Lapeyre <[email protected]> Co-authored-by: Julien Gacon <[email protected]> Co-authored-by: Eli Arbel <[email protected]> Co-authored-by: Raynel Sanchez <[email protected]> Co-authored-by: Henry Zou <[email protected]> Co-authored-by: Shelly Garion <[email protected]> Co-authored-by: Alexander Ivrii <[email protected]>
* Fix oversight from Qiskit#12185 where two input parsing functions were not migrated from transpile to generate_preset_pm with the others. * Add fix to reno from Qiskit#12185
* linting * linting...relax check for 3-qubit circuit * update test docstrings * black update * bind RZZ to pi/2 if Rzz(theta) in basis * Apply suggestions from code review --------- Co-authored-by: Matthew Treinish <[email protected]>
* deprecate qobj and assemble * reno * shallow deprecation of assemble * test.python.compiler.test_disassembler * fakebackend pulse * test.python.circuit.test_parameters * PulseQobjInstruction is used by GenericBackendV2 * test.python.scheduler.test_basic_scheduler * test.python.result.test_result * test.python.pulse.test_calibration_entries * test.python.compiler.test_assembler * test.python.transpiler.test_star_prerouting * test.python.pulse.test_instruction_schedule_map * test.python.providers.basic_provider.test_basic_simulator * test.python.primitives.test_backend_sampler_v2 * test.python.compiler.test_disassembler * test.python.compiler.test_compiler * test.python.circuit.test_scheduled_circuit * test.python.providers.test_fake_backends * test.python.circuit.test_unitary * test.python.transpiler.test_sabre_swap * test.python.providers.fake_provider.test_fake_backends * Aer using Provider ABC * aer warnings * reno * another pass on reno * test.python.pulse * test.python.compiler.test_compiler * add module to fiterwarning * test.python.compiler.test_transpiler * fixing obscure expcetion handleing for comparison * Apply suggestions from code review Co-authored-by: Elena Peña Tapia <[email protected]> * remove catch * new deprecate warning message * lint qiskit/assembler/assemble_circuits.py * concurrency warnings * ignore aer warnings * Update test/python/providers/fake_provider/test_fake_backends.py Co-authored-by: Elena Peña Tapia <[email protected]> * Update test/python/circuit/test_parameters.py Co-authored-by: Elena Peña Tapia <[email protected]> * Update qiskit/providers/models/pulsedefaults.py Co-authored-by: Elena Peña Tapia <[email protected]> * Update test/python/providers/fake_provider/test_fake_backends.py Co-authored-by: Elena Peña Tapia <[email protected]> * Update test/python/providers/fake_provider/test_generic_backend_v2.py Co-authored-by: Elena Peña Tapia <[email protected]> * lint * Qiskit#12649 (comment) * Qiskit#12649 (comment) * Update test/python/transpiler/test_sabre_swap.py Co-authored-by: Elena Peña Tapia <[email protected]> * Update qiskit/providers/models/pulsedefaults.py Co-authored-by: Elena Peña Tapia <[email protected]> * ignore Treating CircuitInstruction... * another unnecessary catch from aer * another unnecessary catch from aer, again * removing more unnecesary catches --------- Co-authored-by: Elena Peña Tapia <[email protected]>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
On top of Qiskit#10996
Details and comments
Cleaning up
Bit._register
andBit._index
is hard.