-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Final layout is not invoked in the transpiler unless the swap mapper is called. #10818
Comments
Actually
The final layout is mapping the qubit object in it's position in The qiskit/qiskit/quantum_info/operators/operator.py Lines 410 to 426 in cd507ad
qc_ibm.layout so that it's operator is the same as the input circuit qc 's.
The |
@mtreinish while I agree with all you views and why I just started an issue on this. I still think there is a bug as whatever pass is used in optimization permuted the qubits so in this case final_layout should be changed as it is different from the initial layout I used in the circuit. I agree that it is none as the assumption is initial_layout= final_layout in this case so this is my fix I am proposing that if a initial_layout is set before the swapper we copy that into final and if the swapper changes it great but this implies final is the same as the circuit I made which it is not. The transpiler picked a better set. |
This commit updates the TranspileLayout class to make it easier to work with. The TranspileLayout class was orginally just an a container class that took the information returned from the transpiler needed to reverse the transpiler layout permutation (in the absence of ancillas) so that `QuantumCircuit.from_circuit()` could compare Operator instances across a `transpile()`. However, the internal data structures used by the transpiler are hard to work with, and don't map well to the normal reasoning around how the transpiler transforms the circuit. To improve the usability of the class this commit adds 4 new methods to the class: - initial_layout_list() and final_layout_list() which compute a list form of the initial_layout and final_layout respectively - full_layout() which generates a list that maps the input circuits qubit positions in the input circuit to the final position at the end of the circuit (which is what most people think of when they hear "final layout") - permute_sparse_pauli_op() which takes in a SparsePauliOp object and permutes it based on the full layout. This is especially useful when combined with the Estimator primitive To implement these functions a few extra pieces of information are needed to fully implement them. The first is we need to know the number of original circuit qubits. This is used to account for any ancillas that are added in the circuit, once we have the input circuit count we can use the original_qubit_indices attribute to discern which qubits in the initial layout are from the original circuit and which are ancillas. The second piece of information needed is the list of qubits in the output circuit. as this is needed to look up the position of the virtual qubit in the final_layout. These are both added as optional private attributes to the TranspileLayout class and there are some small changes to the pass manager and QPY to accomodate them. Similarly the change in the TranspileLayout class requires a new QPY version to include the missing details that were not being serialized in QPY and weren't representable in the previous payload format. Fixes Qiskit#10826 Fixes Qiskit#10818
* Improve the ergonomics of the TranspileLayout class This commit updates the TranspileLayout class to make it easier to work with. The TranspileLayout class was orginally just an a container class that took the information returned from the transpiler needed to reverse the transpiler layout permutation (in the absence of ancillas) so that `QuantumCircuit.from_circuit()` could compare Operator instances across a `transpile()`. However, the internal data structures used by the transpiler are hard to work with, and don't map well to the normal reasoning around how the transpiler transforms the circuit. To improve the usability of the class this commit adds 4 new methods to the class: - initial_layout_list() and final_layout_list() which compute a list form of the initial_layout and final_layout respectively - full_layout() which generates a list that maps the input circuits qubit positions in the input circuit to the final position at the end of the circuit (which is what most people think of when they hear "final layout") - permute_sparse_pauli_op() which takes in a SparsePauliOp object and permutes it based on the full layout. This is especially useful when combined with the Estimator primitive To implement these functions a few extra pieces of information are needed to fully implement them. The first is we need to know the number of original circuit qubits. This is used to account for any ancillas that are added in the circuit, once we have the input circuit count we can use the original_qubit_indices attribute to discern which qubits in the initial layout are from the original circuit and which are ancillas. The second piece of information needed is the list of qubits in the output circuit. as this is needed to look up the position of the virtual qubit in the final_layout. These are both added as optional private attributes to the TranspileLayout class and there are some small changes to the pass manager and QPY to accomodate them. Similarly the change in the TranspileLayout class requires a new QPY version to include the missing details that were not being serialized in QPY and weren't representable in the previous payload format. Fixes #10826 Fixes #10818 * Handle None for the private TranspileLayout fields in QPY * Add test for full_layout with ancillas * Rework interface to be more consistent This commit reworks the names of the new methods added in this API to be more self consistent. It uses the format '*_index_layout' to replace the `*_layout_list` name. Similarly new methods `*_virtual_layout` are added for methods that return layout objects. * Apply suggestions from code review Co-authored-by: Jake Lishman <[email protected]> * Remove permute_sparse_pauli_op() This commit remove the TranspileLayout.permute_sparse_pauli_op() method. This was a bit out of place on the TranspileLayout class, and it will instead be replaced in a follow-up PR by a apply_layout() method on the SparePauliOp class that takes in a TranspileLayout object. * Update docs * Fix docs build post-rebase * Fix docs issues --------- Co-authored-by: Jake Lishman <[email protected]>
* Improve the ergonomics of the TranspileLayout class This commit updates the TranspileLayout class to make it easier to work with. The TranspileLayout class was orginally just an a container class that took the information returned from the transpiler needed to reverse the transpiler layout permutation (in the absence of ancillas) so that `QuantumCircuit.from_circuit()` could compare Operator instances across a `transpile()`. However, the internal data structures used by the transpiler are hard to work with, and don't map well to the normal reasoning around how the transpiler transforms the circuit. To improve the usability of the class this commit adds 4 new methods to the class: - initial_layout_list() and final_layout_list() which compute a list form of the initial_layout and final_layout respectively - full_layout() which generates a list that maps the input circuits qubit positions in the input circuit to the final position at the end of the circuit (which is what most people think of when they hear "final layout") - permute_sparse_pauli_op() which takes in a SparsePauliOp object and permutes it based on the full layout. This is especially useful when combined with the Estimator primitive To implement these functions a few extra pieces of information are needed to fully implement them. The first is we need to know the number of original circuit qubits. This is used to account for any ancillas that are added in the circuit, once we have the input circuit count we can use the original_qubit_indices attribute to discern which qubits in the initial layout are from the original circuit and which are ancillas. The second piece of information needed is the list of qubits in the output circuit. as this is needed to look up the position of the virtual qubit in the final_layout. These are both added as optional private attributes to the TranspileLayout class and there are some small changes to the pass manager and QPY to accomodate them. Similarly the change in the TranspileLayout class requires a new QPY version to include the missing details that were not being serialized in QPY and weren't representable in the previous payload format. Fixes Qiskit#10826 Fixes Qiskit#10818 * Handle None for the private TranspileLayout fields in QPY * Add test for full_layout with ancillas * Rework interface to be more consistent This commit reworks the names of the new methods added in this API to be more self consistent. It uses the format '*_index_layout' to replace the `*_layout_list` name. Similarly new methods `*_virtual_layout` are added for methods that return layout objects. * Apply suggestions from code review Co-authored-by: Jake Lishman <[email protected]> * Remove permute_sparse_pauli_op() This commit remove the TranspileLayout.permute_sparse_pauli_op() method. This was a bit out of place on the TranspileLayout class, and it will instead be replaced in a follow-up PR by a apply_layout() method on the SparePauliOp class that takes in a TranspileLayout object. * Update docs * Fix docs build post-rebase * Fix docs issues --------- Co-authored-by: Jake Lishman <[email protected]>
Environment
What is happening?
In the following code
The transpiler performs a mapping but only initial_layout is updated not the final_laytout is set to none
gives
This should give
How can we reproduce the issue?
see code above
What should happen?
This should give
Any suggestions?
In the pass_manager after choosing the initial_layout to the swap mapper set the final_layout and only update it after the final layout.
Personally I find the notation very confusing. It took me a while (actually I never did @nonhermitian explained it to me) to realize
initial_layout
is not theinitial_layout
but theinitial_layout
to the swap mapper and thefinal_layout
is the layout after the swap mapper (also no idea what 'input_qubit_mapping' is). Personally I think layout should just be the final one but if the user wants the history of how the layout changed then the should have meta data that correlates passes used with layout changes. But I think this would be a longer issue. My suggestion is to perform a quick update to set final_layout for this example and then in the future create an issue for what should be in the layout after the transpiler and how a user can get meta data that includes how the layout changes.The text was updated successfully, but these errors were encountered: