§
    º³Ùg×?  ã                  óÈ   — d Z ddlmZ ddlZddl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mZmZmZmZ dd	lmZ dd
lmZmZ ddlmZ  G d„ d¦  «        Zdd„Zdd„ZdS )aã  
A convenient way to track reusable subschedules by name and qubit.

This can be used for scheduling circuits with custom definitions, for instance::

    inst_map = InstructionScheduleMap()
    inst_map.add('new_inst', 0, qubit_0_new_inst_schedule)

    sched = schedule(quantum_circuit, backend, inst_map)

An instance of this class is instantiated by Pulse-enabled backends and populated with defaults
(if available)::

    inst_map = backend.defaults().instruction_schedule_map

é    )ÚannotationsN)Údefaultdict)ÚIterableÚCallable)Úcircuit)ÚParameterExpression)ÚCalibrationEntryÚScheduleDefÚCallableDefÚPulseQobjDefÚCalibrationPublisher)Ú
PulseError)ÚScheduleÚScheduleBlock)Údeprecate_pulse_funcc                  ó°   — e Zd ZdZed„ ¦   «         Zd*d„Zed+d„¦   «         Zd,d„Z	d-d„Z
d.d„Zd/d„Zd0d„Zd1d„Z	 d2d3d„Zd4d#„Zd/d$„Zd0d%„Zd5d'„Zd(„ Zd)„ ZdS )6ÚInstructionScheduleMapa  Mapping from :py:class:`~qiskit.circuit.QuantumCircuit`
    :py:class:`qiskit.circuit.Instruction` names and qubits to
    :py:class:`~qiskit.pulse.Schedule` s. In particular, the mapping is formatted as type::

         Dict[str, Dict[Tuple[int], Schedule]]

    where the first key is the name of a circuit instruction (e.g. ``'u1'``, ``'measure'``), the
    second key is a tuple of qubit indices, and the final value is a Schedule implementing the
    requested instruction.

    These can usually be seen as gate calibrations.
    c                óš   — t          t          j        t           t          ¦  «        ¦  «        | _        t          t
          ¦  «        | _        dS )z=Initialize a circuit instruction to schedule mapper instance.N)r   Ú	functoolsÚpartialr	   Ú_mapÚsetÚ_qubit_instructions©Úselfs    ú[/granary/edev/quantum/lib/python3.11/site-packages/qiskit/pulse/instruction_schedule_map.pyÚ__init__zInstructionScheduleMap.__init__B   s>   € õ �	Ô)­+Õ7GÑHÔHÑIÔIð 	Œ	õ
 @KÍ3Ñ?OÔ?OˆÔ Ð Ð ó    ÚreturnÚboolc                ó‚   — | j                              ¦   «         D ]$}|                     ¦   «         D ]}|j        r  dS ŒŒ%dS )z9Return ``True`` if the map has user provided instruction.TF)r   ÚvaluesÚuser_provided)r   Ú
qubit_instÚentrys      r   Úhas_custom_gatez&InstructionScheduleMap.has_custom_gateQ   s_   € àœ)×*Ò*Ñ,Ô,ð 	 ð 	 ˆJØ#×*Ò*Ñ,Ô,ð  ð  �ØÔ&ð  Ø˜4˜4˜4ð ð ð ˆur   ú	list[str]c                óN   — t          | j                             ¦   «         ¦  «        S )a#  Return all instructions which have definitions.

        By default, these are typically the basis gates along with other instructions such as
        measure and reset.

        Returns:
            The names of all the circuit instructions which have Schedule definitions in this.
        )Úlistr   Úkeysr   s    r   Úinstructionsz#InstructionScheduleMap.instructionsY   s   € õ �D”I—N’NÑ$Ô$Ñ%Ô%Ð%r   Úinstructionú%str | circuit.instruction.Instructionúlist[int | tuple[int, ...]]c                ó¢   — t          |¦  «        }|| j        vrg S d„ t          | j        |                              ¦   «         ¦  «        D ¦   «         S )a/  Return a list of the qubits for which the given instruction is defined. Single qubit
        instructions return a flat list, and multiqubit instructions return a list of ordered
        tuples.

        Args:
            instruction: The name of the circuit instruction.

        Returns:
            Qubit indices which have the given instruction defined. This is a list of tuples if the
            instruction has an arity greater than 1, or a flat list of ints otherwise.

        Raises:
            PulseError: If the instruction is not found.
        c                óH   — g | ]}t          |¦  «        d k    r|d         n|‘Œ S )é   r   )Úlen)Ú.0Úqubitss     r   ú
