§
    º³Ùg…L  ã                   ó>  — d Z ddlZddlmZ ddlZddlZddlmZmZm	Z	 ddl
mZ ddlmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZmZ ddl m!Z! ddl"m#Z#m$Z$m%Z%m&Z&m'Z' ddl(m)Z)  ej*        e+¦  «        Z, G d„ de¦  «        Z-d„ Z.d„ Z/dS )z@Routing via SWAP insertion using the SABRE method from Li et al.é    N)Údeepcopy)ÚSwitchCaseOpÚClbitÚClassicalRegister)ÚSwapGate)Úcondition_resourcesÚnode_resources)Údag_to_circuit)ÚTransformationPass)ÚCouplingMap)ÚTranspilerError)ÚLayout)ÚTarget)Údisjoint_utils)Ú
DAGCircuitÚ	DAGOpNode)Ú	CPU_COUNT)Úsabre_routingÚ	HeuristicÚ
SetScalingÚNeighborTableÚSabreDAG)ÚNLayoutc                   ó*   ‡ — e Zd ZdZdˆ fd„	Zd„ Zˆ xZS )Ú	SabreSwapa  Map input circuit onto a backend topology via insertion of SWAPs.

    Implementation of the SWAP-based heuristic search from the SABRE qubit
    mapping paper [2] (Algorithm 1) with the modifications from the LightSABRE
    paper [1]. The heuristic aims to minimize the number of lossy SWAPs inserted
    and the depth of the circuit.

    This algorithm starts from an initial layout of virtual qubits onto physical
    qubits, and iterates over the circuit DAG until all gates are exhausted,
    inserting SWAPs along the way. It only considers 2-qubit gates as only those
    are germane for the mapping problem (it is assumed that 3+ qubit gates are
    already decomposed).

    In each iteration, it will first check if there are any gates in the
    ``front_layer`` that can be directly applied. If so, it will apply them and
    remove them from ``front_layer``, and replenish that layer with new gates
    if possible. Otherwise, it will try to search for SWAPs, insert the SWAPs,
    and update the mapping.

    The search for SWAPs is restricted, in the sense that we only consider
    physical qubits in the neighborhood of those qubits involved in
    ``front_layer``. These give rise to a ``swap_candidate_list`` which is
    scored according to some heuristic cost function. The best SWAP is
    implemented and ``current_layout`` updated.

    This transpiler pass adds onto the SABRE algorithm in that it will run
    multiple trials of the algorithm with different seeds. The best output,
    determined by the trial with the least amount of SWAPed inserted, will
    be selected from the random trials.

    **References:**

    [1] Henry Zou and Matthew Treinish and Kevin Hartman and Alexander Ivrii and Jake Lishman.
    "LightSABRE: A Lightweight and Enhanced SABRE Algorithm"
    `arXiv:2409.08368 <https://doi.org/10.48550/arXiv.2409.08368>`__
    [2] Li, Gushu, Yufei Ding, and Yuan Xie. "Tackling the qubit mapping problem
    for NISQ-era quantum devices." ASPLOS 2019.
    `arXiv:1809.02573 <https://arxiv.org/pdf/1809.02573.pdf>`_
    ÚbasicNFc                 óŠ  •— t          ¦   «                              ¦   «          t          |t          ¦  «        r&|| _        | j                             ¦   «         | _        n|| _        d| _        | j        �S| j        j        sGt          |t          ¦  «        rt          | j        ¦  «        | _        | j         
                    ¦   «          d| _        | j        �0t          t          j        | j        j        ¦  «        ¦  «        | _        || _        || _        |€t$          | _        n|| _        || _        d| _        d| _        d| _        dS )a`  SabreSwap initializer.

        Args:
            coupling_map (Union[CouplingMap, Target]): CouplingMap of the target backend.
            heuristic (str): The type of heuristic to use when deciding best
                swap strategy ('basic' or 'lookahead' or 'decay').
            seed (int): random seed used to tie-break among candidate swaps.
            fake_run (bool): if true, it only pretend to do routing, i.e., no
                swap is effectively added.
            trials (int): The number of seed trials to run sabre with. These will
                be run in parallel (unless the PassManager is already running in
                parallel). If not specified this defaults to the number of physical
                CPUs on the local system. For reproducible results it is recommended
                that you set this explicitly, as the output will be deterministic for
                a fixed number of trials.

        Raises:
            TranspilerError: If the specified heuristic is not valid.

        Additional Information:

            The search space of possible SWAPs on physical qubits is explored
            by assigning a score to the layout that would result from each SWAP.
            The goodness of a layout is evaluated based on how viable it makes
            the remaining virtual gates that must be applied. A few heuristic
            cost functions are supported

            - 'basic':

            The sum of distances for corresponding physical qubits of
            interacting virtual qubits in the front_layer.

            .. math::

                H_{basic} = \sum_{gate \in F} D[\pi(gate.q_1)][\pi(gate.q2)]

            - 'lookahead':

            This is the sum of two costs: first is the same as the basic cost.
            Second is the basic cost but now evaluated for the
            extended set as well (i.e. :math:`|E|` number of upcoming successors to gates in
            front_layer F). This is weighted by some amount EXTENDED_SET_WEIGHT (W) to
            signify that upcoming gates are less important that the front_layer.

            .. math::

                H_{decay}=\frac{1}{\left|{F}\right|}\sum_{gate \in F} D[\pi(gate.q_1)][\pi(gate.q2)]
                    + W*\frac{1}{\left|{E}\right|} \sum_{gate \in E} D[\pi(gate.q_1)][\pi(gate.q2)]

            - 'decay':

            This is the same as 'lookahead', but the whole cost is multiplied by a
            decay factor. This increases the cost if the SWAP that generated the
            trial layout was recently used (i.e. it penalizes increase in depth).

            .. math::

                H_{decay} = max(decay(SWAP.q_1), decay(SWAP.q_2)) {
                    \frac{1}{\left|{F}\right|} \sum_{gate \in F} D[\pi(gate.q_1)][\pi(gate.q2)]\\
                    + W *\frac{1}{\left|{E}\right|} \sum_{gate \in E} D[\pi(gate.q_1)][\pi(gate.q2)]
                    }
        N)ÚsuperÚ__init__Ú
isinstancer   ÚtargetÚbuild_coupling_mapÚcoupling_mapÚis_symmetricr   r   Úmake_symmetricÚ_neighbor_tabler   Ú	rustworkxÚadjacency_matrixÚgraphÚ	heuristicÚseedr   ÚtrialsÚfake_runÚ_qubit_indicesÚ_clbit_indicesÚdist_matrix)Úselfr#   r*   r+   r-   r,   Ú	__class__s         €úa/granary/edev/quantum/lib/python3.11/site-packages/qiskit/transpiler/passes/routing/sabre_swap.pyr   zSabreSwap.__init__Q   s1  ø€ õ@ 	‰Œ×ÒÑÔÐõ �l¥FÑ+Ô+ð 	Ø&ˆDŒKØ $¤× >Ò >Ñ @Ô @ˆDÔÐà ,ˆDÔØˆDŒKØÔÐ(°Ô1BÔ1OÐ(õ ˜,­Ñ4Ô4ð @Ý$,¨TÔ->Ñ$?Ô$?�Ô!ØÔ×,Ò,Ñ.Ô.Ð.Ø#ˆÔØÔÐ(Ý#0ÝÔ*¨4Ô+<Ô+BÑCÔCñ$ô $ˆDÔ ð #ˆŒØˆŒ	Øˆ>Ý#ˆDŒKˆKà ˆDŒKà ˆŒØ"ˆÔØ"ˆÔØˆÔÐÐó    c           	      óT  ‡ — ‰ j         €t          d¦  «        ‚t          |j        ¦  «        dk    s|j                             dd¦  «        €t          d¦  «        ‚t          |j        ¦  «        }‰ j                              ¦   «         }||k     rt          d|› d|› d�¦  «        ‚||k    rt          d	|› d
|› d�¦  «        ‚t          ‰ j        t          ¦  «        r	‰ j        }�n!‰ j        dk    r2t          d|z  ¬¦  «         
                    dt          j        ¦  «        }nä‰ j        dk    rQt          d|z  ¬¦  «         
                    dt          j        ¦  «                             ddt          j        ¦  «        }nˆ‰ j        dk    ret          d|z  ¬¦  «         
                    dt          j        ¦  «                             ddt          j        ¦  «                             dd¦  «        }nt          d‰ j        › d�¦  «        ‚t          j        |‰ j        €‰ j         n‰ j        ¦  «         ‰ j         j        ‰ _        |j        d         }t)          j        |¦  «        }d„ t-          |¦  «        D ¦   «         ‰ _        ˆ fd„|                     ¦   «                              ¦   «         D ¦   «         }t5          |t          |j        ¦  «        ‰ j                              ¦   «         ¦  «        }t7          |‰ j                              ¦   «         ‰ j        ¦  «        \  }	}
t9          j        ¦   «         }t=          |	‰ j        ‰ j        ||‰ j         ‰ j!        ¦  «        �^ }}t9          j        ¦   «         }tE          j#        d||z
  ¦  «         t)          tI          tK          |j        |¦  «        ¦  «        ¦  «        }‰ j&        d         €|‰ j&        d<   n.| '                    ‰ j&        d         |j        ¦  «        ‰ j&        d<   ‰ j(        r|S tS          | *                    ¦   «         ||||j        |
¦  «        S )au  Run the SabreSwap pass on `dag`.

        Args:
            dag (DAGCircuit): the directed acyclic graph to be mapped.
        Returns:
            DAGCircuit: A dag mapped to be compatible with the coupling_map.
        Raises:
            TranspilerError: if the coupling map or the layout are not
            compatible with the DAG, or if the coupling_map=None
        Nz+SabreSwap cannot run with coupling_map=Noneé   Úqz*Sabre swap runs on physical circuits only.zFewer qubits in the circuit (z) than the coupling map (zŒ). Have you run a layout pass and then expanded your DAG with ancillas? See `FullAncillaAllocation`, `EnlargeWithAncilla` and `ApplyLayout`.zMore qubits in the circuit (z&) than available in the coupling map (z0). This circuit cannot be routed to this device.r   é
   )Úattempt_limitg      ð?Ú	lookaheadg      à?é   Údecaygü©ñÒMbP?é   z
Heuristic z not recognized.c                 ó   — i | ]\  }}||“Œ	S © r?   )Ú.0ÚidxÚbits      r3   ú
<dictcomp>z!SabreSwap.run.<locals>.<dictcomp>ò   s   € ÐVÐVÐV©H¨C°˜s CÐVÐVÐVr4   c                 ó2   •— i | ]\  }}‰j         |         |“ŒS r?   )r.   )r@   ÚkÚvr1   s      €r3   rC   z!SabreSwap.run.<locals>.<dictcomp>ó   s4   ø€ ð 
ð 
ð 
Ù*.¨!¨QˆDÔ Ô" Að
ð 
ð 
r4   z.Sabre swap algorithm execution complete in: %sÚfinal_layout)+r#   r   ÚlenÚqregsÚgetÚqubitsÚsizer    r*   r   Ú
with_basicr   ÚSizeÚwith_lookaheadÚ
with_decayr   Ú$require_layout_isolated_to_componentr!   Údistance_matrixr0   r   Úgenerate_trivial_layoutÚ	enumerater.   Úget_virtual_bitsÚitemsr   Ú_build_sabre_dagÚtimeÚperf_counterr   r&   r,   r+   ÚloggingÚdebugÚdictÚzipÚproperty_setÚcomposer-   Ú_apply_sabre_resultÚcopy_empty_like)r1   ÚdagÚnum_dag_qubitsÚnum_coupling_qubitsr*   Úcanonical_registerÚcurrent_layoutÚlayout_mappingÚinitial_layoutÚ	sabre_dagÚcircuit_to_dag_dictÚsabre_startÚsabre_resultÚfinal_permutationÚ
sabre_stoprG   s   `               r3   ÚrunzSabreSwap.run³   sU  ø€ ð ÔÐ$Ý!Ð"OÑPÔPÐPåˆsŒy‰>Œ>˜QÒÐ #¤)§-¢-°°TÑ":Ô":Ð"BÝ!Ð"NÑOÔOÐOå˜SœZ™œˆØ"Ô/×4Ò4Ñ6Ô6ÐØÐ/Ò/Ð/Ý!ðX°ð Xð XØ(ðXð Xð Xñô ð ð Ð/Ò/Ð/Ý!ðA¨~ð Að AØ(ðAð Að Añô ð õ �d”n¥iÑ0Ô0ð 	QØœˆI‰IØŒ^˜wÒ&Ð&Ý!°°^Ñ0CÐDÑDÔD×OÒOØ•Z”_ñô ˆIˆIð Œ^˜{Ò*Ð*å¨¨^Ñ(;Ð<Ñ<Ô<ß’˜C¥¤Ñ1Ô1ß’  R­¬Ñ9Ô9ð ˆIð
 Œ^˜wÒ&Ð&å¨¨^Ñ(;Ð<Ñ<Ô<ß’˜C¥¤Ñ1Ô1ß’  R­¬Ñ9Ô9ß’˜E 1Ñ%Ô%ð	 ˆIõ "Ð"O¨t¬~Ð"OÐ"OÐ"OÑPÔPÐPÝÔ;Ø d¤kÐ&9�Ô"Ð"¸t¼{ñ	
ô 	
ð 	
ð  Ô,Ô<ˆÔà œY sœ^ÐÝÔ7Ð8JÑKÔKˆØVÐV½	ÐBTÑ8UÔ8UÐVÑVÔVˆÔð
ð 
ð 
ð 
Ø2@×2QÒ2QÑ2SÔ2S×2YÒ2YÑ2[Ô2[ð
ñ 
ô 
ˆõ ! µ°S´Z±´À$ÔBS×BXÒBXÑBZÔBZÑ[Ô[ˆå)9ØØÔ×"Ò"Ñ$Ô$ØÔñ*
ô *
Ñ&ˆ	Ð&õ
 Ô'Ñ)Ô)ˆÝ+8ØØÔ ØÔØØØŒKØŒIñ,
ô ,
Ñ(ˆÐ(õ Ô&Ñ(Ô(ˆ
ÝŒÐFÈ
ÐU`ÑH`ÑaÔaÐaÝ�d¥3 s¤zÐ3DÑ#EÔ#EÑFÔFÑGÔGˆØÔ˜^Ô,Ð4Ø0<ˆDÔ˜nÑ-Ð-à0<×0DÒ0DØÔ! .Ô1°3´:ñ1ô 1ˆDÔ˜nÑ-ð Œ=ð 	ØˆJÝ"Ø×ÒÑ!Ô!ØØØØŒJØñ
ô 
ð 	
r4   )r   NFN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ro   Ú__classcell__)r2   s   @r3   r   r   (   se   ø€ € € € € ð&ð &ðP` ð ` ð ` ð ` ð ` ð ` ðDf
ð f
ð f
ð f
ð f
ð f
ð f
r4   r   c                 óR   ‡‡‡‡‡— ddl mŠ i Šˆˆˆfd„Šˆˆfd„Š ‰| |¦  «        ‰fS )Nr   )Úcircuit_to_dagc                 ót   •— t          | ¦  «        }|‰v r	‰|         }n ‰| ¦  «        }|‰|<    ‰||¦  «        S ©N)Úid)ÚblockÚblock_qubit_indicesÚblock_idÚ	block_dagrv   rj   Úprocess_dags       €€€r3   Úrecursez!_build_sabre_dag.<locals>.recurse"  sS   ø€ Ý�e‘9”9ˆØÐ*Ð*Ð*Ø+¨HÔ5ˆIˆIà&˜ uÑ-Ô-ˆIØ,5Ð Ñ)Øˆ{˜9Ð&9Ñ:Ô:Ð:r4   c                 ó’  •‡ ‡‡— g }i }‰                       ¦   «         D �]†Št          ‰j        ¦  «        }‰j        �,|                     t          ‰j        ¦  «        j        ¦  «         ‰                     ¦   «         r£t          ‰j	        t          ¦  «        r‰‰j	        j        }t          |t          ¦  «        r|                     |¦  «         nRt          |t          ¦  «        r|                     |¦  «         n'|                     t          |¦  «        j        ¦  «         ˆ fd„|D ¦   «         }‰                     ¦   «         r"ˆˆ	ˆfd„‰j	        j        D ¦   «         |‰j        <   |                     ‰j        ˆfd„‰j        D ¦   «         |‰                     ¦   «         f¦  «         �Œˆt+          ‰‰                      ¦   «         ||¦  «        S )Nc                 óD   •— h | ]}‰                      |¦  «        j        ’ŒS r?   )Úfind_bitÚindex)r@   Úxr}   s     €r3   ú	<setcomp>z8_build_sabre_dag.<locals>.process_dag.<locals>.<setcomp>:  s*   ø€ ÐEÐEÐE°Q�Y×'Ò'¨Ñ*Ô*Ô0ÐEÐEÐEr4   c           
      óp   •— g | ]2} ‰|ˆfd „t          |j        ‰j        ¦  «        D ¦   «         ¦  «        ‘Œ3S )c                 ó(   •— i | ]\  }}|‰|         “ŒS r?   r?   )r@   ÚinnerÚouterÚwire_maps      €r3   rC   zD_build_sabre_dag.<locals>.process_dag.<locals>.<listcomp>.<dictcomp>?  s#   ø€ ÐbÐbÐb±L°E¸5˜ ¨¤ÐbÐbÐbr4   )r]   rK   Úqargs)r@   rz   Únoder   rŠ   s     €€€r3   ú
