
    z	i~4                         S r SSKJr  SSKrSSKrSSKrSSKJr  SSKJ	r	  SSK
Jr  SSKJr  SSKJr  SS	KJrJr  \R&                  " \5      r " S
 S\5      r " S S\5      rg)z:VF2Layout pass to find a layout using subgraph isomorphism    )EnumN)vf2_mapping)Layout)AnalysisPass)TranspilerError)	vf2_utils)vf2_layout_passMultiQEncounteredc                   $    \ rS rSrSrSrSrSrSrg)VF2LayoutStopReason    z Stop reasons for VF2Layout pass.zsolution foundznonexistent solutionz>2q gates in basis N)	__name__
__module____qualname____firstlineno____doc__SOLUTION_FOUNDNO_SOLUTION_FOUNDMORE_THAN_2Q__static_attributes__r       d/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/transpiler/passes/layout/vf2_layout.pyr   r       s    *%N.'Lr   r   c                   D   ^  \ rS rSrSr       SU 4S jjrS rSrU =r$ )	VF2Layout(   a  A pass for choosing a Layout of a circuit onto a Coupling graph, as
a subgraph isomorphism problem, solved by VF2++.

If a solution is found that means there is a "perfect layout" and that no
further swap mapping or routing is needed. If a solution is found the layout
will be set in the property set as ``property_set['layout']``. However, if no
solution is found, no ``property_set['layout']`` is set. The stopping reason is
set in ``property_set['VF2Layout_stop_reason']`` in all the cases and will be
one of the values enumerated in ``VF2LayoutStopReason`` which has the
following values:

    * ``"solution found"``: If a perfect layout was found.
    * ``"nonexistent solution"``: If no perfect layout was found.
    * ``">2q gates in basis"``: If VF2Layout can't work with basis

By default, this pass will construct a heuristic scoring map based on
the error rates in the provided ``target`` (or ``properties`` if ``target``
is not provided). However, analysis passes can be run prior to this pass
and set ``vf2_avg_error_map`` in the property set with a :class:`~.ErrorMap`
instance. If a value is ``NaN`` that is treated as an ideal edge
For example if an error map is created as::

    from qiskit.transpiler.passes.layout.vf2_utils import ErrorMap

    error_map = ErrorMap(3)
    error_map.add_error((0, 0), 0.0024)
    error_map.add_error((0, 1), 0.01)
    error_map.add_error((1, 1), 0.0032)

