@@ -53,29 +53,29 @@ class BasicGateFuser final : public Fuser<IO, Gate> {
5353
5454 /* *
5555 * Stores sets of gates that can be applied together. Only one- and
56- * two-qubit gates will get fused. Gates fused with this method are not
57- * multiplied together until ApplyFusedGate is called on the output.
58- * To respect specific time boundaries while fusing gates, use the other
59- * version of this method below.
56+ * two-qubit gates will get fused. To respect specific time boundaries while
57+ * fusing gates, use the other version of this method below.
6058 * @param param Options for gate fusion.
6159 * @param num_qubits The number of qubits acted on by 'gates'.
6260 * @param gates The gates (or pointers to the gates) to be fused.
6361 * Gate times of the gates that act on the same qubits should be ordered.
6462 * Gates that are out of time order should not cross the time boundaries
6563 * set by measurement gates.
64+ * @param fuse_matrix If true, multiply gate matrices together.
6665 * @return A vector of fused gate objects. Each element is a set of gates
6766 * acting on a specific pair of qubits which can be applied as a group.
6867 */
6968 static std::vector<GateFused> FuseGates (const Parameter& param,
7069 unsigned num_qubits,
71- const std::vector<Gate>& gates) {
72- return FuseGates (param, num_qubits, gates.cbegin (), gates.cend (), {});
70+ const std::vector<Gate>& gates,
71+ bool fuse_matrix = true ) {
72+ return FuseGates (
73+ param, num_qubits, gates.cbegin (), gates.cend (), {}, fuse_matrix);
7374 }
7475
7576 /* *
7677 * Stores sets of gates that can be applied together. Only one- and
77- * two-qubit gates will get fused. Gates fused with this method are not
78- * multiplied together until ApplyFusedGate is called on the output.
78+ * two-qubit gates will get fused.
7979 * @param param Options for gate fusion.
8080 * @param num_qubits The number of qubits acted on by 'gates'.
8181 * @param gates The gates (or pointers to the gates) to be fused.
@@ -85,43 +85,44 @@ class BasicGateFuser final : public Fuser<IO, Gate> {
8585 * @param times_to_split_at Ordered list of time steps (boundaries) at which
8686 * to separate fused gates. Each element of the output will contain gates
8787 * from a single 'window' in this list.
88+ * @param fuse_matrix If true, multiply gate matrices together.
8889 * @return A vector of fused gate objects. Each element is a set of gates
8990 * acting on a specific pair of qubits which can be applied as a group.
9091 */
9192 static std::vector<GateFused> FuseGates (
9293 const Parameter& param,
9394 unsigned num_qubits, const std::vector<Gate>& gates,
94- const std::vector<unsigned >& times_to_split_at) {
95+ const std::vector<unsigned >& times_to_split_at,
96+ bool fuse_matrix = true ) {
9597 return FuseGates (param, num_qubits, gates.cbegin (), gates.cend (),
96- times_to_split_at);
98+ times_to_split_at, fuse_matrix );
9799 }
98100
99101 /* *
100102 * Stores sets of gates that can be applied together. Only one- and
101- * two-qubit gates will get fused. Gates fused with this method are not
102- * multiplied together until ApplyFusedGate is called on the output.
103- * To respect specific time boundaries while fusing gates, use the other
104- * version of this method below.
103+ * two-qubit gates will get fused. To respect specific time boundaries while
104+ * fusing gates, use the other version of this method below.
105105 * @param param Options for gate fusion.
106106 * @param num_qubits The number of qubits acted on by gates.
107107 * @param gfirst, glast The iterator range [gfirst, glast) to fuse gates
108108 * (or pointers to gates) in. Gate times of the gates that act on the same
109109 * qubits should be ordered. Gates that are out of time order should not
110110 * cross the time boundaries set by measurement gates.
111+ * @param fuse_matrix If true, multiply gate matrices together.
111112 * @return A vector of fused gate objects. Each element is a set of gates
112113 * acting on a specific pair of qubits which can be applied as a group.
113114 */
114115 static std::vector<GateFused> FuseGates (
115116 const Parameter& param, unsigned num_qubits,
116117 typename std::vector<Gate>::const_iterator gfirst,
117- typename std::vector<Gate>::const_iterator glast) {
118- return FuseGates (param, num_qubits, gfirst, glast, {});
118+ typename std::vector<Gate>::const_iterator glast,
119+ bool fuse_matrix = true ) {
120+ return FuseGates (param, num_qubits, gfirst, glast, {}, fuse_matrix);
119121 }
120122
121123 /* *
122124 * Stores sets of gates that can be applied together. Only one- and
123- * two-qubit gates will get fused. Gates fused with this method are not
124- * multiplied together until ApplyFusedGate is called on the output.
125+ * two-qubit gates will get fused.
125126 * @param param Options for gate fusion.
126127 * @param num_qubits The number of qubits acted on by gates.
127128 * @param gfirst, glast The iterator range [gfirst, glast) to fuse gates
@@ -132,14 +133,16 @@ class BasicGateFuser final : public Fuser<IO, Gate> {
132133 * @param times_to_split_at Ordered list of time steps (boundaries) at which
133134 * to separate fused gates. Each element of the output will contain gates
134135 * from a single 'window' in this list.
136+ * @param fuse_matrix If true, multiply gate matrices together.
135137 * @return A vector of fused gate objects. Each element is a set of gates
136138 * acting on a specific pair of qubits which can be applied as a group.
137139 */
138140 static std::vector<GateFused> FuseGates (
139141 const Parameter& param, unsigned num_qubits,
140142 typename std::vector<Gate>::const_iterator gfirst,
141143 typename std::vector<Gate>::const_iterator glast,
142- const std::vector<unsigned >& times_to_split_at) {
144+ const std::vector<unsigned >& times_to_split_at,
145+ bool fuse_matrix = true ) {
143146 std::vector<GateFused> gates_fused;
144147
145148 if (gfirst >= glast) return gates_fused;
@@ -243,11 +246,11 @@ class BasicGateFuser final : public Fuser<IO, Gate> {
243246 }
244247
245248 gates_fused.push_back ({pgate->kind , pgate->time , pgate->qubits ,
246- pgate, {pgate}});
249+ pgate, {pgate}, {} });
247250 } else if (pgate->qubits .size () == 1 ) {
248251 unsigned q0 = pgate->qubits [0 ];
249252
250- GateFused gate_f = {pgate->kind , pgate->time , {q0}, pgate, {}};
253+ GateFused gate_f = {pgate->kind , pgate->time , {q0}, pgate, {}, {} };
251254
252255 last[q0] = Advance (last[q0], gates_lat[q0], gate_f.gates );
253256 gate_f.gates .push_back (gates_lat[q0][last[q0]]);
@@ -260,7 +263,8 @@ class BasicGateFuser final : public Fuser<IO, Gate> {
260263
261264 if (Done (last[q0], pgate->time , gates_lat[q0])) continue ;
262265
263- GateFused gate_f = {pgate->kind , pgate->time , {q0, q1}, pgate, {}};
266+ GateFused gate_f =
267+ {pgate->kind , pgate->time , {q0, q1}, pgate, {}, {}};
264268
265269 do {
266270 last[q0] = Advance (last[q0], gates_lat[q0], gate_f.gates );
@@ -290,7 +294,7 @@ class BasicGateFuser final : public Fuser<IO, Gate> {
290294
291295 const auto & mea_gates_at_time = measurement_gates[pgate->time ];
292296
293- GateFused gate_f = {pgate->kind , pgate->time , {}, pgate, {}};
297+ GateFused gate_f = {pgate->kind , pgate->time , {}, pgate, {}, {} };
294298 gate_f.gates .reserve (mea_gates_at_time.size ());
295299
296300 // Fuse measurement gates with equal times.
@@ -307,6 +311,14 @@ class BasicGateFuser final : public Fuser<IO, Gate> {
307311 if (gate_it == glast) break ;
308312 }
309313
314+ if (fuse_matrix) {
315+ for (auto & gate_f : gates_fused) {
316+ if (gate_f.kind != gate::kMeasurement && gate_f.kind != gate::kDecomp ) {
317+ CalculateFusedMatrix (gate_f);
318+ }
319+ }
320+ }
321+
310322 return gates_fused;
311323 }
312324
@@ -338,7 +350,7 @@ class BasicGateFuser final : public Fuser<IO, Gate> {
338350 std::vector<GateFused>& gates_fused) {
339351 auto pgate = gates_lat[q][k];
340352
341- GateFused gate_f = {pgate->kind , pgate->time , {q}, pgate, {}};
353+ GateFused gate_f = {pgate->kind , pgate->time , {q}, pgate, {}, {} };
342354 gate_f.gates .push_back (pgate);
343355
344356 k = Advance (k + 1 , gates_lat[q], gate_f.gates );
0 commit comments