<listcomp>z9_build_sabre_dag.<locals>.process_dag.<locals>.<listcomp><  sa   ø€ ð .ð .ð .ð
 ð	 �GØØbÐbÐbÐbÅCÈÌÐVZÔV`ÑDaÔDaÐbÑbÔbñô ð.ð .ð .r4   c                 ó    •— g | ]
}‰|         ‘ŒS r?   r?   )r@   r„   rŠ   s     €r3   r�   z9_build_sabre_dag.<locals>.process_dag.<locals>.<listcomp>F  s   ø€ Ð5Ð5Ð5 Q�X˜a”[Ð5Ð5Ð5r4   )Útopological_op_nodesÚsetÚcargsÚ	conditionÚupdater   ÚclbitsÚis_control_flowr    Úopr   r!   r   Úaddr   r	   ÚblocksÚ_node_idÚappendr‹   Úis_directiver   Ú
num_clbits)
r}   rŠ   Údag_listÚnode_blocksÚ
cargs_bitsr!   r‘   rŒ   Únum_physical_qubitsr   s
   ``     @€€r3   r~   z%_build_sabre_dag.<locals>.process_dag+  sç  øøøø€ ØˆØˆØ×2Ò2Ñ4Ô4ð 	ñ 	ˆDÝ˜TœZ™œˆJØŒ~Ð)Ø×!Ò!Õ"5°d´nÑ"EÔ"EÔ"LÑMÔMÐMØ×#Ò#Ñ%Ô%ð E­*°T´W½lÑ*KÔ*Kð EØœœ�Ý˜f¥eÑ,Ô,ð EØ—N’N 6Ñ*Ô*Ð*Ð*Ý Õ(9Ñ:Ô:ð EØ×%Ò% fÑ-Ô-Ð-Ð-à×%Ò%¥n°VÑ&<Ô&<Ô&CÑDÔDÐDØEÐEÐEÐE¸*ÐEÑEÔEˆEØ×#Ò#Ñ%Ô%ð ð.ð .ð .ð .ð .ð .ð
 "&¤¤ð.ñ .ô .�˜DœMÑ*ð �OŠOà”MØ5Ð5Ð5Ð5¨$¬*Ð5Ñ5Ô5ØØ×%Ò%Ñ'Ô'ð	ñô ð ñ õ Ð+¨Y×-AÒ-AÑ-CÔ-CÀXÈ{Ñ[Ô[Ð[r4   )Úqiskit.convertersrv   )rb   r    Úqubit_indicesrv   rj   r~   r   s    ` @@@@r3   rW   rW     sƒ   øøøøø€ Ø0Ð0Ð0Ð0Ð0Ð0ð Ðð;ð ;ð ;ð ;ð ;ð ;ð ;ð \ð  \ð  \ð  \ð  \ð  \ðD ˆ;�s˜MÑ*Ô*Ð,?Ð?Ð?r4   c                 óº   ‡ ‡‡‡‡‡	‡