that represents the error map for a 2 qubit target, where the avg 1q error
rate is ``0.0024`` on qubit 0 and ``0.0032`` on qubit 1. Then the avg 2q
error rate for gates that operate on (0, 1) is 0.01 and (1, 0) is not
supported by the target. This will be used for scoring if it's set as the
``vf2_avg_error_map`` key in the property set when :class:`~.VF2Layout` is run.
c                    > [         TU ]  5         Xpl        Xl        X l        X0l        X@l        XPl        X`l        SU l	        g)a3  Initialize a ``VF2Layout`` pass instance

Args:
    coupling_map (CouplingMap): Directed graph representing a coupling map.
    strict_direction (bool): If True, considers the direction of the coupling map.
                             Default is False.
    seed (int): Sets the seed of the PRNG. -1 Means no node shuffling.
    call_limit (int): The number of state visits to attempt in each execution of
        VF2.
    time_limit (float): The total time limit in seconds to run ``VF2Layout``
    max_trials (int): The maximum number of trials to run VF2 to find
        a layout. If this is not specified the number of trials will be limited
        based on the number of edges in the interaction graph or the coupling graph
        (whichever is larger) if no other limits are set. If set to a value <= 0 no
        limit on the number of trials will be set.
    target (Target): A target representing the backend device to run ``VF2Layout`` on.
        If specified it will supersede a set value for
        ``coupling_map`` if the :class:`.Target` contains connectivity constraints. If the value
        of ``target`` models an ideal backend without any constraints then the value of
        ``coupling_map``
        will be used.

Raises:
    TypeError: At runtime, if neither ``coupling_map`` or ``target`` are provided.
N)
super__init__targetcoupling_mapstrict_directionseed
call_limit
time_limit
max_trialsavg_error_map)	selfr!   r"   r#   r$   r%   r&   r    	__class__s	           r   r   VF2Layout.__init__M   s>    F 	( 0	$$$!r   c                 z  ^" U R                   c  U R                  c  [        S5      eU R                  c&  U R                   U R                   R                  5       p2OU R                   c#  U R                  n[        R
                  " U5      nOVU R                   R                  5       nUc-  [        R
                  " U R                  5      nU R                  nOU R                   nU R                  S   U l        U R                  S:X  Ga#   [        UUU R                  U R                  U R                  U R                  U R                  5      nUc  [        R"                  U R                  S'   g[        R$                  U R                  S'   UR'                  5        VVs0 s H  u  pVUR(                  U   U_M     nnn[+        U5      n[        R,                  " XU5      U R                  S'   UR.                  R1                  5        H!  n	U R                  S   R3                  U	5        M#     gU R                  c  [        R4                  " X#5      U l        [        R6                  " XR                  5      n
U
c  [        R                   U R                  S'   gU
u  pm"n[        R8                  " U5      n[        R:                  " X5      n[        R<                  " X0R                  U R                  5      u  nnUb  UR>                  b  [A        [B        RD                  RG                  UR>                  5      5      n[A        [I        [K        U5      5      5      RM                  U5      nU(       a%  URO                  U Vs/ s H  nUU   PM
     sn5        U R                  cj  U R                  c]  U R                  cP  [K        URQ                  5       5      n[K        URR                  RQ                  5       5      n[U        UU5      S-   U l        [V        RY                  S5        [[        UUS	S
S
U R                  S9nSnSn[\        R\                  " 5       nSnU"4S jnU GH  nUS-  n[V        RY                  SU5        [        R$                  nUR'                  5        VVs0 s H  u  nnUUU   _M     nnn[K        U5      [K        U5      :X  a  U" U5      n  GOXU R                  c  U" U5      n  GO@[        R^                  " U R                  UUT"UU R                  UUS9n U S:X  a  U" U5      n  GO [V        RY                  SUU 5        Uc  U" U5      nU nO+U U:  a%  U" U5      n[V        RY                  SUU UU5        UnU nU R                  bC  U R                  S:  a3  UU R                  :  a#  [V        RY                  SUU R                  5          O`[\        R\                  " 5       U-
  n!U R                  c  GM  U!U R                  :  d  GM  [V        RY                  SU!U R                  5          O   Uc  [        R"                  nO[        R`                  " UUURc                  5       T"U R                  5      nUc  [        R"                  U R                  S'   g[        R,                  " XU5      U R                  S'   UR.                  R1                  5        H!  n	U R                  S   R3                  U	5        M#     WU R                  S'   g! [         a     [        R                   U R                  S'    gf = fs  snnf s  snf s  snnf )zrun the layout methodNz)coupling_map or target must be specified.vf2_avg_error_mapVF2Layout_stop_reasonlayout   zRunning VF2 to find mappingsTF)subgraphid_orderinducedr$   r   c                 t   > [        U R                  5        VVs0 s H  u  pTU   U_M     snn5      $ s  snnf )N)r   items)layout_mappingkvreverse_im_graph_node_maps      r   mapping_to_layout(VF2Layout.run.<locals>.mapping_to_layout   s8    ~G[G[G]^G]tq4Q7:G]^__^s   4
   zRunning trial: %s)	edge_listbit_listg        zTrial %s has score %szAFound layout %s has a lower score (%s) than previous best %s (%s)z'Trial %s is >= configured max trials %sz<VF2Layout has taken %s which exceeds configured max time: %s)2r    r!   r   build_coupling_mapr   build_dummy_targetproperty_setr'   r#   r	   r"   r$   r%   r&   r
   r   r   r   r   r5   qubitsr   allocate_idle_qubitsqregsvaluesadd_registerbuild_average_error_mapbuild_interaction_graphbuild_edge_listbuild_bit_listshuffle_coupling_graphqargsset	itertoolschainfrom_iterablerangelen
differenceremove_nodes_fromr=   graphmaxloggerdebugr   timescore_layoutmap_free_qubits	num_nodes)#r(   dagr    r!   r/   virtphysmappingchosen_layoutregresultim_graphim_graph_node_map
free_nodesscoring_edge_listscoring_bit_listcm_graphcm_nodeshas_operations	to_removeiim_graph_edge_countcm_graph_edge_countmappingschosen_layout_score
start_timetrialsr:   stop_reasoncm_iim_ir6   layout_scoreelapsed_timer9   s#                                     @r   runVF2Layout.runz   sU   ;;4#4#4#<!"MNN$#';;0N0N0PL[[ ,,L11,?F  ;;99;L#"55d6G6GH#00!../BC99?())OOOOOO&& ~=P=b=b!!"9:9L9[9[D56@FO*$szz$'-GO"7OM*3*H*HVc*dDh'yy'')!!(+88= * %!*!B!B6!XD2238M8MN>9L9Y9YD56MSJ%>
%55h?$33HP&==))T%:%:
(
 &,,": !>!>v||!LMNE#h-01<<^LI**+KAHQK+KL ??"t'>4??CZ"%h&8&8&:";"%l&8&8&B&B&D"E!"57JKbPDO34
 "YY[
	`  GaKFLL,f5-<<KEL]]_U_ztTdHTN2_NU
 8}H- 1. A !!) 1. A$11""!)%%+)	L s" 1. ALL0&,G$ 1. A&2# 33*>:W !' !'&2#*t/BvQUQ`Q`G`FPTP_P_`99;3L*|t/NR OO
 u  v  -??K%55""$)""M $=P=b=b!!"9:*3*H*HVc*dDh'yy'')!!(+88= * 6A12[ % =P=]=]!!"9: P8 ,L@ Vs%   A[? \,5\2\7?'\)(\))r'   r$   r!   r&   r#   r"   r    r%   )NFNNNNN)	r   r   r   r   r   r   ry   r   __classcell__)r)   s   @r   r   r   (   s4    "L +"ZkA kAr   r   )r   enumr   rN   loggingrY   	rustworkxr   qiskit.transpiler.layoutr   qiskit.transpiler.basepassesr   qiskit.transpiler.exceptionsr   qiskit.transpiler.passes.layoutr   qiskit._accelerate.vf2_layoutr	   r
   	getLoggerr   rW   r   r   r   r   r   <module>r      sW    A     ! + 5 8 5 L 
		8	$($ (}A }Ar   