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

Circuit library modernization #13046

Open
8 of 24 tasks
Cryoris opened this issue Aug 27, 2024 · 3 comments
Open
8 of 24 tasks

Circuit library modernization #13046

Cryoris opened this issue Aug 27, 2024 · 3 comments
Assignees
Labels
mod: circuit Related to the core of the `QuantumCircuit` class or the circuit library Rust This PR or issue is related to Rust code in the repository type: epic A theme of work that contain sub-tasks
Milestone

Comments

@Cryoris
Copy link
Contributor

Cryoris commented Aug 27, 2024

Summary

Modernize the circuit library to improve compiler quality and construction speed. The library circuits are classified in two categories:

  • Abstract blocks Operations defined by an action they perform (e.g. mathematical transformation), but can be synthesized in different fashions. These will be Instruction/Gate objects with a detached synthesis, that the compiler can reason about.
    Examples: QFT, Pauli evolutions, arithmetic circuits, MCX gates.
  • Structural circuits Circuit defined by their structure (the circuit is unique and cannot be built another way). These will be Python functions returning a QuantumCircuit.
    Examples: n-local circuits, quantum volume

Changes are to be pending-deprecated for 1.3, deprecated for 1.4 and finalized for 2.0.

Examples

The move to abstract blocks allows the compiler to reason about the circuit building blocks, where previously there was an eager construction:

circuit = ...
circuit.append(MCXGate(n), range(n - 1), [n])  # compiler can now allocate auxiliary qubits for efficient synthesis
circuit.append(QFTGate(2 * n), range(2 * n))  # compiler can choose optimal method based on topology or following measurements
circuit.measure_all()

Python functions can be used as drop-in replacement,

circuit = two_local(num_qubits, ["rx", "ry"], "cx", entanglement="pairwise")

but can enable performance-improvements, e.g. by directly composing onto output circuits.

Abstract blocks

Structural circuits

Performance

@Cryoris Cryoris added type: epic A theme of work that contain sub-tasks Rust This PR or issue is related to Rust code in the repository mod: circuit Related to the core of the `QuantumCircuit` class or the circuit library labels Aug 27, 2024
@Cryoris Cryoris added this to the 1.3.0 milestone Aug 27, 2024
@MozammilQ
Copy link
Contributor

@Cryoris , am I allowed to start with "Structural Circuits"?
and, are markings with '@Cryoris' like in 'n_local & friends' in performance, indicates you are working on it, right?

@Cryoris
Copy link
Contributor Author

Cryoris commented Sep 11, 2024

Hi @MozammilQ, it's great to see you're interested! We would like to have some PRs done by the dev team first to figure out the details and have some examples ready. Once that's done it you're very welcome to help 🙂

@LukasMansour
Copy link

LukasMansour commented Sep 11, 2024

@Cryoris, I would be interested in implementing a multitude of quantum arithmetic circuits for synthesis. When the time is right please let me know.

Qiskit team should also decide if they really want these circuits as part of the core library or not.

mtreinish added a commit to mtreinish/qiskit-core that referenced this issue Sep 28, 2024
mtreinish added a commit to mtreinish/qiskit-core that referenced this issue Sep 28, 2024
This commit adds a new function quantum_volume used for generating a
quantum volume model circuit. This new function is defined in Rust and
multithreaded to improve the throughput of the circuit generation. This
new function will eventually replace the existing QuantumVolume class as
part of Qiskit#13046. Since quantum volume is a circuit defined by it's
structure using a generator function is inline with the goals of Qiskit#13046.

Right now the performance is bottlenecked by the creation of the
UnitaryGate objects as these are still defined solely in Python. We'll
likely need to port the class to have a rust native representation to
further speed up the construction of the circuit.
github-merge-queue bot pushed a commit that referenced this issue Oct 3, 2024
* Add Rust quantum volume function

This commit adds a new function quantum_volume used for generating a
quantum volume model circuit. This new function is defined in Rust and
multithreaded to improve the throughput of the circuit generation. This
new function will eventually replace the existing QuantumVolume class as
part of #13046. Since quantum volume is a circuit defined by it's
structure using a generator function is inline with the goals of #13046.

Right now the performance is bottlenecked by the creation of the
UnitaryGate objects as these are still defined solely in Python. We'll
likely need to port the class to have a rust native representation to
further speed up the construction of the circuit.

* Adjust type hints on python function

Co-authored-by: Julien Gacon <[email protected]>

* Add missing __future__ import

The previous commit was relying on the behavior of the annotations
future import but neglected to add it. This commit corrects the
oversight.

* Add comment on random unitary algorithm

* Reduce allocations random_unitaries

The previous implementation had 4 heap allocations for each random
unitary constructed, this commit uses some fixed sized stack allocated
arrays and reduces that to two allocations one for q and r from the
factorization. We'll always need at least one for the `Array2` that gets
stored in each `UnitaryGate` as a numpy array. But to reduce to just
this we'll need a method of computing the QR factorization without an
allocation for the result space, nalgebtra might be a path for doing
that. While this currently isn't a bottleneck as the `UnitaryGate`
python object creation is the largest source of runtime, but assuming
that's fixed in the future this might have a larger impact.

* Preallocate unitaries for serial path

When executing in the serial path we previously were working directly
with an iterator where the 2q unitaries we're created on the iterator
that we passed directly to circuit constructor. However testing shows
that precomputing all the unitaries into a Vec and passing the iterator
off of that to the circuit constructor is marginally but consistently
faster. So this commit pivots to using that instead.

* Fix determinism and error handling of of qv function

This commit fixes two issues in the reproducibility of the quantum
volume circuit. The first was the output unitary matrices for a fixed
seed would differ between the parallel and serial execution path. This
was because how the RNGs were used was different in the different code
paths. This change results in the serial path being marginally less
efficient, but it shouldn't be a big deal when compared to getting
different results in different contexts. The second was the seed usage
in parallel mode was dependent on the number of threads on the local
system. This was problematic because the exact circuit generated between
two systems would be different even with a fixed seed. This was fixed to
avoid depending on the number of threads to determine how the seeds were
used across multiple threads.

The last fix here was a change to the error handling so that the
CircuitData constructor used to create the circuit object can handle a
fallible iterator. Previously we were throwing away the python error and
panicking if the Python call to generate the UnitaryGate object raised
an error for any reason.

* Mention the new function is multithreaded in docstring

* Update qiskit/circuit/library/quantum_volume.py

Co-authored-by: Julien Gacon <[email protected]>

---------

Co-authored-by: Julien Gacon <[email protected]>
Co-authored-by: Julien Gacon <[email protected]>
ElePT pushed a commit to ElePT/qiskit that referenced this issue Oct 3, 2024
* Add Rust quantum volume function

This commit adds a new function quantum_volume used for generating a
quantum volume model circuit. This new function is defined in Rust and
multithreaded to improve the throughput of the circuit generation. This
new function will eventually replace the existing QuantumVolume class as
part of Qiskit#13046. Since quantum volume is a circuit defined by it's
structure using a generator function is inline with the goals of Qiskit#13046.

Right now the performance is bottlenecked by the creation of the
UnitaryGate objects as these are still defined solely in Python. We'll
likely need to port the class to have a rust native representation to
further speed up the construction of the circuit.

* Adjust type hints on python function

Co-authored-by: Julien Gacon <[email protected]>

* Add missing __future__ import

The previous commit was relying on the behavior of the annotations
future import but neglected to add it. This commit corrects the
oversight.

* Add comment on random unitary algorithm

* Reduce allocations random_unitaries

The previous implementation had 4 heap allocations for each random
unitary constructed, this commit uses some fixed sized stack allocated
arrays and reduces that to two allocations one for q and r from the
factorization. We'll always need at least one for the `Array2` that gets
stored in each `UnitaryGate` as a numpy array. But to reduce to just
this we'll need a method of computing the QR factorization without an
allocation for the result space, nalgebtra might be a path for doing
that. While this currently isn't a bottleneck as the `UnitaryGate`
python object creation is the largest source of runtime, but assuming
that's fixed in the future this might have a larger impact.

* Preallocate unitaries for serial path

When executing in the serial path we previously were working directly
with an iterator where the 2q unitaries we're created on the iterator
that we passed directly to circuit constructor. However testing shows
that precomputing all the unitaries into a Vec and passing the iterator
off of that to the circuit constructor is marginally but consistently
faster. So this commit pivots to using that instead.

* Fix determinism and error handling of of qv function

