-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Use nalgebra::Matrix4 as output for instructions_to_matrix #15871
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,7 +12,7 @@ | |
|
|
||
| use super::optimize_1q_gates_decomposition::matmul_1q; | ||
| use hashbrown::{HashMap, HashSet}; | ||
| use nalgebra::Matrix2; | ||
| use nalgebra::{Matrix2, Matrix4, U4}; | ||
| use ndarray::ArrayView2; | ||
| use ndarray::{Array2, aview2}; | ||
| use num_complex::Complex64; | ||
|
|
@@ -25,14 +25,14 @@ use qiskit_circuit::circuit_data::CircuitData; | |
| use qiskit_circuit::dag_circuit::{DAGCircuit, NodeType}; | ||
| use qiskit_circuit::gate_matrix::{ | ||
| CH_GATE, CX_GATE, CY_GATE, CZ_GATE, DCX_GATE, ECR_GATE, ISWAP_GATE, ONE_QUBIT_IDENTITY, | ||
| TWO_QUBIT_IDENTITY, | ||
| }; | ||
| use qiskit_circuit::imports::QI_OPERATOR; | ||
| use qiskit_circuit::interner::Interned; | ||
| use qiskit_circuit::operations::StandardGate; | ||
| use qiskit_circuit::operations::{ArrayType, Operation, Param, UnitaryGate}; | ||
| use qiskit_circuit::packed_instruction::PackedOperation; | ||
| use qiskit_quantum_info::convert_2q_block_matrix::{blocks_to_matrix, get_matrix_from_inst}; | ||
| use qiskit_synthesis::linalg::nalgebra_array_view; | ||
| use qiskit_synthesis::two_qubit_decompose::RXXEquivalent; | ||
| use qiskit_synthesis::two_qubit_decompose::{ | ||
| TwoQubitBasisDecomposer, TwoQubitControlledUDecomposer, | ||
|
|
@@ -44,6 +44,29 @@ use crate::passes::unitary_synthesis::{PARAM_SET, TWO_QUBIT_BASIS_SET}; | |
| use crate::target::{Qargs, Target}; | ||
| use qiskit_circuit::PhysicalQubit; | ||
|
|
||
| static IDENTITY_2Q: Matrix4<Complex64> = Matrix4::new( | ||
| // Row 1 | ||
| Complex64::ONE, | ||
| Complex64::ZERO, | ||
| Complex64::ZERO, | ||
| Complex64::ZERO, | ||
| // Row 2 | ||
| Complex64::ZERO, | ||
| Complex64::ONE, | ||
| Complex64::ZERO, | ||
| Complex64::ZERO, | ||
| // Row 3 | ||
| Complex64::ZERO, | ||
| Complex64::ZERO, | ||
| Complex64::ONE, | ||
| Complex64::ZERO, | ||
| // Row 4 | ||
| Complex64::ZERO, | ||
| Complex64::ZERO, | ||
| Complex64::ZERO, | ||
| Complex64::ONE, | ||
| ); | ||
|
Comment on lines
+47
to
+68
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like this matrix: no need to think whether the elements are passed in row-major or column-major order 😄
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally I would have been able to use |
||
|
|
||
| #[allow(clippy::large_enum_variant)] | ||
| #[derive(Clone, Debug)] | ||
| pub enum DecomposerType { | ||
|
|
@@ -367,12 +390,13 @@ fn py_run_consolidate_blocks( | |
| let matrix = blocks_to_matrix(dag, &block, block_index_map).ok(); | ||
| if let Some(matrix) = matrix { | ||
| let num_basis_gates = match decomposer { | ||
| DecomposerType::TwoQubitBasis(ref decomp) => { | ||
| decomp.num_basis_gates_inner(matrix.view())? | ||
| } | ||
| DecomposerType::TwoQubitControlledU(ref decomp) => { | ||
| decomp.num_basis_gates_inner(matrix.view())? | ||
| } | ||
| DecomposerType::TwoQubitBasis(ref decomp) => decomp.num_basis_gates_inner( | ||
| nalgebra_array_view::<Complex64, U4, U4>(matrix.as_view()), | ||
| )?, | ||
| DecomposerType::TwoQubitControlledU(ref decomp) => decomp | ||
| .num_basis_gates_inner(nalgebra_array_view::<Complex64, U4, U4>( | ||
| matrix.as_view(), | ||
| ))?, | ||
| }; | ||
|
|
||
| if force_consolidate | ||
|
|
@@ -381,15 +405,13 @@ fn py_run_consolidate_blocks( | |
| || (basis_gates.is_some() && outside_basis) | ||
| || (target.is_some() && outside_basis) | ||
| { | ||
| if approx::abs_diff_eq!(aview2(&TWO_QUBIT_IDENTITY), matrix) { | ||
| if approx::abs_diff_eq!(IDENTITY_2Q, matrix) { | ||
| for node in block { | ||
| dag.remove_op_node(node); | ||
| } | ||
| } else { | ||
| // TODO: Use Matrix4/ArrayType::TwoQ when we're using nalgebra | ||
| // for consolidation | ||
| let unitary_gate = UnitaryGate { | ||
| array: ArrayType::NDArray(matrix), | ||
| array: ArrayType::TwoQ(matrix), | ||
| }; | ||
| let qubit_pos_map = block_index_map | ||
| .into_iter() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also consider
OperationRef::Operationvariant here (and if so, then also inget_matrix_from_inst)?We should also extend this to
PauliProductRotation, but this can be done for all relevant functions in a separate PR.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just mirrored what was already there. I think we do want to expand this for any unitary operation. So this will be PPR and Operations that have a unitary matrix. Ideally we'd probably cover PPR and unitary
OperationRef::Operations inPackedInstruction::try_matrix_as_nalgebra_2qthis check is just the fallback for whether we call out to python and usequantum_info.Operatorto compute the unitary from a gate's definition.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That being said I think we should fix this in a separate PR that fixes all the matrix methods