— t          ¦   «         Š
ˆ fd„Šˆˆ
fd„Šˆˆˆˆˆ	fd„Š	d„ t          |j        ¦  «        D ¦   «         } ‰	‰ ||||¦  «        d         S )aŸ  Apply the ``SabreResult`` to ``out_dag``, mutating it in place.  This function in effect
    performs the :class:`.ApplyLayout` transpiler pass with ``initial_layout`` and the Sabre routing
    simultaneously, though it assumes that ``out_dag`` has already been prepared as containing the
    right physical qubits.

    Mutates ``out_dag`` in place and returns it.  Mutates ``initial_layout`` in place as scratch
    space.

    Args:
        out_dag (DAGCircuit): the physical DAG that the output should be written to.
        in_dag (DAGCircuit): the source of the nodes that are being routed.
        sabre_result (tuple[SwapMap, Sequence[int], NodeBlockResults]): the result object from the
            Rust run of the Sabre routing algorithm.
        initial_layout (NLayout): a Rust-space mapping of virtual indices (i.e. those of the qubits
            in ``in_dag``) to physical ones.
        physical_qubits (list[Qubit]): an indexable sequence of :class:`.circuit.Qubit` objects
            representing the physical qubits of the circuit.  Note that disjoint-coupling
            handling can mean that these are not strictly a "canonical physical register" in order.
        circuit_to_dag_dict (Mapping[int, DAGCircuit]): a mapping of the Python object identity
            (as returned by :func:`id`) of a control-flow block :class:`.QuantumCircuit` to a
            :class:`.DAGCircuit` that represents the same thing.
    c                 óD  •— t          ¦   «         }|                     ‰j        ¦  «         ‰j                             ¦   «         D ]}|                     |¦  «         Œ|                     | j        ¦  «         | j        D ]}| 	                    |¦  «         Œ| j
        |_
        |S rx   )r   Ú