This commit fixes two issues in the reproducibility of the quantum
volume circuit. The first was the output unitary matrices for a fixed
seed would differ between the parallel and serial execution path. This
was because how the RNGs were used was different in the different code
paths. This change results in the serial path being marginally less
efficient, but it shouldn't be a big deal when compared to getting
different results in different contexts. The second was the seed usage
in parallel mode was dependent on the number of threads on the local
system. This was problematic because the exact circuit generated between
two systems would be different even with a fixed seed. This was fixed to
avoid depending on the number of threads to determine how the seeds were
used across multiple threads.

The last fix here was a change to the error handling so that the
CircuitData constructor used to create the circuit object can handle a
fallible iterator. Previously we were throwing away the python error and
panicking if the Python call to generate the UnitaryGate object raised
an error for any reason.

* Mention the new function is multithreaded in docstring

* Update qiskit/circuit/library/quantum_volume.py

Co-authored-by: Julien Gacon <[email protected]>

---------

Co-authored-by: Julien Gacon <[email protected]>
Co-authored-by: Julien Gacon <[email protected]>
ElePT pushed a commit to ElePT/qiskit that referenced this issue Oct 7, 2024
* Add Rust quantum volume function

This commit adds a new function quantum_volume used for generating a
quantum volume model circuit. This new function is defined in Rust and
multithreaded to improve the throughput of the circuit generation. This
new function will eventually replace the existing QuantumVolume class as
part of Qiskit#13046. Since quantum volume is a circuit defined by it's
structure using a generator function is inline with the goals of Qiskit#13046.

Right now the performance is bottlenecked by the creation of the
UnitaryGate objects as these are still defined solely in Python. We'll
likely need to port the class to have a rust native representation to
further speed up the construction of the circuit.

* Adjust type hints on python function

Co-authored-by: Julien Gacon <[email protected]>

* Add missing __future__ import

The previous commit was relying on the behavior of the annotations
future import but neglected to add it. This commit corrects the
oversight.

* Add comment on random unitary algorithm

* Reduce allocations random_unitaries

The previous implementation had 4 heap allocations for each random
unitary constructed, this commit uses some fixed sized stack allocated
arrays and reduces that to two allocations one for q and r from the
factorization. We'll always need at least one for the `Array2` that gets
stored in each `UnitaryGate` as a numpy array. But to reduce to just
this we'll need a method of computing the QR factorization without an
allocation for the result space, nalgebtra might be a path for doing
that. While this currently isn't a bottleneck as the `UnitaryGate`
python object creation is the largest source of runtime, but assuming
that's fixed in the future this might have a larger impact.

* Preallocate unitaries for serial path

When executing in the serial path we previously were working directly
with an iterator where the 2q unitaries we're created on the iterator
that we passed directly to circuit constructor. However testing shows
that precomputing all the unitaries into a Vec and passing the iterator
off of that to the circuit constructor is marginally but consistently
faster. So this commit pivots to using that instead.

* Fix determinism and error handling of of qv function

This commit fixes two issues in the reproducibility of the quantum
volume circuit. The first was the output unitary matrices for a fixed
seed would differ between the parallel and serial execution path. This
was because how the RNGs were used was different in the different code
paths. This change results in the serial path being marginally less
efficient, but it shouldn't be a big deal when compared to getting
different results in different contexts. The second was the seed usage
in parallel mode was dependent on the number of threads on the local
system. This was problematic because the exact circuit generated between
two systems would be different even with a fixed seed. This was fixed to
avoid depending on the number of threads to determine how the seeds were
used across multiple threads.

The last fix here was a change to the error handling so that the
CircuitData constructor used to create the circuit object can handle a
fallible iterator. Previously we were throwing away the python error and
panicking if the Python call to generate the UnitaryGate object raised
an error for any reason.

* Mention the new function is multithreaded in docstring

* Update qiskit/circuit/library/quantum_volume.py

Co-authored-by: Julien Gacon <[email protected]>

---------

Co-authored-by: Julien Gacon <[email protected]>
Co-authored-by: Julien Gacon <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mod: circuit Related to the core of the `QuantumCircuit` class or the circuit library Rust This PR or issue is related to Rust code in the repository type: epic A theme of work that contain sub-tasks
Projects
None yet
Development

No branches or pull requests

5 participants