<listcomp>zBInstructionScheduleMap.qubits_with_instruction.<locals>.<listcomp>y   s@   € ð 
ð 
ð 
àõ ˜V™œ¨Ò)Ð)ˆF�1ŒIˆI¨vð
ð 
ð 
r   )Ú_get_instruction_stringr   Úsortedr*   )r   r,   s     r   Úqubits_with_instructionz.InstructionScheduleMap.qubits_with_instructione   s_   € õ" .¨kÑ:Ô:ˆØ˜dœiÐ'Ð'ØˆIð
ð 
å  ¤¨;Ô!7×!<Ò!<Ñ!>Ô!>Ñ?Ô?ð
ñ 
ô 
ð 	
r   r4   úint | Iterable[int]c                ó€   — t          |¦  «        | j        v r't          | j        t          |¦  «                 ¦  «        S g S )aä  Return a list of the instruction names that are defined by the backend for the given
        qubit or qubits.

        Args:
            qubits: A qubit index, or a list or tuple of indices.

        Returns:
            All the instructions which are defined on the qubits.

            For 1 qubit, all the 1Q instructions defined. For multiple qubits, all the instructions
            which apply to that whole set of qubits (e.g. ``qubits=[0, 1]`` may return ``['cx']``).
        )Ú	_to_tupler   r)   )r   r4   s     r   Úqubit_instructionsz)InstructionScheduleMap.qubit_instructions~   s=   € õ �VÑÔ Ô 8Ð8Ð8Ý˜Ô0µ¸6Ñ1BÔ1BÔCÑDÔDÐDØˆ	r   c                ój   — t          |¦  «        }|| j        v ot          |¦  «        | j        |         v S )a  Is the instruction defined for the given qubits?

        Args:
            instruction: The instruction for which to look.
            qubits: The specific qubits for the instruction.

        Returns:
            True iff the instruction is defined.
        )r6   r   r;   ©r   r,   r4   s      r   ÚhaszInstructionScheduleMap.has�   s7   € õ .¨kÑ:Ô:ˆØ˜dœiÐ'ÐW­I°fÑ,=Ô,=ÀÄÈ;ÔAWÐ,WÐWr   ÚNonec           	     óp  — t          |¦  «        }|                      |t          |¦  «        ¦  «        sƒt          j        ¦   «         5  t          j        dt          dd¬¦  «         || j        v r)t          d|› d|  	                    |¦  «        › d�¦  «        ‚t          d|› d�¦  «        ‚# 1 swxY w Y   d	S d	S )
a  Error if the given instruction is not defined.

        Args:
            instruction: The instruction for which to look.
            qubits: The specific qubits for the instruction.

        Raises:
            PulseError: If the instruction is not defined on the qubits.
        Úignorez".*The entire Qiskit Pulse package*Úqiskit)ÚcategoryÚmessageÚmodulezOperation 'z)' exists, but is only defined for qubits ú.z!' is not defined for this system.N)
