
    z	i
                    R   S 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
r
SSKrSSKrSSKrSSK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   \RB                  " \"5      r# " S S\5      r$ " S S\5      r%\	RL                  " \%5         " S S\%5      r'g)z_
A target object represents the minimum set of information the transpiler needs
from a backend
    )annotationsN)OptionalListAny)Mapping)
BaseTargetBaseInstructionProperties)get_standard_gate_name_mapping)duration_in_dt)CouplingMap)TranspilerError)InstructionDurations)TimingConstraints)QubitPropertiesc                  X   ^  \ rS rSrSr  SU 4S jjr  S   SU 4S jjjrS rSrU =r	$ )	InstructionProperties5   a  A representation of the properties of a gate implementation.

This class provides the optional properties that a backend can provide
about an instruction. These represent the set that the transpiler can
currently work with if present. However, if your backend provides additional
properties for instructions you should subclass this to add additional
custom attributes for those custom/additional properties by the backend.
c                ,   > [         [        U ]  XU5      $ N)superr   __new__)clsdurationerrorargskwargs	__class__s        R/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/transpiler/target.pyr   InstructionProperties.__new__?   s     *C85
 	
    c                "   > [         TU ]  5         g)zCreate a new ``InstructionProperties`` object

Args:
    duration: The duration, in seconds, of the instruction on the
        specified set of qubits
    error: The average error rate for the instruction on the specified
        set of qubits.
N)r   __init__)selfr   r   r   s      r   r"   InstructionProperties.__init__J   s     	r    c                <    SU R                    SU R                   S3$ )NzInstructionProperties(duration=z, error=)r   r   r#   s    r   __repr__InstructionProperties.__repr__Y   s     0x

|STUUr     NN)r   float | Noner   r-   )
__name__
__module____qualname____firstlineno____doc__r   r"   r)   __static_attributes____classcell__r   s   @r   r   r   5   sE     	
 "&"  V Vr    r   c                    ^  \ rS rSrSrSr         S#                 S$U 4S jjjrS%U 4S jjr\S 5       r	\	R                  S 5       r	S&SS	.U 4S
 jjjrU 4S jrS rS rS r\S 5       r\S 5       rS rS rS'S jrS rS rS rS(S jrS rS rS rS rS rS rS)U 4S jjrS*U 4S jjr S+S  jr!\"       S,                 S-S! jj5       r#S"r$U =r%$ ).Target]   a  
The intent of the ``Target`` object is to inform Qiskit's compiler about
the constraints of a particular backend so the compiler can compile an
input circuit to something that works and is optimized for a device. It
currently contains a description of instructions on a backend and their
properties as well as some timing information. However, this exact
interface may evolve over time as the needs of the compiler change. These
changes will be done in a backwards compatible and controlled manner when
they are made (either through versioning, subclassing, or mixins) to add
on to the set of information exposed by a target.

As a basic example, let's assume backend has two qubits, supports
:class:`~qiskit.circuit.library.UGate` on both qubits and
:class:`~qiskit.circuit.library.CXGate` in both directions. To model this
you would create the target like::

    from qiskit.transpiler import Target, InstructionProperties
    from qiskit.circuit.library import UGate, CXGate
    from qiskit.circuit import Parameter

    gmap = Target()
    theta = Parameter('theta')
    phi = Parameter('phi')
    lam = Parameter('lambda')
    u_props = {
        (0,): InstructionProperties(duration=5.23e-8, error=0.00038115),
        (1,): InstructionProperties(duration=4.52e-8, error=0.00032115),
    }
    gmap.add_instruction(UGate(theta, phi, lam), u_props)
    cx_props = {
        (0,1): InstructionProperties(duration=5.23e-7, error=0.00098115),
        (1,0): InstructionProperties(duration=4.52e-7, error=0.00132115),
    }
    gmap.add_instruction(CXGate(), cx_props)

Each instruction in the ``Target`` is indexed by a unique string name that uniquely
identifies that instance of an :class:`~qiskit.circuit.Instruction` object in
the Target. There is a 1:1 mapping between a name and an
:class:`~qiskit.circuit.Instruction` instance in the target and each name must
be unique. By default, the name is the :attr:`~qiskit.circuit.Instruction.name`
attribute of the instruction, but can be set to anything. This lets a single
target have multiple instances of the same instruction class with different
parameters. For example, if a backend target has two instances of an
:class:`~qiskit.circuit.library.RXGate` one is parameterized over any theta
while the other is tuned up for a theta of pi/6 you can add these by doing something
like::

    import math

    from qiskit.transpiler import Target, InstructionProperties
    from qiskit.circuit.library import RXGate
    from qiskit.circuit import Parameter

    target = Target()
    theta = Parameter('theta')
    rx_props = {
        (0,): InstructionProperties(duration=5.23e-8, error=0.00038115),
    }
    target.add_instruction(RXGate(theta), rx_props)
    rx_30_props = {
        (0,): InstructionProperties(duration=1.74e-6, error=.00012)
    }
    target.add_instruction(RXGate(math.pi / 6), rx_30_props, name='rx_30')

Then in the ``target`` object accessing by ``rx_30`` will get the fixed
angle :class:`~qiskit.circuit.library.RXGate` while ``rx`` will get the
parameterized :class:`~qiskit.circuit.library.RXGate`.

You can optionally specify a bound on valid values on a gate in the target
by using the ``angle_bounds`` keyword argument when calling the :meth:`.add_instruction`
method. Bounds are set on operations not individual instructions, so when
you call :meth:`.add_instruction` the bounds are applied for all qargs that it
is defined on. The bounds are specified of a list of 2-tuples of floats where
the first float is the lower bound and the second float is the upper bound. For example,
if you specfied an angle bound::

    [(0.0, 3.14), (-3.14, 3.14), (0.0, 1.0)]

this indicates the angle bounds for a 3 parameter gate where the first
parameter accepts angles between 0 and 3.14, the second between -3.14 and
3.14, and the third parameter between 0 and 1. All bounds are set
inclusively as well. A bound can also be specified with ``None`` instead
of a 2-tuple which indicates that parameter has no constraints. For example::

    [(0.0, 3.14, None, None)]

indicates an angle bound for a 3 parameter gate where only the first
parameter is restricted to angles between 0.0 and 3.14 and the other
parameters accept any value.

You can check if any operations in the target have angle bounds set with,
:meth:`.has_angle_bounds` and also if a specific name in the target has
angle bounds set with :meth:`.gate_has_angle_bounds`. Whether a particular
set of parameter values conforms to the angle bounds can be checked
with :meth:`.supported_angle_bound`. In the preset pass managers the
:class:`.WrapAngles` pass is used to enforce the angle bounds, for this
to work you need to provide a function to the :class:`.WrapAngleRegistry`
used by the pass. You can see more details on this in:
:ref:`angle-bounds-on-gates`.

This class can be queried via the mapping protocol, using the
instruction's name as a key. You can modify any property for an
instruction via the :meth:`.update_instruction_properties` method.
Modification via the mapping protocol or mutating the attributes of
a :class:`.InstructionProperties` object is **not** supported and
doing so will invalidate the internal state of the object.

.. note::

    This class assumes that qubit indices start at 0 and are a contiguous
    set if you want a submapping the bits will need to be reindexed in
    a new :class:`Target` object.

.. note::

    This class only supports additions of gates, qargs, and properties.
    If you need to remove one of these the best option is to iterate over
    an existing object and create a new subset (or use one of the methods
    to do this). The object internally caches different views and these
    would potentially be invalidated by removals.

Subclassing
-----------

While it is technically possible to subclass :class:`Target`, beware that the majority of the
built-in information is in Rust and is queried from Rust in built-in transpiler passes.
Python-space overrides are not visible to Rust, and you should not rely on these to change the
behavior of Qiskit's built-in transpiler passes.  :class:`Target` is largely supposed to be a
representation of a QPU that has specialized *constructors*, not specialized subclasses; the
usual API for constructing a :class:`Target` should be a function that returns a base
:class:`Target`, not a subclass with a custom initializer.

You may use subclassing to add *addition* Python-space properties to your :class:`Target`, for
example to then interpret in custom backend-specific transpiler stages; the :class:`Target` is
passed to stage-plugin constructors.

You should not subclass :class:`Target` to attempt to modify the behavior of Qiskit's built-in
passes; the Python-space subclassing will not be seen by passes written in Rust.