add_qubitsrK   rI   ÚvaluesÚadd_qregÚ
add_clbitsr”   ÚcregsÚadd_cregÚglobal_phase)rz   ÚemptyÚqregÚcregÚout_dags       €r3   Ú	empty_dagz&_apply_sabre_result.<locals>.empty_dags  s    ø€ Ý‘”ˆØ×Ò˜œÑ(Ô(Ð(Ø”M×(Ò(Ñ*Ô*ð 	!ð 	!ˆDØ�NŠN˜4Ñ Ô Ð Ð Ø×Ò˜œÑ&Ô&Ð&Ø”Kð 	!ð 	!ˆDØ�NŠN˜4Ñ Ô Ð Ð Ø"Ô/ˆÔØˆr4   c                 ó–   •— |D ]D\  }}‰|         ‰|         f}|                      ||¦  «         |                      ‰|dd¬¦  «         ŒEd S )Nr?   F©Úcheck)Úswap_physicalÚapply_operation_back)Údest_dagÚswapsÚlayoutÚaÚbrK   Úphysical_qubitsÚswap_singletons         €€r3   Úapply_swapsz(_apply_sabre_result.<locals>.apply_swaps~  sn   ø€ Øð 	Sð 	S‰DˆAˆqØ% aÔ(¨/¸!Ô*<Ð=ˆFØ× Ò   AÑ&Ô&Ð&Ø×)Ò)¨.¸&À"ÈEÐ)ÑRÔRÐRÐRð	Sð 	Sr4   c           
      ó’  •‡‡— |\  }}}|D �]7}|                      |¦  «        }	||v r ‰| ||         ‰¦  «         |	                     ¦   «         seˆˆˆfd„|	j        D ¦   «         }
