
    z	i7J                        S 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  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  SSKJr  SSKJr  SSKJr  SS jr " S S\5      rSS jr SS jr!SS jr"SS jr#g)z#
Unitary Synthesis Transpiler Pass
    )annotations)Any)CONTROL_FLOW_OP_NAMES)CircuitInstruction)circuit_to_dagdag_to_circuit)
DAGCircuit)	DAGOpNode)one_qubit_decompose)TransformationPass)CouplingMap)TranspilerError)plugin)Target)run_main_loopNc                    U c  [        5       nO[        U 5      nUc  [        R                  n/ nUR                  5        H7  u  pE[        U5      R	                  U5      (       d  M&  UR                  U5        M9     U$ )zQFind the matching basis string keys from the list of basis gates from the target.)setr   ONE_QUBIT_EULER_BASIS_GATESitemsissubsetappend)basis_gates
basis_dict	basis_set	out_basisbasisgatess         n/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/transpiler/passes/synthesis/unitary_synthesis.py_choose_basesr   $   so    E	$	(DD
I"((*u:y))U# +     c                  ~   ^  \ rS rSrSr          S                   SU 4S jjjrS	S jrS rSrU =r	$ )
UnitarySynthesis6   z0Synthesize gates according to their basis gates.c                  > [         TU ]  5         [        U=(       d    S5      U l        X l        Xl        Xpl        SU l        US:w  a  [        R                  " 5       U l        X0l
        X@l        XPl        Xl        U
b  [        U
R                  5      S:  a  U
OSU l        U
b  U
R#                  5       U l
        U(       a  X`l        OU(       a
  SS/U l        OS/U l        [        U R$                  5      U R                  -
  U l        U R                  S:w  a>  U R                  U R                  R&                  ;  a  [)        SU R                   S35      egg)	a  Synthesize unitaries over some basis gates.

This pass can approximate 2-qubit unitaries given some
gate fidelities (via ``target``).
More approximation can be forced by setting a heuristic dial
``approximation_degree``.

Args:
    basis_gates (list[str]): List of gate names to target. If this is
        not specified the ``target`` argument must be used. If both this
        and the ``target`` are specified the value of ``target`` will
        be used and this will be ignored.
    approximation_degree (float): heuristic dial used for circuit approximation
        (1.0=no approximation, 0.0=maximal approximation). Approximation can
        make the synthesized circuit cheaper at the cost of straying from
        the original unitary. If None, approximation is done based on gate fidelities.
    coupling_map (CouplingMap): the coupling map of the target
        in case synthesis is done on a physical circuit. The
        directionality of the coupling_map will be taken into
        account if ``pulse_optimize`` is ``True``/``None`` and ``natural_direction``
        is ``True``/``None``.
    pulse_optimize (bool): Whether to optimize pulses during
        synthesis. A value of ``None`` will attempt it but fall
        back if it does not succeed. A value of ``True`` will raise
        an error if pulse-optimized synthesis does not succeed.
    natural_direction (bool): Whether to apply synthesis considering
        directionality of 2-qubit gates. Only applies when
        ``pulse_optimize`` is ``True`` or ``None``. The natural direction is
        determined by first checking to see whether the
        coupling map is unidirectional.  If there is no
        coupling map or the coupling map is bidirectional,
        the gate direction with the shorter
        duration from the target properties will be used. If
        set to True, and a natural direction can not be
        determined, raises :class:`.TranspilerError`. If set to None, no
        exception will be raised if a natural direction can
        not be determined.
    synth_gates (list[str]): List of gates to synthesize. If None and
        ``pulse_optimize`` is False or None, default to
        ``['unitary']``. If ``None`` and ``pulse_optimize == True``,
        default to ``['unitary', 'swap']``
    method (str): The unitary synthesis method plugin to use.
    min_qubits: The minimum number of qubits in the unitary to synthesize. If this is set
        and the unitary is less than the specified number of qubits it will not be
        synthesized.
    plugin_config: Optional extra configuration arguments (as a ``dict``)
        which are passed directly to the specified unitary synthesis
        plugin. By default, this will have no effect as the default
        plugin has no extra arguments. Refer to the documentation of
        your unitary synthesis plugin on how to use this.
    target: The optional :class:`~.Target` for the target device the pass
        is compiling for. If specified this will supersede the values
        set for ``basis_gates`` and ``coupling_map``.

Raises:
    TranspilerError: if ``method`` was specified but is not found in the
        installed plugins list. The list of installed plugins can be queried with
        :func:`~qiskit.transpiler.passes.synthesis.plugin.unitary_synthesis_plugin_names`
 Ndefaultr   unitaryswapzSpecified method 'z' not found in plugin list)super__init__r   _basis_gates_approximation_degree_min_qubitsmethodpluginsr   UnitarySynthesisPluginManager_coupling_map_pulse_optimize_natural_direction_plugin_configlenoperation_names_targetbuild_coupling_map_synth_gatesext_pluginsr   )selfr   approximation_degreecoupling_mappulse_optimizenatural_directionsynth_gatesr.   
min_qubitsplugin_configtarget	__class__s              r   r*   UnitarySynthesis.__init__9   s+   P 	 1r2%9"%Y!??ADL)-"3+ "(!3F<R<R8SVW8Wv]a!'!:!:!<D +%.$7!%.K! 1 12T5F5FF;;)#4<<;S;S(S!$6t{{mC]"^__ )T#r    c                ~   [        U R                  5      R                  UR                  5       5      (       d  U$ U R                  (       a.  U R                  R
                  U R                     R                  nOSSKJ	n  U" 5       nSU R                  0nS=pVS=pxU R                  S:X  a	  Un	Un
X$4/nO+U R                  R
                  S   R                  n	0 n
X$4X4/nU R                  U	l        U R                  S:X  a  U R                  Ul        UR                  (       d  U	R                  (       a*  [        UR                  5       VVs0 s H  u  pX_M	     snnO0 nU R                  S:X  a  U R                  b#  [        U R                  R!                  5       5      O	[        5       n[#        U[%        UR'                  5       5      U R(                  U R*                  U R,                  U R                  UU R                  U R.                  U R0                  5
      nU$ U GH  u  nnUR2                  (       a  U R,                  US'   UR4                  (       a  U R.                  US'   UR6                  (       a  U R0                  US'   UR8                  (       a#  U=(       d    [;        U R*                  5      nUUS	'   UR<                  (       a#  U=(       d    [?        U R*                  5      nUUS
'   UR@                  (       a#  U=(       d    [C        U R*                  5      nUUS'   URD                  (       a#  U=(       d    [G        U R*                  5      nUUS'   URH                  nUb  [K        U R,                  U5      US'   URL                  (       d  GMs  U R*                  US'   GM     U RO                  XX$X5      nU$ s  snnf )zRun the UnitarySynthesis pass on ``dag``.

Args:
    dag: input dag.

Returns:
    Output dag with UnitaryGates synthesized to target basis.
r   )DefaultUnitarySynthesisconfigNr&   r   r?   r>   gate_lengthsgate_errorsgate_lengths_by_qubitgate_errors_by_qubitmatched_basisrC   )(r   r9   intersection	count_opsr/   r:   r.   obj?qiskit.transpiler.passes.synthesis.default_unitary_synth_pluginrG   r4   r,   supports_coupling_map	enumeratequbitsr1   	get_edgesr   listvaluesr-   r7   r+   r3   r2   supports_basis_gatessupports_natural_directionsupports_pulse_optimizesupports_gate_lengths_build_gate_lengthssupports_gate_errors_build_gate_errorssupports_gate_lengths_by_qubit_build_gate_lengths_by_qubitsupports_gate_errors_by_qubit_build_gate_errors_by_qubitsupported_basesr   supports_target_run_main_loop)r;   dagplugin_methodrG   plugin_kwargs_gate_lengths_gate_errors_gate_lengths_by_qubit_gate_errors_by_qubitdefault_methoddefault_kwargsmethod_listibitqubit_indices_coupling_edgesoutr.   kwargsrc   s                       r   runUnitarySynthesis.run   sS    4$$%223==?CCJ<< LL44T[[AEEM 45M)143F3F(G'++9==;;)#
 +N*N)9:K "\\55i@DDNN)9N;[\K 04/I/I,;;)#262L2LM/ 22n6Z6Z #,CJJ"78"7SV"78 	 ;;)#7;7I7I7UD&&0023[^[`   ]))+,  !!!!**''$$C J"-..,0,=,=F=)44262I2IF./11/3/C/CF+,//$1$V5H5VM-:F>*..#/#S3Edll3SL,8F=)88-C .GcH* 7MF2377,A -E`F) 6KF12"("8"8"..;D<M<M._F?+)))'+||F8$7 #.: %%M.C Jo 9s   
N9c                  ^^ UR                  5        H  nUR                  [        ;  a  M  UR                  R	                  UR                  R
                   VV	V
s/ s H`  n[        U R                  [        U5      [        UR                  UR                  5       V	V
s0 s H
  u  pXU
   _M     sn
n	UUUU5      SS9PMb     sn
n	n5      nUR                  X{5        M     UR                  5       nUR                  5        GH  nUR                  U R                  ;   Ga  [!        UR                  5      U R"                  :  Ga]  SnUR$                  n[!        UR                  5      nUR&                  b  XR&                  :  d  UR(                  b  XR(                  :  a  XVnnOX4nnUR*                  (       a/  U R,                  UR                   Vs/ s H  nUU   PM
     sn4US'   UR.                  " U40 UD6nUc  UR1                  U5        GM  [3        U[4        5      (       a  [7        [        UR                  UR                  5      5      mUR                  5        H8  n[9        U4S jUR                   5       5      Ul        UR1                  U5        M:     U=R:                  UR:                  -  sl        GM  Uu  nnnUR                  m[=        U5      nU H  u  nnnUcP  [<        R>                  " URA                  5       RC                  URD                  [9        U4S jU 5       5      S95      nO?[<        R>                  " [F        RH                  " U[9        U4S jU 5       5      U5      5      nUR1                  U5        M     U=R:                  U-  sl        GM  UR1                  U5        GM     U$ s  sn
n	f s  sn
n	nf s  snf )	zRInner loop for the optimizer, after all DAG-independent set-up has been completed.F)copy_operationsNr=   c              3  .   >#    U  H
  nTU   v   M     g 7fNr%   ).0x	qubit_maps     r   	<genexpr>2UnitarySynthesis._run_main_loop.<locals>.<genexpr>@  s     *LA9Q<   c              3  .   >#    U  H
  nTU   v   M     g 7fr{   r%   r|   r}   rT   s     r   r   r   P  s     0JEqEr   )paramsrT   c              3  .   >#    U  H
  nTU   v   M     g 7fr{   r%   r   s     r   r   r   V  s     /I5aq	5r   )%op_nodesnamer   opreplace_blocksblocksr   re   r   ziprT   qargssubstitute_nodecopy_empty_liketopological_op_nodesr9   r5   r-   matrix
max_qubitsrA   rR   r1   rv   _apply_op_node_back
isinstancer	   dicttupleglobal_phaser
   from_instruction_to_circuit_instructionreplacer   r   from_standard)r;   rf   rr   rg   rh   rm   rn   nodeblockinnerouternew_opout_dag	synth_dagr'   n_qubitsr.   ru   r}   	node_listr   gateuser_gate_noder   r   r~   rT   s                            @@r   re   UnitarySynthesis._run_main_loop  sY    LLNDyy 55WW++  "& "0 #++*51 58djj4Q4QLE !&U'; ;4Q *)**
 ). "0F& -- #0 %%',,.DyyD---#djj/TEUEU2U 	++tzz?!,,8XH`H`=`#..:xJbJb?b%3FFF%2FF//**37::>:aq):>.F>* #JJw9&9	$//5i44 $S)9)94::%F GI ) > > @%**L*L%L
33D9 !A ((I,B,BB((4=1I|T!ZZF%.t_N
 #	<#,#=#= . F F H P P+9+@+@+00JE0J+J !Q !"$D $-#=#= 2 @ @$(%/I5/I*I6!"$D
  33D9 # ((L8((++D1g /h K	F ?s   AN>N8 /N>O8N>)r,   r+   r1   r-   r3   r4   r2   r9   r7   r.   r/   )
Ng      ?NNNNr&   r   NN)r   z	list[str]r<   zfloat | Noner=   r   r>   bool | Noner?   r   r@   zlist[str] | Noner.   strrA   intrB   r   rC   r   )rf   r	   returnr	   )
__name__
__module____qualname____firstlineno____doc__r*   rv   re   __static_attributes____classcell__)rD   s   @r   r"   r"   6   s    : "&-0$(&*)-(,"d`d` +d` "	d`
 $d` 'd` &d` d` d` d` d` d`LkZQ Qr    r"   c                    0 nU b[  U R                  5        HG  u  p#0 X'   UR                  5        H*  u  pEUc  M
  UR                  c  M  UR                  X   U'   M,     MI     U$ )zBuilds a ``gate_lengths`` dictionary from ``target`` (BackendV2).

The dictionary has the form:
{gate_name: {(qubits,): duration}}
)r   duration)rC   rI   r   	prop_dictqubit
gate_propss         r   r\   r\   `  si     L%||~OD!#L%.__%6!)j.A.A.M0:0C0CL&u- &7  .
 r    c                    0 nU b[  U R                  5        HG  u  p#0 X'   UR                  5        H*  u  pEUc  M
  UR                  c  M  UR                  X   U'   M,     MI     U$ )zBuilds a ``gate_error`` dictionary from ``target`` (BackendV2).

The dictionary has the form:
{gate_name: {(qubits,): error_rate}}
)r   error)rC   rJ   r   r   r   r   s         r   r^   r^   p  si     K%||~OD "K%.__%6!)j.>.>.J/9/?/?K%e, &7  .
 r    c                8   0 nU b  U R                   b  U R                    Hw  nU R                  U5      n/ nU HN  nU R                  U5      n[        X   R	                  US5      SS5      nU(       d  M<  UR                  Xg45        MP     U(       d  Ms  XAU'   My     U$ )zz
Builds a `gate_lengths` dictionary from `target (BackendV2)`.

The dictionary has the form:
{(qubits): [Gate, duration]}
Nr   r   operation_names_for_qargsoperation_from_namegetattrgetr   )rC   rI   rT   namesoperation_and_durationsr   	operationr   s           r   r`   r`     s     Lfll6llF44V<E&(#"66t<	"6<#3#3FD#A:tT8+22I3HI	 
 '&'>V$ # r    c                8   0 nU b  U R                   b  U R                    Hw  nU R                  U5      n/ nU HN  nU R                  U5      n[        X   R	                  US5      SS5      nU(       d  M<  UR                  Xg45        MP     U(       d  Ms  XAU'   My     U$ )zu
Builds a `gate_error` dictionary from `target (BackendV2)`.

The dictionary has the form:
{(qubits): [Gate, error]}
Nr   r   )rC   rJ   rT   r   operation_and_errorsr   r   r   s           r   rb   rb     s     Kfll6llF44V<E#% "66t<	 0 0 >N5(//0BC	 
 $#&:F# # r    r{   )$r   
__future__r   typingr   qiskit.circuit.controlflowr   qiskit.circuitr   qiskit.convertersr   r   qiskit.dagcircuit.dagcircuitr	   qiskit.dagcircuit.dagnoder
   qiskit.synthesis.one_qubitr   qiskit.transpiler.basepassesr   qiskit.transpiler.couplingr   qiskit.transpiler.exceptionsr   "qiskit.transpiler.passes.synthesisr   qiskit.transpiler.targetr   $qiskit._accelerate.unitary_synthesisr   r   r"   r\   r^   r`   rb   r%   r    r   <module>r      s_    #  < - < 3 / : ; 2 8 5 + >$g) gT	  ,r    