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 | //////////////////////////////////////////////////////// | |||
16 | // ALL METHODS TO SET AND GET BASIC CIRCUIT INFORMATION// | |||
17 | //////////////////////////////////////////////////////// | |||
18 | ||||
19 | #include <stdexcept> | |||
20 | #include <tkassert/Assert.hpp> | |||
21 | #include <tklog/TketLog.hpp> | |||
22 | ||||
23 | #include "Circuit.hpp" | |||
24 | #include "DAGDefs.hpp" | |||
25 | #include "DAGProperties.hpp" | |||
26 | #include "OpType/OpDesc.hpp" | |||
27 | #include "OpType/OpType.hpp" | |||
28 | #include "Ops/OpPtr.hpp" | |||
29 | #include "Utils/GraphHeaders.hpp" | |||
30 | ||||
31 | namespace tket { | |||
32 | ||||
33 | ✗ | Circuit::Circuit(const std::string &_name) : Circuit() { name = _name; } | ||
34 | ||||
35 | 257407 | Circuit::Circuit(unsigned n, const std::optional<std::string> _name) | ||
36 | 257407 | : Circuit() { | ||
37 |
1/2✓ Branch 1 taken 257407 times.
✗ Branch 2 not taken.
|
257407 | name = _name; | |
38 |
3/6✓ Branch 1 taken 257407 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 257407 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 257407 times.
✗ Branch 8 not taken.
|
257407 | add_q_register(q_default_reg(), n); | |
39 | 257407 | } | ||
40 | ||||
41 | 244 | Circuit::Circuit(unsigned n, unsigned m, const std::optional<std::string> _name) | ||
42 |
1/2✓ Branch 2 taken 244 times.
✗ Branch 3 not taken.
|
244 | : Circuit(n, _name) { | |
43 |
3/6✓ Branch 1 taken 244 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 244 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 244 times.
✗ Branch 8 not taken.
|
244 | add_c_register(c_default_reg(), m); | |
44 | 244 | } | ||
45 | ||||
46 | // Copy constructor. | |||
47 | // Makes no assumptions about the graph | |||
48 | 99336 | Circuit::Circuit(const Circuit &circ) : Circuit() { | ||
49 |
1/2✓ Branch 1 taken 99336 times.
✗ Branch 2 not taken.
|
99336 | copy_graph(circ); | |
50 |
1/2✓ Branch 1 taken 99336 times.
✗ Branch 2 not taken.
|
99336 | phase = circ.get_phase(); | |
51 |
1/2✓ Branch 1 taken 99336 times.
✗ Branch 2 not taken.
|
99336 | name = circ.name; | |
52 | 99336 | } | ||
53 | ||||
54 | // copy assignment. Moves boundary pointers. | |||
55 | 80844 | Circuit &Circuit::operator=(const Circuit &other) // (1) | ||
56 | { | |||
57 |
2/4✓ Branch 1 taken 80844 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 80844 times.
✗ Branch 5 not taken.
|
80844 | dag = DAG(); | |
58 |
1/2✓ Branch 2 taken 80844 times.
✗ Branch 3 not taken.
|
80844 | boundary = boundary_t(); | |
59 | 80844 | copy_graph(other); | ||
60 | 80844 | phase = other.get_phase(); | ||
61 | 80844 | name = other.name; | ||
62 | 80844 | return *this; | ||
63 | } | |||
64 | ||||
65 | 57 | void Circuit::assert_valid() const { // | ||
66 | TKET_ASSERT(is_valid(dag)); | |||
67 | 57 | } | ||
68 | ||||
69 | 182 | VertexVec Circuit::all_inputs() const { | ||
70 |
1/2✓ Branch 1 taken 182 times.
✗ Branch 2 not taken.
|
182 | VertexVec ins = q_inputs(); | |
71 |
1/2✓ Branch 1 taken 182 times.
✗ Branch 2 not taken.
|
182 | VertexVec c_ins = c_inputs(); | |
72 |
1/2✓ Branch 5 taken 182 times.
✗ Branch 6 not taken.
|
182 | ins.insert(ins.end(), c_ins.begin(), c_ins.end()); | |
73 | 364 | return ins; | ||
74 | 182 | } | ||
75 | ||||
76 | 9932 | VertexVec Circuit::q_inputs() const { | ||
77 | 9932 | VertexVec ins; | ||
78 |
1/2✓ Branch 2 taken 9932 times.
✗ Branch 3 not taken.
|
1/2✓ Decision 'true' taken 9932 times.
✗ Decision 'false' not taken.
|
9932 | for (auto [it, end] = boundary.get<TagType>().equal_range(UnitType::Qubit); |
79 |
4/6✓ Branch 1 taken 15228 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 25160 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15228 times.
✓ Branch 7 taken 9932 times.
|
25160 | it != end; it++) { | |
80 |
2/4✓ Branch 1 taken 15228 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15228 times.
✗ Branch 5 not taken.
|
15228 | ins.push_back(it->in_); | |
81 | } | |||
82 | 9932 | return ins; | ||
83 | } | |||
84 | ||||
85 | 193 | VertexVec Circuit::c_inputs() const { | ||
86 | 193 | VertexVec ins; | ||
87 |
1/2✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
|
1/2✓ Decision 'true' taken 193 times.
✗ Decision 'false' not taken.
|
193 | for (auto [it, end] = boundary.get<TagType>().equal_range(UnitType::Bit); |
88 |
4/6✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 219 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 26 times.
✓ Branch 7 taken 193 times.
|
219 | it != end; it++) { | |
89 |
2/4✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 26 times.
✗ Branch 5 not taken.
|
26 | ins.push_back(it->in_); | |
90 | } | |||
91 | 193 | return ins; | ||
92 | } | |||
93 | ||||
94 | 9 | VertexVec Circuit::all_outputs() const { | ||
95 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | VertexVec outs = q_outputs(); | |
96 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | VertexVec c_outs = c_outputs(); | |
97 |
1/2✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
|
9 | outs.insert(outs.end(), c_outs.begin(), c_outs.end()); | |
98 | 18 | return outs; | ||
99 | 9 | } | ||
100 | ||||
101 | 6564 | VertexVec Circuit::q_outputs() const { | ||
102 | 6564 | VertexVec outs; | ||
103 |
1/2✓ Branch 2 taken 6564 times.
✗ Branch 3 not taken.
|
1/2✓ Decision 'true' taken 6564 times.
✗ Decision 'false' not taken.
|
6564 | for (auto [it, end] = boundary.get<TagType>().equal_range(UnitType::Qubit); |
104 |
4/6✓ Branch 1 taken 10183 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16747 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 10183 times.
✓ Branch 7 taken 6564 times.
|
16747 | it != end; it++) { | |
105 |
2/4✓ Branch 1 taken 10183 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10183 times.
✗ Branch 5 not taken.
|
10183 | outs.push_back(it->out_); | |
106 | } | |||
107 | 6564 | return outs; | ||
108 | } | |||
109 | ||||
110 | 18 | VertexVec Circuit::c_outputs() const { | ||
111 | 18 | VertexVec outs; | ||
112 |
1/2✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
|
1/2✓ Decision 'true' taken 18 times.
✗ Decision 'false' not taken.
|
18 | for (auto [it, end] = boundary.get<TagType>().equal_range(UnitType::Bit); |
113 |
4/6✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20 times.
✓ Branch 7 taken 18 times.
|
38 | it != end; it++) { | |
114 |
2/4✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
|
20 | outs.push_back(it->out_); | |
115 | } | |||
116 | 18 | return outs; | ||
117 | } | |||
118 | ||||
119 | 133061 | qubit_vector_t Circuit::all_qubits() const { | ||
120 | 133061 | qubit_vector_t all_qbs; | ||
121 |
1/2✓ Branch 2 taken 133061 times.
✗ Branch 3 not taken.
|
1/2✓ Decision 'true' taken 133061 times.
✗ Decision 'false' not taken.
|
133061 | for (auto [it, end] = boundary.get<TagType>().equal_range(UnitType::Qubit); |
122 |
3/4✓ Branch 1 taken 623071 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 490010 times.
✓ Branch 4 taken 133061 times.
|
623071 | it != end; it++) { | |
123 |
4/8✓ Branch 1 taken 490010 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 490010 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 490010 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 490010 times.
✗ Branch 12 not taken.
|
490010 | all_qbs.push_back(Qubit(it->id_)); | |
124 | } | |||
125 |
1/2✓ Branch 3 taken 133061 times.
✗ Branch 4 not taken.
|
133061 | std::sort(all_qbs.begin(), all_qbs.end()); | |
126 | 133061 | return all_qbs; | ||
127 | } | |||
128 | ||||
129 | 350 | qubit_vector_t Circuit::created_qubits() const { | ||
130 | 350 | qubit_vector_t all_created_qbs; | ||
131 |
3/4✓ Branch 1 taken 350 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 980 times.
✓ Branch 9 taken 350 times.
|
0/1? Decision couldn't be analyzed.
|
1330 | for (const Qubit &q : all_qubits()) { |
132 |
3/4✓ Branch 1 taken 980 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
✓ Branch 4 taken 950 times.
|
2/2✓ Decision 'true' taken 30 times.
✓ Decision 'false' taken 950 times.
|
980 | if (is_created(q)) { |
133 |
1/2✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
|
30 | all_created_qbs.push_back(q); | |
134 | } | |||
135 | 350 | } | ||
136 | 350 | return all_created_qbs; | ||
137 | } | |||
138 | ||||
139 | 348 | qubit_vector_t Circuit::discarded_qubits() const { | ||
140 | 348 | qubit_vector_t all_discarded_qbs; | ||
141 |
3/4✓ Branch 1 taken 348 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 976 times.
✓ Branch 9 taken 348 times.
|
0/1? Decision couldn't be analyzed.
|
1324 | for (const Qubit &q : all_qubits()) { |
142 |
3/4✓ Branch 1 taken 976 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 968 times.
|
2/2✓ Decision 'true' taken 8 times.
✓ Decision 'false' taken 968 times.
|
976 | if (is_discarded(q)) { |
143 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | all_discarded_qbs.push_back(q); | |
144 | } | |||
145 | 348 | } | ||
146 | 348 | return all_discarded_qbs; | ||
147 | } | |||
148 | ||||
149 | 24905 | bit_vector_t Circuit::all_bits() const { | ||
150 | 24905 | bit_vector_t all_bs; | ||
151 |
1/2✓ Branch 2 taken 24905 times.
✗ Branch 3 not taken.
|
1/2✓ Decision 'true' taken 24905 times.
✗ Decision 'false' not taken.
|
24905 | for (auto [it, end] = boundary.get<TagType>().equal_range(UnitType::Bit); |
152 |
3/4✓ Branch 1 taken 26052 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1147 times.
✓ Branch 4 taken 24905 times.
|
26052 | it != end; it++) { | |
153 |
4/8✓ Branch 1 taken 1147 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1147 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1147 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 1147 times.
✗ Branch 12 not taken.
|
1147 | all_bs.push_back(Bit(it->id_)); | |
154 | } | |||
155 |
1/2✓ Branch 3 taken 24905 times.
✗ Branch 4 not taken.
|
24905 | std::sort(all_bs.begin(), all_bs.end()); | |
156 | 24905 | return all_bs; | ||
157 | } | |||
158 | ||||
159 | 199 | unit_vector_t Circuit::all_units() const { | ||
160 | 199 | unit_vector_t all_us; | ||
161 |
5/8✓ Branch 4 taken 1594 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1594 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1793 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1594 times.
✓ Branch 13 taken 199 times.
|
0/1? Decision couldn't be analyzed.
|
1793 | for (const BoundaryElement &el : boundary.get<TagID>()) { |
162 |
1/2✓ Branch 1 taken 1594 times.
✗ Branch 2 not taken.
|
1594 | all_us.push_back(el.id_); | |
163 | } | |||
164 | 199 | return all_us; | ||
165 | } | |||
166 | ||||
167 | 47 | std::map<Bit, unsigned> Circuit::bit_readout() const { | ||
168 | 47 | std::map<Bit, unsigned> res; | ||
169 | ||||
170 | // Order bits to generate indices | |||
171 |
1/2✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
|
47 | bit_vector_t all_bs = all_bits(); | |
172 |
1/2✓ Branch 3 taken 47 times.
✗ Branch 4 not taken.
|
47 | std::sort(all_bs.begin(), all_bs.end()); | |
173 | 47 | unsigned i = 0; | ||
174 |
2/2✓ Branch 4 taken 167 times.
✓ Branch 5 taken 47 times.
|
2/2✓ Decision 'true' taken 167 times.
✓ Decision 'false' taken 47 times.
|
214 | for (const Bit &b : all_bs) { |
175 |
1/2✓ Branch 2 taken 167 times.
✗ Branch 3 not taken.
|
167 | res.insert({b, i}); | |
176 | 167 | i++; | ||
177 | } | |||
178 | ||||
179 | 94 | return res; | ||
180 | 47 | } | ||
181 | ||||
182 | 46 | std::map<Qubit, unsigned> Circuit::qubit_readout() const { | ||
183 | 46 | std::map<Qubit, unsigned> res; | ||
184 |
1/2✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
|
46 | std::map<Bit, unsigned> bmap = bit_readout(); | |
185 | ||||
186 | // Find measurement map from qubits to index | |||
187 |
1/2✓ Branch 2 taken 46 times.
✗ Branch 3 not taken.
|
1/2✓ Decision 'true' taken 46 times.
✗ Decision 'false' not taken.
|
46 | for (auto [it, end] = boundary.get<TagType>().equal_range(UnitType::Qubit); |
188 |
4/6✓ Branch 1 taken 163 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 209 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 163 times.
✓ Branch 7 taken 46 times.
|
209 | it != end; it++) { | |
189 |
1/2✓ Branch 1 taken 163 times.
✗ Branch 2 not taken.
|
163 | Vertex q_out = it->out_; | |
190 |
2/4✓ Branch 1 taken 163 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 163 times.
✗ Branch 5 not taken.
|
163 | Vertex last_gate = source(get_nth_in_edge(q_out, 0)); | |
191 |
3/4✓ Branch 1 taken 163 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 162 times.
✓ Branch 4 taken 1 times.
|
2/2✓ Decision 'true' taken 162 times.
✓ Decision 'false' taken 1 times.
|
163 | if (get_OpType_from_Vertex(last_gate) == OpType::Measure) { |
192 |
2/4✓ Branch 1 taken 162 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 162 times.
✗ Branch 5 not taken.
|
162 | Vertex possible_c_out = target(get_nth_out_edge(last_gate, 1)); | |
193 |
3/4✓ Branch 1 taken 162 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 161 times.
✓ Branch 4 taken 1 times.
|
2/2✓ Decision 'true' taken 161 times.
✓ Decision 'false' taken 1 times.
|
162 | if (get_OpType_from_Vertex(possible_c_out) == OpType::ClOutput) { |
194 |
2/4✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 161 times.
✗ Branch 5 not taken.
|
161 | Bit b(get_id_from_out(possible_c_out)); | |
195 |
4/8✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 161 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 161 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 161 times.
✗ Branch 12 not taken.
|
161 | res.insert({Qubit(it->id_), bmap.at(b)}); | |
196 | 161 | } | ||
197 | } | |||
198 | } | |||
199 | ||||
200 | 92 | return res; | ||
201 | 46 | } | ||
202 | ||||
203 | 1 | std::map<Qubit, Bit> Circuit::qubit_to_bit_map() const { | ||
204 | 1 | std::map<Qubit, Bit> res; | ||
205 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1/2✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
|
1 | for (auto [it, end] = boundary.get<TagType>().equal_range(UnitType::Qubit); |
206 |
4/6✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 1 times.
|
5 | it != end; it++) { | |
207 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | Vertex q_out = it->out_; | |
208 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
4 | Vertex last_gate = source(get_nth_in_edge(q_out, 0)); | |
209 |
3/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
|
2/2✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 1 times.
|
4 | if (get_OpType_from_Vertex(last_gate) == OpType::Measure) { |
210 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
3 | Vertex possible_c_out = target(get_nth_out_edge(last_gate, 1)); | |
211 |
3/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 1 times.
|
3 | if (get_OpType_from_Vertex(possible_c_out) == OpType::ClOutput) { |
212 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | Bit b(get_id_from_out(possible_c_out)); | |
213 |
3/6✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
|
2 | res.insert({Qubit(it->id_), b}); | |
214 | 2 | } | ||
215 | } | |||
216 | } | |||
217 | ||||
218 | 1 | return res; | ||
219 | } | |||
220 | ||||
221 | 415 | bool Circuit::contains_unit(const UnitID &id) const { | ||
222 |
2/4✓ Branch 4 taken 415 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 415 times.
✗ Branch 8 not taken.
|
415 | return boundary.get<TagID>().find(id) != boundary.get<TagID>().end(); | |
223 | } | |||
224 | ||||
225 | 430689 | Vertex Circuit::get_in(const UnitID &id) const { | ||
226 |
1/2✓ Branch 2 taken 430689 times.
✗ Branch 3 not taken.
|
430689 | boundary_t::iterator found = boundary.get<TagID>().find(id); | |
227 |
3/4✓ Branch 3 taken 430689 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 430685 times.
|
2/2✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 430685 times.
|
430689 | if (found == boundary.get<TagID>().end()) |
228 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | throw CircuitInvalidity( | |
229 |
2/4✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
8 | "Circuit does not contain unit with id: " + id.repr()); | |
230 |
1/2✓ Branch 1 taken 430685 times.
✗ Branch 2 not taken.
|
430685 | return found->in_; | |
231 | } | |||
232 | ||||
233 | 1087706 | Vertex Circuit::get_out(const UnitID &id) const { | ||
234 |
1/2✓ Branch 2 taken 1087706 times.
✗ Branch 3 not taken.
|
1087706 | boundary_t::iterator found = boundary.get<TagID>().find(id); | |
235 |
2/4✓ Branch 3 taken 1087706 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1087706 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1087706 times.
|
1087706 | if (found == boundary.get<TagID>().end()) |
236 | ✗ | throw CircuitInvalidity( | ||
237 | ✗ | "Circuit does not contain unit with id: " + id.repr()); | ||
238 |
1/2✓ Branch 1 taken 1087706 times.
✗ Branch 2 not taken.
|
1087706 | return found->out_; | |
239 | } | |||
240 | ||||
241 | 20285 | UnitID Circuit::get_id_from_in(const Vertex &in) const { | ||
242 | boundary_t::index<TagIn>::type::iterator found = | |||
243 |
1/2✓ Branch 2 taken 20285 times.
✗ Branch 3 not taken.
|
20285 | boundary.get<TagIn>().find(in); | |
244 |
2/4✓ Branch 3 taken 20285 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 20285 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 20285 times.
|
20285 | if (found == boundary.get<TagIn>().end()) |
245 | ✗ | throw CircuitInvalidity("Input not found in Circuit"); | ||
246 |
1/2✓ Branch 1 taken 20285 times.
✗ Branch 2 not taken.
|
40570 | return found->id_; | |
247 | } | |||
248 | ||||
249 | 20561 | UnitID Circuit::get_id_from_out(const Vertex &out) const { | ||
250 | boundary_t::index<TagOut>::type::iterator found = | |||
251 |
1/2✓ Branch 2 taken 20561 times.
✗ Branch 3 not taken.
|
20561 | boundary.get<TagOut>().find(out); | |
252 |
2/4✓ Branch 3 taken 20561 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 20561 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 20561 times.
|
20561 | if (found == boundary.get<TagOut>().end()) |
253 | ✗ | throw CircuitInvalidity("Output not found in Circuit"); | ||
254 |
1/2✓ Branch 1 taken 20561 times.
✗ Branch 2 not taken.
|
41122 | return found->id_; | |
255 | } | |||
256 | ||||
257 | 1118132 | opt_reg_info_t Circuit::get_reg_info(std::string reg_name) const { | ||
258 | boundary_t::index<TagReg>::type::iterator found = | |||
259 |
1/2✓ Branch 2 taken 1118132 times.
✗ Branch 3 not taken.
|
1118132 | boundary.get<TagReg>().find(reg_name); | |
260 |
3/4✓ Branch 3 taken 1118132 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 665088 times.
✓ Branch 6 taken 453044 times.
|
2/2✓ Decision 'true' taken 665088 times.
✓ Decision 'false' taken 453044 times.
|
1118132 | if (found == boundary.get<TagReg>().end()) |
261 | 665088 | return std::nullopt; | ||
262 | else | |||
263 |
2/4✓ Branch 1 taken 453044 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 453044 times.
✗ Branch 5 not taken.
|
453044 | return found->reg_info(); | |
264 | } | |||
265 | ||||
266 | ✗ | register_t Circuit::get_reg(std::string reg_name) const { | ||
267 | ✗ | register_t reg; | ||
268 |
0/1? Decision couldn't be analyzed.
|
✗ | for (auto [it, end] = boundary.get<TagReg>().equal_range(reg_name); it != end; | |
269 | ✗ | it++) { | ||
270 |
0/2✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
|
✗ | if (it->id_.reg_dim() != 1) | |
271 | ✗ | throw CircuitInvalidity("Cannot linearise register " + reg_name); | ||
272 | ✗ | reg.insert({it->id_.index()[0], it->id_}); | ||
273 | } | |||
274 | ✗ | return reg; | ||
275 | } | |||
276 | ||||
277 | // returns the total number of vertices in dag | |||
278 | // just a wrapper for a boost method. | |||
279 | // makes no assumptions about graph structure. | |||
280 | 39127 | unsigned Circuit::n_vertices() const { return boost::num_vertices(this->dag); } | ||
281 | ||||
282 | 283962 | unsigned Circuit::n_qubits() const { | ||
283 |
1/2✓ Branch 2 taken 283962 times.
✗ Branch 3 not taken.
|
283962 | return boundary.get<TagType>().count(UnitType::Qubit); | |
284 | } | |||
285 | ||||
286 | 223633 | unsigned Circuit::n_bits() const { | ||
287 |
1/2✓ Branch 2 taken 223633 times.
✗ Branch 3 not taken.
|
223633 | return boundary.get<TagType>().count(UnitType::Bit); | |
288 | } | |||
289 | ||||
290 | 38788 | unsigned Circuit::n_units() const { return boundary.size(); } | ||
291 | ||||
292 | 38781 | unsigned Circuit::n_gates() const { return n_vertices() - 2 * n_units(); } | ||
293 | ||||
294 | 86070 | bool Circuit::is_created(const Qubit &id) const { | ||
295 |
1/2✓ Branch 2 taken 86070 times.
✗ Branch 3 not taken.
|
86070 | return get_OpType_from_Vertex(get_in(id)) == OpType::Create; | |
296 | } | |||
297 | ||||
298 | 86063 | bool Circuit::is_discarded(const Qubit &id) const { | ||
299 |
1/2✓ Branch 2 taken 86063 times.
✗ Branch 3 not taken.
|
86063 | return get_OpType_from_Vertex(get_out(id)) == OpType::Discard; | |
300 | } | |||
301 | ||||
302 | // given a vertex, returns a set of all its successor vertices | |||
303 | // this set can be empty, and no warnings are given if it is | |||
304 | // there are no checks to ensure the vertex exists in the graph | |||
305 | 136774 | VertexVec Circuit::get_successors(const Vertex &vert) const { | ||
306 |
1/2✓ Branch 1 taken 136774 times.
✗ Branch 2 not taken.
|
136774 | EdgeVec outs = get_all_out_edges(vert); | |
307 | 136774 | VertexVec children; | ||
308 | 136774 | std::unordered_set<Vertex> lookup; | ||
309 |
2/2✓ Branch 5 taken 163749 times.
✓ Branch 6 taken 136774 times.
|
2/2✓ Decision 'true' taken 163749 times.
✓ Decision 'false' taken 136774 times.
|
300523 | for (const Edge &e : outs) { |
310 |
1/2✓ Branch 1 taken 163749 times.
✗ Branch 2 not taken.
|
163749 | Vertex succ = target(e); | |
311 |
3/4✓ Branch 2 taken 163749 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 162427 times.
✓ Branch 6 taken 1322 times.
|
2/2✓ Decision 'true' taken 162427 times.
✓ Decision 'false' taken 1322 times.
|
163749 | if (lookup.find(succ) == lookup.end()) { |
312 |
1/2✓ Branch 1 taken 162427 times.
✗ Branch 2 not taken.
|
162427 | children.push_back(succ); | |
313 |
1/2✓ Branch 1 taken 162427 times.
✗ Branch 2 not taken.
|
162427 | lookup.insert(succ); | |
314 | } | |||
315 | } | |||
316 | 273548 | return children; | ||
317 | 136774 | } | ||
318 | ||||
319 | 18 | VertexVec Circuit::get_successors_of_type( | ||
320 | const Vertex &vert, EdgeType type) const { | |||
321 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | EdgeVec outs = get_out_edges_of_type(vert, type); | |
322 | 18 | VertexVec children; | ||
323 | 18 | std::unordered_set<Vertex> lookup; | ||
324 |
2/2✓ Branch 5 taken 17 times.
✓ Branch 6 taken 18 times.
|
2/2✓ Decision 'true' taken 17 times.
✓ Decision 'false' taken 18 times.
|
35 | for (const Edge &e : outs) { |
325 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
17 | Vertex succ = target(e); | |
326 |
2/4✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 17 times.
✗ Branch 6 not taken.
|
1/2✓ Decision 'true' taken 17 times.
✗ Decision 'false' not taken.
|
17 | if (lookup.find(succ) == lookup.end()) { |
327 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
17 | children.push_back(succ); | |
328 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
17 | lookup.insert(succ); | |
329 | } | |||
330 | } | |||
331 | 36 | return children; | ||
332 | 18 | } | ||
333 | ||||
334 | // given a vertex, returns a set of all its predecessor vertices | |||
335 | // this set can be empty, and no warnings are given if it is | |||
336 | // there are no checks to ensure the vertex exists in the graph | |||
337 | 115639 | VertexVec Circuit::get_predecessors(const Vertex &vert) const { | ||
338 |
1/2✓ Branch 1 taken 115639 times.
✗ Branch 2 not taken.
|
115639 | EdgeVec ins = get_in_edges(vert); | |
339 | 115639 | VertexVec parents; | ||
340 | 115639 | std::unordered_set<Vertex> lookup; | ||
341 |
2/2✓ Branch 5 taken 144799 times.
✓ Branch 6 taken 115639 times.
|
2/2✓ Decision 'true' taken 144799 times.
✓ Decision 'false' taken 115639 times.
|
260438 | for (const Edge &e : ins) { |
342 |
1/2✓ Branch 1 taken 144799 times.
✗ Branch 2 not taken.
|
144799 | Vertex pred = source(e); | |
343 |
3/4✓ Branch 2 taken 144799 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 143480 times.
✓ Branch 6 taken 1319 times.
|
2/2✓ Decision 'true' taken 143480 times.
✓ Decision 'false' taken 1319 times.
|
144799 | if (lookup.find(pred) == lookup.end()) { |
344 |
1/2✓ Branch 1 taken 143480 times.
✗ Branch 2 not taken.
|
143480 | parents.push_back(pred); | |
345 |
1/2✓ Branch 1 taken 143480 times.
✗ Branch 2 not taken.
|
143480 | lookup.insert(pred); | |
346 | } | |||
347 | } | |||
348 | 231278 | return parents; | ||
349 | 115639 | } | ||
350 | ||||
351 | 14 | VertexVec Circuit::get_predecessors_of_type( | ||
352 | const Vertex &vert, EdgeType type) const { | |||
353 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | EdgeVec ins = get_in_edges_of_type(vert, type); | |
354 | 14 | VertexVec parents; | ||
355 | 14 | std::unordered_set<Vertex> lookup; | ||
356 |
2/2✓ Branch 5 taken 14 times.
✓ Branch 6 taken 14 times.
|
2/2✓ Decision 'true' taken 14 times.
✓ Decision 'false' taken 14 times.
|
28 | for (const Edge &e : ins) { |
357 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | Vertex pred = source(e); | |
358 |
2/4✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
|
1/2✓ Decision 'true' taken 14 times.
✗ Decision 'false' not taken.
|
14 | if (lookup.find(pred) == lookup.end()) { |
359 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | parents.push_back(pred); | |
360 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | lookup.insert(pred); | |
361 | } | |||
362 | } | |||
363 | 28 | return parents; | ||
364 | 14 | } | ||
365 | ||||
366 | // Just a wrapper for a boost method | |||
367 | 3 | unsigned Circuit::n_edges() const { return boost::num_edges(dag); } | ||
368 | ||||
369 | ✗ | unsigned Circuit::n_edges_of_type(const EdgeType &et) const { | ||
370 | ✗ | unsigned count = 0; | ||
371 | ✗ | BGL_FORALL_EDGES(e, dag, DAG) { | ||
372 |
0/2✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
|
✗ | if (dag[e].type == et) { | |
373 | ✗ | ++count; | ||
374 | } | |||
375 | } | |||
376 | ✗ | return count; | ||
377 | } | |||
378 | ||||
379 | // return the ports corresponding to an edge | |||
380 | 16182 | std::pair<port_t, port_t> Circuit::get_ports(const Edge &edge) const { | ||
381 | 16182 | return dag[edge].ports; | ||
382 | } | |||
383 | ||||
384 | 20561260 | port_t Circuit::get_source_port(const Edge &edge) const { | ||
385 | 20561260 | return dag[edge].ports.first; | ||
386 | } | |||
387 | ||||
388 | 21096799 | port_t Circuit::get_target_port(const Edge &edge) const { | ||
389 | 21096799 | return dag[edge].ports.second; | ||
390 | } | |||
391 | ||||
392 | 29741843 | EdgeType Circuit::get_edgetype(const Edge &edge) const { | ||
393 | 29741843 | return dag[edge].type; | ||
394 | } | |||
395 | ||||
396 | 7487376 | EdgeVec Circuit::get_in_edges(const Vertex &vert) const { | ||
397 |
1/2✓ Branch 1 taken 7487376 times.
✗ Branch 2 not taken.
|
7487376 | unsigned n = n_in_edges(vert); | |
398 |
1/2✓ Branch 2 taken 7487376 times.
✗ Branch 3 not taken.
|
7487376 | EdgeVec inedges(n); | |
399 |
1/2✓ Branch 2 taken 7487376 times.
✗ Branch 3 not taken.
|
7487376 | std::vector<bool> port_found(n, false); | |
400 |
11/16✓ Branch 1 taken 7487376 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6785986 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20977722 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 14191738 times.
✓ Branch 10 taken 6785984 times.
✓ Branch 12 taken 14191738 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 14191738 times.
✓ Branch 15 taken 6785984 times.
✓ Branch 17 taken 14273360 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 6785986 times.
✓ Branch 20 taken 7487374 times.
|
28465096 | BGL_FORALL_INEDGES(vert, e, dag, DAG) { | |
401 |
1/2✓ Branch 1 taken 14191738 times.
✗ Branch 2 not taken.
|
14191738 | port_t port = get_target_port(e); | |
402 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 14191736 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 14191736 times.
|
14191738 | if (port >= n) { |
403 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | inedges.resize(port + 1); | |
404 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | port_found.resize(port + 1, false); | |
405 |
3/4✓ Branch 1 taken 14191736 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 14191734 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 14191734 times.
|
14191736 | } else if (port_found[port]) { |
406 |
2/4✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
2 | throw CircuitInvalidity("Vertex has multiple inputs on the same port"); | |
407 | } | |||
408 |
1/2✓ Branch 1 taken 14191736 times.
✗ Branch 2 not taken.
|
14191736 | port_found[port] = true; | |
409 |
1/2✓ Branch 2 taken 14191736 times.
✗ Branch 3 not taken.
|
14191736 | inedges[port] = e; | |
410 | } | |||
411 |
2/2✓ Branch 0 taken 14191734 times.
✓ Branch 1 taken 7487372 times.
|
2/2✓ Decision 'true' taken 14191734 times.
✓ Decision 'false' taken 7487372 times.
|
21679106 | for (unsigned i = 0; i < n; i++) |
412 |
3/4✓ Branch 1 taken 14191734 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 14191732 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 14191732 times.
|
14191734 | if (!port_found[i]) { |
413 |
2/4✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
2 | throw CircuitInvalidity("Input ports on Vertex are non-contiguous"); | |
414 | } | |||
415 | 14974744 | return inedges; | ||
416 | 7487380 | } | ||
417 | ||||
418 | 1305722 | EdgeVec Circuit::get_in_edges_of_type(const Vertex &vert, EdgeType type) const { | ||
419 |
2/2✓ Branch 1 taken 1305720 times.
✓ Branch 2 taken 2 times.
|
1305722 | EdgeVec ins = get_in_edges(vert); | |
420 | 1305720 | EdgeVec matching; | ||
421 |
2/2✓ Branch 5 taken 3178160 times.
✓ Branch 6 taken 1305720 times.
|
2/2✓ Decision 'true' taken 3178160 times.
✓ Decision 'false' taken 1305720 times.
|
4483880 | for (const Edge &e : ins) { |
422 |
3/4✓ Branch 1 taken 3178160 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1677808 times.
✓ Branch 4 taken 1500352 times.
|
2/2✓ Decision 'true' taken 1677808 times.
✓ Decision 'false' taken 1500352 times.
|
3178160 | if (get_edgetype(e) == type) { |
423 |
1/2✓ Branch 1 taken 1677808 times.
✗ Branch 2 not taken.
|
1677808 | matching.push_back(e); | |
424 | } | |||
425 | } | |||
426 | 2611440 | return matching; | ||
427 | 1305720 | } | ||
428 | ||||
429 | 512458 | std::vector<std::optional<Edge>> Circuit::get_linear_out_edges( | ||
430 | const Vertex &vert) const { | |||
431 | 512458 | unsigned n = n_ports(vert); | ||
432 |
1/2✓ Branch 2 taken 512458 times.
✗ Branch 3 not taken.
|
512458 | std::vector<std::optional<Edge>> outedges(n); | |
433 |
12/18✓ Branch 1 taken 512458 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 512273 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 625688 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1137961 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 625690 times.
✓ Branch 13 taken 512271 times.
✓ Branch 15 taken 625690 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 625690 times.
✓ Branch 18 taken 512271 times.
✓ Branch 20 taken 1024729 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 512273 times.
✓ Branch 23 taken 512456 times.
|
1650417 | BGL_FORALL_OUTEDGES(vert, e, dag, DAG) { | |
434 |
3/4✓ Branch 1 taken 625690 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 612 times.
✓ Branch 4 taken 625078 times.
|
2/2✓ Decision 'true' taken 625078 times.
✓ Decision 'false' taken 612 times.
|
625690 | if (get_edgetype(e) == EdgeType::Boolean) continue; |
435 |
1/2✓ Branch 1 taken 625078 times.
✗ Branch 2 not taken.
|
625078 | port_t port = get_source_port(e); | |
436 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 625078 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 625078 times.
|
625078 | if (port >= n) { |
437 | ✗ | throw CircuitInvalidity("Vertex has an output on an unexpected port"); | ||
438 | } | |||
439 |
2/2✓ Branch 2 taken 2 times.
✓ Branch 3 taken 625076 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 625076 times.
|
625078 | if (outedges[port]) { |
440 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
2 | throw CircuitInvalidity( | |
441 | 4 | "Vertex has multiple linear outputs on the same port"); | ||
442 | } | |||
443 | 625076 | outedges[port] = e; | ||
444 | } | |||
445 | 512456 | return outedges; | ||
446 | 2 | } | ||
447 | ||||
448 | 3214 | Edge Circuit::get_linear_edge(const Edge &e) const { | ||
449 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3212 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 3212 times.
|
3214 | if (get_edgetype(e) == EdgeType::Boolean) { |
450 |
3/6✓ 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.
|
2 | Edge linear_edge = get_nth_out_edge(source(e), get_source_port(e)); | |
451 | 2 | return linear_edge; | ||
452 | } else { | |||
453 | 3212 | return e; | ||
454 | } | |||
455 | } | |||
456 | ||||
457 | 231084 | EdgeVec Circuit::get_all_out_edges(const Vertex &vert) const { | ||
458 |
2/2✓ Branch 1 taken 231083 times.
✓ Branch 2 taken 1 times.
|
231084 | std::vector<std::optional<Edge>> lin_outs = get_linear_out_edges(vert); | |
459 |
1/2✓ Branch 1 taken 231083 times.
✗ Branch 2 not taken.
|
231083 | std::vector<EdgeVec> b_bundles = get_b_out_bundles(vert); | |
460 | 231083 | EdgeVec outs; | ||
461 |
2/2✓ Branch 1 taken 267399 times.
✓ Branch 2 taken 231083 times.
|
2/2✓ Decision 'true' taken 267399 times.
✓ Decision 'false' taken 231083 times.
|
498482 | for (unsigned i = 0; i < lin_outs.size(); ++i) { |
462 | 267399 | std::optional<Edge> &l_out = lin_outs[i]; | ||
463 |
2/2✓ Branch 1 taken 267321 times.
✓ Branch 2 taken 78 times.
|
2/2✓ Decision 'true' taken 267321 times.
✓ Decision 'false' taken 78 times.
|
267399 | if (l_out) { |
464 |
1/2✓ Branch 2 taken 267321 times.
✗ Branch 3 not taken.
|
267321 | outs.push_back(*l_out); | |
465 |
1/2✓ Branch 7 taken 267321 times.
✗ Branch 8 not taken.
|
267321 | outs.insert(outs.end(), b_bundles[i].begin(), b_bundles[i].end()); | |
466 | } | |||
467 | } | |||
468 | 462166 | return outs; | ||
469 | 231083 | } | ||
470 | ||||
471 | 382947 | EdgeVec Circuit::get_out_edges_of_type( | ||
472 | const Vertex &vert, EdgeType type) const { | |||
473 |
2/2✓ Branch 0 taken 115378 times.
✓ Branch 1 taken 267569 times.
|
2/2✓ Decision 'true' taken 115378 times.
✓ Decision 'false' taken 267569 times.
|
382947 | if (type == EdgeType::Boolean) { |
474 |
1/2✓ Branch 1 taken 115378 times.
✗ Branch 2 not taken.
|
115378 | std::vector<EdgeVec> bundles = get_b_out_bundles(vert); | |
475 | 115378 | EdgeVec outs; | ||
476 |
2/2✓ Branch 4 taken 139913 times.
✓ Branch 5 taken 115378 times.
|
2/2✓ Decision 'true' taken 139913 times.
✓ Decision 'false' taken 115378 times.
|
255291 | for (const EdgeVec &b : bundles) { |
477 |
1/2✓ Branch 5 taken 139913 times.
✗ Branch 6 not taken.
|
139913 | outs.insert(outs.end(), b.begin(), b.end()); | |
478 | } | |||
479 | 115378 | return outs; | ||
480 | 115378 | } else { | ||
481 |
2/2✓ Branch 1 taken 267568 times.
✓ Branch 2 taken 1 times.
|
267569 | std::vector<std::optional<Edge>> outs = get_linear_out_edges(vert); | |
482 | 267568 | EdgeVec matching; | ||
483 |
2/2✓ Branch 5 taken 341124 times.
✓ Branch 6 taken 267568 times.
|
2/2✓ Decision 'true' taken 341124 times.
✓ Decision 'false' taken 267568 times.
|
608692 | for (const std::optional<Edge> &e : outs) { |
484 |
7/8✓ Branch 1 taken 340114 times.
✓ Branch 2 taken 1010 times.
✓ Branch 5 taken 340114 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 200570 times.
✓ Branch 8 taken 139544 times.
✓ Branch 9 taken 200570 times.
✓ Branch 10 taken 140554 times.
|
2/2✓ Decision 'true' taken 200570 times.
✓ Decision 'false' taken 140554 times.
|
341124 | if (e && get_edgetype(*e) == type) { |
485 |
1/2✓ Branch 2 taken 200570 times.
✗ Branch 3 not taken.
|
200570 | matching.push_back(*e); | |
486 | } | |||
487 | } | |||
488 | 267568 | return matching; | ||
489 | 267568 | } | ||
490 | } | |||
491 | ||||
492 | 1286618 | std::vector<EdgeVec> Circuit::get_b_out_bundles(const Vertex &vert) const { | ||
493 | 1286618 | unsigned n = n_ports(vert); | ||
494 |
1/2✓ Branch 2 taken 1286618 times.
✗ Branch 3 not taken.
|
1286618 | std::vector<EdgeVec> bundles(n); | |
495 |
12/18✓ Branch 1 taken 1286618 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1196003 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1262732 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2458735 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1262732 times.
✓ Branch 13 taken 1196003 times.
✓ Branch 15 taken 1262732 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 1262732 times.
✓ Branch 18 taken 1196003 times.
✓ Branch 20 taken 2482621 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 1196003 times.
✓ Branch 23 taken 1286618 times.
|
3745353 | BGL_FORALL_OUTEDGES(vert, e, dag, DAG) { | |
496 |
3/4✓ Branch 1 taken 1262732 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1583 times.
✓ Branch 4 taken 1261149 times.
|
2/2✓ Decision 'true' taken 1583 times.
✓ Decision 'false' taken 1261149 times.
|
1262732 | if (get_edgetype(e) == EdgeType::Boolean) { |
497 |
1/2✓ Branch 1 taken 1583 times.
✗ Branch 2 not taken.
|
1583 | port_t port = get_source_port(e); | |
498 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1583 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1583 times.
|
1583 | if (port > n) { |
499 | ✗ | throw CircuitInvalidity("Vertex has an output on an unexpected port"); | ||
500 | } | |||
501 |
2/4✓ Branch 1 taken 1583 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1583 times.
✗ Branch 5 not taken.
|
1583 | bundles.at(port).push_back(e); | |
502 | } | |||
503 | } | |||
504 | 1286618 | return bundles; | ||
505 | } | |||
506 | ||||
507 | 13545 | std::vector<EdgeVec> Circuit::get_b_in_bundles(const Vertex &vert) const { | ||
508 | 13545 | unsigned n = n_ports(vert); | ||
509 |
1/2✓ Branch 2 taken 13545 times.
✗ Branch 3 not taken.
|
13545 | std::vector<EdgeVec> bundles(n); | |
510 |
12/18✓ Branch 1 taken 13545 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13545 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 31942 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 45487 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 31942 times.
✓ Branch 13 taken 13545 times.
✓ Branch 15 taken 31942 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 31942 times.
✓ Branch 18 taken 13545 times.
✓ Branch 20 taken 27090 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 13545 times.
✓ Branch 23 taken 13545 times.
|
59032 | BGL_FORALL_INEDGES(vert, e, dag, DAG) { | |
511 |
3/4✓ Branch 1 taken 31942 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5953 times.
✓ Branch 4 taken 25989 times.
|
2/2✓ Decision 'true' taken 5953 times.
✓ Decision 'false' taken 25989 times.
|
31942 | if (get_edgetype(e) == EdgeType::Boolean) { |
512 |
1/2✓ Branch 1 taken 5953 times.
✗ Branch 2 not taken.
|
5953 | port_t port = get_target_port(e); | |
513 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 5953 times.
|
5953 | if (port > n) { |
514 | ✗ | throw CircuitInvalidity("Vertex has an output on an unexpected port"); | ||
515 | } | |||
516 |
2/4✓ Branch 1 taken 5953 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5953 times.
✗ Branch 5 not taken.
|
5953 | bundles.at(port).push_back(e); | |
517 | } | |||
518 | } | |||
519 | 13545 | return bundles; | ||
520 | } | |||
521 | ||||
522 | // n represents the port of the edge at vert_from | |||
523 | // there are no checks to ensure the vertex exists in the graph | |||
524 | // will only return Quantum or Classical edges | |||
525 | 12656281 | Edge Circuit::get_nth_out_edge(const Vertex &vert_from, const port_t &n) const { | ||
526 |
9/18✓ Branch 1 taken 12656281 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12656281 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2575996 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 15232277 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 15232277 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 15232277 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 15232277 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 12656281 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 12656281 times.
✗ Branch 23 not taken.
|
15232277 | BGL_FORALL_OUTEDGES(vert_from, e, dag, DAG) { | |
527 |
8/10✓ Branch 1 taken 15232277 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15213754 times.
✓ Branch 4 taken 18523 times.
✓ Branch 6 taken 15213754 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 12656281 times.
✓ Branch 9 taken 2557473 times.
✓ Branch 10 taken 12656281 times.
✓ Branch 11 taken 2575996 times.
|
2/2✓ Decision 'true' taken 12656281 times.
✓ Decision 'false' taken 2575996 times.
|
15232277 | if (get_edgetype(e) != EdgeType::Boolean && get_source_port(e) == n) { |
528 | 12656281 | return e; | ||
529 | } | |||
530 | } | |||
531 | ✗ | throw MissingEdge(); | ||
532 | } | |||
533 | ||||
534 | 978 | EdgeVec Circuit::get_nth_b_out_bundle( | ||
535 | const Vertex &vert_from, const port_t &n) const { | |||
536 | 978 | EdgeVec bundle; | ||
537 |
12/18✓ Branch 1 taken 978 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 978 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5730 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6708 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5730 times.
✓ Branch 13 taken 978 times.
✓ Branch 15 taken 5730 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 5730 times.
✓ Branch 18 taken 978 times.
✓ Branch 20 taken 1956 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 978 times.
✓ Branch 23 taken 978 times.
|
7686 | BGL_FORALL_OUTEDGES(vert_from, e, dag, DAG) { | |
538 |
8/10✓ Branch 1 taken 5730 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4504 times.
✓ Branch 4 taken 1226 times.
✓ Branch 6 taken 4504 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4489 times.
✓ Branch 9 taken 15 times.
✓ Branch 10 taken 4489 times.
✓ Branch 11 taken 1241 times.
|
2/2✓ Decision 'true' taken 4489 times.
✓ Decision 'false' taken 1241 times.
|
5730 | if (get_edgetype(e) == EdgeType::Boolean && get_source_port(e) == n) { |
539 |
1/2✓ Branch 1 taken 4489 times.
✗ Branch 2 not taken.
|
4489 | bundle.push_back(e); | |
540 | } | |||
541 | } | |||
542 | 978 | return bundle; | ||
543 | } | |||
544 | ||||
545 | // n represents the port of the edge at vert_to | |||
546 | // there are no checks to ensure the vertex exists in the graph | |||
547 | 1112617 | Edge Circuit::get_nth_in_edge(const Vertex &vert_to, const port_t &n) const { | ||
548 |
9/18✓ Branch 1 taken 1112617 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1112617 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 52623 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1165240 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1165240 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1165240 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 1165240 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1112617 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 1112617 times.
✗ Branch 23 not taken.
|
1165240 | BGL_FORALL_INEDGES(vert_to, e, dag, DAG) { | |
549 |
3/4✓ Branch 1 taken 1165240 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1112617 times.
✓ Branch 4 taken 52623 times.
|
2/2✓ Decision 'true' taken 1112617 times.
✓ Decision 'false' taken 52623 times.
|
1165240 | if (get_target_port(e) == n) { |
550 | 1112617 | return e; | ||
551 | } | |||
552 | } | |||
553 | ✗ | throw MissingEdge(); | ||
554 | } | |||
555 | ||||
556 | // there are no checks to ensure the vertex exists in the graph | |||
557 | 8207826 | unsigned Circuit::n_in_edges(const Vertex &vert) const { | ||
558 | 8207826 | return boost::in_degree(vert, dag); | ||
559 | } | |||
560 | ||||
561 | 1529114 | unsigned Circuit::n_in_edges_of_type(const Vertex &vert, EdgeType et) const { | ||
562 | 1529114 | unsigned count = 0; | ||
563 |
12/18✓ Branch 1 taken 1529114 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1516011 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3506119 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 5022130 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3506119 times.
✓ Branch 13 taken 1516011 times.
✓ Branch 15 taken 3506119 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 3506119 times.
✓ Branch 18 taken 1516011 times.
✓ Branch 20 taken 3045125 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 1516011 times.
✓ Branch 23 taken 1529114 times.
|
6551244 | BGL_FORALL_INEDGES(vert, e, dag, DAG) { | |
564 |
3/4✓ Branch 1 taken 3506119 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2050380 times.
✓ Branch 4 taken 1455739 times.
|
2/2✓ Decision 'true' taken 1529114 times.
✓ Decision 'false' taken 1977005 times.
|
3506119 | if (get_edgetype(e) == et) ++count; |
565 | } | |||
566 | 1529114 | return count; | ||
567 | } | |||
568 | ||||
569 | // there are no checks to ensure the vertex exists in the graph | |||
570 | 503931 | unsigned Circuit::n_out_edges(const Vertex &vert) const { | ||
571 | 503931 | return boost::out_degree(vert, dag); | ||
572 | } | |||
573 | ||||
574 | 198262 | unsigned Circuit::n_out_edges_of_type(const Vertex &vert, EdgeType et) const { | ||
575 | 198262 | unsigned count = 0; | ||
576 |
12/18✓ Branch 1 taken 198262 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 197905 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 245349 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 443254 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 245349 times.
✓ Branch 13 taken 197905 times.
✓ Branch 15 taken 245349 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 245349 times.
✓ Branch 18 taken 197905 times.
✓ Branch 20 taken 396167 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 197905 times.
✓ Branch 23 taken 198262 times.
|
641516 | BGL_FORALL_OUTEDGES(vert, e, dag, DAG) { | |
577 |
3/4✓ Branch 1 taken 245349 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 75438 times.
✓ Branch 4 taken 169911 times.
|
2/2✓ Decision 'true' taken 198262 times.
✓ Decision 'false' taken 47087 times.
|
245349 | if (get_edgetype(e) == et) ++count; |
578 | } | |||
579 | 198262 | return count; | ||
580 | } | |||
581 | ||||
582 | 22 | bool Circuit::is_quantum_node(const Vertex &vert) const { | ||
583 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
44 | return n_in_edges_of_type(vert, EdgeType::Classical) == 0 && | |
584 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
44 | n_out_edges_of_type(vert, EdgeType::Classical) == 0; | |
585 | } | |||
586 | ||||
587 | ✗ | bool Circuit::is_classical_node(const Vertex &vert) const { | ||
588 | ✗ | return n_in_edges_of_type(vert, EdgeType::Quantum) == 0 && | ||
589 | ✗ | n_out_edges_of_type(vert, EdgeType::Quantum) == 0; | ||
590 | } | |||
591 | ||||
592 | 1812745 | unsigned Circuit::n_ports(const Vertex &vert) const { | ||
593 | 1812745 | return get_Op_signature_from_Vertex(vert).size(); | ||
594 | } | |||
595 | ||||
596 | // there are no checks to ensure the vertex exists in the graph | |||
597 | // returns a pointer to the op, try not to dereference and do anything with the | |||
598 | // op | |||
599 | 16340700 | const Op_ptr Circuit::get_Op_ptr_from_Vertex(const Vertex &vert) const { | ||
600 | 16340700 | return this->dag[vert].op; | ||
601 | } | |||
602 | ||||
603 | 1687012 | const std::optional<std::string> &Circuit::get_opgroup_from_Vertex( | ||
604 | const Vertex &vert) const { | |||
605 | 1687012 | return this->dag[vert].opgroup; | ||
606 | } | |||
607 | ||||
608 | 4 | const std::unordered_set<std::string> Circuit::get_opgroups() const { | ||
609 | 4 | std::unordered_set<std::string> opgroups; | ||
610 |
7/8✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 65 times.
✓ Branch 6 taken 4 times.
✓ Branch 8 taken 65 times.
✓ Branch 9 taken 4 times.
✓ Branch 11 taken 4 times.
✓ Branch 12 taken 4 times.
|
73 | BGL_FORALL_VERTICES(v, dag, DAG) { | |
611 |
2/4✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 65 times.
✗ Branch 5 not taken.
|
65 | std::optional<std::string> v_opgroup = get_opgroup_from_Vertex(v); | |
612 |
2/2✓ Branch 1 taken 24 times.
✓ Branch 2 taken 41 times.
|
2/2✓ Decision 'true' taken 24 times.
✓ Decision 'false' taken 41 times.
|
65 | if (v_opgroup) { |
613 |
2/4✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
|
24 | opgroups.insert(v_opgroup.value()); | |
614 | } | |||
615 | 65 | } | ||
616 | 4 | return opgroups; | ||
617 | } | |||
618 | ||||
619 | 3216 | void Circuit::set_vertex_Op_ptr(const Vertex &vert, const Op_ptr &op) { | ||
620 | 3216 | this->dag[vert].op = op; | ||
621 | 3216 | } | ||
622 | ||||
623 | 19335 | OpDesc Circuit::get_OpDesc_from_Vertex(const Vertex &vert) const { | ||
624 |
1/2✓ Branch 3 taken 19335 times.
✗ Branch 4 not taken.
|
38670 | return get_Op_ptr_from_Vertex(vert)->get_desc(); | |
625 | } | |||
626 | ||||
627 | // there are no checks to ensure the vertex exists in the graph | |||
628 | 8881577 | OpType Circuit::get_OpType_from_Vertex(const Vertex &vert) const { | ||
629 | 8881577 | return get_Op_ptr_from_Vertex(vert)->get_type(); | ||
630 | } | |||
631 | ||||
632 | 1812745 | op_signature_t Circuit::get_Op_signature_from_Vertex(const Vertex &vert) const { | ||
633 |
1/2✓ Branch 3 taken 1812745 times.
✗ Branch 4 not taken.
|
3625490 | return get_Op_ptr_from_Vertex(vert)->get_signature(); | |
634 | } | |||
635 | ||||
636 | // there are no checks to ensure the vertex exists in the graph | |||
637 | // checks that the edge belongs to the vertex | |||
638 | 1016463 | Edge Circuit::get_next_edge(const Vertex &vert, const Edge &in_edge) const { | ||
639 |
3/4✓ Branch 1 taken 1016463 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1016462 times.
|
2/2✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 1016462 times.
|
1016463 | if (target(in_edge) != vert) |
640 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | throw CircuitInvalidity( | |
641 | 2 | "Cannot get next edge: Edge is not an in edge to Vertex"); | ||
642 |
1/2✓ Branch 1 taken 1016462 times.
✗ Branch 2 not taken.
|
1016462 | port_t order = get_target_port(in_edge); | |
643 |
1/2✓ Branch 1 taken 1016462 times.
✗ Branch 2 not taken.
|
2032924 | return get_nth_out_edge(vert, order); | |
644 | } | |||
645 | ||||
646 | // there are no checks to ensure the vertex exists in the graph | |||
647 | // checks that the edge belongs to the vertex | |||
648 | 294785 | Edge Circuit::get_last_edge(const Vertex &vert, const Edge &out_edge) const { | ||
649 |
3/4✓ Branch 1 taken 294785 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 294784 times.
|
2/2✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 294784 times.
|
294785 | if (source(out_edge) != vert) |
650 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | throw CircuitInvalidity( | |
651 | 2 | "Cannot get last edge: Edge is not an out edge from Vertex"); | ||
652 |
1/2✓ Branch 1 taken 294784 times.
✗ Branch 2 not taken.
|
294784 | port_t order = get_source_port(out_edge); | |
653 |
1/2✓ Branch 1 taken 294784 times.
✗ Branch 2 not taken.
|
589568 | return get_nth_in_edge(vert, order); | |
654 | } | |||
655 | ||||
656 | // // given a vertex and corresponding in edge, returns next vertex | |||
657 | // and edge | |||
658 | // there are no checks to ensure the vertex exists in the graph | |||
659 | 843 | std::pair<Vertex, Edge> Circuit::get_next_pair( | ||
660 | const Vertex ¤t_vertex, const Edge &inedge) const { | |||
661 |
1/2✓ Branch 1 taken 843 times.
✗ Branch 2 not taken.
|
843 | Edge new_edge = get_next_edge(current_vertex, inedge); | |
662 |
1/2✓ Branch 1 taken 843 times.
✗ Branch 2 not taken.
|
843 | Vertex new_vert = target(new_edge); | |
663 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 842 times.
|
2/2✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 842 times.
|
843 | if (new_vert == current_vertex) { |
664 |
2/4✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
1 | throw CircuitInvalidity("A qubit path is looping"); | |
665 | } | |||
666 | 1684 | return {new_vert, new_edge}; | ||
667 | } | |||
668 | ||||
669 | // given a vertex and corresponding out edge, returns previous vertex | |||
670 | // and edge pair | |||
671 | // there are no checks to ensure the vertex exists in the graph | |||
672 | 43576 | std::pair<Vertex, Edge> Circuit::get_prev_pair( | ||
673 | const Vertex ¤t_vertex, const Edge &outedge) const { | |||
674 |
1/2✓ Branch 1 taken 43576 times.
✗ Branch 2 not taken.
|
43576 | Edge last_edge = get_last_edge(current_vertex, outedge); | |
675 |
1/2✓ Branch 1 taken 43576 times.
✗ Branch 2 not taken.
|
43576 | Vertex last_vertex = source(last_edge); | |
676 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 43575 times.
|
2/2✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 43575 times.
|
43576 | if (last_vertex == current_vertex) { |
677 |
2/4✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
1 | throw CircuitInvalidity("A qubit path is looping"); | |
678 | } | |||
679 | ||||
680 | 87150 | return {last_vertex, last_edge}; | ||
681 | } | |||
682 | ||||
683 | ✗ | bool Circuit::detect_initial_Op(const Vertex &vertex) const { | ||
684 | ✗ | OpType type = get_OpType_from_Vertex(vertex); | ||
685 | ✗ | return is_initial_q_type(type) || type == OpType::ClInput; | ||
686 | } | |||
687 | ||||
688 | 5136039 | bool Circuit::detect_final_Op(const Vertex &vertex) const { | ||
689 | 5136039 | OpType type = get_OpType_from_Vertex(vertex); | ||
690 |
4/4✓ Branch 1 taken 4195663 times.
✓ Branch 2 taken 940376 times.
✓ Branch 3 taken 271085 times.
✓ Branch 4 taken 3924578 times.
|
5136039 | return is_final_q_type(type) || type == OpType::ClOutput; | |
691 | } | |||
692 | ||||
693 | 1097625 | bool Circuit::detect_boundary_Op(const Vertex &vertex) const { | ||
694 | 1097625 | OpType type = get_OpType_from_Vertex(vertex); | ||
695 |
4/4✓ Branch 1 taken 1096891 times.
✓ Branch 2 taken 734 times.
✓ Branch 4 taken 44 times.
✓ Branch 5 taken 1096847 times.
|
1097625 | return is_boundary_q_type(type) || is_boundary_c_type(type); | |
696 | } | |||
697 | ||||
698 | 19335 | bool Circuit::detect_singleq_unitary_op(const Vertex &vert) const { | ||
699 |
1/2✓ Branch 1 taken 19335 times.
✗ Branch 2 not taken.
|
19335 | const OpDesc desc = get_OpDesc_from_Vertex(vert); | |
700 |
6/8✓ Branch 1 taken 19335 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18772 times.
✓ Branch 4 taken 563 times.
✓ Branch 6 taken 18772 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15720 times.
✓ Branch 9 taken 3052 times.
|
38670 | return desc.is_gate() && desc.is_singleq_unitary(); | |
701 | 19335 | } | ||
702 | ||||
703 | 72774 | unsigned Circuit::qubit_index( | ||
704 | const Vertex &vert, PortType port_type, port_t port) const { | |||
705 | const EdgeVec edges = (port_type == PortType::Source) | |||
706 | ? get_out_edges_of_type(vert, EdgeType::Quantum) | |||
707 |
4/6✓ Branch 0 taken 21647 times.
✓ Branch 1 taken 51127 times.
✓ Branch 3 taken 21647 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 51127 times.
✗ Branch 7 not taken.
|
72774 | : get_in_edges_of_type(vert, EdgeType::Quantum); | |
708 | 72774 | unsigned n_edges = edges.size(); | ||
709 |
1/2✓ Branch 0 taken 104988 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 104988 times.
✗ Decision 'false' not taken.
|
104988 | for (unsigned i = 0; i < n_edges; i++) { |
710 | 104988 | const Edge &e = edges[i]; | ||
711 |
3/4✓ Branch 0 taken 32980 times.
✓ Branch 1 taken 72008 times.
✓ Branch 3 taken 32980 times.
✗ Branch 4 not taken.
|
104988 | port_t p = (port_type == PortType::Source) ? get_source_port(e) | |
712 |
1/2✓ Branch 1 taken 72008 times.
✗ Branch 2 not taken.
|
72008 | : get_target_port(e); | |
713 |
2/2✓ Branch 0 taken 72774 times.
✓ Branch 1 taken 32214 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 177762 times.
|
177762 | if (p == port) return i; |
714 | } | |||
715 |
0/2✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
|
✗ | throw std::domain_error("Invalid port for vertex"); | |
716 | 72774 | } | ||
717 | ||||
718 | 44695 | std::optional<Pauli> Circuit::commuting_basis( | ||
719 | const Vertex &vert, PortType port_type, port_t port) const { | |||
720 |
1/2✓ Branch 1 taken 44695 times.
✗ Branch 2 not taken.
|
44695 | Op_ptr op = get_Op_ptr_from_Vertex(vert); | |
721 |
2/2✓ Branch 2 taken 4 times.
✓ Branch 3 taken 44691 times.
|
2/2✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 44691 times.
|
44695 | if (op->get_type() == OpType::Conditional) { |
722 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | op = static_cast<const Conditional &>(*op).get_op(); | |
723 | } | |||
724 |
2/4✓ Branch 2 taken 44695 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 44695 times.
✗ Branch 6 not taken.
|
89390 | return op->commuting_basis(qubit_index(vert, port_type, port)); | |
725 | 44695 | } | ||
726 | ||||
727 | 28079 | bool Circuit::commutes_with_basis( | ||
728 | const Vertex &vert, const std::optional<Pauli> &colour, PortType port_type, | |||
729 | port_t port) const { | |||
730 |
1/2✓ Branch 1 taken 28079 times.
✗ Branch 2 not taken.
|
28079 | Op_ptr op = get_Op_ptr_from_Vertex(vert); | |
731 |
2/2✓ Branch 2 taken 33 times.
✓ Branch 3 taken 28046 times.
|
2/2✓ Decision 'true' taken 33 times.
✓ Decision 'false' taken 28046 times.
|
28079 | if (op->get_type() == OpType::Conditional) { |
732 |
1/2✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
|
33 | op = static_cast<const Conditional &>(*op).get_op(); | |
733 | } | |||
734 |
2/4✓ Branch 2 taken 28079 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 28079 times.
✗ Branch 6 not taken.
|
56158 | return op->commutes_with_basis(colour, qubit_index(vert, port_type, port)); | |
735 | 28079 | } | ||
736 | ||||
737 | } // namespace tket | |||
738 |