|                      t	          j        |	                     ¦   «                              |
¬¦  «        ¦  «        d¬¦  «         Œ¨||         }g }t          | j	        ¦  «        }t          |	j        j        |¦  «        D ]Ú\  }}ˆfd„t          |j	        |	j        ¦  «        D ¦   «         } ‰ ‰|¦  «        ‰t          |¦  «                 |j        j        |j        j        |j        j        f|‰                     ¦   «         ¦  «        \  }} ‰||j        |¦  «         |                     |¦  «         |                     |                     ¦   «         ¦  «         ŒÛg }|D ].} |j        |Ž  |                     t1          |¦  «        ¦  «         Œ/|	j                             |¦  «        }|r|d         j	        nd}|                      |||	j        d¬¦  «         �Œ9| ‰fS )zûThe main recursive worker.  Mutates ``dest_dag`` and ``layout`` and returns them.

        ``root_virtual_map`` is a mapping of the (virtual) qubit in ``source_dag`` to the index of
        the virtual qubit in the root source DAG that it is bound to.c                 óR   •— g | ]#}‰‰                      ‰|         ¦  «                 ‘Œ$S r?   )Úvirtual_to_physical)r@   r7   r¸   r»   Úroot_logical_maps     €€€r3   r�   z8_apply_sabre_result.<locals>.recurse.<locals>.<listcomp>�  sC   ø€ ð ð ð àð $ F×$>Ò$>Ð?OÐPQÔ?RÑ$SÔ$SÔTðð ð r4   )rK   Fr²   c                 ó(   •— i | ]\  }}|‰|         “ŒS r?   r?   )r@   rˆ   r‰   rÁ   s      €r3   rC   z8_apply_sabre_result.<locals>.recurse.<locals>.<dictcomp>   s2   ø€ ð *ð *ð *Ù7C°u¸e�EÐ+¨EÔ2ð*ð *ð *r4   r   r?   )rŒ   r•   r‹   Ú_apply_op_node_backr   Úfrom_instructionÚ_to_circuit_instructionÚreplacer�   rK   r]   r–   r˜   ry   ÚresultÚmapÚ