Further, as the core of :class:`Target` is written in Rust, it uses :meth:`~object.__new__` as
its initializer, and you must ensure that the correct arguments are passed through to the
underlying implementation.  If you override the signature of the :meth:`~object.__init__`
method, you must also include an override of :meth:`~object.__new__` with the same signature,
which calls ``super().__new__()`` in a correct manner.
)	_gate_map_coupling_graph_instruction_durations_instruction_schedule_map_non_global_basis_strict_non_global_basisNc
                   > Ub  [        U5      n[        [        U ]  U UUUUUUUUU	5
      n0 Ul        SUl        SUl        SUl        SUl        SUl	        U$ )a	  
Create a new :class:`Target` object.

Args:
    description (str): An optional string to describe the Target.
    num_qubits (int): An optional int to specify the number of qubits
        the backend target has. This is not a hard limit on the construction; any call to
        :meth:`add_instruction` will cause the set `num_qubits` to update to accommodate any
        concrete ``qargs`` in the given properties.

        This can be explicitly set to ``None`` to indicate a :class:`Target` representing a
        simulator or other abstract machine that imposes no limits on the number of qubits.
        In this case, all instructions added to the target should be global (with
        ``properties=None`` or ``properties={None: None}``).
    dt (float): The system time resolution of input signals in seconds
    granularity (int): An integer value representing minimum pulse gate
        resolution in units of ``dt``. A user-defined pulse gate should
        have duration of a multiple of this granularity value.
    min_length (int): An integer value representing minimum pulse gate
        length in units of ``dt``. A user-defined pulse gate should be
        longer than this length.
    pulse_alignment (int): An integer value representing a time
        resolution of gate instruction starting time. Gate instruction
        should start at time which is a multiple of the alignment
        value.
    acquire_alignment (int): An integer value representing a time
        resolution of measure instruction starting time. Measure
        instruction should start at time which is a multiple of the
        alignment value.
    qubit_properties (list): A list of :class:`~.QubitProperties`
        objects defining the characteristics of each qubit on the
        target device. If specified the length of this list must match
        the number of qubits in the target, where the index in the list
        matches the qubit number the properties are defined for. If some
        qubits don't have properties available you can set that entry to
        ``None``
    concurrent_measurements(list): A list of sets of qubits that must be
        measured together. This must be provided
        as a nested list like ``[[0, 1], [2, 3, 4]]``.
Raises:
    ValueError: If both ``num_qubits`` and ``qubit_properties`` are both
        defined and the value of ``num_qubits`` differs from the length of
        ``qubit_properties``.
N)
strr   r7   r   r9   r:   r;   r<   r>   r=   )r   description
num_qubitsdtgranularity
min_lengthpulse_alignmentacquire_alignmentqubit_propertiesconcurrent_measurements_subclass_kwargsoutr   s               r   r   Target.__new__   s{    r "k*KFC(#
 "%)"(,% $'+$
r    c                   > U(       a-  U R                   c  [        TU ]	  U5      U l         U R                   $ U R                  c  [        TU ]	  U5      U l        U R                  $ )a  Return the non-global operation names for the target

The non-global operations are those in the target which don't apply
on all qubits (for single qubit operations) or all multi-qubit qargs
(for multi-qubit operations).

Args:
    strict_direction (bool): If set to ``True`` the multi-qubit
        operations considered as non-global respect the strict
        direction (or order of qubits in the qargs is significant). For
        example, if ``cx`` is defined on ``(0, 1)`` and ``ecr`` is
        defined over ``(1, 0)`` by default neither would be considered
        non-global, but if ``strict_direction`` is set ``True`` both
        ``cx`` and ``ecr`` would be returned.

Returns:
    List[str]: A list of operation names for operations that aren't global in this target
)r=   r   _get_non_global_operation_namesr>   )r#   strict_directionr   s     r   get_non_global_operation_names%Target.get_non_global_operation_namesI  sb    & ,,4050W$1- 000!!)%*W%LM]%^D"%%%r    c                    U R                   $ )z
Return dt.)_dtr(   s    r   rC   	Target.dtf  s     xxr    c                    Xl         SU l        g)z0Set dt and invalidate instruction duration cacheN)rS   r;   )r#   rC   s     r   rC   rT   k  s     &*#r    angle_boundsc                 > [         R                  " U5      nU(       d  U=(       d    UR                  nO"U(       d  [        S5      eUb  [        S5      eUnUb  U(       a  SS0nX`R                  ;   a  [        SU S35      e[        TU ]  XX$S9  X R                  U'   SU l        SU l	        SU l
        SU l        SU l        g)a  Add a new instruction to the :class:`~qiskit.transpiler.Target`

As ``Target`` objects are strictly additive this is the primary method
for modifying a ``Target``. Typically, you will use this to fully populate
a ``Target`` before using it in :class:`~qiskit.providers.BackendV2`. For
example::

    from qiskit.circuit.library import CXGate
    from qiskit.transpiler import Target, InstructionProperties

    target = Target()
    cx_properties = {
        (0, 1): None,
        (1, 0): None,
        (0, 2): None,
        (2, 0): None,
        (0, 3): None,
        (2, 3): None,
        (3, 0): None,
        (3, 2): None
    }
    target.add_instruction(CXGate(), cx_properties)

Will add a :class:`~qiskit.circuit.library.CXGate` to the target with no
properties (duration, error, etc) with the coupling edge list:
``(0, 1), (1, 0), (0, 2), (2, 0), (0, 3), (2, 3), (3, 0), (3, 2)``. If
there are properties available for the instruction you can replace the
``None`` value in the properties dictionary with an
:class:`~qiskit.transpiler.InstructionProperties` object. This pattern
is repeated for each :class:`~qiskit.circuit.Instruction` the target
supports.

Args:
    instruction (Union[qiskit.circuit.Instruction, Type[qiskit.circuit.Instruction]]):
        The operation object to add to the map. If it's parameterized any value
        of the parameter can be set. Optionally for variable width
        instructions (such as control flow operations such as :class:`~.ForLoop` or
        :class:`~MCXGate`) you can specify the class. If the class is specified than the
        ``name`` argument must be specified. When a class is used the gate is treated as global
        and not having any properties set.
    properties (dict): A dictionary of qarg entries to an
        :class:`~qiskit.transpiler.InstructionProperties` object for that
        instruction implementation on the backend. Properties are optional
        for any instruction implementation, if there are no
        :class:`~qiskit.transpiler.InstructionProperties` available for the
        backend the value can be None. If there are no constraints on the
        instruction (as in a noiseless/ideal simulation) this can be set to
        ``{None, None}`` which will indicate it runs on all qubits (or all
        available permutations of qubits for multi-qubit gates). The first
        ``None`` indicates it applies to all qubits and the second ``None``
        indicates there are no
        :class:`~qiskit.transpiler.InstructionProperties` for the
        instruction. By default, if properties is not set it is equivalent to
        passing ``{None: None}``.
    name (str): An optional name to use for identifying the instruction. If not
        specified the :attr:`~qiskit.circuit.Instruction.name` attribute
        of ``gate`` will be used. All gates in the ``Target`` need unique
        names. Backends can differentiate between different
        parameterization of a single gate by providing a unique name for
        each (e.g. `"rx30"`, `"rx60", ``"rx90"`` similar to the example in the
        documentation for the :class:`~qiskit.transpiler.Target` class).
    angle_bounds (list): The bounds on the parameters for a given gate. This is specified by
        a list of tuples (low, high) which represent the low and high bound (inclusively) on
        what float values are allowed for the parameter in that position. If a parameter
        doesn't have an angle bound you can use ``None`` to represent that. For example if
        a 3 parameter gate only had a bound on the second parameter you would represent
        that with: ``[None, [0, 3.14], None]`` which means the first and third parameter
        allow any value but the second parameter only accepts values between 0 and 3.14.
Raises:
    AttributeError: If gate is already in map
    TranspilerError: If an operation class is passed in for ``instruction`` and no name
        is specified or ``properties`` is set.
zLA name must be specified when defining a supported global operation by classNzAAn instruction added globally by class can't have properties set.zInstruction z is already in the targetrV   )inspectisclassnamer   r9   AttributeErrorr   add_instructionr:   r;   r<   r=   r>   )r#   instruction
propertiesr[   rW   is_classinstruction_namer   s          r   r]   Target.add_instructionq  s    T ??;/#7{'7'7 %b  %%W   $J~~- <0@/AAZ![\\: 	  	
 ,6'(#&*#)-&(,%!%r    c                d   > [         TU ]  XU5        X0R                  U   U'   SU l        SU l        g)a  Update the property object for an instruction qarg pair already in the Target.

For ease of access, a user is able to obtain the mapping between an instruction's
applicable qargs and its instruction properties via the mapping protocol (using ``__getitem__``),
with the instruction's name as the key. This method is the only way to
modify/update the properties of an instruction in the ``Target``. Usage of the mapping protocol
for modifications is not supported.

Args:
    instruction (str): The instruction name to update
    qargs (tuple): The qargs to update the properties of
    properties (InstructionProperties): The properties to set for this instruction
Raises:
    KeyError: If ``instruction`` or ``qarg`` are not in the target
N)r   update_instruction_propertiesr9   r;   r<   )r#   r^   qargsr_   r   s       r   rd   $Target.update_instruction_properties  s5      	-k*M-7{#E*&*#)-&r    c                d    SU R                   U   ;   a  gU R                   U   R                  5       $ )zGet the qargs for a given operation name

Args:
   operation (str): The operation name to get qargs for
Returns:
    set: The set of qargs the gate instance applies to.
Nr9   keys)r#   	operations     r   qargs_for_operation_nameTarget.qargs_for_operation_name  s0     4>>),,~~i(--//r    c                p   U R                   b  U R                   $ / nU R                  R                  5        HZ  u  p#UR                  5        HA  u  pEUc  M
  UR                  c  M  UR	                  U[        U5      UR                  S45        MC     M\     [        XR                  S9U l         U R                   $ )zGet an InstructionDurations object from the target

Returns:
    InstructionDurations: The instruction duration represented in the
        target
s)rC   )r;   r9   itemsr   appendlistr   rC   )r#   out_durationsr^   	props_mapqargr_   s         r   	durationsTarget.durations  s     &&2...&*nn&:&:&<"K$-OO$5 )j.A.A.M!((+tDz:CVCVX[)\] %6 '= ';=WW&U#***r    c                n    [        U R                  U R                  U R                  U R                  5      $ )zGet an :class:`~qiskit.transpiler.TimingConstraints` object from the target

Returns:
    TimingConstraints: The timing constraints represented in the ``Target``
)r   rD   rE   rF   rG   r(   s    r   timing_constraintsTarget.timing_constraints	  s0     !doot/C/CTE[E[
 	
r    c                6    U R                   R                  5       $ )z&Get the operation names in the target.rh   r(   s    r   operation_namesTarget.operation_names  s     ~~""$$r    c                    U R                   R                  5        VVVs/ s H   u  pU  H  nU R                  U   U4PM     M"     snnn$ s  snnnf )zGet the list of tuples (:class:`~qiskit.circuit.Instruction`, (qargs))
for the target

For globally defined variable width operations the tuple will be of the form
``(class, None)`` where class is the actual operation class that
is globally defined.
)r9   ro   _gate_name_map)r#   opre   rt   s       r   instructionsTarget.instructions  sU     "^^113
3	   $d+ ,3
 	
 
s   'Ac                    U R                   R                  5        VVs/ s H  o"R                  5         H  o3PM     M     nnnXA   $ s  snnf )a  Get the instruction properties for a specific instruction tuple

This method is to be used in conjunction with the
:attr:`~qiskit.transpiler.Target.instructions` attribute of a
:class:`~qiskit.transpiler.Target` object. You can use this method to quickly
get the instruction properties for an element of
:attr:`~qiskit.transpiler.Target.instructions` by using the index in that list.
However, if you're not working with :attr:`~qiskit.transpiler.Target.instructions`
directly it is likely more efficient to access the target directly via the name
and qubits to get the instruction properties. For example, if
:attr:`~qiskit.transpiler.Target.instructions` returned::

    [(XGate(), (0,)), (XGate(), (1,))]

you could get the properties of the ``XGate`` on qubit 1 with::

    props = target.instruction_properties(1)

but just accessing it directly via the name would be more efficient::

    props = target['x'][(1,)]

(assuming the ``XGate``'s canonical name in the target is ``'x'``)
This is especially true for larger targets as this will scale worse with the number
of instruction tuples in a target.

Args:
    index (int): The index of the instruction tuple from the
        :attr:`~qiskit.transpiler.Target.instructions` attribute. For, example
        if you want the properties from the third element in
        :attr:`~qiskit.transpiler.Target.instructions` you would set this to be ``2``.
Returns:
    InstructionProperties: The instruction properties for the specified instruction tuple
r9   values)r#   indexre   
inst_propsinstruction_propertiess        r   r   Target.instruction_properties'  sK    H %)NN$9$9$;"
$;5lln
JnJ$; 	 "
 &,,"
s   "Ac                   [         R                  " SS9U l        U R                  b?  U R                  R	                  [        U R                  5       Vs/ s H  n0 PM     sn5        U R                  R                  5        H  u  p#Uc(  U R                  U   R                  S:X  a	  S U l          g M0  UR                  5        H  u  pEUc+  U R                  U5      R                  S:X  a
  S U l            g M3  [        U5      S:X  a  UU R                  US   '   MV  [        U5      S:X  d  Mg   U R                  R                  " U6 nXVU'   M     M     U R                  nU R                  R                  5       S:X  a#  Ub  [!        S U 5       5      (       a  S U l        g g g s  snf ! [         R                   a$    U R                  R                  " / UQX%0P76    GM  f = f)NF
multigraph      r   c              3  (   #    U  H  oS L v   M
     g 7fr   r+   .0xs     r   	<genexpr>/Target._build_coupling_graph.<locals>.<genexpr>k  s      :EqdEs   )rx	PyDiGraphr:   rB   add_nodes_fromranger9   ro   r~   operation_from_namelenget_edge_dataNoEdgeBetweenNodesadd_edgere   	num_edgesany)r#   _gateqarg_maprt   r_   	edge_datare   s           r   _build_coupling_graphTarget._build_coupling_graphO  s   !||u=??&  //U4??=S0T=S=S0TU"nn224ND&&t,771<+/D($,NN$4 <//5@@AE/3,t9>" ((a1 Y!^Q$($8$8$F$F$M	*4$ %5 5, 

))+q0MS :E :::#'D  ; 11 1U* 00 Q,,55PtPd=OPQs   F(F  3GGc                   U R                   c  gSU R                   ;  a6  [        S U R                    5       5      (       a  [        R                  S5        Ub  [        R
                  " SS9nUR                  S/U R                  -  5        X   R                  5        H8  u  pE[        U5      S:w  a  [        SU S35      eUR                  " / UQX0P76   M:     [        5       nX6l        U$ U R                  c  U R                  5         U R                  bI  [        5       nU(       a  U R!                  5       Ul        U$ U R                  R#                  5       Ul        U$ g)	aW  Get a :class:`~qiskit.transpiler.CouplingMap` from this target.

If there is a mix of two qubit operations that have a connectivity
constraint and those that are globally defined this will also return
``None`` because the globally connectivity means there is no constraint
on the target. If you wish to see the constraints of the two qubit
operations that have constraints you should use the ``two_q_gate``
argument to limit the output to the gates which have a constraint.

Args:
    two_q_gate (str): An optional gate name for a two qubit gate in
        the ``Target`` to generate the coupling map for. If specified the
        output coupling map will only have edges between qubits where
        this gate is present.
    filter_idle_qubits (bool): If set to ``True`` the output :class:`~.CouplingMap`
        will remove any qubits that don't have any operations defined in the
        target. Note that using this argument will result in an output
        :class:`~.CouplingMap` object which has holes in its indices
        which might differ from the assumptions of the class. The typical use
        case of this argument is to be paired with
        :meth:`.CouplingMap.connected_components` which will handle the holes
        as expected.
Returns:
    CouplingMap: The :class:`~qiskit.transpiler.CouplingMap` object
        for this target. If there are no connectivity constraints in
        the target this will return ``None``.

Raises:
    ValueError: If a non-two qubit gate is passed in for ``two_q_gate``.
    IndexError: If an Instruction not in the ``Target`` is passed in for
        ``two_q_gate``.
Nc              3  >   #    U  H  n[        U5      S :  v   M     g7f)r   N)r   r   s     r   r   ,Target.build_coupling_map.<locals>.<genexpr>  s     )Ij#a&1*js   zThis Target object contains multiqubit gates that operate on > 2 qubits. This will not be reflected in the output coupling map.Fr   r   zSpecified two_q_gate: z is not a 2 qubit instruction)re   r   loggerwarningr   r   r   rB   ro   r   
ValueErrorr   r   graphr:   r   _filter_coupling_graphcopy)r#   
two_q_gatefilter_idle_qubitscoupling_graphre   r_   cmaps          r   build_coupling_mapTarget.build_coupling_mapo  sE   B ::tzz!c)Idjj)I&I&INN+ !\\U;N))4&4??*BC%)%5%;%;%=!u:?$0<YZ  ''II0HI &> =D'JK'&&( +=D!!88:
 K "11668
Kr    c                >   [        [        R                  R                  S U R                   5       5      5      nU R
                  R                  5       n[        UR                  5       5      R                  U5      nU(       a  UR                  [        U5      5        U$ )Nc              3  .   #    U  H  oc  M  Uv   M     g 7fr   r+   r   s     r   r   0Target._filter_coupling_graph.<locals>.<genexpr>  s     :bj11js   	)set	itertoolschainfrom_iterablere   r:   r   node_indices
differenceremove_nodes_fromrq   )r#   has_operationsr   	to_removes       r   r   Target._filter_coupling_graph  sq    Y__:::bdjj:bbc$$))+**,-88H	##DO4r    c                ,    [        U R                  5      $ r   )iterr9   r(   s    r   __iter__Target.__iter__  s    DNN##r    c                     U R                   U   $ r   r9   )r#   keys     r   __getitem__Target.__getitem__  s    ~~c""r    c                0     X   $ ! [          a    Us $ f = f)zOGets an item from the Target. If not found return a provided default or `None`.)KeyError)r#   r   defaults      r   get
Target.get  s#    	9 	N	s    c                ,    [        U R                  5      $ r   r   r9   r(   s    r   __len__Target.__len__      4>>""r    c                    XR                   ;   $ r   r   )r#   items     r   __contains__Target.__contains__  s    ~~%%r    c                6    U R                   R                  5       $ )z/Return the keys (operation_names) of the Targetrh   r(   s    r   ri   Target.keys  s    ~~""$$r    c                6    U R                   R                  5       $ )z[Return the Property Map (qargs -> InstructionProperties) of every instruction in the Targetr   r(   s    r   r   Target.values  s    ~~$$&&r    c                6    U R                   R                  5       $ )zZReturns pairs of Gate names and its property map (str, dict[tuple, InstructionProperties]))r9   ro   r(   s    r   ro   Target.items  s    ~~##%%r    c                   [         R                  " 5       nU R                  b   UR                  SU R                   S35        OUR                  S5        UR                  SU R                   S35        UR                  S5        U R
                  R                  5        GH'  u  p#UR                  SU S35        UR                  5        H  u  pEUc  M
  Uc  UR                  SU S35        M$  SU S3/n[        US	S 5      nUb  UR                  S
US S35        [        USS 5      nUb  UR                  SUS S35        [        USS 5      n	U	bQ  U	R                  5        V
Vs/ s H  u  pSU
 SU S3PM     nn
nSR                  U5      nUR                  SU S35        UR                  SR                  U5      5        M     GM*     UR                  5       $ s  snn
f )NzTarget: 
zTarget
zNumber of qubits: zInstructions:
	z		z:
r   z			Duration: gz sec.
r   z			Error Rate: r_   z				z:  z			Extra properties:
)ioStringIOrA   writerB   r9   ro   getattrrp   joingetvalue)r#   outputinst
qarg_propsrt   propsprop_str_piecesr   r   extra_propsr   valueextra_props_piecesextra_props_strs                 r   __str__Target.__str__  s   'LL8D$4$4#5R89LL$)$//):"=>&' $ 4 4 6DLL2dV2')//1<=LL4vR1%)$s#3"4"5*d;'#**-=hq\+QRw5$#**-?ay+KL%e\4@*FQFWFWFY*FY
(3%r%3FY ' * ')gg.@&AO#**-FFWWY+Z[RWW_56)  2 !7.   *s   #G
c                |   > U R                   U R                  U R                  U R                  [        TU ]  5       S.$ )N)r9   r   instruction_durationsinstruction_schedule_mapbase)r9   r:   r;   r<   r   __getstate__)r#   r   s    r   r   Target.__getstate__  s:    "22%)%@%@(,(F(FG(*
 	
r    c                z   > US   U l         US   U l        US   U l        US   U l        [        TU ]  US   5        g )Nr9   r   r   r   r   )r9   r:   r;   r<   r   __setstate__)r#   stater   s     r   r   Target.__setstate__  sJ    {+$%56&+,C&D#)./I)J&U6]+r    c                ,    [        XR                  5      $ )zConvert a given duration in seconds to units of dt

Args:
    duration: The duration in seconds, such as in an :class:`.InstructionProperties`
        field for an instruction in the target.

Returns
    duration: The duration in units of dt
)r   rC   )r#   r   s     r   seconds_to_dtTarget.seconds_to_dt  s     h00r    c	                   Sn	Sn
SnSnUb0  UR                   n	UR                  n
UR                  nUR                  nSnU " UUU	U
UUUUS9n[	        5       nUb  UR                  U5        Uc3  U H+  nUU;  a  [        SU S35      eUR                  UU   US9  M-     U$ / n/ n/ nUc  [        UR                  5      nU H  nUU;  a  [        SU S35      eUU   nUR                  S:X  a  UR                  U5        M@  UR                  S:X  a  UR                  U5        Mc  [        R                  " U5      (       a  UR                  U5        M  [        SU SUR                   S	35      e   U H`  n0 n[        U5       H8  nSnSnUb   UR!                  UUS
S9nUc  Uc  SUU4'   M*  [#        UUS9UU4'   M:     UR                  UU   UUS9  Mb     [%        UR'                  5       5      nU HU  n0 nU H6  nSnSnUb   UR!                  UUS
S9nUc
  Uc  SUU'   M)  [#        UUS9UU'   M8     UR                  UU   UUS9  MW     U H  nUR                  UU   US9  M     U$ ! [         a    Sn Nf = f! [         a    Sn Ntf = f)a
  Create a target object from the individual global configuration

Prior to the creation of the :class:`~.Target` class, the constraints
of a backend were represented by a collection of different objects
which combined represent a subset of the information contained in
the :class:`~.Target`. This function provides a simple interface
to convert those separate objects to a :class:`~.Target`.

This constructor will use the input from ``basis_gates``, ``num_qubits``,
and ``coupling_map`` to build a base model of the backend and the
``instruction_durations``, ``backend_properties``, and ``inst_map`` inputs
are then queried (in that order) based on that model to look up the properties
of each instruction and qubit. If there is an inconsistency between the inputs
any extra or conflicting information present in ``instruction_durations``,
``backend_properties``, or ``inst_map`` will be ignored.

Args:
    basis_gates: The list of basis gate names for the backend. For the
        target to be created these names must either be in the output
        from :func:`~.get_standard_gate_name_mapping` or present in the
        specified ``custom_name_mapping`` argument.
    num_qubits: The number of qubits supported on the backend.
    coupling_map: The coupling map representing connectivity constraints
        on the backend. If specified all gates from ``basis_gates`` will
        be supported on all qubits (or pairs of qubits).
    instruction_durations: Optional instruction durations for instructions. If specified
        it will take priority for setting the ``duration`` field in the
        :class:`~InstructionProperties` objects for the instructions in the target.
    concurrent_measurements(list): A list of sets of qubits that must be
        measured together. This must be provided
        as a nested list like ``[[0, 1], [2, 3, 4]]``.
    dt: The system time resolution of input signals in seconds
    timing_constraints: Optional timing constraints to include in the
        :class:`~.Target`
    custom_name_mapping: An optional dictionary that maps custom gate/operation names in
        ``basis_gates`` to an :class:`~.Operation` object representing that
        gate/operation. By default, most standard gates names are mapped to the
        standard gate object from :mod:`qiskit.circuit.library` this only needs
        to be specified if the input ``basis_gates`` defines gates in names outside
        that set.

Returns:
    Target: the target built from the input configuration

Raises:
    TranspilerError: If the input basis gates contain > 2 qubits and ``coupling_map`` is
    specified.
    KeyError: If no mapping is available for a specified ``basis_gate``.
r   N)rB   rC   rD   rE   rF   rG   rH   rI   zThe specified basis gate: zL is not present in the standard gate names or a provided custom_name_mapping)r[   r   z has z qubits. This constructor method only supports fixed width operations with <= 2 qubits (because connectivity is defined on a CouplingMap).rn   )unitr'   )r_   r[   )rD   rE   rF   rG   r
   updater   r]   r   r   rB   rp   rY   rZ   r   r   r   r   rq   	get_edges)r   basis_gatesrB   coupling_mapr   rI   rC   rx   custom_name_mappingrD   rE   rF   rG   rH   targetname_mappingr   one_qubit_gatestwo_qubit_gates!global_ideal_variable_width_gatesgate_objgate_propertiesqubitr   r   edgesedges                              r   from_configurationTarget.from_configuration  si   z 
),88K+66J0@@O 2 D D!#!+/-$;	
 67* 34 #|+"4TF ;B B  &&|D'9&E $R C !O O02-! !3!34
#|+"4TF ;B B  (-&&!+#**40((A-#**40__X..5<<TB)4TF%@S@S?T U_ _  $& (FH":.E E#H,8,'<'@'@uSV'@'WH })94814I%-U51 /  &&|D'9o\`&a% (& //12E'"$!D E#H,8,'<'@'@tRU'@'VH })904-0E%-U1- "  &&|D'9o\`&a% (& :&&|D'9&E :A  / ,'+H,(  / ,'+H,s$   I&I8&I54I58JJ)r:   rS   r9   r;   r<   r>   r=   )	Nr   Nr   r   r   r   NN)rA   z
str | NonerB   
int | NonerC   r-   rD   intrE   r  rF   r  rG   r  rH   list | NonerI   r  )Fr,   )NFr   )returndict)r   tuple)r   floatr  r  )NNNNNNN)r  z	list[str]rB   r  r  zCouplingMap | Noner   zInstructionDurations | NonerI   zOptional[List[List[int]]]rC   r-   rx   zTimingConstraints | Noner  zdict[str, Any] | Noner  r7   )&r.   r/   r0   r1   r2   	__slots__r   rP   propertyrC   setterr]   rd   rk   ru   rx   r{   r   r   r   r   r   r   r   r   r   r   ri   r   ro   r   r   r   r   classmethodr  r3   r4   r5   s   @r   r7   r7   ]   s   PdI #'!" !"(,/3NN N 	N
 N N N N &N "-N N`&:   YY+ +
