16
16
17
17
from qiskit import QuantumCircuit , ClassicalRegister
18
18
from qiskit .providers .backend import Backend
19
+ from qiskit_experiments .exceptions import QiskitError
19
20
from .composite_experiment import CompositeExperiment , BaseExperiment
20
21
from .composite_analysis import CompositeAnalysis
21
22
@@ -63,20 +64,27 @@ def circuits(self):
63
64
64
65
sub_circuits = []
65
66
sub_qubits = []
67
+ sub_maps = []
66
68
sub_size = []
67
69
num_qubits = 0
68
70
69
71
# Generate data for combination
70
- for expr in self ._experiments :
72
+ for sub_exp in self ._experiments :
73
+
74
+ # Generate transpiled subcircuits
75
+ circuits = sub_exp ._transpiled_circuits ()
76
+
71
77
# Add subcircuits
72
- circs = expr .circuits ()
73
- sub_circuits .append (circs )
74
- sub_size .append (len (circs ))
78
+ sub_circuits .append (circuits )
79
+ sub_size .append (len (circuits ))
75
80
76
- # Add sub qubits
77
- qubits = list (range (num_qubits , num_qubits + expr .num_qubits ))
81
+ # Sub experiment logical qubits in the combined circuits full qubits
82
+ qubits = list (range (num_qubits , num_qubits + sub_exp .num_qubits ))
78
83
sub_qubits .append (qubits )
79
- num_qubits += expr .num_qubits
84
+ # Construct mapping for the sub-experiments logical qubits to physical qubits
85
+ # in the full combined circuits
86
+ sub_maps .append ({q : qubits [i ] for i , q in enumerate (sub_exp .physical_qubits )})
87
+ num_qubits += sub_exp .num_qubits
80
88
81
89
# Generate empty joint circuits
82
90
num_circuits = max (sub_size )
@@ -97,9 +105,37 @@ def circuits(self):
97
105
sub_circ = sub_circuits [exp_idx ][circ_idx ]
98
106
num_clbits = circuit .num_clbits
99
107
qubits = sub_qubits [exp_idx ]
108
+ qargs_map = sub_maps [exp_idx ]
100
109
clbits = list (range (num_clbits , num_clbits + sub_circ .num_clbits ))
101
110
circuit .add_register (ClassicalRegister (sub_circ .num_clbits ))
102
- circuit .append (sub_circ , qubits , clbits )
111
+
112
+ # Apply transpiled subcircuit
113
+ # Note that this assumes the circuit was not expanded to use
114
+ # any qubits outside the specified physical qubits
115
+ for inst , qargs , cargs in sub_circ .data :
116
+ try :
117
+ mapped_qargs = [
118
+ circuit .qubits [qargs_map [sub_circ .find_bit (i ).index ]] for i in qargs
119
+ ]
120
+ except KeyError as ex :
121
+ # Instruction is outside physical qubits for the component
122
+ # experiment.
123
+ # This could legitimately happen if the subcircuit was
124
+ # explicitly scheduled during transpilation which would
125
+ # insert delays on all auxillary device qubits.
126
+ # We skip delay instructions to allow for this.
127
+ if inst .name == "delay" :
128
+ continue
129
+ raise QiskitError (
130
+ "Component experiment has been transpiled outside of the "
131
+ "allowed physical qubits for that component. Check the "
132
+ "experiment is valid on the backends coupling map."
133
+ ) from ex
134
+ mapped_cargs = [
135
+ circuit .clbits [clbits [sub_circ .find_bit (i ).index ]] for i in cargs
136
+ ]
137
+ circuit ._append (inst , mapped_qargs , mapped_cargs )
138
+
103
139
# Add subcircuit metadata
104
140
circuit .metadata ["composite_index" ].append (exp_idx )
105
141
circuit .metadata ["composite_metadata" ].append (sub_circ .metadata )
@@ -114,6 +150,6 @@ def circuits(self):
114
150
)
115
151
116
152
# Add joint circuit to returned list
117
- joint_circuits .append (circuit . decompose () )
153
+ joint_circuits .append (circuit )
118
154
119
155
return joint_circuits
0 commit comments