
    z	i%                         S 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\5      r " S S\R.                  \   5      rg)z?Unify time unit in circuit for scheduling and following passes.    )Set)DelayDuration)expr)duration_in_dt)
DAGCircuit)TransformationPass)TranspilerError)InstructionDurations)Target)apply_prefixc                   l   ^  \ rS rSrSrSS\S\4U 4S jjjrS\4S jr	\
S\\   S	\4S
 j5       rSrU =r$ )TimeUnitConversion   ae  Choose a time unit to be used in the following time-aware passes,
and make all circuit time units consistent with that.

This pass will add a :attr:`.Instruction.duration` metadata to each op whose duration is known
which will be used by subsequent scheduling passes for scheduling.

If ``dt`` (in seconds) is known to transpiler, the unit ``'dt'`` is chosen. Otherwise,
the unit to be selected depends on what units are used in delays and instruction durations:

* ``'s'``: if they are all in SI units.
* ``'dt'``: if they are all in the unit ``'dt'``.
* raise error: if they are a mix of SI units and ``'dt'``.
inst_durationstargetc                    > [         TU ]  5         U=(       d
    [        5       U l        Ub  UR	                  5       U l        USL=(       d    USLU l        g)a\  TimeUnitAnalysis initializer.

Args:
    inst_durations (InstructionDurations): A dictionary of durations of instructions.
    target: The :class:`~.Target` representing the target backend, if both
          ``inst_durations`` and ``target`` are specified then this argument will take
          precedence and ``inst_durations`` will be ignored.


N)super__init__r   r   	durations_durations_provided)selfr   r   	__class__s      r/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/transpiler/passes/scheduling/time_unit_conversion.pyr   TimeUnitConversion.__init__*   sO     	,F0D0F"("2"2"4D#1#=#StAS     dagc                    [        5       nU R                  (       a1  UR                  U R                  [	        U R                  SS5      5        0 nSnSnUR                  [        S9 GHl  n[        UR                  R                  [        R                  5      (       a  [        S [        R                  " UR                  R                  5       5       5      (       a  SU R                  S'   Us  $ [        UR                   5      nUR                  R                  R#                  U5      nUR%                  5       (       a  Sn['        US	5      nOSnUS
:  a#  [)        SUR                  R                   S35      eXUR*                  '   OUR                  R,                  S:X  a  SnOSnUR                   b  GMP  U(       d  GMZ  U(       d  GMd  [)        S5      e   UR                   cc  UR/                  5       n	U R1                  U	5      n
U=(       d    U
S;   nU=(       d    U
S;   nU(       a  U(       a  [)        S5      eU(       a  SnOSnOSnUR                  [        5       H  nUR                  R3                  5       nUR*                  U;   a  X6R*                     Ul	        O,UR5                  UR                  UR,                  U5      Ul	        Xl        UR7                  Xl5        M     XR                  S'   U$ )zRun the TimeUnitAnalysis pass on `dag`.

Args:
    dag (DAGCircuit): DAG to be checked.

Returns:
    DAGCircuit: DAG with consistent timing and op nodes annotated with duration.

Raises:
    TranspilerError: if the units are not unifiable
dtNF)opc              3   V   #    U  H  n[        U[        R                  5      v   M!     g 7fN)
isinstancer   Stretch).0xs     r   	<genexpr>)TimeUnitConversion.run.<locals>.<genexpr>[   s"      9`AJq$,,//9`s   ')stretch	time_unitTg      ?r   zExpression 'z"' resolves to a negative duration!cFail to unify time units in delays. SI units and dt unit must not be mixed when dt is not supplied.>   SImixed>   r   r-   zYFail to unify time units. SI units and dt unit must not be mixed when dt is not supplied.s)r   r   updater   getattrop_nodesr   r#   r    durationr   Expranyiter_identifiersproperty_set_EvalDurationImplr   accept	in_cyclesr   r
   _node_idunit
units_used_unified
to_mutable_convert_unitsubstitute_node)r   r   r   expression_durationshas_dthas_sinodevisitorr2   units_otherunified_unitr*   r    s                r   runTimeUnitConversion.run<   s    ./##!!$"5"5wt?R?RTXZ^7_`  "  LLEL*D$''**DII66 9=9N9NtwwO_O_9`   6?D%%k2J+N,=,=>77++227;$$&&!F-h<H!Fa<)&tww'7'7&88Z[  7?T]]377<<4'!F!F  (VV%M ? +H $(335K==5L>|>F>|>F&%M  	 !	I LL'D##%B}} 442==A,::2;;QZ[G) ( *3+&
r   unit_setreturnc                     U (       d  g[        U 5      S:X  a  SU ;   a  gSnU  H  nUR                  S5      (       a  M  Sn  O   U(       a  gg)	Nnone   r   Tr.   Fr,   r-   )lenendswith)rJ   all_sir;   s      r   r=   TimeUnitConversion._unified   sO    x=A$("2D==%% 
 r   )r   r   )NN)__name__
__module____qualname____firstlineno____doc__r   r   r   r   rH   staticmethodr   strr=   __static_attributes____classcell__)r   s   @r   r   r      sZ    T'; TF T T$`z `D 3s8   r   r   c                   V    \ rS rSrSrSrSS jrS rS\4S jr	S\4S	 jr
S\4S
 jrSrg)r7      zEvaluates the expression to a single float result.