d&W[ d& d&L.*
0+"
 % % 
 
&-P(@BH$##&%'&!B
,
1  "&+/=A=A7;59ff f )	f
  ;f ";f f 5f 3f 
f fr    r7   c                     ^  \ rS rSrSr          SU 4S jjr          SU 4S jjrS rS rU 4S jr	\
SSS	.     SS
 jj5       rSrU =r$ )_FakeTargeti  a%  
Pseudo-target class for INTERNAL use in the transpilation pipeline.
It's essentially an empty :class:`.Target` instance with a `coupling_map`
argument that allows to store connectivity constraints without basis gates.
This is intended to replace the use of loose constraints in the pipeline.
Nc                0   > [         TU ]  U UUUUUUUU	U
S9
$ )N)	rA   rB   rC   rD   rE   rF   rG   rH   rI   )r   r   )r   r  rA   rB   rC   rD   rE   rF   rG   rH   rI   r   s              r   r   _FakeTarget.__new__  s9     w#!#!+/-$;  
 	
r    c                   > [         TU ]  5         Ub  [        U[        5      (       a  Xl        g [        U5      U l        g r   )r   r"   
isinstancer   _coupling_map)r#   r  rA   rB   rC   rD   rE   rF   rG   rH   rI   r   s              r   r"   _FakeTarget.__init__  s5     	:lK#H#H!-!,\!:Dr    c                ,    [        U R                  5      $ r   r   r(   s    r   r   _FakeTarget.__len__  r   r    c                B    [         R                  " U R                  5      $ r   )r   deepcopyr%  )r#   r   r   s      r   r   _FakeTarget.build_coupling_map  s    }}T//00r    c                X   > [        U R                  5      S:X  a  g[        TU ]  " U0 UD6$ )zChecks whether an instruction is supported by the
Target based on instruction name and qargs. Note that if there are no
basis gates in the Target, this method will always return ``True``.
r   T)r   r{   r   instruction_supported)r#   r   r   r   s      r   r-  !_FakeTarget.instruction_supported  s0    
 t##$)70$A&AAr    rB   r  c               L    Uc  Ub  [        UR                  5      nU " X1US.UD6$ )Nr/  )r   r   )r   rB   r  r   r   s        r   r  _FakeTarget.from_configuration	  s1     ,":\//0Jd|UfUUr    )r%  )
NNr   Nr   r   r   r   NN)rB   r  r  zCouplingMap | list | Noner  r   )r.   r/   r0   r1   r2   r   r"   r   r   r-  r  r  r3   r4   r5   s   @r   r   r     s      $
8  $;&#1B  "&26	V V 0	V 
V Vr    r   )(r2   
__future__r   r   typingr   r   r   collections.abcr   r   r   loggingrY   	rustworkxr   qiskit._accelerate.targetr   r	   %qiskit.circuit.library.standard_gatesr
   qiskit.circuit.durationr   qiskit.transpiler.couplingr   qiskit.transpiler.exceptionsr   'qiskit.transpiler.instruction_durationsr   $qiskit.transpiler.timing_constraintsr   qiskit.providers.backendr   	getLoggerr.   r   r   r7   registerr   r+   r    r   <module>rA     s   
 #  & & # 	    
 Q 2 2 8 H B 5			8	$%V5 %VPaZ aH    QV& QVr    