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

Use qubit-index newtypes in Rust space #10761

Merged
merged 2 commits into from
Sep 5, 2023

Conversation

jakelishman
Copy link
Member

@jakelishman jakelishman commented Sep 1, 2023

Summary

This converts all of our Rust-space components that are concerned with virtual and physical qubits (via the NLayout class) to represent those integers with newtypes wrapping them as half-size indices, and changes the NLayout API to only allow access via these types and not by raw integers.

The way this is done should have no overhead in time usage from Rust, and is actually a reduction in memory usage because all the qubits are stored at half the width they were previously (for most systems). This is done to add type safety to all our components that were concerned with the mixing of these two qubits. The implementation of this commit already turned up the logical bug fixed by gh-10756.

Details and comments

The biggest use of .index() is in Sabre in the distance matrices. I considering adding a newtype wrapper around the distance matrix that implements Index<[PhysicalQubit; 2], Output = f64> to enforce type-safe access to that during Sabre, but that can potentially be done in a follow-up commit. I think some other changes I'd potentially like to make around the Sabre interfaces might invalidate that, though, so I've left it for this commit.

I've not made the fix of #10756, so this PR will conflict with that one. I'll fix up whichever merges second; it's an easy fix.

This PR also takes the opportunity to standardise on VirtualQubit throughout the Rust components, which is more consistent with our Python-space usage, and doesn't have the naming clash with the QEC concept of a logical qubit.

edit: In (relatively casual) benchmarks I ran of this, I saw no change in runtime of SabreSwap, which is as expected.

@jakelishman jakelishman added Changelog: None Do not include in changelog Rust This PR or issue is related to Rust code in the repository mod: transpiler Issues and PRs related to Transpiler labels Sep 1, 2023
@jakelishman jakelishman requested a review from a team as a code owner September 1, 2023 18:08
@qiskit-bot
Copy link
Collaborator

One or more of the the following people are requested to review this:

This converts all of our Rust-space components that are concerned with
virtual and physical qubits (via the `NLayout` class) to represent those
integers with newtypes wrapping them as half-size indices, and changes
the `NLayout` API to only allow access via these types and not by raw
integers.

The way this is done should have no overhead in time usage from Rust,
and is actually a reduction in memory usage because all the qubits are
stored at half the width they were previously (for most systems).  This
is done to add type safety to all our components that were concerned
with the mixing of these two qubits.  The implementation of this commit
already turned up the logical bug fixed by Qiskitgh-10756.
@mtreinish mtreinish self-assigned this Sep 5, 2023
@mtreinish mtreinish added this to the 0.45.0 milestone Sep 5, 2023
Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, thanks for doing this. Besides shrinking the memory overhead of sabre's rust component and vf2 scoring, leveraging the type checker to validate we're reasoning about the correct type of qubit is a big win. Also I really like the VirtualQubit::to_phys() and PhysicalQubit::to_virt() syntax it's a lot nicer looking than the syntax before.

Just a couple small comments/questions inline.

}
}

unsafe impl numpy::Element for $id {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the first unsafe block we have in the rust code so far? Maybe it's time we start using miri (https://github.com/rust-lang/miri) in CI. This is super minor use now and unlikely to have an issue as we're just implementing the numpy traits which are unsafe because of their nature. But just something to think about moving forward.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think but am not 100% sure that unsafe impl doesn't implicitly allow unsafe code within function definitions - it's just a marker that the trait's contract can't be reasonably enforced by the compiler. In this case, the object has to be safe to be managed by Numpy (give or take, I think that means it needs to be a valid Numpy scalar and not implement Drop), but there's no actual unsafe Rust code needed.

crates/accelerate/src/nlayout.rs Show resolved Hide resolved
crates/accelerate/src/nlayout.rs Show resolved Hide resolved
crates/accelerate/src/nlayout.rs Show resolved Hide resolved
crates/accelerate/src/sabre_swap/neighbor_table.rs Outdated Show resolved Hide resolved
crates/accelerate/src/sabre_swap/neighbor_table.rs Outdated Show resolved Hide resolved
crates/accelerate/src/sabre_layout.rs Show resolved Hide resolved
This reverts the changes to the coupling-map generation and the indexing
into `NeighborTable` that were designed to make it more type safe in
favour of doing that in a separate commit.
Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for splitting out the NeighborTable changes.

@mtreinish mtreinish enabled auto-merge September 5, 2023 18:05
@mtreinish mtreinish added this pull request to the merge queue Sep 5, 2023
Merged via the queue into Qiskit:main with commit 887bb9c Sep 5, 2023
@jakelishman jakelishman deleted the rust/qubit-newtype branch September 5, 2023 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: None Do not include in changelog mod: transpiler Issues and PRs related to Transpiler Rust This PR or issue is related to Rust code in the repository
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants