@@ -99,82 +99,79 @@ pub(crate) fn cancel_commutations(
99
99
( 0 ..dag. num_qubits ( ) as u32 ) . for_each ( |qubit| {
100
100
let wire = Qubit ( qubit) ;
101
101
if let Some ( wire_commutation_set) = commutation_set. get ( & Wire :: Qubit ( wire) ) {
102
- wire_commutation_set
103
- . iter ( )
104
- . enumerate ( )
105
- . for_each ( |( com_set_idx, com_set) | {
106
- // This ensures that we only have DAGOPNodes in the current com_set, yuck...
107
- if let NodeType :: Operation ( _node0) = & dag. dag [ * com_set. first ( ) . unwrap ( ) ] {
108
- com_set. iter ( ) . for_each ( |node| {
109
- let op = match & dag. dag [ * node] {
110
- NodeType :: Operation ( instr) => instr,
111
- _ => panic ! ( "Unexpected type in commutation set." ) ,
112
- } ;
113
- let num_qargs = dag. get_qargs ( op. qubits ) . len ( ) ;
114
- // no support for cancellation of parameterized gates
115
- if op
116
- . params_view ( )
117
- . iter ( )
118
- . all ( |p| !matches ! ( p, Param :: ParameterExpression ( _) ) )
119
- {
120
- if let Some ( op_gate) = op. op . try_standard_gate ( ) {
121
- if num_qargs == 1usize && SUPPORTED_GATES . contains ( & op_gate) {
122
- cancellation_sets
123
- . entry ( CancellationSetKey {
124
- gate : GateOrRotation :: Gate ( op_gate) ,
125
- qubits : smallvec ! [ wire] ,
126
- com_set_index : com_set_idx,
127
- second_index : None ,
128
- } )
129
- . or_insert_with ( Vec :: new)
130
- . push ( * node) ;
131
- }
102
+ for ( com_set_idx, com_set) in wire_commutation_set. iter ( ) . enumerate ( ) {
103
+ if let Some ( & nd) = com_set. first ( ) {
104
+ if !matches ! ( dag. dag[ nd] , NodeType :: Operation ( _) ) {
105
+ continue ;
106
+ }
107
+ } else {
108
+ continue ;
109
+ }
110
+ com_set. iter ( ) . for_each ( |node| {
111
+ let instr = match & dag. dag [ * node] {
112
+ NodeType :: Operation ( instr) => instr,
113
+ _ => panic ! ( "Unexpected type in commutation set." ) ,
114
+ } ;
115
+ let num_qargs = dag. get_qargs ( instr. qubits ) . len ( ) ;
116
+ // no support for cancellation of parameterized gates
117
+ if !instr. is_parameterized ( ) {
118
+ if let Some ( op_gate) = instr. op . try_standard_gate ( ) {
119
+ if num_qargs == 1 && SUPPORTED_GATES . contains ( & op_gate) {
120
+ cancellation_sets
121
+ . entry ( CancellationSetKey {
122
+ gate : GateOrRotation :: Gate ( op_gate) ,
123
+ qubits : smallvec ! [ wire] ,
124
+ com_set_index : com_set_idx,
125
+ second_index : None ,
126
+ } )
127
+ . or_insert_with ( Vec :: new)
128
+ . push ( * node) ;
129
+ }
132
130
133
- if num_qargs == 1usize && Z_ROTATIONS . contains ( & op_gate) {
134
- cancellation_sets
135
- . entry ( CancellationSetKey {
136
- gate : GateOrRotation :: ZRotation ,
137
- qubits : smallvec ! [ wire] ,
138
- com_set_index : com_set_idx,
139
- second_index : None ,
140
- } )
141
- . or_insert_with ( Vec :: new)
142
- . push ( * node) ;
143
- }
144
- if num_qargs == 1usize && X_ROTATIONS . contains ( & op_gate) {
145
- cancellation_sets
146
- . entry ( CancellationSetKey {
147
- gate : GateOrRotation :: XRotation ,
148
- qubits : smallvec ! [ wire] ,
149
- com_set_index : com_set_idx,
150
- second_index : None ,
151
- } )
152
- . or_insert_with ( Vec :: new)
153
- . push ( * node) ;
154
- }
155
- // Don't deal with Y rotation, because Y rotation doesn't commute with
156
- // CNOT, so it should be dealt with by optimized1qgate pass
157
- if num_qargs == 2usize
158
- && dag. get_qargs ( op. qubits ) . first ( ) . unwrap ( ) == & wire
159
- {
160
- let second_qarg = dag. get_qargs ( op. qubits ) [ 1 ] ;
161
- cancellation_sets
162
- . entry ( CancellationSetKey {
163
- gate : GateOrRotation :: Gate ( op_gate) ,
164
- qubits : smallvec ! [ wire, second_qarg] ,
165
- com_set_index : com_set_idx,
166
- second_index : node_indices
167
- . get ( & ( * node, Wire :: Qubit ( second_qarg) ) )
168
- . copied ( ) ,
169
- } )
170
- . or_insert_with ( Vec :: new)
171
- . push ( * node) ;
172
- }
173
- }
131
+ if num_qargs == 1 && Z_ROTATIONS . contains ( & op_gate) {
132
+ cancellation_sets
133
+ . entry ( CancellationSetKey {
134
+ gate : GateOrRotation :: ZRotation ,
135
+ qubits : smallvec ! [ wire] ,
136
+ com_set_index : com_set_idx,
137
+ second_index : None ,
138
+ } )
139
+ . or_insert_with ( Vec :: new)
140
+ . push ( * node) ;
141
+ }
142
+ if num_qargs == 1 && X_ROTATIONS . contains ( & op_gate) {
143
+ cancellation_sets
144
+ . entry ( CancellationSetKey {
145
+ gate : GateOrRotation :: XRotation ,
146
+ qubits : smallvec ! [ wire] ,
147
+ com_set_index : com_set_idx,
148
+ second_index : None ,
149
+ } )
150
+ . or_insert_with ( Vec :: new)
151
+ . push ( * node) ;
152
+ }
153
+ // Don't deal with Y rotation, because Y rotation doesn't commute with
154
+ // CNOT, so it should be dealt with by optimized1qgate pass
155
+ if num_qargs == 2
156
+ && dag. get_qargs ( instr. qubits ) . first ( ) . unwrap ( ) == & wire
157
+ {
158
+ let second_qarg = dag. get_qargs ( instr. qubits ) [ 1 ] ;
159
+ cancellation_sets
160
+ . entry ( CancellationSetKey {
161
+ gate : GateOrRotation :: Gate ( op_gate) ,
162
+ qubits : smallvec ! [ wire, second_qarg] ,
163
+ com_set_index : com_set_idx,
164
+ second_index : node_indices
165
+ . get ( & ( * node, Wire :: Qubit ( second_qarg) ) )
166
+ . copied ( ) ,
167
+ } )
168
+ . or_insert_with ( Vec :: new)
169
+ . push ( * node) ;
174
170
}
175
- } )
171
+ }
176
172
}
177
173
} )
174
+ }
178
175
}
179
176
} ) ;
180
177
@@ -193,12 +190,10 @@ pub(crate) fn cancel_commutations(
193
190
if matches ! ( cancel_key. gate, GateOrRotation :: ZRotation )
194
191
|| matches ! ( cancel_key. gate, GateOrRotation :: XRotation )
195
192
{
196
- let run_op = match & dag. dag [ * cancel_set. first ( ) . unwrap ( ) ] {
197
- NodeType :: Operation ( instr) => instr,
193
+ let run_qarg = match & dag. dag [ * cancel_set. first ( ) . unwrap ( ) ] {
194
+ NodeType :: Operation ( instr) => dag . get_qargs ( instr. qubits ) [ 0 ] ,
198
195
_ => panic ! ( "Unexpected type in commutation set run." ) ,
199
196
} ;
200
-
201
- let run_qarg = dag. get_qargs ( run_op. qubits ) . first ( ) . unwrap ( ) ;
202
197
let mut total_angle: f64 = 0.0 ;
203
198
let mut total_phase: f64 = 0.0 ;
204
199
for current_node in cancel_set {
@@ -214,33 +209,35 @@ pub(crate) fn cancel_commutations(
214
209
. as_deref ( )
215
210
. is_some_and ( |attr| attr. condition . is_some ( ) )
216
211
|| node_qargs. len ( ) > 1
217
- || & node_qargs[ 0 ] != run_qarg
212
+ || node_qargs[ 0 ] != run_qarg
218
213
{
219
- panic ! ( "internal error" ) ;
214
+ return Err ( QiskitError :: new_err ( "internal error" ) ) ;
220
215
}
221
216
222
217
let node_angle = if ROTATION_GATES . contains ( & node_op_name) {
223
218
match node_op. params_view ( ) . first ( ) {
224
- Some ( Param :: Float ( f) ) => * f ,
219
+ Some ( Param :: Float ( f) ) => Ok ( * f ) ,
225
220
_ => return Err ( QiskitError :: new_err ( format ! (
226
- "Rotational gate with parameter expression encoutned in cancellation {:?}" ,
221
+ "Rotational gate with parameter expression encountered in cancellation {:?}" ,
227
222
node_op. op
228
223
) ) )
229
224
}
230
225
} else if HALF_TURNS . contains ( & node_op_name) {
231
- PI
226
+ Ok ( PI )
232
227
} else if QUARTER_TURNS . contains ( & node_op_name) {
233
- PI / 2.0
228
+ Ok ( PI / 2.0 )
234
229
} else if EIGHTH_TURNS . contains ( & node_op_name) {
235
- PI / 4.0
230
+ Ok ( PI / 4.0 )
236
231
} else {
237
- panic ! ( "Angle for operation {node_op_name} is not defined" )
232
+ Err ( QiskitError :: new_err ( format ! (
233
+ "Angle for operation {} is not defined" ,
234
+ node_op_name
235
+ ) ) )
238
236
} ;
239
- total_angle += node_angle;
237
+ total_angle += node_angle? ;
240
238
241
- if let Some ( definition) = node_op. op . definition ( node_op. params_view ( ) ) {
242
- total_phase += match definition. global_phase ( ) { Param :: Float ( f) => f, _ => panic ! ( "PackedInstruction with definition has no global phase set as floating point number" ) } ;
243
- }
239
+ let Param :: Float ( new_phase) = node_op. op . definition ( node_op. params_view ( ) ) . unwrap ( ) . global_phase ( ) . clone ( ) else { unreachable ! ( ) } ;
240
+ total_phase += new_phase
244
241
}
245
242
246
243
let new_op = if matches ! ( cancel_key. gate, GateOrRotation :: ZRotation ) {
@@ -254,20 +251,12 @@ pub(crate) fn cancel_commutations(
254
251
let gate_angle = euler_one_qubit_decomposer:: mod_2pi ( total_angle, 0. ) ;
255
252
256
253
let new_op_phase: f64 = if gate_angle. abs ( ) > _CUTOFF_PRECISION {
257
- let new_index = dag. insert_1q_on_incoming_qubit (
254
+ dag. insert_1q_on_incoming_qubit (
258
255
( * new_op, & [ total_angle] ) ,
259
256
* cancel_set. first ( ) . unwrap ( ) ,
260
257
) ;
261
- let new_node = match & dag. dag [ new_index] {
262
- NodeType :: Operation ( instr) => instr,
263
- _ => panic ! ( "Unexpected type in commutation set run." ) ,
264
- } ;
265
-
266
- if let Some ( definition) = new_node. op . definition ( new_node. params_view ( ) ) {
267
- match definition. global_phase ( ) { Param :: Float ( f) => * f, _ => panic ! ( "PackedInstruction with definition has no global phase set as floating point number" ) }
268
- } else {
269
- 0.0
270
- }
258
+ let Param :: Float ( new_phase) = new_op. definition ( & [ Param :: Float ( total_angle) ] ) . unwrap ( ) . global_phase ( ) . clone ( ) else { unreachable ! ( ) ; } ;
259
+ new_phase
271
260
} else {
272
261
0.0
273
262
} ;
0 commit comments