
    z	i-                        S r SSKJr  SSKJr  SSKrSSKJrJr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  \R.                  " \5      r " S S\5      rg)z$Padding pass to fill empty timeslot.    )annotations)IterableN)QubitClbitInstruction)Delay)
DAGCircuitDAGNode)TransformationPass)TranspilerError)Target)InstructionDurationsc                     ^  \ rS rSrSr  S   SU 4S jjjrS rSS jrSS jrSS jr	 S         SS jjr
            SS	 jrS
rU =r$ )BasePadding   a  The base class of padding pass.

This pass requires one of scheduling passes to be executed before itself.
Since there are multiple scheduling strategies, the selection of scheduling
pass is left in the hands of the pass manager designer.
Once a scheduling analysis pass is run, ``node_start_time`` is generated
in the :attr:`property_set`.  This information is represented by a python dictionary of
the expected instruction execution times keyed on the node instances.
Entries in the dictionary are only created for non-delay nodes.
The padding pass expects all ``DAGOpNode`` in the circuit to be scheduled.

This base class doesn't define any sequence to interleave, but it manages
the location where the sequence is inserted, and provides a set of information necessary
to construct the proper sequence. Thus, a subclass of this pass just needs to implement
:meth:`_pad` method, in which the subclass constructs a circuit block to insert.
This mechanism removes lots of boilerplate logic to manage whole DAG circuits.

Note that padding pass subclasses should define interleaving sequences satisfying:

    - Interleaved sequence does not change start time of other nodes
    - Interleaved sequence should have total duration of the provided ``time_interval``.

Any manipulation violating these constraints may prevent this base pass from correctly
tracking the start time of each instruction,
which may result in violation of hardware alignment constraints.
c                :   > [         TU ]  5         Xl        X l        g)zBasePadding initializer.

Args:
    target: The :class:`~.Target` representing the target backend.
        If it supplied and it does not support delay instruction on a qubit,
        padding passes do not pad any idle time of the qubit.
N)super__init__target	durations)selfr   r   	__class__s      r/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/transpiler/passes/scheduling/padding/base_padding.pyr   BasePadding.__init__:   s     	"    c                   UR                   S:X  a  UR                  R                  $ UR                   S:X  a  gU R                  (       d  U R                  (       d  gUR
                   Vs/ s H  o2R                  U5      R                  PM     nnU R                  (       a  U R                  R                  UR                   5      nU(       d  gUR                  [        U5      5      nU(       d  gU R                  R                  c  UR                  $ U R                  R                  UR                  5      nU$ U R                  R                  UR                   U5      $ s  snf )z,Get duration of a given node in the circuit.delaybarrierr   N)nameopdurationr   r   qargsfind_bitindexgettupledtseconds_to_dt)r   nodedagqargindices
props_dictpropsress           r   get_durationBasePadding.get_durationJ   s    9977###99	!{{4>>8<

C
<<%++
C;;3JNN5>2E{{~~%~~%kk//?
~~!!$))W55 Ds   )$Ec                   U R                  U5        U R                  S   R                  5       n[        5       nUR                  R                  5        H  nUR                  U5        M     UR                  R                  5        H  nUR                  U5        M     U R                  S   R                  5         UR                  Ul
        UR                  Ul        U R                  S   Ul        UR                  Ul        UR                   Vs0 s H  ofS_M     nnSnUR                  5        GH8  n	X;   Ga  X)   n
