Skip to content

Commit 823cc88

Browse files
authored
Replace infallible expect with compile-time checks in VF2 (#16010)
These are a few cases in the VF2 layout passes where we use `expect` on places that _can_ be handled by the compiler, or brought closer to the place where the assumption can be easily validated.
1 parent 0d63a93 commit 823cc88

1 file changed

Lines changed: 27 additions & 26 deletions

File tree

crates/transpiler/src/passes/vf2/vf2_layout.rs

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -316,9 +316,11 @@ struct VirtualInteractions<T> {
316316
}
317317
impl<T: Default> VirtualInteractions<T> {
318318
/// Create a set of virtual interactions from a DAG, and a weighter function for a single
319-
/// interaction. The weighter should return `true` on success, or `false` if no weight could be
320-
/// created (indicating a necessary failure of the layout pass).
321-
fn from_dag<W>(dag: &DAGCircuit, weighter: W) -> PyResult<Option<Self>>
319+
/// interaction.
320+
///
321+
/// The weighter should return `true` on success, or `false` if no weight could be created
322+
/// (indicating a necessary failure of the layout pass).
323+
fn try_from_dag<W>(dag: &DAGCircuit, weighter: W) -> PyResult<Option<Self>>
322324
where
323325
W: Fn(&mut T, &PackedInstruction, usize) -> bool,
324326
{
@@ -337,6 +339,19 @@ impl<T: Default> VirtualInteractions<T> {
337339
Ok(Some(out))
338340
}
339341

342+
/// Create a set of virtual interactions from a DAG, and a weighter function for a single
343+
/// interaction.
344+
fn from_dag<W>(dag: &DAGCircuit, weighter: W) -> PyResult<Self>
345+
where
346+
W: Fn(&mut T, &PackedInstruction, usize),
347+
{
348+
Self::try_from_dag(dag, |weight, inst, count| {
349+
weighter(weight, inst, count);
350+
true
351+
})
352+
.map(|res| res.expect("weighter is infallible so should always produce interactions"))
353+
}
354+
340355
/// Add interactions from a given DAG. Returns `false` if the weighter ever returned `false`.
341356
fn add_interactions_from<W>(
342357
&mut self,
@@ -658,14 +673,11 @@ where
658673
max_trials == 0 || trials <= max_trials
659674
};
660675
let mut vf2 = vf2.with_call_limit(config.call_limit.0).into_iter();
661-
let (mut mapping, _score) = vf2.next()?.expect("error is infallible");
676+
let Ok((mut mapping, _score)) = vf2.next()?;
662677
if can_continue() {
663678
vf2.call_limit = config.call_limit.1;
664-
if let Some((new_mapping, _score)) = vf2
665-
.take_while(|_| can_continue())
666-
.last()
667-
.map(|v| v.expect("error is infallible"))
668-
{
679+
if let Some(result) = vf2.take_while(|_| can_continue()).last() {
680+
let Ok((new_mapping, _)) = result;
669681
mapping = new_mapping;
670682
}
671683
}
@@ -702,12 +714,8 @@ where
702714
for node in interactions.graph.node_indices() {
703715
let needle = interactions.graph.node_weight(node)?;
704716
let haystack = coupling.node_weight(node_map(node))?;
705-
score = W::Score::combine(
706-
&score,
707-
&scorer
708-
.score(needle, haystack)
709-
.expect("error is infallible")?,
710-
);
717+
let Ok(partial) = scorer.score(needle, haystack);
718+
score = W::Score::combine(&score, &partial?);
711719
}
712720
for edge in interactions.graph.edge_references() {
713721
let needle = edge.weight();
@@ -716,12 +724,8 @@ where
716724
.edges_connecting(node_map(edge.source()), node_map(edge.target()))
717725
.next()?
718726
.weight();
719-
score = W::Score::combine(
720-
&score,
721-
&scorer
722-
.score(needle, haystack)
723-
.expect("error is infallible")?,
724-
);
727+
let Ok(partial) = scorer.score(needle, haystack);
728+
score = W::Score::combine(&score, &partial?);
725729
}
726730
Some(score)
727731
}
@@ -737,11 +741,8 @@ pub fn vf2_layout_pass_average(
737741
) -> PyResult<Vf2PassReturn> {
738742
let add_interaction = |count: &mut usize, _: &PackedInstruction, repeats: usize| {
739743
*count += repeats;
740-
true
741744
};
742-
let interactions = VirtualInteractions::from_dag(dag, add_interaction)?
743-
.expect("weighting function is infallible");
744-
745+
let interactions = VirtualInteractions::from_dag(dag, add_interaction)?;
745746
let score =
746747
|count: &usize, err: &f64| -> Result<f64, Infallible> { Ok(*err * (*count as f64)) };
747748
let target_error_map = avg_error_map
@@ -819,7 +820,7 @@ pub fn vf2_layout_pass_exact(
819820
}
820821
true
821822
};
822-
let Some(mut interactions) = VirtualInteractions::from_dag(dag, add_interaction)? else {
823+
let Some(mut interactions) = VirtualInteractions::try_from_dag(dag, add_interaction)? else {
823824
return Ok(Vf2PassReturn::NoSolution);
824825
};
825826

0 commit comments

Comments
 (0)