mirror of https://github.com/Qiskit/qiskit.git
110 lines
5.7 KiB
YAML
110 lines
5.7 KiB
YAML
---
|
|
features:
|
|
- |
|
|
Add support for representing an operation that has a variable width
|
|
to the :class:`~.Target` class. Previously, a :class:`~.Target` object
|
|
needed to have an instance of :class:`~Operation` defined for each
|
|
operation supported in the target. This was used for both validation
|
|
of arguments and parameters of the operation. However, for operations
|
|
that have a variable width this wasn't possible because each instance
|
|
of an :class:`~Operation` class can only have a fixed number of qubits.
|
|
For cases where a backend supports variable width operations the
|
|
instruction can be added with the class of the operation instead of an
|
|
instance. In such cases the operation will be treated as globally
|
|
supported on all qubits. For example, if building a target like::
|
|
|
|
from qiskit.circuit import Parameter, Measure, IfElseOp, ForLoopOp, WhileLoopOp
|
|
from qiskit.circuit.library import IGate, RZGate, SXGate, XGate, CXGate
|
|
from qiskit.transpiler import Target, InstructionProperties
|
|
|
|
theta = Parameter("theta")
|
|
|
|
ibm_target = Target()
|
|
i_props = {
|
|
(0,): InstructionProperties(duration=35.5e-9, error=0.000413),
|
|
(1,): InstructionProperties(duration=35.5e-9, error=0.000502),
|
|
(2,): InstructionProperties(duration=35.5e-9, error=0.0004003),
|
|
(3,): InstructionProperties(duration=35.5e-9, error=0.000614),
|
|
(4,): InstructionProperties(duration=35.5e-9, error=0.006149),
|
|
}
|
|
ibm_target.add_instruction(IGate(), i_props)
|
|
rz_props = {
|
|
(0,): InstructionProperties(duration=0, error=0),
|
|
(1,): InstructionProperties(duration=0, error=0),
|
|
(2,): InstructionProperties(duration=0, error=0),
|
|
(3,): InstructionProperties(duration=0, error=0),
|
|
(4,): InstructionProperties(duration=0, error=0),
|
|
}
|
|
ibm_target.add_instruction(RZGate(theta), rz_props)
|
|
sx_props = {
|
|
(0,): InstructionProperties(duration=35.5e-9, error=0.000413),
|
|
(1,): InstructionProperties(duration=35.5e-9, error=0.000502),
|
|
(2,): InstructionProperties(duration=35.5e-9, error=0.0004003),
|
|
(3,): InstructionProperties(duration=35.5e-9, error=0.000614),
|
|
(4,): InstructionProperties(duration=35.5e-9, error=0.006149),
|
|
}
|
|
ibm_target.add_instruction(SXGate(), sx_props)
|
|
x_props = {
|
|
(0,): InstructionProperties(duration=35.5e-9, error=0.000413),
|
|
(1,): InstructionProperties(duration=35.5e-9, error=0.000502),
|
|
(2,): InstructionProperties(duration=35.5e-9, error=0.0004003),
|
|
(3,): InstructionProperties(duration=35.5e-9, error=0.000614),
|
|
(4,): InstructionProperties(duration=35.5e-9, error=0.006149),
|
|
}
|
|
ibm_target.add_instruction(XGate(), x_props)
|
|
cx_props = {
|
|
(3, 4): InstructionProperties(duration=270.22e-9, error=0.00713),
|
|
(4, 3): InstructionProperties(duration=305.77e-9, error=0.00713),
|
|
(3, 1): InstructionProperties(duration=462.22e-9, error=0.00929),
|
|
(1, 3): InstructionProperties(duration=497.77e-9, error=0.00929),
|
|
(1, 2): InstructionProperties(duration=227.55e-9, error=0.00659),
|
|
(2, 1): InstructionProperties(duration=263.11e-9, error=0.00659),
|
|
(0, 1): InstructionProperties(duration=519.11e-9, error=0.01201),
|
|
(1, 0): InstructionProperties(duration=554.66e-9, error=0.01201),
|
|
}
|
|
ibm_target.add_instruction(CXGate(), cx_props)
|
|
measure_props = {
|
|
(0,): InstructionProperties(duration=5.813e-6, error=0.0751),
|
|
(1,): InstructionProperties(duration=5.813e-6, error=0.0225),
|
|
(2,): InstructionProperties(duration=5.813e-6, error=0.0146),
|
|
(3,): InstructionProperties(duration=5.813e-6, error=0.0215),
|
|
(4,): InstructionProperties(duration=5.813e-6, error=0.0333),
|
|
}
|
|
ibm_target.add_instruction(Measure(), measure_props)
|
|
ibm_target.add_instruction(IfElseOp, name="if_else")
|
|
ibm_target.add_instruction(ForLoopOp, name="for_loop")
|
|
ibm_target.add_instruction(WhileLoopOp, name="while_loop")
|
|
|
|
The :class:`~.IfElseOp`, :class:`~.ForLoopOp`, and :class:`~.WhileLoopOp`
|
|
operations are globally supported for any number of qubits. This is then
|
|
reflected by other calls in the :class:`~.Target` API such as
|
|
:meth:`~.Target.instruction_supported`::
|
|
|
|
ibm_target.instruction_supported(operation_class=WhileLoopOp, qargs=(0, 2, 3, 4))
|
|
ibm_target.instruction_supported('if_else', qargs=(0, 1))
|
|
|
|
both return ``True``.
|
|
upgrade:
|
|
- |
|
|
For :class:`~.Target` objects that only contain globally defined 2 qubit
|
|
operations without any connectivity constaints the return from the
|
|
:meth:`.Target.build_coupling_map` method will now return ``None`` instead
|
|
of a :class:`~.CouplingMap` object that contains ``num_qubits`` nodes
|
|
and no edges. This change was made to better reflect the actual
|
|
connectivity constraints of the :class:`~.Target` because in this case
|
|
there are no connectivity constraints on the backend being modeled by
|
|
the :class:`~.Target`, not a lack of connectivity. If you desire the
|
|
previous behavior for any reason you can reproduce it by checking for a
|
|
``None`` return and manually building a coupling map, for example::
|
|
|
|
from qiskit.transpiler import Target, CouplingMap
|
|
from qiskit.circuit.library import CXGate
|
|
|
|
target = Target(num_qubits=3)
|
|
target.add_instruction(CXGate())
|
|
cmap = target.build_coupling_map()
|
|
if cmap is None:
|
|
cmap = CouplingMap()
|
|
for i in range(target.num_qubits):
|
|
cmap.add_physical_qubit(i)
|