Skip to content

Commit 041c042

Browse files
Avoid panics in Optimize1qGatesDecomposition (Qiskit#15117) (Qiskit#15119)
These pathways are still error conditions, but at a minimum, we should not be panicking on legitimate (if incorrect) inputs from Python space. (cherry picked from commit 1c294b4) Co-authored-by: Jake Lishman <[email protected]>
1 parent b42d8ce commit 041c042

File tree

3 files changed

+26
-11
lines changed

3 files changed

+26
-11
lines changed

crates/transpiler/src/passes/optimize_1q_gates_decomposition.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ pub fn run_optimize_1q_gates_decomposition(
7676
};
7777
if basis_gates_per_qubit[qubit.index()].is_none() {
7878
let basis_gates = match target {
79-
Some(target) => Some(target.operation_names_for_qargs(&[qubit]).unwrap()),
79+
Some(target) => Some(target.operation_names_for_qargs(&[qubit])?),
8080
None => {
8181
let basis = basis_gates.as_ref();
8282
basis.map(|basis| basis.iter().map(|x| x.as_str()).collect())
8383
}
8484
};
8585
basis_gates_per_qubit[qubit.index()] = basis_gates;
8686
}
87-
let basis_gates = &basis_gates_per_qubit[qubit.index()].as_ref();
87+
let basis_gates = basis_gates_per_qubit[qubit.index()].as_ref();
8888

8989
let target_basis_set = &mut target_basis_per_qubit[qubit.index()];
9090
if !target_basis_set.initialized() {
@@ -93,21 +93,23 @@ pub fn run_optimize_1q_gates_decomposition(
9393
.iter()
9494
.enumerate()
9595
.filter_map(|(idx, gates)| {
96-
if !gates
97-
.iter()
98-
.all(|gate| basis_gates.as_ref().unwrap().contains(gate))
99-
{
96+
if !gates.iter().all(|gate| {
97+
basis_gates
98+
.expect("the target path always provides a hash set")
99+
.contains(gate)
100+
}) {
100101
return None;
101102
}
102103
let basis = EULER_BASIS_NAMES[idx];
103104
Some(basis)
104105
})
105106
.for_each(|basis| target_basis_set.add_basis(basis)),
106107
None => match &global_decomposers {
107-
Some(bases) => bases
108-
.iter()
109-
.map(|basis| EulerBasis::__new__(basis).unwrap())
110-
.for_each(|basis| target_basis_set.add_basis(basis)),
108+
Some(bases) => {
109+
for basis in bases.iter() {
110+
target_basis_set.add_basis(EulerBasis::__new__(basis)?)
111+
}
112+
}
111113
None => match basis_gates {
112114
Some(gates) => EULER_BASES
113115
.iter()
@@ -144,7 +146,9 @@ pub fn run_optimize_1q_gates_decomposition(
144146
if let Some(target) = target {
145147
error *= compute_error_term_from_target(inst.op.name(), target, qubit);
146148
}
147-
inst.op.matrix_as_static_1q(inst.params_view()).unwrap()
149+
inst.op
150+
.matrix_as_static_1q(inst.params_view())
151+
.expect("collect_1q_runs only collects gates that can produce a matrix")
148152
} else {
149153
unreachable!("Can only have op nodes here")
150154
}

crates/transpiler/src/target/errors.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,9 @@ pub enum TargetError {
4949
#[error["Lower bound {low} is not less than higher bound {high}."]]
5050
InvalidBounds { low: f64, high: f64 },
5151
}
52+
53+
impl From<TargetError> for ::pyo3::PyErr {
54+
fn from(val: TargetError) -> Self {
55+
crate::TranspilerError::new_err(val.to_string())
56+
}
57+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
fixes:
3+
- |
4+
:class:`.Optimize1qGatesDecomposition` will now raise a :exc:`.TranspilerError` instead of a
5+
Rust-space panic when attempting to run on a circuit that is too large for the :class:`.Target`.

0 commit comments

Comments
 (0)