r6   r?   r;   ÚwarningsÚcatch_warningsÚfilterwarningsÚDeprecationWarningr   r   r8   r>   s      r   Ú
assert_hasz!InstructionScheduleMap.assert_hasž   s/  € õ .¨kÑ:Ô:ˆØ�xŠx˜¥Y¨vÑ%6Ô%6Ñ7Ô7ð 	_õ Ô(Ñ*Ô*ð _ð _ÝÔ'ØÝ/Ø@Ø#ð	ñ ô ð ð  $¤)Ð+Ð+Ý$ðH kð Hð HØ×7Ò7¸ÑDÔDðHð Hð Hñô ð õ !Ð!]¨{Ð!]Ð!]Ð!]Ñ^Ô^Ð^ð_ð _ð _ð _øøøð _ð _ð _ð _ð _ð _ð		_ð 	_s   ÁA#B)Â)B-Â0B-Úparamsúcomplex | ParameterExpressionÚkwparamsúSchedule | ScheduleBlockc                óD   —  |                       ||¦  «        j        |i |¤ŽS )al  Return the defined :py:class:`~qiskit.pulse.Schedule` or
        :py:class:`~qiskit.pulse.ScheduleBlock` for the given instruction on the given qubits.

        If all keys are not specified this method returns schedule with unbound parameters.

        Args:
            instruction: Name of the instruction or the instruction itself.
            qubits: The qubits for the instruction.
            *params: Command parameters for generating the output schedule.
            **kwparams: Keyworded command parameters for generating the schedule.

        Returns:
            The Schedule defined for the input.
        )Ú_get_calibration_entryÚget_schedule)r   r,   r4   rM   rO   s        r   ÚgetzInstructionScheduleMap.get½   s.   € ð* Mˆt×*Ò*¨;¸Ñ?Ô?ÔLÈfÐaÐX`ÐaÐaÐar   r	   c                óŒ   — t          |¦  «        }|                      ||¦  «         | j        |         t          |¦  «                 S )a™  Return the :class:`.CalibrationEntry` without generating schedule.

        When calibration entry is un-parsed Pulse Qobj, this returns calibration
        without parsing it. :meth:`CalibrationEntry.get_schedule` method
        must be manually called with assigned parameters to get corresponding pulse schedule.

        This method is expected be directly used internally by the V2 backend converter
        for faster loading of the backend calibrations.

        Args:
            instruction: Name of the instruction or the instruction itself.
            qubits: The qubits for the instruction.

        Returns:
            The calibration entry.
        )r6   rL   r   r;   r>   s      r   rR   z-InstructionScheduleMap._get_calibration_entryÔ   s?   € õ* .¨kÑ:Ô:ˆØ�Š˜ VÑ,Ô,Ð,àŒy˜Ô%¥i°Ñ&7Ô&7Ô8Ð8r   NÚscheduleúBSchedule | ScheduleBlock | Callable[..., Schedule | ScheduleBlock]Ú	argumentsúlist[str] | Nonec                ó²  — t          |¦  «        }t          |¦  «        }|st          d|› d�¦  «        ‚t          |t          t
          f¦  «        rt          |¦  «        }nIt          |¦  «        r+|rt          j	        dt          ¦  «         t          ¦   «         }nt          d¦  «        ‚|                     |d¬¦  «         |                      |||¦  «         dS )aî  Add a new known instruction for the given qubits and its mapping to a pulse schedule.

        Args:
            instruction: The name of the instruction to add.
            qubits: The qubits which the instruction applies to.
            schedule: The Schedule that implements the given instruction.
            arguments: List of parameter names to create a parameter-bound schedule from the
                associated gate instruction. If :py:meth:`get` is called with arguments rather
                than keyword arguments, this parameter list is used to map the input arguments to
                parameter objects stored in the target schedule.

        Raises:
            PulseError: If the qubits are provided as an empty iterable.
        zCannot add definition z with no target qubits.zZArguments are overruled by the callback function signature. Input `arguments` are ignored.zcSupplied schedule must be one of the Schedule, ScheduleBlock or a callable that outputs a schedule.T)r#   N)r6   r;   r   Ú
isinstancer   r   r
   ÚcallablerH   ÚwarnÚUserWarningr   ÚdefineÚ_add)r   r,   r4   rV   rX   r%   s         r   ÚaddzInstructionScheduleMap.addî   s÷   € õ* .¨kÑ:Ô:ˆõ ˜6Ñ"Ô"ˆØð 	\ÝÐZ°kÐZÐZÐZÑ[Ô[Ð[õ �h¥­=Ð 9Ñ:Ô:ð 	Ý&1°)Ñ&<Ô&<ˆEˆEÝ�hÑÔð 	Øð Ý”ð5åñô ð õ
  ‘M”MˆEˆEåð4ñô ð ð 	�Š�X¨TˆÑ2Ô2Ð2Ø�	Š	�+˜v uÑ-Ô-Ð-Ð-Ð-r   Úinstruction_nameÚstrútuple[int, ...]r%   c                óf   — || j         |         |<   | j        |                              |¦  «         dS )a  A method to resister calibration entry.

        .. note::

            This is internal fast-path function, and caller must ensure
            the entry is properly formatted. This function may be used by other programs
            that load backend calibrations to create Qiskit representation of it.

        Args:
            instruction_name: Name of instruction.
            qubits: List of qubits that this calibration is applied.
            entry: Calibration entry to register.

        :meta public:
        N)r   r   ra   )r   rb   r4   r%   s       r   r`   zInstructionScheduleMap._add  s9   € ð* /4ˆŒ	Ð"Ô# FÑ+ØÔ  Ô(×,Ò,Ð-=Ñ>Ô>Ð>Ð>Ð>r   c                ó"  — t          |¦  «        }t          |¦  «        }|                      ||¦  «         | j        |         |= | j        |         s| j        |= | j        |                              |¦  «         | j        |         s
| j        |= dS dS )zäRemove the given instruction from the listing of instructions defined in self.

        Args:
            instruction: The name of the instruction to add.
            qubits: The qubits which the instruction applies to.
        N)r6   r;   rL   r   r   Úremover>   s      r   rg   zInstructionScheduleMap.remove5  s¡   € õ .¨kÑ:Ô:ˆÝ˜6Ñ"Ô"ˆØ�Š˜ VÑ,Ô,Ð,àŒI�kÔ" 6Ð*ØŒy˜Ô%ð 	'Ø”	˜+Ð&àÔ  Ô(×/Ò/°Ñ<Ô<Ð<ØÔ'¨Ô/ð 	1ØÔ(¨Ð0Ð0Ð0ð	1ð 	1r   c                ót   — t          |¦  «        } | j        ||g|¢R i |¤Ž}|                      ||¦  «         |S )a»  Remove and return the defined schedule for the given instruction on the given
        qubits.

        Args:
            instruction: Name of the instruction.
            qubits: The qubits for the instruction.
            *params: Command parameters for generating the output schedule.
            **kwparams: Keyworded command parameters for generating the schedule.

        Returns:
            The Schedule defined for the input.
        )r6   rT   rg   )r   r,   r4   rM   rO   rV   s         r   ÚpopzInstructionScheduleMap.popJ  sM   € õ& .¨kÑ:Ô:ˆØ�4”8˜K¨ÐE°&ÐEÐEÐE¸HÐEÐEˆØ�Š�K Ñ(Ô(Ð(Øˆr   útuple[str, ...]c                óˆ  — t          |¦  «        }|                      ||¦  «         t          j        ¦   «         5  t          j        dt
          ¬¦  «         | j        |         t          |¦  «                                      ¦   «         }ddd¦  «         n# 1 swxY w Y   t          |j
                             ¦   «         ¦  «        S )a&  Return the list of parameters taken by the given instruction on the given qubits.

        Args:
            instruction: Name of the instruction.
            qubits: The qubits for the instruction.

        Returns:
            The names of the parameters required by the instruction.
        rB   )ÚactionrD   N)r6   rL   rH   rI   ÚsimplefilterrK   r   r;   Úget_signatureÚtupleÚ
