Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | // Copyright 2019-2022 Cambridge Quantum Computing | |||
2 | // | |||
3 | // Licensed under the Apache License, Version 2.0 (the "License"); | |||
4 | // you may not use this file except in compliance with the License. | |||
5 | // You may obtain a copy of the License at | |||
6 | // | |||
7 | // http://www.apache.org/licenses/LICENSE-2.0 | |||
8 | // | |||
9 | // Unless required by applicable law or agreed to in writing, software | |||
10 | // distributed under the License is distributed on an "AS IS" BASIS, | |||
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
12 | // See the License for the specific language governing permissions and | |||
13 | // limitations under the License. | |||
14 | ||||
15 | #include "PhasePoly.hpp" | |||
16 | ||||
17 | #include <algorithm> | |||
18 | #include <stdexcept> | |||
19 | #include <string> | |||
20 | #include <tklog/TketLog.hpp> | |||
21 | #include <vector> | |||
22 | ||||
23 | #include "Circuit/Boxes.hpp" | |||
24 | #include "Circuit/Circuit.hpp" | |||
25 | #include "Converters/Gauss.hpp" | |||
26 | #include "OpType/OpType.hpp" | |||
27 | #include "Ops/MetaOp.hpp" | |||
28 | #include "Ops/OpJsonFactory.hpp" | |||
29 | #include "Ops/OpPtr.hpp" | |||
30 | #include "Utils/GraphHeaders.hpp" | |||
31 | #include "Utils/Json.hpp" | |||
32 | ||||
33 | namespace tket { | |||
34 | ||||
35 | /* Used only for gray_synth */ | |||
36 | struct SynthStruct { | |||
37 | std::list<phase_term_t> terms; | |||
38 | std::set<unsigned> remaining_indices; | |||
39 | std::optional<unsigned> target; | |||
40 | }; | |||
41 | ||||
42 | // update the phase gadgets when adding a CNOT | |||
43 | 585 | static void adjust_vectors( | ||
44 | unsigned ctrl, unsigned tgt, std::list<SynthStruct>& Q) { | |||
45 |
2/2✓ Branch 5 taken 445 times.
✓ Branch 6 taken 585 times.
|
2/2✓ Decision 'true' taken 445 times.
✓ Decision 'false' taken 585 times.
|
1030 | for (SynthStruct& S : Q) { |
46 |
2/2✓ Branch 4 taken 478 times.
✓ Branch 5 taken 445 times.
|
2/2✓ Decision 'true' taken 478 times.
✓ Decision 'false' taken 445 times.
|
923 | for (std::pair<std::vector<bool>, Expr>& term : S.terms) { |
47 | 478 | std::vector<bool>& vec = term.first; | ||
48 |
3/6✓ Branch 1 taken 478 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 478 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 478 times.
✗ Branch 10 not taken.
|
478 | vec[ctrl] = vec[ctrl] ^ vec[tgt]; | |
49 | } | |||
50 | } | |||
51 | 585 | } | ||
52 | ||||
53 | // see https://arxiv.org/pdf/1712.01859.pdf p12, line 18 | |||
54 | // get qubit with either greatest or least hamming weight | |||
55 | 1008 | static unsigned find_best_split( | ||
56 | const std::list<phase_term_t>& terms, const std::set<unsigned>& indices) { | |||
57 | 1008 | int max = -1; | ||
58 | 1008 | int max_i = -1; | ||
59 |
2/2✓ Branch 5 taken 4488 times.
✓ Branch 6 taken 1008 times.
|
2/2✓ Decision 'true' taken 4488 times.
✓ Decision 'false' taken 1008 times.
|
5496 | for (unsigned i : indices) { |
60 |
1/2✓ Branch 3 taken 4488 times.
✗ Branch 4 not taken.
|
4488 | int num_ones = std::count_if( | |
61 | terms.begin(), terms.end(), | |||
62 | 17803 | [=](const std::pair<std::vector<bool>, Expr>& term) { | ||
63 | 17803 | return term.first[i]; | ||
64 | 4488 | }); | ||
65 | 4488 | int num_zeros = terms.size() - num_ones; | ||
66 | ||||
67 |
4/4✓ Branch 0 taken 3217 times.
✓ Branch 1 taken 1271 times.
✓ Branch 2 taken 57 times.
✓ Branch 3 taken 3160 times.
|
2/2✓ Decision 'true' taken 1328 times.
✓ Decision 'false' taken 3160 times.
|
4488 | if (num_zeros > max || num_ones > max) { |
68 |
2/2✓ Branch 0 taken 622 times.
✓ Branch 1 taken 706 times.
|
1328 | max = num_zeros > num_ones ? num_zeros : num_ones; | |
69 | 1328 | max_i = i; | ||
70 | } | |||
71 | } | |||
72 | ||||
73 | 1008 | return (unsigned)max_i; | ||
74 | } | |||
75 | ||||
76 | // divide into S0 and S1 based on value at qubit j | |||
77 | 1008 | static std::pair<std::list<phase_term_t>, std::list<phase_term_t>> split( | ||
78 | std::list<phase_term_t>& terms, int j) { | |||
79 | 1008 | std::list<phase_term_t> zeros; | ||
80 | 1008 | std::list<phase_term_t> ones; | ||
81 | ||||
82 |
2/2✓ Branch 1 taken 3240 times.
✓ Branch 2 taken 1008 times.
|
2/2✓ Decision 'true' taken 3240 times.
✓ Decision 'false' taken 1008 times.
|
4248 | while (!terms.empty()) { |
83 |
3/4✓ Branch 2 taken 3240 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1271 times.
✓ Branch 6 taken 1969 times.
|
2/2✓ Decision 'true' taken 1271 times.
✓ Decision 'false' taken 1969 times.
|
3240 | if (terms.front().first[j]) |
84 | 1271 | ones.splice(ones.end(), terms, terms.begin()); | ||
85 | else | |||
86 | 1969 | zeros.splice(zeros.end(), terms, terms.begin()); | ||
87 | } | |||
88 | ||||
89 |
1/2✓ Branch 1 taken 1008 times.
✗ Branch 2 not taken.
|
2016 | return std::make_pair(zeros, ones); | |
90 | 1008 | } | ||
91 | ||||
92 | /* see: arXiv:1712.01859 */ | |||
93 | 265 | Circuit gray_synth( | ||
94 | unsigned n_qubits, const std::list<phase_term_t>& parities, | |||
95 | const MatrixXb& linear_transformation) { | |||
96 |
1/2✓ Branch 1 taken 265 times.
✗ Branch 2 not taken.
|
265 | MatrixXb A = linear_transformation; | |
97 |
1/2✓ Branch 2 taken 265 times.
✗ Branch 3 not taken.
|
265 | Circuit circ(n_qubits); | |
98 | 265 | std::list<SynthStruct> Q; // used to recur over | ||
99 | std::set<unsigned> | |||
100 | 265 | indices; // correspond to qubits which have to be recurred over | ||
101 |
3/4✓ Branch 1 taken 1600 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1600 times.
✓ Branch 4 taken 265 times.
|
0/1? Decision couldn't be analyzed.
|
1865 | for (unsigned i = 0; i < n_qubits; ++i) indices.insert(i); |
102 |
3/6✓ Branch 1 taken 265 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 265 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 265 times.
✗ Branch 8 not taken.
|
265 | Q.push_front({parities, indices, std::nullopt}); | |
103 | ||||
104 |
2/2✓ Branch 1 taken 2281 times.
✓ Branch 2 taken 265 times.
|
2/2✓ Decision 'true' taken 2281 times.
✓ Decision 'false' taken 265 times.
|
2546 | while (!Q.empty()) { |
105 |
1/2✓ Branch 2 taken 2281 times.
✗ Branch 3 not taken.
|
2281 | SynthStruct S = Q.front(); | |
106 | 2281 | Q.pop_front(); | ||
107 | ||||
108 |
2/2✓ Branch 1 taken 612 times.
✓ Branch 2 taken 1669 times.
|
2/2✓ Decision 'true' taken 1669 times.
✓ Decision 'false' taken 612 times.
|
2281 | if (S.terms.size() == 0) continue; |
109 | // only one column in GraySynth matrix being recurred over | |||
110 |
6/6✓ Branch 1 taken 832 times.
✓ Branch 2 taken 837 times.
✓ Branch 4 taken 661 times.
✓ Branch 5 taken 171 times.
✓ Branch 6 taken 661 times.
✓ Branch 7 taken 1008 times.
|
2/2✓ Decision 'true' taken 661 times.
✓ Decision 'false' taken 1008 times.
|
1669 | else if (S.terms.size() == 1 && S.target) { |
111 | // special case to avoid doing extra recursion | |||
112 | 661 | unsigned tgt = *(S.target); | ||
113 | 661 | auto& [vec, angle] = S.terms.front(); | ||
114 |
2/2✓ Branch 1 taken 4492 times.
✓ Branch 2 taken 661 times.
|
2/2✓ Decision 'true' taken 4492 times.
✓ Decision 'false' taken 661 times.
|
5153 | for (unsigned ctrl = 0; ctrl < vec.size(); ++ctrl) { |
115 |
7/8✓ Branch 0 taken 3831 times.
✓ Branch 1 taken 661 times.
✓ Branch 3 taken 3831 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 585 times.
✓ Branch 7 taken 3246 times.
✓ Branch 8 taken 585 times.
✓ Branch 9 taken 3907 times.
|
2/2✓ Decision 'true' taken 585 times.
✓ Decision 'false' taken 3907 times.
|
4492 | if (ctrl != tgt && vec[ctrl]) { |
116 |
2/4✓ Branch 3 taken 585 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 585 times.
✗ Branch 7 not taken.
|
585 | circ.add_op<unsigned>(OpType::CX, {ctrl, tgt}); | |
117 |
1/2✓ Branch 1 taken 585 times.
✗ Branch 2 not taken.
|
585 | adjust_vectors(ctrl, tgt, Q); | |
118 |
2/2✓ Branch 1 taken 4609 times.
✓ Branch 2 taken 585 times.
|
2/2✓ Decision 'true' taken 4609 times.
✓ Decision 'false' taken 585 times.
|
5194 | for (unsigned i = 0; i < A.rows(); i++) { |
119 | // do column operation on linear | |||
120 | // transformation | |||
121 | // this will allow us to correct for the CXs | |||
122 | // we produce here using Gaussian elim | |||
123 |
2/4✓ Branch 1 taken 4609 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4609 times.
✗ Branch 5 not taken.
|
4609 | A(i, ctrl) ^= A(i, tgt); | |
124 | } | |||
125 | } | |||
126 | } | |||
127 |
2/4✓ Branch 3 taken 661 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 661 times.
✗ Branch 7 not taken.
|
661 | circ.add_op<unsigned>(OpType::Rz, angle, {tgt}); | |
128 |
1/2✓ Branch 1 taken 1008 times.
✗ Branch 2 not taken.
|
1/2✓ Decision 'true' taken 1008 times.
✗ Decision 'false' not taken.
|
1008 | } else if (!S.remaining_indices.empty()) { |
129 |
1/2✓ Branch 1 taken 1008 times.
✗ Branch 2 not taken.
|
1008 | unsigned i = find_best_split(S.terms, S.remaining_indices); | |
130 |
1/2✓ Branch 1 taken 1008 times.
✗ Branch 2 not taken.
|
1008 | auto [S0, S1] = split(S.terms, i); | |
131 | ||||
132 |
1/2✓ Branch 1 taken 1008 times.
✗ Branch 2 not taken.
|
1008 | S.remaining_indices.erase(i); | |
133 | ||||
134 |
2/2✓ Branch 1 taken 297 times.
✓ Branch 2 taken 711 times.
|
2/2✓ Decision 'true' taken 297 times.
✓ Decision 'false' taken 711 times.
|
1008 | if (S.target) { |
135 |
3/6✓ Branch 1 taken 297 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 297 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 297 times.
✗ Branch 8 not taken.
|
297 | Q.push_front({S1, S.remaining_indices, S.target}); | |
136 | } else { | |||
137 |
3/6✓ Branch 1 taken 711 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 711 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 711 times.
✗ Branch 9 not taken.
|
711 | Q.push_front({S1, S.remaining_indices, i}); | |
138 | } | |||
139 |
3/6✓ Branch 1 taken 1008 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1008 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1008 times.
✗ Branch 8 not taken.
|
1008 | Q.push_front({S0, S.remaining_indices, S.target}); | |
140 | 1008 | } | ||
141 |
2/2✓ Branch 1 taken 1669 times.
✓ Branch 2 taken 612 times.
|
2281 | } | |
142 |
1/2✓ Branch 1 taken 265 times.
✗ Branch 2 not taken.
|
265 | DiagMatrix m(A); | |
143 |
1/2✓ Branch 1 taken 265 times.
✗ Branch 2 not taken.
|
265 | CXMaker cxmaker(n_qubits, false); | |
144 |
1/2✓ Branch 1 taken 265 times.
✗ Branch 2 not taken.
|
265 | m.gauss(cxmaker); | |
145 |
2/4✓ Branch 1 taken 265 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 265 times.
✗ Branch 5 not taken.
|
265 | circ.append(cxmaker._circ.dagger()); | |
146 | 530 | return circ; | ||
147 | 265 | } | ||
148 | ||||
149 | 391 | PhasePolyBox::PhasePolyBox(const Circuit& circ) | ||
150 |
4/8✓ Branch 2 taken 391 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 391 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 391 times.
✗ Branch 11 not taken.
✓ Branch 15 taken 391 times.
✗ Branch 16 not taken.
|
391 | : Box(OpType::PhasePolyBox), n_qubits_(circ.n_qubits()) { | |
151 |
1/2✓ Branch 1 taken 391 times.
✗ Branch 2 not taken.
|
391 | Circuit newcirc(circ); | |
152 | ||||
153 | // check for classical bits | |||
154 |
2/4✓ Branch 1 taken 391 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 391 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 391 times.
|
391 | if (newcirc.n_bits() != 0) |
155 | ✗ | throw std::invalid_argument( | ||
156 | "Cannot construct phase polynomial from classical controlled " | |||
157 | ✗ | "gates"); | ||
158 | ||||
159 | // check the gateset of the circuit | |||
160 |
6/10✓ Branch 1 taken 391 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 391 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3407 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3407 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3407 times.
✓ Branch 14 taken 391 times.
|
0/1? Decision couldn't be analyzed.
|
3798 | for (const Command& com : newcirc) { |
161 | 3407 | OpType ot = com.get_op_ptr()->get_type(); | ||
162 | ||||
163 |
2/3✓ Branch 0 taken 2492 times.
✓ Branch 1 taken 915 times.
✗ Branch 2 not taken.
|
3407 | switch (ot) { | |
164 |
1/1✓ Decision 'true' taken 2492 times.
|
2492 | case OpType::CX: { | |
165 | 2492 | break; | ||
166 | } | |||
167 |
1/1✓ Decision 'true' taken 915 times.
|
915 | case OpType::Rz: { | |
168 | 915 | break; | ||
169 | } | |||
170 |
0/1✗ Decision 'true' not taken.
|
✗ | default: { | |
171 | ✗ | throw BadOpType("Only CXs and Rzs allowed in Phase Polynomials", ot); | ||
172 | } | |||
173 | } | |||
174 | 3798 | } | ||
175 | ||||
176 | // replace wireswaps with three CX | |||
177 |
3/4✓ Branch 1 taken 399 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 391 times.
|
0/1? Decision couldn't be analyzed.
|
399 | while (newcirc.has_implicit_wireswaps()) { |
178 | 8 | bool foundswap = false; | ||
179 | ||||
180 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | qubit_map_t perm = newcirc.implicit_qubit_permutation(); | |
181 |
2/2✓ Branch 5 taken 37 times.
✓ Branch 6 taken 8 times.
|
2/2✓ Decision 'true' taken 37 times.
✓ Decision 'false' taken 8 times.
|
45 | for (const std::pair<const Qubit, Qubit>& pair : perm) { |
182 |
3/4✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
✓ Branch 4 taken 12 times.
|
2/2✓ Decision 'true' taken 25 times.
✓ Decision 'false' taken 12 times.
|
37 | if (pair.first != pair.second) { |
183 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 17 times.
|
2/2✓ Decision 'true' taken 8 times.
✓ Decision 'false' taken 17 times.
|
25 | if (!foundswap) { |
184 |
1/2✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
|
8 | newcirc.replace_implicit_wire_swap(pair.first, pair.second); | |
185 | 8 | foundswap = true; | ||
186 | } | |||
187 | } | |||
188 | } | |||
189 | 8 | } | ||
190 | ||||
191 | // generate box | |||
192 |
1/2✓ Branch 2 taken 391 times.
✗ Branch 3 not taken.
|
391 | signature_ = op_signature_t(n_qubits_, EdgeType::Quantum); | |
193 | 391 | unsigned i = 0; | ||
194 |
3/4✓ Branch 1 taken 391 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 2218 times.
✓ Branch 8 taken 391 times.
|
0/1? Decision couldn't be analyzed.
|
2609 | for (const Qubit& qb : newcirc.all_qubits()) { |
195 |
2/4✓ Branch 1 taken 2218 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2218 times.
✗ Branch 5 not taken.
|
2218 | qubit_indices_.insert({qb, i}); | |
196 | 2218 | ++i; | ||
197 | 391 | } | ||
198 |
2/4✓ Branch 1 taken 391 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 391 times.
✗ Branch 5 not taken.
|
391 | linear_transformation_ = MatrixXb::Identity(n_qubits_, n_qubits_); | |
199 |
6/10✓ Branch 1 taken 391 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 391 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3431 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3431 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3431 times.
✓ Branch 14 taken 391 times.
|
0/1? Decision couldn't be analyzed.
|
3822 | for (const Command& com : newcirc) { |
200 | 3431 | OpType ot = com.get_op_ptr()->get_type(); | ||
201 |
1/2✓ Branch 1 taken 3431 times.
✗ Branch 2 not taken.
|
3431 | unit_vector_t qbs = com.get_args(); | |
202 |
2/2✓ Branch 0 taken 2516 times.
✓ Branch 1 taken 915 times.
|
2/2✓ Decision 'true' taken 2516 times.
✓ Decision 'false' taken 915 times.
|
3431 | if (ot == OpType::CX) { |
203 |
2/4✓ Branch 2 taken 2516 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2516 times.
✗ Branch 6 not taken.
|
2516 | unsigned ctrl = qubit_indices_.left.at(Qubit(qbs[0])); | |
204 |
2/4✓ Branch 2 taken 2516 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2516 times.
✗ Branch 6 not taken.
|
2516 | unsigned target = qubit_indices_.left.at(Qubit(qbs[1])); | |
205 |
2/2✓ Branch 0 taken 19261 times.
✓ Branch 1 taken 2516 times.
|
2/2✓ Decision 'true' taken 19261 times.
✓ Decision 'false' taken 2516 times.
|
21777 | for (unsigned j = 0; j < n_qubits_; ++j) { |
206 |
1/2✓ Branch 1 taken 19261 times.
✗ Branch 2 not taken.
|
19261 | linear_transformation_.row(target)[j] ^= | |
207 |
3/6✓ Branch 1 taken 19261 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 19261 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 19261 times.
✗ Branch 8 not taken.
|
38522 | linear_transformation_.row(ctrl)[j]; | |
208 | } | |||
209 |
1/2✓ Branch 0 taken 915 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 915 times.
✗ Decision 'false' not taken.
|
915 | } else if (ot == OpType::Rz) { |
210 |
2/4✓ Branch 2 taken 915 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 915 times.
✗ Branch 6 not taken.
|
915 | unsigned qb = qubit_indices_.left.at(Qubit(qbs[0])); | |
211 |
1/2✓ Branch 2 taken 915 times.
✗ Branch 3 not taken.
|
915 | std::vector<bool> boolvec(n_qubits_); | |
212 |
2/2✓ Branch 0 taken 5733 times.
✓ Branch 1 taken 915 times.
|
2/2✓ Decision 'true' taken 5733 times.
✓ Decision 'false' taken 915 times.
|
6648 | for (unsigned j = 0; j < n_qubits_; ++j) { |
213 |
3/6✓ Branch 1 taken 5733 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5733 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5733 times.
✗ Branch 8 not taken.
|
5733 | boolvec[j] = linear_transformation_.row(qb)[j]; | |
214 | } | |||
215 |
1/2✓ Branch 1 taken 915 times.
✗ Branch 2 not taken.
|
915 | PhasePolynomial::iterator pp_it = phase_polynomial_.find(boolvec); | |
216 |
2/2✓ Branch 2 taken 895 times.
✓ Branch 3 taken 20 times.
|
2/2✓ Decision 'true' taken 895 times.
✓ Decision 'false' taken 20 times.
|
915 | if (pp_it == phase_polynomial_.end()) |
217 |
4/8✓ Branch 3 taken 895 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 895 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 895 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 895 times.
✗ Branch 13 not taken.
|
895 | phase_polynomial_[boolvec] = com.get_op_ptr()->get_params().at(0); | |
218 | else | |||
219 |
3/6✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 20 times.
✗ Branch 11 not taken.
|
20 | pp_it->second += com.get_op_ptr()->get_params().at(0); | |
220 | 915 | } else | ||
221 | TKET_ASSERT(!"Only CXs and Rzs allowed in Phase Polynomials"); | |||
222 | 3822 | } | ||
223 | 391 | } | ||
224 | ||||
225 | 6 | PhasePolyBox::PhasePolyBox( | ||
226 | unsigned n_qubits, const boost::bimap<Qubit, unsigned>& qubit_indices, | |||
227 | const PhasePolynomial& phase_polynomial, | |||
228 | 6 | const MatrixXb& linear_transformation) | ||
229 | ✗ | : Box(OpType::PhasePolyBox), | ||
230 | 6 | n_qubits_(n_qubits), | ||
231 | 6 | qubit_indices_(qubit_indices), | ||
232 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
6 | phase_polynomial_(phase_polynomial), | |
233 |
3/6✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 10 not taken.
|
12 | linear_transformation_(linear_transformation) { | |
234 |
7/12✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 11 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 17 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 13 times.
✓ Branch 16 taken 4 times.
|
0/1? Decision couldn't be analyzed.
|
17 | for (const auto& pair : qubit_indices_) { |
235 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 11 times.
|
13 | if (pair.right >= n_qubits) { |
236 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | throw std::invalid_argument( | |
237 | "The creation of a phasepolybox failed: index in qubit " | |||
238 | 4 | "list is out of range"); | ||
239 | } | |||
240 | } | |||
241 | ||||
242 |
2/2✓ Branch 5 taken 4 times.
✓ Branch 6 taken 1 times.
|
2/2✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 1 times.
|
5 | for (auto const& ps : phase_polynomial_) { |
243 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
|
2/2✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 3 times.
|
4 | if (ps.first.size() != n_qubits_) { |
244 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | throw std::invalid_argument( | |
245 | "The creation of a phasepolybox failed: PhasePolynomial " | |||
246 | 2 | "does not match the given number of qubits"); | ||
247 | } | |||
248 | ||||
249 |
3/4✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 1 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 1 times.
|
3 | if (std::none_of( |
250 | 5 | ps.first.begin(), ps.first.end(), [](bool x) { return x; })) { | ||
251 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | throw std::invalid_argument( | |
252 | "The creation of a phasepolybox failed: PhasePolynomial " | |||
253 | 4 | "contains invalid element"); | ||
254 | } | |||
255 | } | |||
256 | ||||
257 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1 times.
|
1 | if (linear_transformation_.rows() != n_qubits) { |
258 | ✗ | throw std::invalid_argument( | ||
259 | "The creation of a phasepolybox failed: row size of the " | |||
260 | ✗ | "linear transformation does not match the number of qubits"); | ||
261 | } | |||
262 | ||||
263 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1 times.
|
1 | if (linear_transformation_.cols() != n_qubits) { |
264 | ✗ | throw std::invalid_argument( | ||
265 | "The creation of a phasepolybox failed: cols size of the " | |||
266 | ✗ | "linear transformation does not match the number of qubits"); | ||
267 | } | |||
268 | ||||
269 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | signature_ = op_signature_t(n_qubits_, EdgeType::Quantum); | |
270 | 21 | } | ||
271 | ||||
272 | 265 | void PhasePolyBox::generate_circuit() const { | ||
273 | 265 | std::list<phase_term_t> phases; | ||
274 |
4/6✓ Branch 4 taken 661 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 661 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 661 times.
✓ Branch 13 taken 265 times.
|
0/1? Decision couldn't be analyzed.
|
926 | for (phase_term_t phase : phase_polynomial_) phases.push_back(phase); |
275 |
1/2✓ Branch 1 taken 265 times.
✗ Branch 2 not taken.
|
265 | Circuit circ = gray_synth(n_qubits_, phases, linear_transformation_); | |
276 | 265 | unit_map_t qmap; | ||
277 |
6/10✓ Branch 1 taken 265 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 265 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1600 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1865 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1600 times.
✓ Branch 13 taken 265 times.
|
0/1? Decision couldn't be analyzed.
|
1865 | for (const auto& pair : qubit_indices_.right) { |
278 |
4/8✓ Branch 1 taken 1600 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1600 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1600 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 1600 times.
✗ Branch 14 not taken.
|
1600 | qmap.insert({Qubit(q_default_reg(), pair.first), pair.second}); | |
279 | } | |||
280 |
1/2✓ Branch 1 taken 265 times.
✗ Branch 2 not taken.
|
265 | circ.rename_units(qmap); | |
281 |
1/2✓ Branch 1 taken 265 times.
✗ Branch 2 not taken.
|
265 | circ_ = std::make_shared<Circuit>(circ); | |
282 | 265 | } | ||
283 | ||||
284 | 133 | PhasePolyBox::PhasePolyBox(const PhasePolyBox& other) | ||
285 | : Box(other), | |||
286 | 133 | n_qubits_(other.n_qubits_), | ||
287 | 133 | qubit_indices_(other.qubit_indices_), | ||
288 |
1/2✓ Branch 1 taken 133 times.
✗ Branch 2 not taken.
|
133 | phase_polynomial_(other.phase_polynomial_), | |
289 |
2/4✓ Branch 2 taken 133 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 133 times.
✗ Branch 6 not taken.
|
266 | linear_transformation_(other.linear_transformation_) {} | |
290 | ||||
291 | ✗ | Op_ptr PhasePolyBox::symbol_substitution( | ||
292 | const SymEngine::map_basic_basic& sub_map) const { | |||
293 | ✗ | Circuit new_circ(*to_circuit()); | ||
294 | ✗ | new_circ.symbol_substitution(sub_map); | ||
295 | ✗ | return std::make_shared<PhasePolyBox>(new_circ); | ||
296 | } | |||
297 | ||||
298 | ✗ | SymSet PhasePolyBox::free_symbols() const { | ||
299 | ✗ | return to_circuit()->free_symbols(); | ||
300 | } | |||
301 | ||||
302 | // Dynamic Eigen matrix requires special treatment to load, to allocate memory | |||
303 | template <typename T> | |||
304 | 1 | Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> load_dynamic_matrix( | ||
305 | const nlohmann::json& j, size_t rows, size_t cols) { | |||
306 | 1 | Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> mat(rows, cols); | ||
307 | ||||
308 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 1 times.
|
3 | for (size_t row = 0; row < j.size(); ++row) { |
309 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | const auto& j_row = j.at(row); | |
310 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
|
2/2✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 2 times.
|
6 | for (size_t col = 0; col < j_row.size(); ++col) { |
311 |
3/6✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
|
4 | mat(row, col) = j_row.at(col).get<T>(); | |
312 | } | |||
313 | } | |||
314 | 1 | return mat; | ||
315 | } | |||
316 | ||||
317 | 1 | nlohmann::json PhasePolyBox::to_json(const Op_ptr& op) { | ||
318 | 1 | const auto& box = static_cast<const PhasePolyBox&>(*op); | ||
319 | 1 | nlohmann::json j = core_box_json(box); | ||
320 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | j["n_qubits"] = box.get_n_qubits(); | |
321 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | j["qubit_indices"] = nlohmann::json::array(); | |
322 |
7/12✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 3 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
✓ Branch 17 taken 1 times.
|
0/1? Decision couldn't be analyzed.
|
3 | for (const auto& pair : box.get_qubit_indices()) { |
323 | 2 | nlohmann::json ind_j; | ||
324 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | ind_j.push_back(pair.left); | |
325 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | ind_j.push_back(pair.right); | |
326 | ||||
327 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | j["qubit_indices"].push_back(ind_j); | |
328 | 2 | } | ||
329 | ||||
330 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | j["phase_polynomial"] = box.get_phase_polynomial(); | |
331 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | j["linear_transformation"] = box.get_linear_transformation(); | |
332 | 1 | return j; | ||
333 | } | |||
334 | ||||
335 | 1 | Op_ptr PhasePolyBox::from_json(const nlohmann::json& j) { | ||
336 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | boost::bimap<Qubit, unsigned> q_ind; | |
337 |
5/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 3 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✓ Branch 12 taken 1 times.
|
0/1? Decision couldn't be analyzed.
|
3 | for (const auto& j_ar : j.at("qubit_indices")) { |
338 |
7/14✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 21 taken 2 times.
✗ Branch 22 not taken.
|
2 | q_ind.insert({j_ar.at(0), j_ar.at(1)}); | |
339 | } | |||
340 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | const unsigned n_qb = j.at("n_qubits").get<unsigned>(); | |
341 | const MatrixXb& lin_trans = | |||
342 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | load_dynamic_matrix<bool>(j.at("linear_transformation"), n_qb, n_qb); | |
343 | ||||
344 | PhasePolyBox box = PhasePolyBox( | |||
345 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
1 | n_qb, q_ind, j.at("phase_polynomial").get<PhasePolynomial>(), lin_trans); | |
346 | return set_box_id( | |||
347 | box, | |||
348 |
4/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
|
3 | boost::lexical_cast<boost::uuids::uuid>(j.at("id").get<std::string>())); | |
349 | 1 | } | ||
350 | ||||
351 | REGISTER_OPFACTORY(PhasePolyBox, PhasePolyBox) | |||
352 | ||||
353 | 37 | CircToPhasePolyConversion::CircToPhasePolyConversion( | ||
354 |
5/10✓ Branch 5 taken 37 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 37 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 37 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 37 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 37 times.
✗ Branch 18 not taken.
|
37 | const Circuit& circ, unsigned min_size) { | |
355 | 37 | min_size_ = min_size; | ||
356 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | circ_ = circ; | |
357 | 37 | box_size_ = 0; | ||
358 | ||||
359 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | nq_ = circ_.n_qubits(); | |
360 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | nb_ = circ_.n_bits(); | |
361 | ||||
362 |
1/2✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
|
37 | qubit_types_ = std::vector<QubitType>(nq_, QubitType::pre); | |
363 | ||||
364 | 37 | unsigned i = 0; | ||
365 |
3/4✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 157 times.
✓ Branch 8 taken 37 times.
|
0/1? Decision couldn't be analyzed.
|
194 | for (const Qubit& qb : circ_.all_qubits()) { |
366 |
1/2✓ Branch 2 taken 157 times.
✗ Branch 3 not taken.
|
157 | qubit_indices_.insert({qb, i}); | |
367 | 157 | ++i; | ||
368 | 37 | } | ||
369 | ||||
370 | 37 | i = 0; | ||
371 |
3/4✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 10 times.
✓ Branch 8 taken 37 times.
|
0/1? Decision couldn't be analyzed.
|
47 | for (const Bit& b : circ_.all_bits()) { |
372 |
1/2✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
10 | bit_indices_.insert({b, i}); | |
373 | 10 | ++i; | ||
374 | 37 | } | ||
375 | ||||
376 |
2/4✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
|
37 | empty_circ_ = Circuit(circ_); | |
377 | ||||
378 | 37 | VertexList bin; | ||
379 | ||||
380 |
7/8✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1528 times.
✓ Branch 6 taken 37 times.
✓ Branch 8 taken 1528 times.
✓ Branch 9 taken 37 times.
✓ Branch 11 taken 37 times.
✓ Branch 12 taken 37 times.
|
1602 | BGL_FORALL_VERTICES(v, empty_circ_.dag, DAG) { | |
381 |
3/4✓ Branch 1 taken 1528 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1194 times.
✓ Branch 4 taken 334 times.
|
2/2✓ Decision 'true' taken 1194 times.
✓ Decision 'false' taken 334 times.
|
1528 | if (!empty_circ_.detect_boundary_Op(v)) { |
382 |
1/2✓ Branch 1 taken 1194 times.
✗ Branch 2 not taken.
|
1194 | bin.push_back(v); | |
383 | } | |||
384 | } | |||
385 | ||||
386 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | empty_circ_.remove_vertices( | |
387 | bin, Circuit::GraphRewiring::Yes, Circuit::VertexDeletion::Yes); | |||
388 | ||||
389 |
2/4✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
|
37 | input_circ_ = Circuit(empty_circ_); | |
390 |
2/4✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 37 times.
✗ Branch 6 not taken.
|
37 | box_circ_ = Circuit(nq_); | |
391 |
2/4✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
|
37 | post_circ_ = Circuit(empty_circ_); | |
392 | ||||
393 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | all_qu_ = circ_.all_qubits(); | |
394 | 37 | } | ||
395 | ||||
396 | 120 | void CircToPhasePolyConversion::add_phase_poly_box() { | ||
397 |
1/2✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
|
120 | qubit_types_.assign(nq_, QubitType::pre); | |
398 | ||||
399 |
2/2✓ Branch 0 taken 114 times.
✓ Branch 1 taken 6 times.
|
2/2✓ Decision 'true' taken 114 times.
✓ Decision 'false' taken 6 times.
|
120 | if (box_size_ >= min_size_) { |
400 |
1/2✓ Branch 1 taken 114 times.
✗ Branch 2 not taken.
|
114 | PhasePolyBox ppbox(box_circ_); | |
401 |
1/2✓ Branch 2 taken 114 times.
✗ Branch 3 not taken.
|
114 | circ_.add_box(ppbox, all_qu_); | |
402 | 114 | } else { | ||
403 |
6/10✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 20 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 20 times.
✓ Branch 14 taken 6 times.
|
0/1? Decision couldn't be analyzed.
|
26 | for (const Command& com : box_circ_) { |
404 | 20 | OpType ot = com.get_op_ptr()->get_type(); | ||
405 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
20 | unit_vector_t qbs = com.get_args(); | |
406 |
2/3✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
20 | switch (ot) { | |
407 |
1/1✓ Decision 'true' taken 12 times.
|
12 | case OpType::CX: { | |
408 |
2/4✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
|
12 | unsigned ctrl = qubit_indices_.at(Qubit(qbs[0])); | |
409 |
2/4✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
|
12 | unsigned target = qubit_indices_.at(Qubit(qbs[1])); | |
410 |
2/4✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
|
12 | circ_.add_op<unsigned>(ot, {ctrl, target}); | |
411 | 12 | break; | ||
412 | } | |||
413 |
1/1✓ Decision 'true' taken 8 times.
|
8 | case OpType::Rz: { | |
414 |
2/4✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
|
8 | unsigned qb = qubit_indices_.at(Qubit(qbs[0])); | |
415 |
3/6✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 10 not taken.
|
16 | auto angle = com.get_op_ptr()->get_params().at(0); | |
416 |
2/4✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
|
8 | circ_.add_op<unsigned>(ot, angle, {qb}); | |
417 | 8 | break; | ||
418 | 8 | } | ||
419 |
0/1✗ Decision 'true' not taken.
|
✗ | default: { | |
420 | // no other types should be in this circuit | |||
421 | TKET_ASSERT(!"invalid op type in phase poly box construction"); | |||
422 | } | |||
423 | } | |||
424 | 26 | } | ||
425 | } | |||
426 | ||||
427 |
6/10✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 120 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 358 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 358 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 358 times.
✓ Branch 14 taken 120 times.
|
0/1? Decision couldn't be analyzed.
|
478 | for (const Command& post_com : post_circ_) { |
428 | 358 | OpType post_ot = post_com.get_op_ptr()->get_type(); | ||
429 | // no other type should be in this list | |||
430 |
4/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
|
11 | bool expected = (post_ot == OpType::H) || (post_ot == OpType::Measure) || | |
431 |
3/4✓ Branch 0 taken 11 times.
✓ Branch 1 taken 347 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
369 | (post_ot == OpType::Collapse) || (post_ot == OpType::Reset); | |
432 | TKET_ASSERT(expected); | |||
433 |
1/2✓ Branch 1 taken 358 times.
✗ Branch 2 not taken.
|
358 | unit_vector_t qbs = post_com.get_args(); | |
434 |
2/4✓ Branch 2 taken 358 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 358 times.
✗ Branch 6 not taken.
|
358 | unsigned qb = qubit_indices_.at(Qubit(qbs[0])); | |
435 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 349 times.
|
2/2✓ Decision 'true' taken 9 times.
✓ Decision 'false' taken 349 times.
|
358 | if (post_ot == OpType::Measure) { |
436 |
2/4✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
|
9 | unsigned b = bit_indices_.at(Bit(qbs[1])); | |
437 |
2/4✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
|
9 | circ_.add_op<unsigned>(post_ot, {qb, b}); | |
438 | } else { | |||
439 |
2/4✓ Branch 3 taken 349 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 349 times.
✗ Branch 7 not taken.
|
349 | circ_.add_op<unsigned>(post_ot, {qb}); | |
440 | } | |||
441 | 478 | } | ||
442 | ||||
443 |
1/2✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
|
120 | post_circ_ = Circuit(empty_circ_); | |
444 |
2/4✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 120 times.
✗ Branch 6 not taken.
|
120 | box_circ_ = Circuit(nq_); | |
445 | 120 | box_size_ = 0; | ||
446 | 120 | } | ||
447 | ||||
448 | 37 | void CircToPhasePolyConversion::convert() { | ||
449 |
6/10✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1194 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1194 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1194 times.
✓ Branch 14 taken 37 times.
|
0/1? Decision couldn't be analyzed.
|
1231 | for (const Command& com : circ_) { |
450 | 1194 | OpType ot = com.get_op_ptr()->get_type(); | ||
451 |
1/2✓ Branch 1 taken 1194 times.
✗ Branch 2 not taken.
|
1194 | unit_vector_t qbs = com.get_args(); | |
452 |
5/6✓ Branch 0 taken 294 times.
✓ Branch 1 taken 402 times.
✓ Branch 2 taken 486 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
1194 | switch (ot) { | |
453 |
1/1✓ Decision 'true' taken 294 times.
|
294 | case OpType::CX: { | |
454 |
2/4✓ Branch 2 taken 294 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 294 times.
✗ Branch 6 not taken.
|
294 | unsigned ctrl = qubit_indices_.at(Qubit(qbs[0])); | |
455 |
2/4✓ Branch 2 taken 294 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 294 times.
✗ Branch 6 not taken.
|
294 | unsigned target = qubit_indices_.at(Qubit(qbs[1])); | |
456 |
2/4✓ Branch 3 taken 294 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 294 times.
✗ Branch 7 not taken.
|
294 | input_circ_.add_op<unsigned>(ot, {ctrl, target}); | |
457 | 294 | break; | ||
458 | } | |||
459 |
1/1✓ Decision 'true' taken 402 times.
|
402 | case OpType::Rz: { | |
460 |
2/4✓ Branch 2 taken 402 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 402 times.
✗ Branch 6 not taken.
|
402 | unsigned qb = qubit_indices_.at(Qubit(qbs[0])); | |
461 |
3/6✓ Branch 3 taken 402 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 402 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 402 times.
✗ Branch 10 not taken.
|
804 | auto angle = com.get_op_ptr()->get_params().at(0); | |
462 |
2/4✓ Branch 3 taken 402 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 402 times.
✗ Branch 7 not taken.
|
402 | input_circ_.add_op<unsigned>(ot, angle, {qb}); | |
463 | 402 | break; | ||
464 | 402 | } | ||
465 | 486 | case OpType::H: | ||
466 | case OpType::Collapse: | |||
467 | case OpType::Reset: { | |||
468 |
2/4✓ Branch 2 taken 486 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 486 times.
✗ Branch 6 not taken.
|
486 | unsigned qb = qubit_indices_.at(Qubit(qbs[0])); | |
469 |
2/4✓ Branch 3 taken 486 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 486 times.
✗ Branch 7 not taken.
|
486 | input_circ_.add_op<unsigned>(ot, {qb}); | |
470 | 486 | break; | ||
471 | } | |||
472 |
1/1✓ Decision 'true' taken 9 times.
|
9 | case OpType::Measure: { | |
473 |
2/4✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
|
9 | unsigned qb = qubit_indices_.at(Qubit(qbs[0])); | |
474 |
2/4✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
|
9 | unsigned b = bit_indices_.at(Bit(qbs[1])); | |
475 |
2/4✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
|
9 | input_circ_.add_op<unsigned>(ot, {qb, b}); | |
476 | 9 | break; | ||
477 | } | |||
478 |
1/1✓ Decision 'true' taken 3 times.
|
3 | case OpType::Barrier: { | |
479 |
2/4✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
|
3 | input_circ_.add_barrier(qbs); | |
480 | 3 | break; | ||
481 | } | |||
482 |
0/1✗ Decision 'true' not taken.
|
✗ | default: { | |
483 | ✗ | throw BadOpType( | ||
484 | "Please rebase with the compiler pass RebaseUFR to only CX, Rz, H, " | |||
485 | "measure, reset, collapse, barrier gates. Found gate of different " | |||
486 | "type", | |||
487 | ✗ | ot); | ||
488 | } | |||
489 | } | |||
490 | 1231 | } | ||
491 | ||||
492 | 74 | VertexList bin; | ||
493 | ||||
494 |
7/8✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1528 times.
✓ Branch 6 taken 37 times.
✓ Branch 8 taken 1528 times.
✓ Branch 9 taken 37 times.
✓ Branch 11 taken 37 times.
✓ Branch 12 taken 37 times.
|
1602 | BGL_FORALL_VERTICES(v, circ_.dag, DAG) { | |
495 |
3/4✓ Branch 1 taken 1528 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1194 times.
✓ Branch 4 taken 334 times.
|
2/2✓ Decision 'true' taken 1194 times.
✓ Decision 'false' taken 334 times.
|
1528 | if (!circ_.detect_boundary_Op(v)) { |
496 |
1/2✓ Branch 1 taken 1194 times.
✗ Branch 2 not taken.
|
1194 | bin.push_back(v); | |
497 | } | |||
498 | } | |||
499 | ||||
500 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | circ_.remove_vertices( | |
501 | bin, Circuit::GraphRewiring::Yes, Circuit::VertexDeletion::Yes); | |||
502 | ||||
503 | /* | |||
504 | this for loop checks all gates in the circuits and try to | |||
505 | find the biggest possible sub circuits which contains only | |||
506 | CX+Rz Gates. This is done in a way that all qubits get | |||
507 | marked if they are currently outside before (pre), in (in) | |||
508 | or outside after (post) of a currently constructed box. If | |||
509 | a qubit is in the pre state and a gate, which is no valid | |||
510 | type in a box should be added, the type is not changed and | |||
511 | the gate is added. If a CX or Rz gate should be added to | |||
512 | this qubit the type is changes to in and the gate is added | |||
513 | to the box. If another gate should be added to a qubit in | |||
514 | state, the state stays the same for CX and Rz and they are | |||
515 | added to the box. If the added gate has a different type | |||
516 | the type of the qubit is changed to post and the gate is | |||
517 | added after the box. If a CX or Rz gate should be added to | |||
518 | a qubit in the post state, the current box is added and a | |||
519 | new box is started to which the current gate is added. All | |||
520 | qubits states are reset to pre. | |||
521 | */ | |||
522 |
6/10✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1194 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1194 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1194 times.
✓ Branch 14 taken 37 times.
|
0/1? Decision couldn't be analyzed.
|
1231 | for (const Command& com : input_circ_) { |
523 | 1194 | OpType ot = com.get_op_ptr()->get_type(); | ||
524 |
1/2✓ Branch 1 taken 1194 times.
✗ Branch 2 not taken.
|
1194 | unit_vector_t qbs = com.get_args(); | |
525 |
5/6✓ Branch 0 taken 3 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 402 times.
✓ Branch 3 taken 486 times.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
|
1194 | switch (ot) { | |
526 |
1/1✓ Decision 'true' taken 3 times.
|
3 | case OpType::Barrier: { | |
527 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | add_phase_poly_box(); | |
528 | ||||
529 |
2/4✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
|
3 | circ_.add_barrier(qbs); | |
530 | 3 | break; | ||
531 | } | |||
532 |
1/1✓ Decision 'true' taken 294 times.
|
294 | case OpType::CX: { | |
533 |
2/4✓ Branch 2 taken 294 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 294 times.
✗ Branch 6 not taken.
|
294 | unsigned ctrl = qubit_indices_.at(Qubit(qbs[0])); | |
534 |
2/4✓ Branch 2 taken 294 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 294 times.
✗ Branch 6 not taken.
|
294 | unsigned target = qubit_indices_.at(Qubit(qbs[1])); | |
535 |
4/4✓ Branch 1 taken 164 times.
✓ Branch 2 taken 130 times.
✓ Branch 3 taken 127 times.
✓ Branch 4 taken 167 times.
|
2/2✓ Decision 'true' taken 127 times.
✓ Decision 'false' taken 331 times.
|
458 | if ((qubit_types_[ctrl] == QubitType::in) && |
536 |
2/2✓ Branch 1 taken 127 times.
✓ Branch 2 taken 37 times.
|
164 | (qubit_types_[target] == QubitType::in)) { | |
537 |
2/4✓ Branch 3 taken 127 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 127 times.
✗ Branch 7 not taken.
|
127 | box_circ_.add_op<unsigned>(OpType::CX, {ctrl, target}); | |
538 | 167 | } else if ( | ||
539 |
4/4✓ Branch 1 taken 121 times.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 88 times.
✓ Branch 4 taken 79 times.
|
288 | (qubit_types_[ctrl] == QubitType::pre) && | |
540 |
2/2✓ Branch 1 taken 88 times.
✓ Branch 2 taken 33 times.
|
121 | (qubit_types_[target] == QubitType::in)) { | |
541 | 88 | qubit_types_[ctrl] = QubitType::in; | ||
542 |
2/4✓ Branch 3 taken 88 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 88 times.
✗ Branch 7 not taken.
|
88 | box_circ_.add_op<unsigned>(OpType::CX, {ctrl, target}); | |
543 | 79 | } else if ( | ||
544 |
4/4✓ Branch 1 taken 37 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 32 times.
✓ Branch 4 taken 47 times.
|
116 | (qubit_types_[ctrl] == QubitType::in) && | |
545 |
2/2✓ Branch 1 taken 32 times.
✓ Branch 2 taken 5 times.
|
37 | (qubit_types_[target] == QubitType::pre)) { | |
546 | 32 | qubit_types_[target] = QubitType::in; | ||
547 |
2/4✓ Branch 3 taken 32 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 32 times.
✗ Branch 7 not taken.
|
32 | box_circ_.add_op<unsigned>(OpType::CX, {ctrl, target}); | |
548 | 47 | } else if ( | ||
549 |
4/4✓ Branch 1 taken 33 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 32 times.
✓ Branch 4 taken 15 times.
|
80 | (qubit_types_[ctrl] == QubitType::pre) && | |
550 |
2/2✓ Branch 1 taken 32 times.
✓ Branch 2 taken 1 times.
|
33 | (qubit_types_[target] == QubitType::pre)) { | |
551 | 32 | qubit_types_[ctrl] = QubitType::in; | ||
552 | 32 | qubit_types_[target] = QubitType::in; | ||
553 |
2/4✓ Branch 3 taken 32 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 32 times.
✗ Branch 7 not taken.
|
32 | box_circ_.add_op<unsigned>(OpType::CX, {ctrl, target}); | |
554 | 15 | } else if ( | ||
555 |
3/4✓ Branch 1 taken 6 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
|
21 | (qubit_types_[ctrl] == QubitType::post) || | |
556 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
6 | (qubit_types_[target] == QubitType::post)) { | |
557 |
1/2✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
|
15 | add_phase_poly_box(); | |
558 | ||||
559 | 15 | qubit_types_[ctrl] = QubitType::in; | ||
560 | 15 | qubit_types_[target] = QubitType::in; | ||
561 |
2/4✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
|
15 | box_circ_.add_op<unsigned>(OpType::CX, {ctrl, target}); | |
562 | } else { | |||
563 | // no other types should be in this list | |||
564 | TKET_ASSERT(!"Invalid Qubit Type in Phase Poly Box creation"); | |||
565 | } | |||
566 | 294 | ++box_size_; | ||
567 | 294 | break; | ||
568 | } | |||
569 |
1/1✓ Decision 'true' taken 402 times.
|
402 | case OpType::Rz: { | |
570 |
2/4✓ Branch 2 taken 402 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 402 times.
✗ Branch 6 not taken.
|
402 | unsigned qb = qubit_indices_.at(Qubit(qbs[0])); | |
571 |
3/6✓ Branch 3 taken 402 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 402 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 402 times.
✗ Branch 10 not taken.
|
804 | auto angle = com.get_op_ptr()->get_params().at(0); | |
572 |
3/4✓ Branch 1 taken 204 times.
✓ Branch 2 taken 133 times.
✓ Branch 3 taken 65 times.
✗ Branch 4 not taken.
|
402 | switch (qubit_types_[qb]) { | |
573 |
1/1✓ Decision 'true' taken 204 times.
|
204 | case QubitType::pre: { | |
574 |
2/4✓ Branch 3 taken 204 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 204 times.
✗ Branch 7 not taken.
|
204 | box_circ_.add_op<unsigned>(OpType::Rz, angle, {qb}); | |
575 | 204 | qubit_types_[qb] = QubitType::in; | ||
576 | 204 | break; | ||
577 | } | |||
578 |
1/1✓ Decision 'true' taken 133 times.
|
133 | case QubitType::in: { | |
579 |
2/4✓ Branch 3 taken 133 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 133 times.
✗ Branch 7 not taken.
|
133 | box_circ_.add_op<unsigned>(OpType::Rz, angle, {qb}); | |
580 | 133 | break; | ||
581 | } | |||
582 |
1/1✓ Decision 'true' taken 65 times.
|
65 | case QubitType::post: { | |
583 |
1/2✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
|
65 | add_phase_poly_box(); | |
584 | ||||
585 | 65 | qubit_types_[qb] = QubitType::in; | ||
586 |
2/4✓ Branch 3 taken 65 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 65 times.
✗ Branch 7 not taken.
|
65 | box_circ_.add_op<unsigned>(OpType::Rz, angle, {qb}); | |
587 | 65 | break; | ||
588 | } | |||
589 |
0/1✗ Decision 'true' not taken.
|
✗ | default: { | |
590 | // no other types should be in this list | |||
591 | TKET_ASSERT(!"Invalid Qubit Type in Phase Poly Box creation"); | |||
592 | } | |||
593 | } | |||
594 | 402 | break; | ||
595 | 402 | } | ||
596 | 486 | case OpType::H: | ||
597 | case OpType::Collapse: | |||
598 | case OpType::Reset: { | |||
599 |
2/4✓ Branch 2 taken 486 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 486 times.
✗ Branch 6 not taken.
|
486 | unsigned qb = qubit_indices_.at(Qubit(qbs[0])); | |
600 |
3/4✓ Branch 1 taken 137 times.
✓ Branch 2 taken 319 times.
✓ Branch 3 taken 30 times.
✗ Branch 4 not taken.
|
486 | switch (qubit_types_[qb]) { | |
601 |
1/1✓ Decision 'true' taken 137 times.
|
137 | case QubitType::pre: { | |
602 |
2/4✓ Branch 3 taken 137 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 137 times.
✗ Branch 7 not taken.
|
137 | circ_.add_op<unsigned>(ot, {qb}); | |
603 | 137 | break; | ||
604 | } | |||
605 |
1/1✓ Decision 'true' taken 319 times.
|
319 | case QubitType::in: { | |
606 |
2/4✓ Branch 3 taken 319 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 319 times.
✗ Branch 7 not taken.
|
319 | post_circ_.add_op<unsigned>(ot, {qb}); | |
607 | 319 | qubit_types_[qb] = QubitType::post; | ||
608 | 319 | break; | ||
609 | } | |||
610 |
1/1✓ Decision 'true' taken 30 times.
|
30 | case QubitType::post: { | |
611 |
2/4✓ Branch 3 taken 30 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 30 times.
✗ Branch 7 not taken.
|
30 | post_circ_.add_op<unsigned>(ot, {qb}); | |
612 | 30 | break; | ||
613 | } | |||
614 |
0/1✗ Decision 'true' not taken.
|
✗ | default: { | |
615 | // no other types should be in this list | |||
616 | TKET_ASSERT(!"Invalid Qubit Type in Phase Poly Box creation"); | |||
617 | } | |||
618 | } | |||
619 | 486 | break; | ||
620 | } | |||
621 |
1/1✓ Decision 'true' taken 9 times.
|
9 | case OpType::Measure: { | |
622 |
2/4✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
|
9 | unsigned qb = qubit_indices_.at(Qubit(qbs[0])); | |
623 |
2/4✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
|
9 | unsigned b = bit_indices_.at(Bit(qbs[1])); | |
624 | ||||
625 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
|
9 | switch (qubit_types_[qb]) { | |
626 |
0/1✗ Decision 'true' not taken.
|
✗ | case QubitType::pre: { | |
627 | ✗ | circ_.add_op<unsigned>(ot, {qb, b}); | ||
628 | ✗ | break; | ||
629 | } | |||
630 |
1/1✓ Decision 'true' taken 1 times.
|
1 | case QubitType::in: { | |
631 |
2/4✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
1 | post_circ_.add_op<unsigned>(ot, {qb, b}); | |
632 | 1 | qubit_types_[qb] = QubitType::post; | ||
633 | 1 | break; | ||
634 | } | |||
635 |
1/1✓ Decision 'true' taken 8 times.
|
8 | case QubitType::post: { | |
636 |
2/4✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
|
8 | post_circ_.add_op<unsigned>(ot, {qb, b}); | |
637 | 8 | break; | ||
638 | } | |||
639 |
0/1✗ Decision 'true' not taken.
|
✗ | default: { | |
640 | // no other types should be in this list | |||
641 | TKET_ASSERT(!"Invalid Qubit Type in Phase Poly Box creation"); | |||
642 | } | |||
643 | } | |||
644 | 9 | break; | ||
645 | } | |||
646 |
0/1✗ Decision 'true' not taken.
|
✗ | default: { | |
647 | ✗ | throw BadOpType( | ||
648 | "Please rebase with the compiler pass RebaseUFR to only CX, Rz, H, " | |||
649 | "measure, reset, collapse, barrier gates. Found gate of different " | |||
650 | "type", | |||
651 | ✗ | ot); | ||
652 | } | |||
653 | } | |||
654 | 1231 | } | ||
655 | ||||
656 | // add the last box to the circuit | |||
657 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | add_phase_poly_box(); | |
658 | 37 | } | ||
659 | ||||
660 | 37 | Circuit CircToPhasePolyConversion::get_circuit() const { return circ_; } | ||
661 | ||||
662 | } // namespace tket | |||
663 |