U R!                  X5      nX-   n[#        X5      n[%        U	R&                  [(        5      (       a  UR+                  U	5        M`  U	R,                   H~  nXU   -
  S:  al  U R/                  UR1                  U5      R2                  5      (       a=  [5        UR7                  UR8                  U   5      5      nU R;                  UUXv   U
U	US9  XU'   M     U R=                  X:U	R&                  U	R,                  U	R>                  5        GM#  [A        S[C        U	5       S35      e   UR                   H  nXU   -
  S:  d  M  U R/                  UR1                  U5      R2                  5      (       d  MA  UR8                  U   n	[5        UR7                  U	5      5      nU R;                  UUXv   UU	US9  M     Xl"        U$ s  snf )a  Run the padding pass on ``dag``.

Args:
    dag: DAG to be checked.

Returns:
    DAGCircuit: DAG with idle time filled with instructions.

Raises:
    TranspilerError: When a particular node is not scheduled, likely some transform pass
        is inserted before this node is called.
node_start_time	time_unitr   )r*   qubitt_startt_end	next_node	prev_nodez
Operation zb is likely added after the circuit is scheduled. Schedule the circuit again if you transformed it.)#_pre_runhookproperty_setcopyr	   qregsvaluesadd_qregcregsadd_cregclearr   metadata_unitglobal_phasequbitstopological_op_nodesr0   max
isinstancer    r   remove_op_noder"   _BasePadding__delay_supportedr#   r$   nextpredecessors
output_map_pad_apply_scheduled_opcargsr   repr	_duration)r   r*   r3   new_dagqregcregbit
idle_aftercircuit_durationr)   t0durt1r9   s                 r   runBasePadding.runc   s    	#++,=>CCE,II$$&DT" 'II$$&DT" ' 	+,224xx<<))+6"//(+

3
1f

3 ,,.D&$*''2X#&'7#< dggu-- &&t,::CsO+a/D4J4J3<<X[K\KbKb4c4c$()=)=g>P>PQT>U)V$W			 '"%$.O"$&*&/ "  ')sO &  ((dggtzz4::V% d -H H A /L >>CS/1A5$:P:PS!''; ; ))#. !5!5d!;<			&O*"'   " -} 4s   Lc                `    U R                   b   U R                   R                  SU4S9(       a  gg)z8Delay operation is supported on the qubit (qarg) or not.r   )r"   TF)r   instruction_supported)r   r+   s     r   __delay_supportedBasePadding.__delay_supported   s,    ;;$++"C"CGTXSZ"C"[r   c                X   SU R                   ;  a0  [        SUR                   SU R                  R                   S35      eU R                   S   S:X  a  [        S5      e[        UR                  5       H3  u  p#U R                  U5      (       a  M  [        R                  SU5        M5     g	)
zExtra routine inserted before running the padding pass.

Args:
    dag: DAG circuit on which the sequence is applied.

Raises:
    TranspilerError: If the whole circuit or instruction is not scheduled.
r3   zThe input circuit zD is not scheduled. Call one of scheduling passes before running the z pass.r4   stretchz9Scheduling cannot run on circuits with stretch durations.z6No padding on qubit %d as delay is not supported on itN)
r;   r   r   r   __name__	enumeraterF   rK   loggerdebug)r   r*   r+   _s       r   r:   BasePadding._pre_runhook   s     D$5$55!$SXXJ /&&*nn&=&=%>fF  [)Y6!"]^^ ,GD))$//L -r   c                    [        U[        5      (       a  U/n[        U[        5      (       a  U/nUR                  X4USS9nX R                  S   U'   g)a  Add new operation to DAG with scheduled information.

This is identical to apply_operation_back + updating the node_start_time property.

Args:
    dag: DAG circuit on which the sequence is applied.
    t_start: Start time of new node.
    oper: New operation that is added to the DAG circuit.
    qubits: The list of qubits that the operation acts on.
    clbits: The list of clbits that the operation acts on.
F)r"   rQ   checkr3   N)rI   r   r   apply_operation_backr;   )r   r*   r6   operrF   clbitsnew_nodes          r   rP   BasePadding._apply_scheduled_op   sX    & fe$$XFfe$$XF++DfTY+Z9@+,X6r   c                    [         e)a5  Interleave instruction sequence in between two nodes.

.. note::
    If a DAGOpNode is added here, it should update node_start_time property
    in the property set so that the added node is also scheduled.
    This is achieved by adding operation via :meth:`_apply_scheduled_op`.

.. note::

    This method doesn't check if the total duration of new DAGOpNode added here
    is identical to the interval (``t_end - t_start``).
    A developer of the pass must guarantee this is satisfied.
    If the duration is greater than the interval, your circuit may be
    compiled down to the target code with extra duration on the backend compiler,
    which is then played normally without error. However, the outcome of your circuit
    might be unexpected due to erroneous scheduling.

Args:
    dag: DAG circuit that sequence is applied.
    qubit: The wire that the sequence is applied on.
    t_start: Absolute start time of this interval.
    t_end: Absolute end time of this interval.
    next_node: Node that follows the sequence.
    prev_node: Node ahead of the sequence.
)NotImplementedError)r   r*   r5   r6   r7   r8   r9   s          r   rO   BasePadding._pad   s    D "!r   )r   r   )NN)r   r   r   r   )r*   r	   )r+   intreturnbool) )
r*   r	   r6   ru   rn   r   rF   zQubit | Iterable[Qubit]ro   zClbit | Iterable[Clbit])r*   r	   r5   r   r6   ru   r7   ru   r8   r
   r9   r
   )re   
__module____qualname____firstlineno____doc__r   r0   r]   rK   r:   rP   rO   __static_attributes____classcell__)r   s   @r   r   r      s    : *.## (# # 62_B< +-AA A 	A
 (A (A6"""" "" 	""
 "" "" "" ""r   r   )r|   
__future__r   collections.abcr   loggingqiskit.circuitr   r   r   qiskit.circuit.delayr   qiskit.dagcircuitr	   r
   qiskit.transpiler.basepassesr   qiskit.transpiler.exceptionsr   qiskit.transpiler.targetr   'qiskit.transpiler.instruction_durationsr   	getLoggerre   rg   r   rx   r   r   <module>r      sJ    + " $  4 4 & 1 ; 8 + H			8	$A"$ A"r   