Skip to content

Add TranspileLayout struct to rust #14778

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

mtreinish
Copy link
Member

Summary

This commit adds a Rust TranspileLayout object which is analgous to the Python space object. It is a self contained struct that is only for Rust and will be used by the C API for the C transpiler so that users will be able to reason about the permutations caused by the transpiler. This will also be used by #14106 to apply a transpilation layout to the SparseObservable in C. This commit only adds the rust struct and it's associated tests, a subsequent PR will add the C API on top. This won't be used until we have a full path transpiler in C though (see #14760).

Details and comments

This commit adds a Rust TranspileLayout object which is analgous to the
Python space object. It is a self contained struct that is only for
Rust and will be used by the C API for the C transpiler so that users
will be able to reason about the permutations caused by the transpiler.
This will also be used by Qiskit#14106 to apply a transpilation layout to the
SparseObservable in C. This commit only adds the rust struct and it's
associated tests, a subsequent PR will add the C API on top. This won't
be used until we have a full path transpiler in C though (see Qiskit#14760).
@mtreinish mtreinish added this to the 2.2.0 milestone Jul 22, 2025
@mtreinish mtreinish requested a review from a team as a code owner July 22, 2025 10:52
@mtreinish mtreinish 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 C API Related to the C API labels Jul 22, 2025
@qiskit-bot
Copy link
Collaborator

One or more of the following people are relevant to this code:

  • @Qiskit/terra-core

Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

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

If we're going to do this, please can we replace the Python-space version at the same time? TranspileLayout in Python is already not well documented and hard to follow1, and I really don't want two parallel structs of the same type in the library at the same time.

Footnotes

  1. as this notification popped, I was literally writing something against TranspileLayout and had to got to the PassManager to figure out what one of the input fields was supposed to represent.

Comment on lines +15 to +29
/// The "layout" caused by transpilation
///
/// In general Qiskit's transpiler is unitary-preserving up to the initial layout
/// and routing permutations. The initial layout permutation is caused by
/// setting and applying the initial layout (the mapping from virtual circuit
/// qubits to physical qubits on the target) and the routing permtuations are
/// caused by swap gate insertion or permutation ellision prior to the initial
/// layout. This struct tracks these details and provide an interface to reason
/// about these permutations.
pub struct TranspileLayout {
initial_layout: NLayout,
routing_permutation: Option<Vec<PhysicalQubit>>,
input_qubit_count: u32,
output_qubit_count: u32,
}
Copy link
Member

Choose a reason for hiding this comment

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

This could do with more documentation, especially routing_permutation - this needs to clearly state how the permutation of routing_permutation is supposed to be interpreted.

Under what circumstances can output_qubit_count be different to the length of initial_layout?

@coveralls
Copy link

coveralls commented Jul 22, 2025

Pull Request Test Coverage Report for Build 16481789778

Details

  • 574 of 580 (98.97%) changed or added relevant lines in 1 file are covered.
  • 9 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+0.08%) to 87.833%

Changes Missing Coverage Covered Lines Changed/Added Lines %
crates/transpiler/src/transpile_layout.rs 574 580 98.97%
Files with Coverage Reduction New Missed Lines %
crates/qasm2/src/lex.rs 3 93.04%
crates/qasm2/src/parse.rs 6 97.56%
Totals Coverage Status
Change from base Build 16481559458: 0.08%
Covered Lines: 82076
Relevant Lines: 93445

💛 - Coveralls

@mtreinish
Copy link
Member Author

If we're going to do this, please can we replace the Python-space version at the same time? TranspileLayout in Python is already not well documented and hard to follow1, and I really don't want two parallel structs of the same type in the library at the same time.

Footnotes

1. as this notification popped, I was _literally_ writing something against `TranspileLayout` and had to got to the `PassManager` to figure out what one of the input fields was supposed to represent. [↩](#user-content-fnref-1-5de68aa40edff11d83cbc5463197f44f)

I considered doing it but I wrote this specifically using the Rust native types to work with the transpiler in rust and c. If you look at #14760 besides the output I was planning to use this as the container throughout the PassManager equivalent to work with all the layouts which we can't do in Python either.

The problem with using it as a replacement in python is the existing class has public attributes that are all python types and the construction is in terms of the python Layout. Also the passmanagers work explicitly with the layout class in different property set fields, we can't change those types or supersede those fields without breaking custom pipelines. So the best we'd really be able to do is take the Layout objects from the property set construct the rust types from the Layout objects to create the rust transpile layout object. Then we'd have to wrap this in a python specific layer that will convert the rust types to the python types when needed (and probably also storing the extra information about shareable qubits we don't need to store in rust). It didn't seem like that buys us very much.

mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Jul 22, 2025
This commit adds the TranspileLayout struct added in Qiskit#14778 to the C
API. It is a straightforward addition to the API as the interface is
fairly simple. Given a pointer to a TranspileLayout the methods return
the arrays for the various views of the layout or the number of qubits
for the input and output circuits.

One small change was made to the PhysicalQubit and VirtualQubit type
definitions to use #[repr(transparent)] which in practice shouldn't
change anything, but it makes it explicit that these can be used
interchangeably with a u32. This simplifies how we can return arrays of
either type to C because it is safe to cast them as pointers to u32s.

Note that nothing in the C API is capable of generating a transpile
layout currently. The intent is for it to be part of the full
transpile() function return (see Qiskit#14778). In the meantime this is
tested solely through rust tests and there aren't any tests written
in C yet. A potential follow up commit can be made to update the
standalone vf2 layout pass function to use a transpile layout inside
it's result type which would be more ergonomic than it's current
layout object in the result. But to keep this PR targeted this doesn't
update that interface and only exposes the struct to the C API.
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Jul 22, 2025
This commit adds the TranspileLayout struct added in Qiskit#14778 to the C
API. It is a straightforward addition to the API as the interface is
fairly simple. Given a pointer to a TranspileLayout the methods return
the arrays for the various views of the layout or the number of qubits
for the input and output circuits.

One small change was made to the PhysicalQubit and VirtualQubit type
definitions to use #[repr(transparent)] which in practice shouldn't
change anything, but it makes it explicit that these can be used
interchangeably with a u32. This simplifies how we can return arrays of
either type to C because it is safe to cast them as pointers to u32s.

Note that nothing in the C API is capable of generating a transpile
layout currently. The intent is for it to be part of the full
transpile() function return (see Qiskit#14778). In the meantime this is
tested solely through rust tests and there aren't any tests written
in C yet. A potential follow up commit can be made to update the
standalone vf2 layout pass function to use a transpile layout inside
it's result type which would be more ergonomic than it's current
layout object in the result. But to keep this PR targeted this doesn't
update that interface and only exposes the struct to the C API.
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Jul 22, 2025
This commit adds the TranspileLayout struct added in Qiskit#14778 to the C
API. It is a straightforward addition to the API as the interface is
fairly simple. Given a pointer to a TranspileLayout the methods return
the arrays for the various views of the layout or the number of qubits
for the input and output circuits.

One small change was made to the PhysicalQubit and VirtualQubit type
definitions to use #[repr(transparent)] which in practice shouldn't
change anything, but it makes it explicit that these can be used
interchangeably with a u32. This simplifies how we can return arrays of
either type to C because it is safe to cast them as pointers to u32s.

Note that nothing in the C API is capable of generating a transpile
layout currently. The intent is for it to be part of the full
transpile() function return (see Qiskit#14778). In the meantime this is
tested solely through rust tests and there aren't any tests written
in C yet. A potential follow up commit can be made to update the
standalone vf2 layout pass function to use a transpile layout inside
it's result type which would be more ergonomic than it's current
layout object in the result. But to keep this PR targeted this doesn't
update that interface and only exposes the struct to the C API.
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Jul 22, 2025
This commit adds the TranspileLayout struct added in Qiskit#14778 to the C
API. It is a straightforward addition to the API as the interface is
fairly simple. Given a pointer to a TranspileLayout the methods return
the arrays for the various views of the layout or the number of qubits
for the input and output circuits.

One small change was made to the PhysicalQubit and VirtualQubit type
definitions to use #[repr(transparent)] which in practice shouldn't
change anything, but it makes it explicit that these can be used
interchangeably with a u32. This simplifies how we can return arrays of
either type to C because it is safe to cast them as pointers to u32s.

Note that nothing in the C API is capable of generating a transpile
layout currently. The intent is for it to be part of the full
transpile() function return (see Qiskit#14778). In the meantime this is
tested solely through rust tests and there aren't any tests written
in C yet. A potential follow up commit can be made to update the
standalone vf2 layout pass function to use a transpile layout inside
it's result type which would be more ergonomic than it's current
layout object in the result. But to keep this PR targeted this doesn't
update that interface and only exposes the struct to the C API.
This commit improves the routing permutation method to make them more
rust native. It updates the return to be a slice of PhysicalQubits
instead of an owned vec. To get the explicit trivial permutation in the
case of None a new method explicit_routing_permutation is added that
returns `Cow<[PhysicalQubits]>` and only allocates in the None case.
This commit updates the final layout method to return a NLayout and a
new method final_index_layout is added to return a Vec.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C API Related to the C API 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.

4 participants