If ``dt`` is provided or all durations are already in ``dt``, the result is in ``dt``.
Otherwise, the result will be in seconds, and all durations MUST be in wall-time (SI).
r   rB   rC   Nc                 ,    Xl         SU l        SU l        g )NFr^   )r   r   s     r   r   _EvalDurationImpl.__init__   s    r   c                 D    U R                   =(       d    U R                  SL$ )z/Returns ``True`` if units are 'dt' after visit.N)rB   r   )r   s    r   r9   _EvalDurationImpl.in_cycles   s    {{1dggT11r   rK   c                   [        UR                  [        5      (       a  UR                  $ [        UR                  [        R                  5      (       a?  U R
                  (       a  U R                  c  [        S5      eSU l        UR                  S   $ [        UR                  [        5      (       a  U R                  (       a  U R                  c  [        S5      eSU l        U R                  b  U R                  OSn[        UR                  [        R                  5      (       a  UR                  S   U-  $ UR                  R                  5       n[        UR                  S   U5      U-  $ [        SU 35      e)Nr+   Tr   rN   invalid duration expression: )r#   valuefloatr   r   rC   r
   rB   r.   r;   r   )r   rD   divisor	from_units       r   visit_value_EvalDurationImpl.visit_value   s"   djj%((::djj(++..{{tww%M  DK::a= djj(++{{tww%M  DK "&!4dgg!G$**hjj11zz!}w..

)I

1y9GCC =dVDEEr   c                :   UR                   R                  U 5      nUR                  R                  U 5      nUR                  [        R
                  R                  R                  :X  a  X#-   $ UR                  [        R
                  R                  R                  :X  a  X#-
  $ UR                  [        R
                  R                  R                  :X  a  X#-  $ UR                  [        R
                  R                  R                  :X  a  X#-  $ [        SU 35      e)Nrd   )leftr8   rightr    r   BinaryOpADDSUBMULDIVr
   )r   rD   rl   rm   s       r   visit_binary_EvalDurationImpl.visit_binary   s    yy%

!!$'77dkknn(((<77dkknn(((<77dkknn(((<77dkknn(((< =dVDEEr   c                8    UR                   R                  U 5      $ r"   )operandr8   )r   rD   s     r   
visit_cast_EvalDurationImpl.visit_cast   s    ||""4((r   r"   )rS   rT   rU   rV   rW   	__slots__r   r9   rf   ri   rt   rx   rZ    r   r   r7   r7      s@     +I
2Fe F6Fu F)U )r   r7   N)rW   typingr   qiskit.circuitr   r   qiskit.circuit.classicalr   qiskit.circuit.durationr   qiskit.dagcircuitr   qiskit.transpiler.basepassesr	   qiskit.transpiler.exceptionsr
   'qiskit.transpiler.instruction_durationsr   qiskit.transpiler.targetr   qiskit.utilsr   r   ExprVisitorrf   r7   r{   r   r   <module>r      sP    F  * ) 2 ( ; 8 H + %T+ Tn;)((/ ;)r   