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 "PhasedXFrontier.hpp" | |||
16 | ||||
17 | #include <string> | |||
18 | ||||
19 | #include "Circuit/CircPool.hpp" | |||
20 | #include "Circuit/CircUtils.hpp" | |||
21 | #include "Circuit/Circuit.hpp" | |||
22 | #include "OpType/OpType.hpp" | |||
23 | #include "OpType/OpTypeInfo.hpp" | |||
24 | #include "StandardSquash.hpp" | |||
25 | #include "Utils/Expression.hpp" | |||
26 | ||||
27 | namespace tket { | |||
28 | ||||
29 | namespace Transforms { | |||
30 | ||||
31 | template <typename T> | |||
32 | 628 | static std::map<T, unsigned> count(std::vector<T> xs) { | ||
33 | 628 | std::map<T, unsigned> cnts; | ||
34 |
2/2✓ Branch 5 taken 1388 times.
✓ Branch 6 taken 628 times.
|
2/2✓ Decision 'true' taken 1388 times.
✓ Decision 'false' taken 628 times.
|
2016 | for (const auto& x : xs) { |
35 |
1/2✓ Branch 1 taken 1388 times.
✗ Branch 2 not taken.
|
1388 | auto it = cnts.find(x); | |
36 |
2/2✓ Branch 2 taken 409 times.
✓ Branch 3 taken 979 times.
|
2/2✓ Decision 'true' taken 409 times.
✓ Decision 'false' taken 979 times.
|
1388 | if (it != cnts.end()) { |
37 | 409 | ++(it->second); | ||
38 | } else { | |||
39 |
1/2✓ Branch 1 taken 979 times.
✗ Branch 2 not taken.
|
979 | cnts[x] = 1; | |
40 | } | |||
41 | } | |||
42 | 628 | return cnts; | ||
43 | } | |||
44 | ||||
45 | 45 | bool PhasedXFrontier::is_finished() { | ||
46 |
2/2✓ Branch 1 taken 134 times.
✓ Branch 2 taken 45 times.
|
2/2✓ Decision 'true' taken 134 times.
✓ Decision 'false' taken 45 times.
|
179 | for (unsigned i = 0; i < circ_.n_qubits(); ++i) { |
47 |
1/2✓ Branch 2 taken 134 times.
✗ Branch 3 not taken.
|
134 | Vertex v = circ_.target(intervals_[i].second); | |
48 |
2/4✓ Branch 1 taken 134 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 134 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 134 times.
|
134 | if (!circ_.detect_final_Op(v)) { |
49 | ✗ | return false; | ||
50 | } | |||
51 | } | |||
52 | 45 | return true; | ||
53 | } | |||
54 | ||||
55 | 176 | std::set<unsigned> PhasedXFrontier::qubits_ending_in(const Vertex& v) const { | ||
56 | 176 | std::set<unsigned> qubits; | ||
57 |
3/4✓ Branch 1 taken 824 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 648 times.
✓ Branch 4 taken 176 times.
|
0/1? Decision couldn't be analyzed.
|
824 | for (unsigned i = 0; i < circ_.n_qubits(); ++i) { |
58 |
3/4✓ Branch 2 taken 648 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 296 times.
|
2/2✓ Decision 'true' taken 352 times.
✓ Decision 'false' taken 296 times.
|
648 | if (circ_.target(intervals_[i].second) == v) { |
59 |
1/2✓ Branch 1 taken 352 times.
✗ Branch 2 not taken.
|
352 | qubits.insert(i); | |
60 | } | |||
61 | } | |||
62 | 176 | return qubits; | ||
63 | } | |||
64 | ||||
65 | 92 | void PhasedXFrontier::squash_intervals() { | ||
66 |
2/2✓ Branch 1 taken 295 times.
✓ Branch 2 taken 92 times.
|
2/2✓ Decision 'true' taken 295 times.
✓ Decision 'false' taken 92 times.
|
387 | for (unsigned i = 0; i < circ_.n_qubits(); ++i) { |
67 | 295 | squash_interval(i); | ||
68 | } | |||
69 | 92 | } | ||
70 | ||||
71 | 2200 | OptEdge PhasedXFrontier::get_beta_edge(unsigned i) const { | ||
72 | 2200 | const auto& [start, end] = intervals_[i]; | ||
73 | 2200 | Edge e = start; | ||
74 |
3/4✓ Branch 1 taken 3061 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2249 times.
✓ Branch 4 taken 812 times.
|
0/1? Decision couldn't be analyzed.
|
3061 | while (e != end) { |
75 |
1/2✓ Branch 1 taken 2249 times.
✗ Branch 2 not taken.
|
2249 | Vertex v = circ_.target(e); | |
76 |
1/2✓ Branch 1 taken 2249 times.
✗ Branch 2 not taken.
|
2249 | OpType type = circ_.get_OpType_from_Vertex(v); | |
77 |
4/4✓ Branch 0 taken 1693 times.
✓ Branch 1 taken 556 times.
✓ Branch 2 taken 832 times.
✓ Branch 3 taken 861 times.
|
2/2✓ Decision 'true' taken 1388 times.
✓ Decision 'false' taken 861 times.
|
2249 | if (type == OpType::PhasedX || type == OpType::NPhasedX) { |
78 | 1388 | return e; | ||
79 | } | |||
80 |
1/2✓ Branch 1 taken 861 times.
✗ Branch 2 not taken.
|
861 | e = circ_.get_next_edge(v, e); | |
81 | } | |||
82 | 812 | return std::nullopt; | ||
83 | } | |||
84 | ||||
85 | 628 | OptEdgeVec PhasedXFrontier::get_all_beta_edges() const { | ||
86 | 628 | OptEdgeVec beta_edges; | ||
87 | 628 | std::vector<Vertex> beta_vertices; | ||
88 |
3/4✓ Branch 1 taken 2828 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2200 times.
✓ Branch 4 taken 628 times.
|
0/1? Decision couldn't be analyzed.
|
2828 | for (unsigned i = 0; i < circ_.n_qubits(); ++i) { |
89 |
1/2✓ Branch 1 taken 2200 times.
✗ Branch 2 not taken.
|
2200 | OptEdge beta_e = get_beta_edge(i); | |
90 |
1/2✓ Branch 1 taken 2200 times.
✗ Branch 2 not taken.
|
2200 | beta_edges.push_back(beta_e); | |
91 |
2/2✓ Branch 1 taken 1388 times.
✓ Branch 2 taken 812 times.
|
2/2✓ Decision 'true' taken 1388 times.
✓ Decision 'false' taken 812 times.
|
2200 | if (beta_e) { |
92 |
2/4✓ Branch 2 taken 1388 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1388 times.
✗ Branch 6 not taken.
|
1388 | beta_vertices.push_back(circ_.target(*beta_e)); | |
93 | } | |||
94 | } | |||
95 | ||||
96 | // for OpType::NPhasedX, we need to reset some betas to zero if they | |||
97 | // are shadowed (i.e. if one NPhasedX is behind another one) | |||
98 |
2/4✓ Branch 1 taken 628 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 628 times.
✗ Branch 5 not taken.
|
628 | std::map<Vertex, unsigned> arities = count(beta_vertices); | |
99 |
2/2✓ Branch 5 taken 2200 times.
✓ Branch 6 taken 628 times.
|
2/2✓ Decision 'true' taken 2200 times.
✓ Decision 'false' taken 628 times.
|
2828 | for (auto& e : beta_edges) { |
100 |
2/2✓ Branch 1 taken 1388 times.
✓ Branch 2 taken 812 times.
|
2/2✓ Decision 'true' taken 1388 times.
✓ Decision 'false' taken 812 times.
|
2200 | if (e) { |
101 |
1/2✓ Branch 2 taken 1388 times.
✗ Branch 3 not taken.
|
1388 | Vertex v = circ_.target(*e); | |
102 |
1/2✓ Branch 1 taken 1388 times.
✗ Branch 2 not taken.
|
1388 | Op_ptr op = circ_.get_Op_ptr_from_Vertex(v); | |
103 |
4/6✓ Branch 1 taken 1388 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1388 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 128 times.
✓ Branch 8 taken 1260 times.
|
2/2✓ Decision 'true' taken 128 times.
✓ Decision 'false' taken 1260 times.
|
1388 | if (arities[v] != op->n_qubits()) { |
104 | 128 | e = std::nullopt; | ||
105 | } | |||
106 | 1388 | } | ||
107 | } | |||
108 | 1256 | return beta_edges; | ||
109 | 628 | } | ||
110 | ||||
111 | 492 | OptVertexVec PhasedXFrontier::get_all_beta_vertices() const { | ||
112 | 492 | OptVertexVec vertices; | ||
113 |
3/4✓ Branch 1 taken 492 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 1714 times.
✓ Branch 9 taken 492 times.
|
0/1? Decision couldn't be analyzed.
|
2206 | for (const auto& e : get_all_beta_edges()) { |
114 |
2/2✓ Branch 1 taken 933 times.
✓ Branch 2 taken 781 times.
|
2/2✓ Decision 'true' taken 933 times.
✓ Decision 'false' taken 781 times.
|
1714 | if (e) { |
115 |
1/2✓ Branch 2 taken 933 times.
✗ Branch 3 not taken.
|
933 | Vertex v = circ_.target(*e); | |
116 |
1/2✓ Branch 2 taken 933 times.
✗ Branch 3 not taken.
|
933 | vertices.push_back(v); | |
117 | } else { | |||
118 | 781 | OptVertex optv; | ||
119 |
1/2✓ Branch 1 taken 781 times.
✗ Branch 2 not taken.
|
781 | vertices.push_back(optv); | |
120 | } | |||
121 | 492 | } | ||
122 | 492 | return vertices; | ||
123 | } | |||
124 | ||||
125 | 148 | std::vector<Expr> PhasedXFrontier::get_all_betas() const { | ||
126 | 148 | std::vector<Expr> betas; | ||
127 |
3/4✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 534 times.
✓ Branch 9 taken 148 times.
|
0/1? Decision couldn't be analyzed.
|
682 | for (const auto& v : get_all_beta_vertices()) { |
128 |
1/2✓ Branch 1 taken 534 times.
✗ Branch 2 not taken.
|
534 | Expr beta = 0.; | |
129 |
2/2✓ Branch 1 taken 341 times.
✓ Branch 2 taken 193 times.
|
2/2✓ Decision 'true' taken 341 times.
✓ Decision 'false' taken 193 times.
|
534 | if (v) { |
130 |
1/2✓ Branch 2 taken 341 times.
✗ Branch 3 not taken.
|
341 | Op_ptr op = circ_.get_Op_ptr_from_Vertex(*v); | |
131 |
2/4✓ Branch 2 taken 341 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 341 times.
✗ Branch 7 not taken.
|
341 | beta = op->get_params().front(); | |
132 | 341 | } | ||
133 |
1/2✓ Branch 1 taken 534 times.
✗ Branch 2 not taken.
|
534 | betas.push_back(beta); | |
134 | 682 | } | ||
135 | 148 | return betas; | ||
136 | } | |||
137 | ||||
138 | 197 | void PhasedXFrontier::next_interval(unsigned i) { | ||
139 | 197 | auto& [start, end] = intervals_[i]; | ||
140 | ||||
141 | // new interval | |||
142 | 197 | start = get_interval_start(end); | ||
143 | 197 | end = get_interval_end(start); | ||
144 | 197 | } | ||
145 | ||||
146 | 81 | void PhasedXFrontier::next_multiqb(const Vertex& v) { | ||
147 |
1/2✓ Branch 1 taken 81 times.
✗ Branch 2 not taken.
|
81 | std::set<unsigned> curr_qubits = qubits_ending_in(v); | |
148 | // move forward | |||
149 |
2/2✓ Branch 5 taken 162 times.
✓ Branch 6 taken 81 times.
|
2/2✓ Decision 'true' taken 162 times.
✓ Decision 'false' taken 81 times.
|
243 | for (unsigned i : curr_qubits) { |
150 |
1/2✓ Branch 1 taken 162 times.
✗ Branch 2 not taken.
|
162 | next_interval(i); | |
151 | } | |||
152 | 81 | } | ||
153 | ||||
154 | 436 | Edge PhasedXFrontier::get_interval_end(Edge e) const { | ||
155 |
1/2✓ Branch 1 taken 436 times.
✗ Branch 2 not taken.
|
436 | Vertex v = circ_.target(e); | |
156 |
8/10✓ Branch 1 taken 885 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 615 times.
✓ Branch 4 taken 270 times.
✓ Branch 6 taken 615 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 449 times.
✓ Branch 9 taken 166 times.
✓ Branch 10 taken 449 times.
✓ Branch 11 taken 436 times.
|
0/1? Decision couldn't be analyzed.
|
885 | while (!circ_.detect_final_Op(v) && !is_interval_boundary(v)) { |
157 |
1/2✓ Branch 1 taken 449 times.
✗ Branch 2 not taken.
|
449 | auto p = circ_.get_next_pair(v, e); | |
158 | 449 | v = p.first; | ||
159 | 449 | e = p.second; | ||
160 | } | |||
161 | 436 | return e; | ||
162 | } | |||
163 | ||||
164 | 197 | Edge PhasedXFrontier::get_interval_start(Edge e) const { | ||
165 |
1/2✓ Branch 1 taken 197 times.
✗ Branch 2 not taken.
|
197 | Vertex v = circ_.target(e); | |
166 |
3/4✓ Branch 1 taken 197 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 184 times.
✓ Branch 4 taken 13 times.
|
2/2✓ Decision 'true' taken 184 times.
✓ Decision 'false' taken 13 times.
|
197 | if (!circ_.detect_final_Op(v)) { |
167 |
1/2✓ Branch 1 taken 184 times.
✗ Branch 2 not taken.
|
184 | e = circ_.get_next_edge(v, e); | |
168 | } | |||
169 | 197 | return e; | ||
170 | } | |||
171 | ||||
172 | 1322 | bool PhasedXFrontier::is_interval_boundary(Op_ptr op) { | ||
173 | 1322 | OpType type = op->get_type(); | ||
174 |
11/18✓ Branch 1 taken 1322 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 978 times.
✓ Branch 4 taken 344 times.
✓ Branch 7 taken 978 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 978 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 517 times.
✓ Branch 14 taken 461 times.
✓ Branch 15 taken 244 times.
✓ Branch 16 taken 273 times.
✓ Branch 18 taken 978 times.
✓ Branch 19 taken 344 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
|
2644 | return is_gate_type(type) && as_gate_ptr(op)->n_qubits() > 1 && | |
175 |
2/2✓ Branch 0 taken 978 times.
✓ Branch 1 taken 344 times.
|
2644 | type != OpType::NPhasedX; | |
176 | } | |||
177 | ||||
178 | 615 | bool PhasedXFrontier::is_interval_boundary(Vertex v) const { | ||
179 |
1/2✓ Branch 1 taken 615 times.
✗ Branch 2 not taken.
|
615 | Op_ptr op = circ_.get_Op_ptr_from_Vertex(v); | |
180 |
1/2✓ Branch 2 taken 615 times.
✗ Branch 3 not taken.
|
1230 | return is_interval_boundary(op); | |
181 | 615 | } | ||
182 | ||||
183 | /** | |||
184 | * @brief Implements the AbstractSquasher interface for squashing to PhasedX+Rz | |||
185 | */ | |||
186 | class PhasedXSquasher : public StandardSquasher { | |||
187 | public: | |||
188 | 75 | PhasedXSquasher() | ||
189 | 75 | : StandardSquasher( | ||
190 |
1/2✓ Branch 2 taken 75 times.
✗ Branch 3 not taken.
|
150 | OpTypeSet{OpType::Rz, OpType::PhasedX}, | |
191 |
1/2✓ Branch 2 taken 75 times.
✗ Branch 3 not taken.
|
225 | CircPool::tk1_to_PhasedXRz) {} | |
192 | ||||
193 | // Accept any single-qubit gate that has TK1 angles to squash it. | |||
194 | 299 | bool accepts(Gate_ptr gp) const override { | ||
195 | 299 | OpType optype = gp->get_type(); | ||
196 | 299 | return is_single_qubit_unitary_type(optype); | ||
197 | } | |||
198 | }; | |||
199 | ||||
200 | 75 | PhasedXFrontier::PhasedXFrontier(Circuit& circ) | ||
201 | 75 | : intervals_(), | ||
202 | 75 | circ_(circ), | ||
203 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | squasher_(std::make_unique<PhasedXSquasher>(), circ, false) { | |
204 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | const unsigned n = circ_.n_qubits(); | |
205 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | intervals_.resize(n); | |
206 | ||||
207 | // initialise intervals | |||
208 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | const qubit_vector_t all_qbs = circ_.all_qubits(); | |
209 |
2/2✓ Branch 0 taken 239 times.
✓ Branch 1 taken 75 times.
|
2/2✓ Decision 'true' taken 239 times.
✓ Decision 'false' taken 75 times.
|
314 | for (unsigned i = 0; i < n; ++i) { |
210 | 239 | Qubit q = all_qbs[i]; | ||
211 |
1/2✓ Branch 1 taken 239 times.
✗ Branch 2 not taken.
|
239 | Vertex v_in = circ_.get_in(q); | |
212 |
1/2✓ Branch 1 taken 239 times.
✗ Branch 2 not taken.
|
239 | EdgeVec e_vec = circ_.get_all_out_edges(v_in); | |
213 | TKET_ASSERT(e_vec.size() == 1); | |||
214 | ||||
215 | // interval [start, end] | |||
216 | 239 | Edge start = e_vec.front(); | ||
217 |
1/2✓ Branch 1 taken 239 times.
✗ Branch 2 not taken.
|
239 | Edge end = get_interval_end(start); | |
218 | 239 | intervals_[i] = {start, end}; | ||
219 | 239 | } | ||
220 | 75 | } | ||
221 | ||||
222 | 295 | void PhasedXFrontier::squash_interval(unsigned i) { | ||
223 | 295 | auto& [start_e, end_e] = intervals_[i]; | ||
224 | ||||
225 | // backup edges | |||
226 |
2/4✓ Branch 1 taken 295 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 295 times.
✗ Branch 5 not taken.
|
295 | VertPort start{circ_.source(start_e), circ_.get_source_port(start_e)}; | |
227 |
2/4✓ Branch 1 taken 295 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 295 times.
✗ Branch 5 not taken.
|
295 | VertPort end{circ_.target(end_e), circ_.get_target_port(end_e)}; | |
228 | ||||
229 |
1/2✓ Branch 1 taken 295 times.
✗ Branch 2 not taken.
|
295 | squasher_.squash_between(start_e, end_e); | |
230 | ||||
231 | // restore interval edges | |||
232 |
1/2✓ Branch 1 taken 295 times.
✗ Branch 2 not taken.
|
295 | start_e = circ_.get_nth_out_edge(start.first, start.second); | |
233 |
1/2✓ Branch 1 taken 295 times.
✗ Branch 2 not taken.
|
295 | end_e = circ_.get_nth_in_edge(end.first, end.second); | |
234 | 295 | } | ||
235 | ||||
236 | 136 | PhasedXFrontier::BackupIntervals PhasedXFrontier::backup_intervals() const { | ||
237 | 136 | BackupIntervals ret; | ||
238 |
3/4✓ Branch 1 taken 622 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 486 times.
✓ Branch 4 taken 136 times.
|
0/1? Decision couldn't be analyzed.
|
622 | for (unsigned i = 0; i < circ_.n_qubits(); ++i) { |
239 | 486 | const auto& [start, end] = intervals_[i]; | ||
240 |
3/6✓ Branch 1 taken 486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 486 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 486 times.
✗ Branch 9 not taken.
|
486 | ret.start.push_back({circ_.source(start), circ_.get_source_port(start)}); | |
241 |
3/6✓ Branch 1 taken 486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 486 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 486 times.
✗ Branch 9 not taken.
|
486 | ret.end.push_back({circ_.target(end), circ_.get_target_port(end)}); | |
242 | } | |||
243 | 136 | return ret; | ||
244 | } | |||
245 | ||||
246 | 136 | void PhasedXFrontier::restore_intervals(const BackupIntervals& b) { | ||
247 |
2/2✓ Branch 1 taken 486 times.
✓ Branch 2 taken 136 times.
|
2/2✓ Decision 'true' taken 486 times.
✓ Decision 'false' taken 136 times.
|
622 | for (unsigned i = 0; i < circ_.n_qubits(); ++i) { |
248 |
1/2✓ Branch 3 taken 486 times.
✗ Branch 4 not taken.
|
486 | Edge start = circ_.get_nth_out_edge(b.start[i].first, b.start[i].second); | |
249 |
1/2✓ Branch 3 taken 486 times.
✗ Branch 4 not taken.
|
486 | Edge end = circ_.get_nth_in_edge(b.end[i].first, b.end[i].second); | |
250 | 486 | intervals_[i].first = start; | ||
251 | 486 | intervals_[i].second = end; | ||
252 | } | |||
253 | 136 | } | ||
254 | ||||
255 | 147 | void PhasedXFrontier::skip_global_gates(unsigned n) { | ||
256 |
2/2✓ Branch 1 taken 516 times.
✓ Branch 2 taken 147 times.
|
2/2✓ Decision 'true' taken 516 times.
✓ Decision 'false' taken 147 times.
|
663 | for (unsigned i = 0; i < circ_.n_qubits(); ++i) { |
257 | 516 | unsigned count = 0; | ||
258 | 516 | auto& [e, end] = intervals_[i]; | ||
259 |
1/2✓ Branch 1 taken 1602 times.
✗ Branch 2 not taken.
|
1/2✓ Decision 'true' taken 1602 times.
✗ Decision 'false' not taken.
|
1602 | while (e != end) { |
260 |
1/2✓ Branch 1 taken 1602 times.
✗ Branch 2 not taken.
|
1602 | Vertex v = circ_.target(e); | |
261 |
1/2✓ Branch 1 taken 1602 times.
✗ Branch 2 not taken.
|
1602 | OpType type = circ_.get_OpType_from_Vertex(v); | |
262 |
1/2✓ Branch 1 taken 1602 times.
✗ Branch 2 not taken.
|
1602 | e = circ_.get_next_edge(v, e); | |
263 |
4/4✓ Branch 0 taken 674 times.
✓ Branch 1 taken 928 times.
✓ Branch 2 taken 928 times.
✓ Branch 3 taken 674 times.
|
2/2✓ Decision 'true' taken 928 times.
✓ Decision 'false' taken 1348 times.
|
2276 | if (type == OpType::NPhasedX || |
264 |
2/6✓ Branch 1 taken 674 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 674 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
674 | (circ_.n_qubits() == 1 && type == OpType::PhasedX)) { | |
265 |
1/2✓ Branch 1 taken 928 times.
✗ Branch 2 not taken.
|
928 | unsigned in_edges = circ_.n_in_edges_of_type(v, EdgeType::Quantum); | |
266 |
1/2✓ Branch 1 taken 928 times.
✗ Branch 2 not taken.
|
928 | unsigned out_edges = circ_.n_out_edges_of_type(v, EdgeType::Quantum); | |
267 |
5/10✓ Branch 1 taken 928 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 928 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 928 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 928 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 928 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 928 times.
|
928 | if (in_edges != circ_.n_qubits() || out_edges != circ_.n_qubits()) { |
268 | ✗ | throw CircuitInvalidity("Found non-global NPhasedX gate"); | ||
269 | } | |||
270 | 928 | ++count; | ||
271 |
2/2✓ Branch 0 taken 516 times.
✓ Branch 1 taken 412 times.
|
2/2✓ Decision 'true' taken 516 times.
✓ Decision 'false' taken 412 times.
|
928 | if (count == n) { |
272 | 516 | break; | ||
273 | } | |||
274 | } | |||
275 | } | |||
276 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 516 times.
|
516 | if (count < n) { |
277 | ✗ | throw CircuitInvalidity("Did not find expected global gates"); | ||
278 | } | |||
279 | } | |||
280 | 147 | } | ||
281 | ||||
282 | 10 | bool PhasedXFrontier::are_phasedx_left() const { | ||
283 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | PhasedXFrontier copy = *this; | |
284 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | const unsigned n = circ_.n_qubits(); | |
285 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 10 times.
|
2/2✓ Decision 'true' taken 34 times.
✓ Decision 'false' taken 10 times.
|
44 | for (unsigned i = 0; i < n; ++i) { |
286 |
1/2✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
|
34 | copy.next_interval(i); | |
287 | } | |||
288 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | OptVertexVec all_phasedx = copy.get_all_beta_vertices(); | |
289 | ||||
290 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
20 | return !all_nullopt(all_phasedx); | |
291 | 10 | } | ||
292 | ||||
293 | 23 | void PhasedXFrontier::insert_1_phasedx(unsigned i) { | ||
294 |
1/2✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
|
23 | std::vector<Expr> betas = get_all_betas(); | |
295 |
1/2✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
|
23 | OptEdgeVec edges = get_all_beta_edges(); | |
296 |
1/2✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
|
23 | OptVertexVec vertices = get_all_beta_vertices(); | |
297 | ||||
298 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 23 times.
|
23 | if (!vertices[i]) { |
299 | ✗ | throw CircuitInvalidity("No PhasedX found on qubit " + std::to_string(i)); | ||
300 | } | |||
301 |
1/2✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
|
23 | Expr beta = betas[i]; | |
302 | ||||
303 | 23 | VertexSet bin; | ||
304 | 23 | EdgeVec in_hole, out_hole; | ||
305 |
2/4✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 23 times.
✗ Branch 6 not taken.
|
23 | Circuit sub1(circ_.n_qubits()); | |
306 |
2/4✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 23 times.
✗ Branch 6 not taken.
|
23 | Circuit sub2(circ_.n_qubits()); | |
307 | ||||
308 |
3/4✓ Branch 1 taken 97 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 74 times.
✓ Branch 4 taken 23 times.
|
0/1? Decision couldn't be analyzed.
|
97 | for (unsigned i = 0; i < circ_.n_qubits(); ++i) { |
309 |
2/2✓ Branch 2 taken 66 times.
✓ Branch 3 taken 8 times.
|
2/2✓ Decision 'true' taken 66 times.
✓ Decision 'false' taken 8 times.
|
74 | if (vertices[i]) { |
310 |
1/2✓ Branch 2 taken 66 times.
✗ Branch 3 not taken.
|
66 | Vertex v = vertices[i].value(); | |
311 |
1/2✓ Branch 2 taken 66 times.
✗ Branch 3 not taken.
|
66 | Edge e = edges[i].value(); | |
312 |
1/2✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
|
66 | Op_ptr op = circ_.get_Op_ptr_from_Vertex(v); | |
313 | 66 | OpType type = op->get_type(); | ||
314 |
1/2✓ Branch 2 taken 66 times.
✗ Branch 3 not taken.
|
66 | Expr new_beta = betas[i] - beta; | |
315 | ||||
316 |
1/2✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
|
66 | in_hole.push_back(e); | |
317 |
2/4✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 66 times.
✗ Branch 5 not taken.
|
66 | out_hole.push_back(circ_.get_next_edge(v, e)); | |
318 | ||||
319 |
3/4✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 58 times.
✓ Branch 4 taken 8 times.
|
2/2✓ Decision 'true' taken 58 times.
✓ Decision 'false' taken 8 times.
|
66 | if (!bin.contains(v)) { |
320 |
1/2✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
|
58 | bin.insert(v); | |
321 | ||||
322 | // v's qubits | |||
323 | 58 | std::vector<unsigned> qubits; | ||
324 |
3/4✓ Branch 1 taken 252 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 194 times.
✓ Branch 4 taken 58 times.
|
0/1? Decision couldn't be analyzed.
|
252 | for (unsigned j = 0; j < circ_.n_qubits(); ++j) { |
325 |
2/2✓ Branch 2 taken 66 times.
✓ Branch 3 taken 128 times.
|
2/2✓ Decision 'true' taken 66 times.
✓ Decision 'false' taken 128 times.
|
194 | if (vertices[j] == v) { |
326 |
1/2✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
|
66 | qubits.push_back(j); | |
327 | } | |||
328 | } | |||
329 | ||||
330 |
3/4✓ Branch 0 taken 50 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
|
1/2✓ Decision 'true' taken 58 times.
✗ Decision 'false' not taken.
|
58 | if (type == OpType::NPhasedX || type == OpType::PhasedX) { |
331 |
2/4✓ Branch 2 taken 58 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 58 times.
✗ Branch 7 not taken.
|
58 | Expr alpha = op->get_params()[1]; | |
332 |
3/4✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 44 times.
|
2/2✓ Decision 'true' taken 14 times.
✓ Decision 'false' taken 44 times.
|
58 | if (!equiv_0(new_beta, 4)) { |
333 |
2/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 14 times.
|
14 | if (equiv_0(new_beta, 2)) { |
334 |
0/2✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
|
✗ | if (qubits.size() % 2) { | |
335 | ✗ | sub1.add_phase(-1); | ||
336 | } | |||
337 | } else { | |||
338 |
6/12✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 14 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 14 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 28 times.
✓ Branch 17 taken 14 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
42 | sub2.add_op(type, {new_beta, 0.}, qubits); | |
339 | } | |||
340 | } | |||
341 |
3/4✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 44 times.
✓ Branch 4 taken 14 times.
|
0/1? Decision couldn't be analyzed.
|
58 | if (!equiv_0(alpha, 2)) { |
342 |
2/2✓ Branch 4 taken 52 times.
✓ Branch 5 taken 44 times.
|
2/2✓ Decision 'true' taken 52 times.
✓ Decision 'false' taken 44 times.
|
96 | for (unsigned q : qubits) { |
343 |
3/6✓ Branch 3 taken 52 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 52 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 52 times.
✗ Branch 10 not taken.
|
52 | sub1.add_op<unsigned>(OpType::Rz, {-alpha}, {q}); | |
344 |
2/4✓ Branch 3 taken 52 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 52 times.
✗ Branch 7 not taken.
|
52 | sub2.add_op<unsigned>(OpType::Rz, {alpha}, {q}); | |
345 | } | |||
346 | } | |||
347 | 58 | } else { | ||
348 | ✗ | throw BadOpType("Encountered invalid beta angle OpType", type); | ||
349 | } | |||
350 | 58 | } | ||
351 | 66 | } else { | ||
352 | 8 | Edge interval_begin = intervals_[i].first; | ||
353 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | in_hole.push_back(interval_begin); | |
354 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | out_hole.push_back(interval_begin); | |
355 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
|
0/1? Decision couldn't be analyzed.
|
8 | if (!equiv_0(beta, 2)) { |
356 |
7/14✓ 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.
✓ Branch 13 taken 8 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 17 not taken.
✓ Branch 20 taken 16 times.
✓ Branch 21 taken 8 times.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
|
24 | sub2.add_op<unsigned>(OpType::PhasedX, {-beta, 0}, {i}); | |
357 |
0/2✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
|
✗ | } else if (!equiv_0(beta, 4)) { | |
358 | ✗ | sub2.add_phase(-1); | ||
359 | } | |||
360 | } | |||
361 | } | |||
362 | ||||
363 |
2/4✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 23 times.
✗ Branch 6 not taken.
|
23 | Circuit sub(circ_.n_qubits()); | |
364 |
1/2✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
|
23 | sub.append(sub1); | |
365 |
7/14✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 23 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 23 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 23 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 23 times.
✗ Branch 16 not taken.
✓ Branch 19 taken 46 times.
✓ Branch 20 taken 23 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
|
69 | sub.add_op<Qubit>(OpType::NPhasedX, {beta, 0}, sub.all_qubits()); | |
366 |
1/2✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
|
23 | sub.append(sub2); | |
367 | ||||
368 |
1/2✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
|
23 | Subcircuit hole{in_hole, out_hole, bin}; | |
369 | ||||
370 | // perform substitution | |||
371 |
1/2✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
|
23 | BackupIntervals backup = backup_intervals(); | |
372 |
1/2✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
|
23 | circ_.substitute(sub, hole, Circuit::VertexDeletion::Yes); | |
373 |
1/2✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
|
23 | restore_intervals(backup); | |
374 | ||||
375 |
1/2✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
|
23 | skip_global_gates(1); | |
376 | 23 | } | ||
377 | ||||
378 | 113 | void PhasedXFrontier::insert_2_phasedx() { | ||
379 | 113 | EdgeVec hole_in, hole_out; | ||
380 |
2/4✓ Branch 2 taken 113 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 113 times.
✗ Branch 6 not taken.
|
113 | Circuit sub1(circ_.n_qubits()); | |
381 |
2/4✓ Branch 2 taken 113 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 113 times.
✗ Branch 6 not taken.
|
113 | Circuit sub2(circ_.n_qubits()); | |
382 |
2/4✓ Branch 2 taken 113 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 113 times.
✗ Branch 6 not taken.
|
113 | Circuit sub3(circ_.n_qubits()); | |
383 | 113 | VertexSet bin; | ||
384 | ||||
385 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | std::vector<Expr> betas = get_all_betas(); | |
386 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | OptEdgeVec edges = get_all_beta_edges(); | |
387 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | OptVertexVec vertices = get_all_beta_vertices(); | |
388 | ||||
389 |
3/4✓ Branch 1 taken 525 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 412 times.
✓ Branch 4 taken 113 times.
|
0/1? Decision couldn't be analyzed.
|
525 | for (unsigned i = 0; i < circ_.n_qubits(); ++i) { |
390 |
2/2✓ Branch 2 taken 261 times.
✓ Branch 3 taken 151 times.
|
2/2✓ Decision 'true' taken 261 times.
✓ Decision 'false' taken 151 times.
|
412 | if (vertices[i]) { |
391 |
1/2✓ Branch 2 taken 261 times.
✗ Branch 3 not taken.
|
261 | Vertex v = vertices[i].value(); | |
392 |
1/2✓ Branch 2 taken 261 times.
✗ Branch 3 not taken.
|
261 | Edge e = edges[i].value(); | |
393 |
1/2✓ Branch 1 taken 261 times.
✗ Branch 2 not taken.
|
261 | Op_ptr op = circ_.get_Op_ptr_from_Vertex(v); | |
394 | 261 | OpType type = op->get_type(); | ||
395 |
1/2✓ Branch 1 taken 261 times.
✗ Branch 2 not taken.
|
261 | hole_in.push_back(e); | |
396 |
2/4✓ Branch 1 taken 261 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 261 times.
✗ Branch 5 not taken.
|
261 | hole_out.push_back(circ_.get_next_edge(v, e)); | |
397 |
1/2✓ Branch 1 taken 261 times.
✗ Branch 2 not taken.
|
261 | bin.insert(v); | |
398 |
1/2✓ Branch 2 taken 261 times.
✗ Branch 3 not taken.
|
261 | Expr beta = betas[i]; | |
399 |
3/4✓ Branch 0 taken 85 times.
✓ Branch 1 taken 176 times.
✓ Branch 2 taken 85 times.
✗ Branch 3 not taken.
|
1/2✓ Decision 'true' taken 261 times.
✗ Decision 'false' not taken.
|
261 | if (type == OpType::NPhasedX || type == OpType::PhasedX) { |
400 |
2/4✓ Branch 2 taken 261 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 261 times.
✗ Branch 7 not taken.
|
261 | Expr alpha = op->get_params()[1]; | |
401 |
3/4✓ Branch 1 taken 261 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 241 times.
✓ Branch 4 taken 20 times.
|
2/2✓ Decision 'true' taken 241 times.
✓ Decision 'false' taken 20 times.
|
261 | if (!equiv_0(alpha, 2)) { |
402 |
3/6✓ Branch 3 taken 241 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 241 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 241 times.
✗ Branch 10 not taken.
|
241 | sub1.add_op<unsigned>(OpType::Rz, {-alpha}, {i}); | |
403 |
2/4✓ Branch 3 taken 241 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 241 times.
✗ Branch 7 not taken.
|
241 | sub3.add_op<unsigned>(OpType::Rz, {alpha}, {i}); | |
404 | } | |||
405 | 261 | } | ||
406 |
2/4✓ Branch 1 taken 261 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 261 times.
✗ Branch 4 not taken.
|
1/2✓ Decision 'true' taken 261 times.
✗ Decision 'false' not taken.
|
261 | if (!equiv_0(beta, 2)) { |
407 |
2/4✓ Branch 3 taken 261 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 261 times.
✗ Branch 7 not taken.
|
261 | sub2.add_op<unsigned>(OpType::Rz, {beta}, {i}); | |
408 |
0/2✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
|
✗ | } else if (!equiv_0(beta, 4)) { | |
409 | ✗ | sub2.add_phase(-1); | ||
410 | } | |||
411 | 261 | } else { | ||
412 | 151 | Edge interval_begin = intervals_[i].first; | ||
413 |
1/2✓ Branch 1 taken 151 times.
✗ Branch 2 not taken.
|
151 | hole_in.push_back(interval_begin); | |
414 |
1/2✓ Branch 1 taken 151 times.
✗ Branch 2 not taken.
|
151 | hole_out.push_back(interval_begin); | |
415 | } | |||
416 | } | |||
417 | ||||
418 |
2/4✓ Branch 2 taken 113 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 113 times.
✗ Branch 6 not taken.
|
113 | Circuit sub(circ_.n_qubits()); | |
419 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | sub.append(sub1); | |
420 |
7/14✓ Branch 2 taken 113 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 113 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 113 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 113 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 113 times.
✗ Branch 16 not taken.
✓ Branch 19 taken 226 times.
✓ Branch 20 taken 113 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
|
339 | sub.add_op(OpType::NPhasedX, {-0.5, 0.5}, sub.all_qubits()); | |
421 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | sub.append(sub2); | |
422 |
7/14✓ Branch 2 taken 113 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 113 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 113 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 113 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 113 times.
✗ Branch 16 not taken.
✓ Branch 19 taken 226 times.
✓ Branch 20 taken 113 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
|
339 | sub.add_op(OpType::NPhasedX, {0.5, 0.5}, sub.all_qubits()); | |
423 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | sub.append(sub3); | |
424 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | Subcircuit hole{hole_in, hole_out, bin}; | |
425 | ||||
426 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | BackupIntervals backup = backup_intervals(); | |
427 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | circ_.substitute(sub, hole, Circuit::VertexDeletion::Yes); | |
428 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | restore_intervals(backup); | |
429 | ||||
430 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | skip_global_gates(2); | |
431 | 113 | } | ||
432 | ||||
433 | 192 | bool all_nullopt(const OptVertexVec& vec) { | ||
434 |
2/2✓ Branch 5 taken 354 times.
✓ Branch 6 taken 100 times.
|
2/2✓ Decision 'true' taken 354 times.
✓ Decision 'false' taken 100 times.
|
454 | for (const OptVertex& v : vec) { |
435 |
2/2✓ Branch 1 taken 92 times.
✓ Branch 2 taken 262 times.
|
2/2✓ Decision 'true' taken 100 times.
✓ Decision 'false' taken 254 times.
|
354 | if (v) return false; |
436 | } | |||
437 | 100 | return true; | ||
438 | } | |||
439 | ||||
440 | } // namespace Transforms | |||
441 | ||||
442 | } // namespace tket | |||
443 |