@@ -122,6 +122,38 @@ class Fuser {
122
122
return epochs;
123
123
}
124
124
125
+ template <typename GateSeq0, typename Parent, typename GateFused>
126
+ static void FuseZeroQubitGates (const GateSeq0& gate_seq0,
127
+ Parent parent, std::size_t first,
128
+ std::vector<GateFused>& fused_gates) {
129
+ GateFused* fuse_to = nullptr ;
130
+
131
+ for (std::size_t i = first; i < fused_gates.size (); ++i) {
132
+ auto & fgate = fused_gates[i];
133
+
134
+ if (fgate.kind != gate::kMeasurement && fgate.kind != gate::kDecomp
135
+ && fgate.parent ->controlled_by .size () == 0
136
+ && !fgate.parent ->unfusible ) {
137
+ fuse_to = &fgate;
138
+ break ;
139
+ }
140
+ }
141
+
142
+ if (fuse_to != nullptr ) {
143
+ // Fuse zero-qubit gates with the first available fused gate.
144
+ for (const auto & g : gate_seq0) {
145
+ fuse_to->gates .push_back (parent (g));
146
+ }
147
+ } else {
148
+ auto g0 = parent (gate_seq0[0 ]);
149
+ fused_gates.push_back ({g0->kind , g0->time , {}, g0, {g0}, {}});
150
+
151
+ for (std::size_t i = 1 ; i < gate_seq0.size (); ++i) {
152
+ fused_gates.back ().gates .push_back (parent (gate_seq0[i]));
153
+ }
154
+ }
155
+ }
156
+
125
157
private:
126
158
static bool AddBoundary (unsigned time, unsigned max_time,
127
159
std::vector<unsigned >& boundaries) {
@@ -144,7 +176,9 @@ inline void CalculateFusedMatrix(FusedGate& gate) {
144
176
MatrixIdentity (unsigned {1 } << gate.qubits .size (), gate.matrix );
145
177
146
178
for (auto pgate : gate.gates ) {
147
- if (gate.qubits .size () == pgate->qubits .size ()) {
179
+ if (pgate->qubits .size () == 0 ) {
180
+ MatrixScalarMultiply (pgate->matrix [0 ], pgate->matrix [1 ], gate.matrix );
181
+ } else if (gate.qubits .size () == pgate->qubits .size ()) {
148
182
MatrixMultiply (gate.qubits .size (), pgate->matrix , gate.matrix );
149
183
} else {
150
184
unsigned mask = 0 ;
0 commit comments