parametersr*   )r   r,   r4   Ú	signatures       r   Úget_parametersz%InstructionScheduleMap.get_parametersb  sõ   € õ .¨kÑ:Ô:ˆà�Š˜ VÑ,Ô,Ð,ÝÔ$Ñ&Ô&ð 	Rð 	RÝÔ!¨Õ<NÐOÑOÔOÐOàœ	 +Ô.­y¸Ñ/@Ô/@ÔA×OÒOÑQÔQˆIð	Rð 	Rð 	Rñ 	Rô 	Rð 	Rð 	Rð 	Rð 	Rð 	Rð 	Røøøð 	Rð 	Rð 	Rð 	Rõ �YÔ)×.Ò.Ñ0Ô0Ñ1Ô1Ð1s   ¹ABÂBÂBc                óÜ   — d}d}| j                              ¦   «         D ]7\  }}t          |¦  «        dk    r|d|d         › d|› d�z  }Œ+|d|› d|› d�z  }Œ8||z   }d	| j        j        › d
|› d�S )Nz1Q instructions:
zMulti qubit instructions:
r1   z  qr   z: ú
z  ú<ú(z)>)r   Úitemsr2   Ú	__class__Ú__name__)r   Úsingle_q_instsÚmulti_q_instsr4   Úinstsr+   s         r   Ú__str__zInstructionScheduleMap.__str__w  s«   € Ø-ˆØ5ˆØ!Ô5×;Ò;Ñ=Ô=ð 	:ð 	:‰MˆF�EÝ�6‰{Œ{˜aÒÐØÐ">¨¨q¬	Ð">Ð">°UÐ">Ð">Ð">Ñ>��àÐ!9 fÐ!9Ð!9°Ð!9Ð!9Ð!9Ñ9��Ø%¨Ñ5ˆØ=�4”>Ô*Ð=Ð=¨\Ð=Ð=Ð=Ð=r   c                ó,  — t          |t          ¦  «        sdS | j        D ]t}|                      |¦  «        D ]\}	 | j        |         t          |¦  «                 |j        |         t          |¦  «                 k    r  dS ŒJ# t          $ r Y   dS w xY wŒudS )NFT)r[   r   r+   r8   r   r;   ÚKeyError)r   ÚotherÚinstÚqindss       r   Ú__eq__zInstructionScheduleMap.__eq__‚  sÂ   € Ý˜%Õ!7Ñ8Ô8ð 	Ø�5àÔ%ð 	!ð 	!ˆDØ×5Ò5°dÑ;Ô;ð !ð !�ð!Ø”y ”¥y°Ñ'7Ô'7Ô8¸E¼JÀtÔ<LÍYÐW\ÑM]ÔM]Ô<^Ò^Ð^Ø$˜u˜u˜uð _øåð !ð !ð !Ø ˜5˜5˜5˜5ð!øøøð	!ð ˆts   ¹AB Â 
BÂB)r   r    )r   r'   )r,   r-   r   r.   )r4   r9   r   r'   )r,   r-   r4   r9   r   r    )r,   r-   r4   r9   r   r@   )
r,   r-   r4   r9   rM   rN   rO   rN   r   rP   )r,   r-   r4   r9   r   r	   )N)
r,   r-   r4   r9   rV   rW   rX   rY   r   r@   )rb   rc   r4   rd   r%   r	   )r,   r-   r4   r9   r   rj   )ry   Ú
__module__Ú__qualname__Ú__doc__r   r   r&   Úpropertyr+   r8   r<   r?   rL   rT   rR   ra   r`   rg   ri   rr   r}   rƒ   © r   r   r   r   4   s‚  € € € € € ðð ð ðPð Pñ ÔðPðð ð ð ð ð	&ð 	&ð 	&ñ „Xð	&ð
ð 
ð 
ð 
ð2ð ð ð ð"Xð Xð Xð Xð_ð _ð _ð _ð>bð bð bð bð.9ð 9ð 9ð 9ð> '+ð-.ð -.ð -.ð -.ð -.ð^?ð ?ð ?ð ?ð01ð 1ð 1ð 1ð*ð ð ð ð02ð 2ð 2ð 2ð*	>ð 	>ð 	>ðð ð ð ð r   r   r"   r9   r   rd   c                óH   — 	 t          | ¦  «        S # t          $ r | fcY S w xY w)z›Return the input as a tuple.

    Args:
        values: An integer, or iterable of integers.

    Returns:
        The input values as a sorted tuple.
    )ro   Ú	TypeError)r"   s    r   r;   r;   �  s<   € ðÝ�V‰}Œ}ÐøÝð ð ð ØˆyÐÐÐðøøøs   ‚ ‘! !r�   r-   rc   c                ó„   — t          | t          ¦  «        r| S 	 | j        S # t          $ r}t	          d¦  «        |‚d }~ww xY w)NzMInput "inst" has no attribute "name". This should be a circuit "Instruction".)r[   rc   ÚnameÚAttributeErrorr   )r�   Úexs     r   r6   r6   Ÿ  s]   € Ý�$�ÑÔð Øˆð	Ø”9ÐøÝð 	ð 	ð 	ÝØ_ñô àðøøøøð	øøøs   ™   
?ª:º?)r"   r9   r   rd   )r�   r-   r   rc   )r†   Ú
__future__r   r   rH   Úcollectionsr   Úcollections.abcr   r   rC   r   Ú"qiskit.circuit.parameterexpressionr   Ú qiskit.pulse.calibration_entriesr	   r
   r   r   r   Úqiskit.pulse.exceptionsr   Úqiskit.pulse.scheduler   r   Úqiskit.utils.deprecate_pulser   r   r;   r6   rˆ   r   r   ú<module>r—      sm  ððð ð  #Ð "Ð "Ð "Ð "Ð "Ø Ð Ð Ð Ø €€€Ø #Ð #Ð #Ð #Ð #Ð #Ø .Ð .Ð .Ð .Ð .Ð .Ð .Ð .à Ð Ð Ð Ð Ð Ø BÐ BÐ BÐ BÐ BÐ Bðð ð ð ð ð ð ð ð ð ð ð ð ð ð /Ð .Ð .Ð .Ð .Ð .Ø 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ø =Ð =Ð =Ð =Ð =Ð =ðYð Yð Yð Yð Yñ Yô Yð Yðx
ð ð ð ð	ð 	ð 	ð 	ð 	ð 	r   