node_orderÚnode_block_resultsÚcopyÚswap_epiloguerš   Úintersection_updateÚ
idle_wiresÚremove_qubitsr
   Úreplace_blocksrµ   r‘   )r¶   Ú
source_dagrÇ   rÁ   r¸   Úswap_maprÉ   rÊ   Únode_idrŒ   rK   Úblock_resultsÚmapped_block_dagsÚidle_qubitsrz   Úblock_resultÚblock_root_logical_mapr}   Úblock_layoutÚmapped_blocksÚmapped_block_dagÚmapped_nodeÚmapped_node_qargsr½   rj   r°   r»   r   s      ``                  €€€€€r3   r   z$_apply_sabre_result.<locals>.recurse„  sÒ  øøø€ ð
 4:Ñ0ˆ�*Ð0Ø!ð 1	cñ 1	cˆGØ—?’? 7Ñ+Ô+ˆDØ˜(Ð"Ð"Ø�˜H h¨wÔ&7¸Ñ@Ô@Ð@Ø×'Ò'Ñ)Ô)ð ðð ð ð ð ð à!œZðñ ô �ð ×,Ò,ÝÔ.Ø×4Ò4Ñ6Ô6×>Ò>ÀfÐ>ÑMÔMñô ð  ð	 -ñ ô ð ð ð /¨wÔ7ˆMØ "ÐÝ˜hœoÑ.Ô.ˆKÝ'*¨4¬7¬>¸=Ñ'IÔ'Ið Hð HÑ#��|ð*ð *ð *ð *ÝGJÈ5Ì<ÐY]ÔYcÑGdÔGdð*ñ *ô *Ð&ð +2¨'Ø�I˜eÑ$Ô$Ø'­¨5©	¬	Ô2à$Ô+Ô/Ø$Ô+Ô6Ø$Ô+Ô>ðð
 +Ø—K’K‘M”Mñ
