qiskit 1.3.0rc1__cp39-abi3-win_amd64.whl → 1.3.1__cp39-abi3-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qiskit/VERSION.txt +1 -1
- qiskit/_accelerate.pyd +0 -0
- qiskit/circuit/add_control.py +110 -92
- qiskit/circuit/library/__init__.py +37 -10
- qiskit/circuit/library/arithmetic/adders/adder.py +30 -5
- qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
- qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +1 -1
- qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +1 -1
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +9 -0
- qiskit/primitives/utils.py +1 -1
- qiskit/providers/__init__.py +2 -2
- qiskit/qpy/__init__.py +5 -5
- qiskit/quantum_info/operators/channel/chi.py +9 -9
- qiskit/quantum_info/operators/channel/choi.py +9 -9
- qiskit/quantum_info/operators/channel/ptm.py +9 -9
- qiskit/quantum_info/operators/channel/quantum_channel.py +3 -3
- qiskit/quantum_info/operators/channel/stinespring.py +9 -9
- qiskit/quantum_info/operators/channel/superop.py +5 -9
- qiskit/quantum_info/states/densitymatrix.py +17 -15
- qiskit/quantum_info/states/stabilizerstate.py +7 -6
- qiskit/quantum_info/states/statevector.py +15 -7
- qiskit/transpiler/passes/basis/decompose.py +24 -4
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +10 -3
- qiskit/transpiler/passes/optimization/inverse_cancellation.py +2 -0
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +8 -9
- qiskit/transpiler/passes/synthesis/hls_plugins.py +89 -21
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +4 -3
- {qiskit-1.3.0rc1.dist-info → qiskit-1.3.1.dist-info}/METADATA +18 -18
- {qiskit-1.3.0rc1.dist-info → qiskit-1.3.1.dist-info}/RECORD +33 -33
- {qiskit-1.3.0rc1.dist-info → qiskit-1.3.1.dist-info}/WHEEL +1 -1
- {qiskit-1.3.0rc1.dist-info → qiskit-1.3.1.dist-info}/entry_points.txt +1 -1
- {qiskit-1.3.0rc1.dist-info → qiskit-1.3.1.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.3.0rc1.dist-info → qiskit-1.3.1.dist-info}/top_level.txt +0 -0
@@ -18,6 +18,8 @@ Pauli Transfer Matrix (PTM) representation of a Quantum Channel.
|
|
18
18
|
from __future__ import annotations
|
19
19
|
import copy as _copy
|
20
20
|
import math
|
21
|
+
from typing import TYPE_CHECKING
|
22
|
+
|
21
23
|
import numpy as np
|
22
24
|
|
23
25
|
from qiskit import _numpy_compat
|
@@ -30,6 +32,9 @@ from qiskit.quantum_info.operators.channel.transformations import _to_ptm
|
|
30
32
|
from qiskit.quantum_info.operators.mixins import generate_apidocs
|
31
33
|
from qiskit.quantum_info.operators.base_operator import BaseOperator
|
32
34
|
|
35
|
+
if TYPE_CHECKING:
|
36
|
+
from qiskit import circuit
|
37
|
+
|
33
38
|
|
34
39
|
class PTM(QuantumChannel):
|
35
40
|
r"""Pauli Transfer Matrix (PTM) representation of a Quantum Channel.
|
@@ -67,21 +72,16 @@ class PTM(QuantumChannel):
|
|
67
72
|
|
68
73
|
def __init__(
|
69
74
|
self,
|
70
|
-
data: QuantumCircuit | Instruction | BaseOperator | np.ndarray,
|
75
|
+
data: QuantumCircuit | circuit.instruction.Instruction | BaseOperator | np.ndarray,
|
71
76
|
input_dims: int | tuple | None = None,
|
72
77
|
output_dims: int | tuple | None = None,
|
73
78
|
):
|
74
79
|
"""Initialize a PTM quantum channel operator.
|
75
80
|
|
76
81
|
Args:
|
77
|
-
data
|
78
|
-
|
79
|
-
|
80
|
-
matrix): data to initialize superoperator.
|
81
|
-
input_dims (tuple): the input subsystem dimensions.
|
82
|
-
[Default: None]
|
83
|
-
output_dims (tuple): the output subsystem dimensions.
|
84
|
-
[Default: None]
|
82
|
+
data: data to initialize superoperator.
|
83
|
+
input_dims: the input subsystem dimensions.
|
84
|
+
output_dims: the output subsystem dimensions.
|
85
85
|
|
86
86
|
Raises:
|
87
87
|
QiskitError: if input data is not an N-qubit channel or
|
@@ -53,9 +53,9 @@ class QuantumChannel(LinearOp):
|
|
53
53
|
"""Initialize a quantum channel Superoperator operator.
|
54
54
|
|
55
55
|
Args:
|
56
|
-
data
|
57
|
-
op_shape
|
58
|
-
num_qubits
|
56
|
+
data: quantum channel data array.
|
57
|
+
op_shape: the operator shape of the channel.
|
58
|
+
num_qubits: the number of qubits if the channel is N-qubit.
|
59
59
|
|
60
60
|
Raises:
|
61
61
|
QiskitError: if arguments are invalid.
|
@@ -17,6 +17,8 @@ from __future__ import annotations
|
|
17
17
|
import copy
|
18
18
|
import math
|
19
19
|
from numbers import Number
|
20
|
+
from typing import TYPE_CHECKING
|
21
|
+
|
20
22
|
import numpy as np
|
21
23
|
|
22
24
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
@@ -32,6 +34,9 @@ from qiskit.quantum_info.operators.channel.transformations import _to_stinesprin
|
|
32
34
|
from qiskit.quantum_info.operators.mixins import generate_apidocs
|
33
35
|
from qiskit.quantum_info.operators.base_operator import BaseOperator
|
34
36
|
|
37
|
+
if TYPE_CHECKING:
|
38
|
+
from qiskit import circuit
|
39
|
+
|
35
40
|
|
36
41
|
class Stinespring(QuantumChannel):
|
37
42
|
r"""Stinespring representation of a quantum channel.
|
@@ -64,21 +69,16 @@ class Stinespring(QuantumChannel):
|
|
64
69
|
|
65
70
|
def __init__(
|
66
71
|
self,
|
67
|
-
data: QuantumCircuit | Instruction | BaseOperator | np.ndarray,
|
72
|
+
data: QuantumCircuit | circuit.instruction.Instruction | BaseOperator | np.ndarray,
|
68
73
|
input_dims: int | tuple | None = None,
|
69
74
|
output_dims: int | tuple | None = None,
|
70
75
|
):
|
71
76
|
"""Initialize a quantum channel Stinespring operator.
|
72
77
|
|
73
78
|
Args:
|
74
|
-
data
|
75
|
-
|
76
|
-
|
77
|
-
matrix): data to initialize superoperator.
|
78
|
-
input_dims (tuple): the input subsystem dimensions.
|
79
|
-
[Default: None]
|
80
|
-
output_dims (tuple): the output subsystem dimensions.
|
81
|
-
[Default: None]
|
79
|
+
data: data to initialize superoperator.
|
80
|
+
input_dims: the input subsystem dimensions.
|
81
|
+
output_dims: the output subsystem dimensions.
|
82
82
|
|
83
83
|
Raises:
|
84
84
|
QiskitError: if input data cannot be initialized as a
|
@@ -33,6 +33,7 @@ from qiskit.quantum_info.operators.op_shape import OpShape
|
|
33
33
|
from qiskit.quantum_info.operators.operator import Operator
|
34
34
|
|
35
35
|
if TYPE_CHECKING:
|
36
|
+
from qiskit import circuit
|
36
37
|
from qiskit.quantum_info.states.densitymatrix import DensityMatrix
|
37
38
|
from qiskit.quantum_info.states.statevector import Statevector
|
38
39
|
|
@@ -62,21 +63,16 @@ class SuperOp(QuantumChannel):
|
|
62
63
|
|
63
64
|
def __init__(
|
64
65
|
self,
|
65
|
-
data: QuantumCircuit | Instruction | BaseOperator | np.ndarray,
|
66
|
+
data: QuantumCircuit | circuit.instruction.Instruction | BaseOperator | np.ndarray,
|
66
67
|
input_dims: tuple | None = None,
|
67
68
|
output_dims: tuple | None = None,
|
68
69
|
):
|
69
70
|
"""Initialize a quantum channel Superoperator operator.
|
70
71
|
|
71
72
|
Args:
|
72
|
-
data
|
73
|
-
|
74
|
-
|
75
|
-
matrix): data to initialize superoperator.
|
76
|
-
input_dims (tuple): the input subsystem dimensions.
|
77
|
-
[Default: None]
|
78
|
-
output_dims (tuple): the output subsystem dimensions.
|
79
|
-
[Default: None]
|
73
|
+
data: data to initialize superoperator.
|
74
|
+
input_dims: the input subsystem dimensions.
|
75
|
+
output_dims: the output subsystem dimensions.
|
80
76
|
|
81
77
|
Raises:
|
82
78
|
QiskitError: if input data cannot be initialized as a
|
@@ -17,6 +17,8 @@ DensityMatrix quantum state class.
|
|
17
17
|
from __future__ import annotations
|
18
18
|
import copy as _copy
|
19
19
|
from numbers import Number
|
20
|
+
from typing import TYPE_CHECKING
|
21
|
+
|
20
22
|
import numpy as np
|
21
23
|
|
22
24
|
from qiskit import _numpy_compat
|
@@ -37,27 +39,27 @@ from qiskit.quantum_info.operators.channel.superop import SuperOp
|
|
37
39
|
from qiskit._accelerate.pauli_expval import density_expval_pauli_no_x, density_expval_pauli_with_x
|
38
40
|
from qiskit.quantum_info.states.statevector import Statevector
|
39
41
|
|
42
|
+
if TYPE_CHECKING:
|
43
|
+
from qiskit import circuit
|
44
|
+
|
40
45
|
|
41
46
|
class DensityMatrix(QuantumState, TolerancesMixin):
|
42
47
|
"""DensityMatrix class"""
|
43
48
|
|
44
49
|
def __init__(
|
45
50
|
self,
|
46
|
-
data: np.ndarray | list | QuantumCircuit | Instruction | QuantumState,
|
51
|
+
data: np.ndarray | list | QuantumCircuit | circuit.instruction.Instruction | QuantumState,
|
47
52
|
dims: int | tuple | list | None = None,
|
48
53
|
):
|
49
54
|
"""Initialize a density matrix object.
|
50
55
|
|
51
56
|
Args:
|
52
|
-
data
|
53
|
-
qiskit.circuit.Instruction):
|
54
|
-
A statevector, quantum instruction or an object with a ``to_operator`` or
|
57
|
+
data: A statevector, quantum instruction or an object with a ``to_operator`` or
|
55
58
|
``to_matrix`` method from which the density matrix can be constructed.
|
56
59
|
If a vector the density matrix is constructed as the projector of that vector.
|
57
60
|
If a quantum instruction, the density matrix is constructed by assuming all
|
58
61
|
qubits are initialized in the zero state.
|
59
|
-
dims
|
60
|
-
of the state (See additional information).
|
62
|
+
dims: The subsystem dimension of the state (See additional information).
|
61
63
|
|
62
64
|
Raises:
|
63
65
|
QiskitError: if input data is not valid.
|
@@ -303,19 +305,17 @@ class DensityMatrix(QuantumState, TolerancesMixin):
|
|
303
305
|
|
304
306
|
def evolve(
|
305
307
|
self,
|
306
|
-
other: Operator | QuantumChannel | Instruction | QuantumCircuit,
|
308
|
+
other: Operator | QuantumChannel | circuit.instruction.Instruction | QuantumCircuit,
|
307
309
|
qargs: list[int] | None = None,
|
308
310
|
) -> DensityMatrix:
|
309
311
|
"""Evolve a quantum state by an operator.
|
310
312
|
|
311
313
|
Args:
|
312
|
-
other
|
313
|
-
|
314
|
-
qargs (list): a list of QuantumState subsystem positions to apply
|
315
|
-
the operator on.
|
314
|
+
other: The operator to evolve by.
|
315
|
+
qargs: a list of QuantumState subsystem positions to apply the operator on.
|
316
316
|
|
317
317
|
Returns:
|
318
|
-
|
318
|
+
The output density matrix.
|
319
319
|
|
320
320
|
Raises:
|
321
321
|
QiskitError: if the operator dimension does not match the
|
@@ -598,7 +598,9 @@ class DensityMatrix(QuantumState, TolerancesMixin):
|
|
598
598
|
return DensityMatrix(state, dims=dims)
|
599
599
|
|
600
600
|
@classmethod
|
601
|
-
def from_instruction(
|
601
|
+
def from_instruction(
|
602
|
+
cls, instruction: circuit.instruction.Instruction | QuantumCircuit
|
603
|
+
) -> DensityMatrix:
|
602
604
|
"""Return the output density matrix of an instruction.
|
603
605
|
|
604
606
|
The statevector is initialized in the state :math:`|{0,\\ldots,0}\\rangle` of
|
@@ -606,10 +608,10 @@ class DensityMatrix(QuantumState, TolerancesMixin):
|
|
606
608
|
by the input instruction, and the output statevector returned.
|
607
609
|
|
608
610
|
Args:
|
609
|
-
instruction
|
611
|
+
instruction: instruction or circuit
|
610
612
|
|
611
613
|
Returns:
|
612
|
-
|
614
|
+
The final density matrix.
|
613
615
|
|
614
616
|
Raises:
|
615
617
|
QiskitError: if the instruction contains invalid instructions for
|
@@ -17,6 +17,7 @@ Stabilizer state class.
|
|
17
17
|
from __future__ import annotations
|
18
18
|
|
19
19
|
from collections.abc import Collection
|
20
|
+
from typing import TYPE_CHECKING
|
20
21
|
|
21
22
|
import numpy as np
|
22
23
|
|
@@ -28,6 +29,9 @@ from qiskit.quantum_info.operators.symplectic.clifford_circuits import _append_x
|
|
28
29
|
from qiskit.quantum_info.states.quantum_state import QuantumState
|
29
30
|
from qiskit.circuit import QuantumCircuit, Instruction
|
30
31
|
|
32
|
+
if TYPE_CHECKING:
|
33
|
+
from qiskit import circuit
|
34
|
+
|
31
35
|
|
32
36
|
class StabilizerState(QuantumState):
|
33
37
|
"""StabilizerState class.
|
@@ -79,17 +83,14 @@ class StabilizerState(QuantumState):
|
|
79
83
|
|
80
84
|
def __init__(
|
81
85
|
self,
|
82
|
-
data: StabilizerState | Clifford | Pauli | QuantumCircuit | Instruction,
|
86
|
+
data: StabilizerState | Clifford | Pauli | QuantumCircuit | circuit.instruction.Instruction,
|
83
87
|
validate: bool = True,
|
84
88
|
):
|
85
89
|
"""Initialize a StabilizerState object.
|
86
90
|
|
87
91
|
Args:
|
88
|
-
data
|
89
|
-
|
90
|
-
Data from which the stabilizer state can be constructed.
|
91
|
-
validate (boolean): validate that the stabilizer state data is
|
92
|
-
a valid Clifford.
|
92
|
+
data: Data from which the stabilizer state can be constructed.
|
93
|
+
validate: validate that the stabilizer state data is a valid Clifford.
|
93
94
|
"""
|
94
95
|
|
95
96
|
# Initialize from another StabilizerState
|
@@ -18,6 +18,7 @@ import copy as _copy
|
|
18
18
|
import math
|
19
19
|
import re
|
20
20
|
from numbers import Number
|
21
|
+
from typing import TYPE_CHECKING
|
21
22
|
|
22
23
|
import numpy as np
|
23
24
|
|
@@ -37,27 +38,34 @@ from qiskit._accelerate.pauli_expval import (
|
|
37
38
|
expval_pauli_with_x,
|
38
39
|
)
|
39
40
|
|
41
|
+
if TYPE_CHECKING:
|
42
|
+
from qiskit import circuit
|
43
|
+
|
40
44
|
|
41
45
|
class Statevector(QuantumState, TolerancesMixin):
|
42
46
|
"""Statevector class"""
|
43
47
|
|
44
48
|
def __init__(
|
45
49
|
self,
|
46
|
-
data:
|
50
|
+
data: (
|
51
|
+
np.ndarray
|
52
|
+
| list
|
53
|
+
| Statevector
|
54
|
+
| Operator
|
55
|
+
| QuantumCircuit
|
56
|
+
| circuit.instruction.Instruction
|
57
|
+
),
|
47
58
|
dims: int | tuple | list | None = None,
|
48
59
|
):
|
49
60
|
"""Initialize a statevector object.
|
50
61
|
|
51
62
|
Args:
|
52
|
-
data
|
53
|
-
qiskit.circuit.Instruction):
|
54
|
-
Data from which the statevector can be constructed. This can be either a complex
|
63
|
+
data: Data from which the statevector can be constructed. This can be either a complex
|
55
64
|
vector, another statevector, a ``Operator`` with only one column or a
|
56
65
|
``QuantumCircuit`` or ``Instruction``. If the data is a circuit or instruction,
|
57
66
|
the statevector is constructed by assuming that all qubits are initialized to the
|
58
67
|
zero state.
|
59
|
-
dims
|
60
|
-
the state (See additional information).
|
68
|
+
dims: The subsystem dimension of the state (See additional information).
|
61
69
|
|
62
70
|
Raises:
|
63
71
|
QiskitError: if input data is not valid.
|
@@ -476,7 +484,7 @@ class Statevector(QuantumState, TolerancesMixin):
|
|
476
484
|
pauli_phase = (-1j) ** pauli.phase if pauli.phase else 1
|
477
485
|
|
478
486
|
if x_mask + z_mask == 0:
|
479
|
-
return pauli_phase * np.linalg.norm(self.data)
|
487
|
+
return pauli_phase * np.linalg.norm(self.data) ** 2
|
480
488
|
|
481
489
|
if x_mask == 0:
|
482
490
|
return pauli_phase * expval_pauli_no_x(self.data, self.num_qubits, z_mask)
|
@@ -17,8 +17,10 @@ from __future__ import annotations
|
|
17
17
|
from collections.abc import Sequence
|
18
18
|
from typing import Type
|
19
19
|
from fnmatch import fnmatch
|
20
|
+
import warnings
|
20
21
|
|
21
22
|
from qiskit.transpiler.basepasses import TransformationPass
|
23
|
+
from qiskit.transpiler.passes.utils import control_flow
|
22
24
|
from qiskit.dagcircuit.dagnode import DAGOpNode
|
23
25
|
from qiskit.dagcircuit.dagcircuit import DAGCircuit
|
24
26
|
from qiskit.converters.circuit_to_dag import circuit_to_dag
|
@@ -58,7 +60,7 @@ class Decompose(TransformationPass):
|
|
58
60
|
output dag where ``gate`` was expanded.
|
59
61
|
"""
|
60
62
|
# We might use HLS to synthesize objects that do not have a definition
|
61
|
-
hls = HighLevelSynthesis() if self.apply_synthesis else None
|
63
|
+
hls = HighLevelSynthesis(qubits_initially_zero=False) if self.apply_synthesis else None
|
62
64
|
|
63
65
|
# Walk through the DAG and expand each non-basis node
|
64
66
|
for node in dag.op_nodes():
|
@@ -66,12 +68,18 @@ class Decompose(TransformationPass):
|
|
66
68
|
if not self._should_decompose(node):
|
67
69
|
continue
|
68
70
|
|
69
|
-
if
|
71
|
+
if node.is_control_flow():
|
72
|
+
decomposition = control_flow.map_blocks(self.run, node.op)
|
73
|
+
dag.substitute_node(node, decomposition, inplace=True)
|
74
|
+
|
75
|
+
elif getattr(node.op, "definition", None) is None:
|
70
76
|
# if we try to synthesize, turn the node into a DAGCircuit and run HLS
|
71
77
|
if self.apply_synthesis:
|
78
|
+
# note that node_as_dag does not include the condition, which will
|
79
|
+
# be propagated in ``substitute_node_with_dag``
|
72
80
|
node_as_dag = _node_to_dag(node)
|
73
81
|
synthesized = hls.run(node_as_dag)
|
74
|
-
dag.substitute_node_with_dag(node, synthesized)
|
82
|
+
dag.substitute_node_with_dag(node, synthesized, propagate_condition=True)
|
75
83
|
|
76
84
|
# else: no definition and synthesis not enabled, so we do nothing
|
77
85
|
else:
|
@@ -123,9 +131,21 @@ class Decompose(TransformationPass):
|
|
123
131
|
|
124
132
|
|
125
133
|
def _node_to_dag(node: DAGOpNode) -> DAGCircuit:
|
134
|
+
# Control flow is already handled separately, however that does not capture
|
135
|
+
# c_if, which we are treating here. We explicitly ignore the condition attribute,
|
136
|
+
# which will be handled by ``substitute_node_with_dag``, so we create a copy of the node
|
137
|
+
# and set the condition to None. Once ``c_if`` is removed for 2.0, this block can go, too.
|
138
|
+
with warnings.catch_warnings():
|
139
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
140
|
+
if getattr(node.op, "condition", None) is not None:
|
141
|
+
op = node.op.copy()
|
142
|
+
op.condition = None
|
143
|
+
node = DAGOpNode(op, node.qargs, node.cargs)
|
144
|
+
|
145
|
+
# create new dag and apply the operation
|
126
146
|
dag = DAGCircuit()
|
127
147
|
dag.add_qubits(node.qargs)
|
128
148
|
dag.add_clbits(node.cargs)
|
129
|
-
|
130
149
|
dag.apply_operation_back(node.op, node.qargs, node.cargs)
|
150
|
+
|
131
151
|
return dag
|
@@ -12,9 +12,11 @@
|
|
12
12
|
|
13
13
|
"""Replace each block of consecutive gates by a single Unitary node."""
|
14
14
|
from __future__ import annotations
|
15
|
+
from math import pi
|
15
16
|
|
16
17
|
from qiskit.synthesis.two_qubit import TwoQubitBasisDecomposer
|
17
|
-
from qiskit.circuit.library.standard_gates import CXGate, CZGate, iSwapGate, ECRGate
|
18
|
+
from qiskit.circuit.library.standard_gates import CXGate, CZGate, iSwapGate, ECRGate, RXXGate
|
19
|
+
|
18
20
|
from qiskit.transpiler.basepasses import TransformationPass
|
19
21
|
from qiskit.transpiler.passmanager import PassManager
|
20
22
|
from qiskit._accelerate.consolidate_blocks import consolidate_blocks
|
@@ -27,6 +29,7 @@ KAK_GATE_NAMES = {
|
|
27
29
|
"cz": CZGate(),
|
28
30
|
"iswap": iSwapGate(),
|
29
31
|
"ecr": ECRGate(),
|
32
|
+
"rxx": RXXGate(pi / 2),
|
30
33
|
}
|
31
34
|
|
32
35
|
|
@@ -70,7 +73,6 @@ class ConsolidateBlocks(TransformationPass):
|
|
70
73
|
if basis_gates is not None:
|
71
74
|
self.basis_gates = set(basis_gates)
|
72
75
|
self.force_consolidate = force_consolidate
|
73
|
-
|
74
76
|
if kak_basis_gate is not None:
|
75
77
|
self.decomposer = TwoQubitBasisDecomposer(kak_basis_gate)
|
76
78
|
elif basis_gates is not None:
|
@@ -79,8 +81,12 @@ class ConsolidateBlocks(TransformationPass):
|
|
79
81
|
self.decomposer = TwoQubitBasisDecomposer(
|
80
82
|
KAK_GATE_NAMES[kak_gates.pop()], basis_fidelity=approximation_degree or 1.0
|
81
83
|
)
|
84
|
+
elif "rzx" in basis_gates:
|
85
|
+
self.decomposer = TwoQubitBasisDecomposer(
|
86
|
+
CXGate(), basis_fidelity=approximation_degree or 1.0
|
87
|
+
)
|
82
88
|
else:
|
83
|
-
self.decomposer =
|
89
|
+
self.decomposer = None
|
84
90
|
else:
|
85
91
|
self.decomposer = TwoQubitBasisDecomposer(CXGate())
|
86
92
|
|
@@ -103,6 +109,7 @@ class ConsolidateBlocks(TransformationPass):
|
|
103
109
|
consolidate_blocks(
|
104
110
|
dag,
|
105
111
|
self.decomposer._inner_decomposer,
|
112
|
+
self.decomposer.gate.name,
|
106
113
|
self.force_consolidate,
|
107
114
|
target=self.target,
|
108
115
|
basis_gates=self.basis_gates,
|
@@ -19,6 +19,7 @@ from qiskit.circuit import Gate
|
|
19
19
|
from qiskit.dagcircuit import DAGCircuit
|
20
20
|
from qiskit.transpiler.basepasses import TransformationPass
|
21
21
|
from qiskit.transpiler.exceptions import TranspilerError
|
22
|
+
from qiskit.transpiler.passes.utils import control_flow
|
22
23
|
|
23
24
|
from qiskit._accelerate.inverse_cancellation import inverse_cancellation
|
24
25
|
|
@@ -74,6 +75,7 @@ class InverseCancellation(TransformationPass):
|
|
74
75
|
|
75
76
|
super().__init__()
|
76
77
|
|
78
|
+
@control_flow.trivial_recurse
|
77
79
|
def run(self, dag: DAGCircuit):
|
78
80
|
"""Run the InverseCancellation pass on `dag`.
|
79
81
|
|
@@ -382,7 +382,7 @@ class HighLevelSynthesis(TransformationPass):
|
|
382
382
|
|
383
383
|
# If the synthesis changed the operation (i.e. it is not None), store the result.
|
384
384
|
if synthesized is not None:
|
385
|
-
synthesized_nodes[node] = (synthesized, synthesized_context)
|
385
|
+
synthesized_nodes[node._node_id] = (synthesized, synthesized_context)
|
386
386
|
|
387
387
|
# If the synthesis did not change anything, just update the qubit tracker.
|
388
388
|
elif not processed:
|
@@ -407,8 +407,9 @@ class HighLevelSynthesis(TransformationPass):
|
|
407
407
|
outer_to_local = context.to_local_mapping()
|
408
408
|
|
409
409
|
for node in dag.topological_op_nodes():
|
410
|
-
|
411
|
-
|
410
|
+
|
411
|
+
if op_tuple := synthesized_nodes.get(node._node_id, None):
|
412
|
+
op, op_context = op_tuple
|
412
413
|
|
413
414
|
if isinstance(op, Operation):
|
414
415
|
out.apply_operation_back(op, node.qargs, node.cargs)
|
@@ -813,6 +814,7 @@ class HighLevelSynthesis(TransformationPass):
|
|
813
814
|
dag._has_calibration_for(node)
|
814
815
|
or len(node.qargs) < self._min_qubits
|
815
816
|
or node.is_directive()
|
817
|
+
or (self._instruction_supported(node.name, qubits) and not node.is_control_flow())
|
816
818
|
):
|
817
819
|
return True
|
818
820
|
|
@@ -830,15 +832,12 @@ class HighLevelSynthesis(TransformationPass):
|
|
830
832
|
# If all the above constraints hold, and it's already supported or the basis translator
|
831
833
|
# can handle it, we'll leave it be.
|
832
834
|
and (
|
833
|
-
self._instruction_supported(node.name, qubits)
|
834
835
|
# This uses unfortunately private details of `EquivalenceLibrary`, but so does the
|
835
836
|
# `BasisTranslator`, and this is supposed to just be temporary til this is moved
|
836
837
|
# into Rust space.
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
in self._equiv_lib.keys()
|
841
|
-
)
|
838
|
+
self._equiv_lib is not None
|
839
|
+
and equivalence.Key(name=node.name, num_qubits=node.num_qubits)
|
840
|
+
in self._equiv_lib.keys()
|
842
841
|
)
|
843
842
|
)
|
844
843
|
|