@@ -37,6 +37,7 @@ use smallvec::{SmallVec, smallvec};
3737use super :: dag:: { InteractionKind , SabreDAG } ;
3838use super :: heuristic:: { BasicHeuristic , DecayHeuristic , Heuristic , LookaheadHeuristic , SetScaling } ;
3939use super :: layer:: { ExtendedSet , FrontLayer } ;
40+ use super :: vec_map:: VecMap ;
4041use crate :: TranspilerError ;
4142use crate :: neighbors:: Neighbors ;
4243use crate :: target:: { Target , TargetCouplingError } ;
@@ -450,8 +451,8 @@ struct State {
450451 extended_set : ExtendedSet ,
451452 /// How many predecessors still need to be satisfied for each node index before it is at the
452453 /// front of the topological iteration through the nodes as they're routed.
453- required_predecessors : Vec < u32 > ,
454- decay : Vec < f64 > ,
454+ required_predecessors : VecMap < NodeIndex , u32 > ,
455+ decay : VecMap < PhysicalQubit , f64 > ,
455456 /// Reusable allocated storage space for accumulating and scoring swaps. This is owned as part
456457 /// of the general state to avoid reallocation costs.
457458 swap_scores : Vec < ( [ PhysicalQubit ; 2 ] , f64 ) > ,
@@ -479,7 +480,7 @@ impl State {
479480 problem : RoutingProblem ,
480481 qubit : PhysicalQubit ,
481482 ) -> Option < NodeIndex > {
482- self . front_layer . qubits ( ) [ qubit. index ( ) ] . and_then ( |( node, other) | {
483+ self . front_layer . qubits ( ) [ qubit] . and_then ( |( node, other) | {
483484 problem
484485 . target
485486 . neighbors
@@ -563,11 +564,10 @@ impl State {
563564 . dag
564565 . edges_directed ( node_id, Direction :: Outgoing )
565566 {
566- let successor_node = edge. target ( ) ;
567- let successor_index = successor_node. index ( ) ;
568- self . required_predecessors [ successor_index] -= 1 ;
569- if self . required_predecessors [ successor_index] == 0 {
570- to_visit. push_back ( successor_node) ;
567+ let successor = edge. target ( ) ;
568+ self . required_predecessors [ successor] -= 1 ;
569+ if self . required_predecessors [ successor] == 0 {
570+ to_visit. push_back ( successor) ;
571571 }
572572 }
573573 }
@@ -625,25 +625,24 @@ impl State {
625625 return ;
626626 } ;
627627 let mut to_visit = self . front_layer . iter_nodes ( ) . copied ( ) . collect :: < Vec < _ > > ( ) ;
628- let mut decremented: IndexMap < usize , u32 , ahash:: RandomState > =
628+ let mut decremented: IndexMap < NodeIndex , u32 , ahash:: RandomState > =
629629 IndexMap :: with_hasher ( ahash:: RandomState :: default ( ) ) ;
630630 let mut i = 0 ;
631631 while i < to_visit. len ( ) && self . extended_set . len ( ) < extended_set_size {
632632 let node = to_visit[ i] ;
633633 for edge in problem. sabre . dag . edges_directed ( node, Direction :: Outgoing ) {
634- let successor_node = edge. target ( ) ;
635- let successor_index = successor_node. index ( ) ;
636- * decremented. entry ( successor_index) . or_insert ( 0 ) += 1 ;
637- self . required_predecessors [ successor_index] -= 1 ;
638- if self . required_predecessors [ successor_index] == 0 {
634+ let successor = edge. target ( ) ;
635+ * decremented. entry ( successor) . or_insert ( 0 ) += 1 ;
636+ self . required_predecessors [ successor] -= 1 ;
637+ if self . required_predecessors [ successor] == 0 {
639638 // TODO: this looks "through" control-flow ops without seeing them, but we
640639 // actually eagerly route control-flow blocks as soon as they're eligible, so
641640 // they should be reflected in the extended set.
642- if let InteractionKind :: TwoQ ( [ a, b] ) = & problem. sabre . dag [ successor_node ] . kind {
641+ if let InteractionKind :: TwoQ ( [ a, b] ) = & problem. sabre . dag [ successor ] . kind {
643642 self . extended_set
644643 . push ( [ a. to_phys ( & self . layout ) , b. to_phys ( & self . layout ) ] ) ;
645644 }
646- to_visit. push ( successor_node ) ;
645+ to_visit. push ( successor ) ;
647646 }
648647 }
649648 i += 1 ;
@@ -703,27 +702,12 @@ impl State {
703702 // If we apply a single swap it could be that we route 2 nodes; that is a setup like
704703 // A - B - A - B
705704 // and we swap the middle two qubits. This cannot happen if we apply 2 or more swaps.
706- if current_swaps. len ( ) > 1 {
707- smallvec ! [ closest_node]
708- } else {
709- // check if the closest node has neighbors that are now routable -- for that we get
710- // the other physical qubit that was swapped and check whether the node on it
711- // is now routable
712- let mut possible_other_qubit = current_swaps[ 0 ]
705+ match current_swaps. as_slice ( ) {
706+ [ swap] => swap
713707 . iter ( )
714- // check if other nodes are in the front layer that are connected by this swap
715- . filter_map ( |& swap_qubit| self . front_layer . qubits ( ) [ swap_qubit. index ( ) ] )
716- // remove the closest_node, which we know we already routed
717- . filter ( |( node_index, _other_qubit) | * node_index != closest_node)
718- . map ( |( _node_index, other_qubit) | other_qubit) ;
719-
720- // if there is indeed another candidate, check if that gate is routable
721- if let Some ( other_qubit) = possible_other_qubit. next ( ) {
722- if let Some ( also_routed) = self . routable_node_on_qubit ( problem, other_qubit) {
723- return smallvec ! [ closest_node, also_routed] ;
724- }
725- }
726- smallvec ! [ closest_node]
708+ . filter_map ( |q| self . routable_node_on_qubit ( problem, * q) )
709+ . collect ( ) ,
710+ _ => smallvec ! [ closest_node] ,
727711 }
728712 }
729713
@@ -781,8 +765,7 @@ impl State {
781765
782766 if let Some ( DecayHeuristic { .. } ) = problem. heuristic . decay {
783767 for ( swap, score) in self . swap_scores . iter_mut ( ) {
784- * score = ( absolute_score + * score)
785- * self . decay [ swap[ 0 ] . index ( ) ] . max ( self . decay [ swap[ 1 ] . index ( ) ] ) ;
768+ * score = ( absolute_score + * score) * self . decay [ swap[ 0 ] ] . max ( self . decay [ swap[ 1 ] ] ) ;
786769 }
787770 }
788771
@@ -875,14 +858,14 @@ pub fn swap_map_trial<'a>(
875858 let mut order = Order :: for_problem ( problem) ;
876859
877860 let num_qubits: u32 = problem. target . num_qubits ( ) . try_into ( ) . unwrap ( ) ;
878- let mut required_predecessors = vec ! [ 0 ; problem. sabre. dag. node_count( ) ] ;
861+ let mut required_predecessors = VecMap :: from ( vec ! [ 0 ; problem. sabre. dag. node_count( ) ] ) ;
879862 for edge in problem. sabre . dag . edge_references ( ) {
880- required_predecessors[ edge. target ( ) . index ( ) ] += 1 ;
863+ required_predecessors[ edge. target ( ) ] += 1 ;
881864 }
882865 let mut state = State {
883866 front_layer : FrontLayer :: new ( num_qubits) ,
884867 extended_set : ExtendedSet :: new ( num_qubits) ,
885- decay : vec ! [ 1. ; num_qubits as usize ] ,
868+ decay : vec ! [ 1. ; num_qubits as usize ] . into ( ) ,
886869 required_predecessors,
887870 layout : initial_layout. clone ( ) ,
888871 swap_scores : Vec :: with_capacity ( problem. target . neighbors . edge_count ( ) / 2 ) ,
@@ -918,8 +901,8 @@ pub fn swap_map_trial<'a>(
918901 state. decay . fill ( 1. ) ;
919902 num_search_steps = 0 ;
920903 } else {
921- state. decay [ best_swap[ 0 ] . index ( ) ] += increment;
922- state. decay [ best_swap[ 1 ] . index ( ) ] += increment;
904+ state. decay [ best_swap[ 0 ] ] += increment;
905+ state. decay [ best_swap[ 1 ] ] += increment;
923906 }
924907 }
925908 }
0 commit comments