+ô 
+Ñ'�	˜<ð �˜I |Ô'AÀ<ÑPÔPÐPØ!×(Ò(¨Ñ3Ô3Ð3Ø×/Ò/°	×0DÒ0DÑ0FÔ0FÑGÔGÐGÐGàˆMØ$5ð Gð GÐ à.Ð Ô.°Ð<Ð<Ø×$Ò$¥^Ð4DÑ%EÔ%EÑFÔFÐFÐFð œ'×0Ò0°Ñ?Ô?ˆKØ;HÐ P ¨aÔ 0Ô 7Ð 7ÈbÐØ×)Ò)¨+Ð7HÈ$Ì*Ð\aÐ)ÑbÔbÐbÑbØ˜ÐÐr4   c                 ó   — i | ]\  }}||“Œ	S r?   r?   )r@   rƒ   rB   s      r3   rC   z'_apply_sabre_result.<locals>.<dictcomp>¾  s   € ÐNÐNÐN¡z u¨c˜˜UÐNÐNÐNr4   r   )r   rT   rK   )r¯   Úin_dagrl   rh   r»   rj   rÁ   r½   r°   r   r¼   s   `   `` @@@@r3   r`   r`   P  sÀ   øøøøøøø€ õB ‘Z”Z€Nð	ð 	ð 	ð 	ð 	ðSð Sð Sð Sð Sð Sð8 ð 8 ð 8 ð 8 ð 8 ð 8 ð 8 ð 8 ð 8 ðt OÐNµY¸v¼}Ñ5MÔ5MÐNÑNÔNÐØˆ7�7˜F LÐ2BÀNÑSÔSÐTUÔVÐVr4   )0rs   rZ   rË   r   rX   r'   Úqiskit.circuitr   r   r   Ú%qiskit.circuit.library.standard_gatesr   Úqiskit.circuit.controlflowr   r	   r¡   r
   Úqiskit.transpiler.basepassesr   Úqiskit.transpiler.couplingr   Úqiskit.transpiler.exceptionsr   Úqiskit.transpiler.layoutr   Úqiskit.transpiler.targetr   Úqiskit.transpiler.passes.layoutr   Úqiskit.dagcircuitr   r   Úqiskit.utils.parallelr   Úqiskit._accelerate.sabrer   r   r   r   r   Úqiskit._accelerate.nlayoutr   Ú	getLoggerrp   Úloggerr   rW   r`   r?   r4   r3   ú<module>rï      sæ  ðð GÐ Fà €€€Ø Ð Ð Ð Ð Ð Ø €€€à Ð Ð Ð à AÐ AÐ AÐ AÐ AÐ AÐ AÐ AÐ AÐ AØ :Ð :Ð :Ð :Ð :Ð :Ø JÐ JÐ JÐ JÐ JÐ JÐ JÐ JØ ,Ð ,Ð ,Ð ,Ð ,Ð ,Ø ;Ð ;Ð ;Ð ;Ð ;Ð ;Ø 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø 8Ð 8Ð 8Ð 8Ð 8Ð 8Ø +Ð +Ð +Ð +Ð +Ð +Ø +Ð +Ð +Ð +Ð +Ð +Ø :Ð :Ð :Ð :Ð :Ð :Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø +Ð +Ð +Ð +Ð +Ð +à bÐ bÐ bÐ bÐ bÐ bÐ bÐ bÐ bÐ bÐ bÐ bÐ bÐ bØ .Ð .Ð .Ð .Ð .Ð .à	ˆÔ	˜8Ñ	$Ô	$€ðq
ð q
ð q
ð q
ð q
Ð"ñ q
ô q
ð q
ðh1@ð 1@ð 1@ðhoWð oWð oWð oWð oWr4   