GCC Code Coverage Report


Directory: ./
File: Predicates/CompilerPass.cpp
Date: 2022-10-15 05:10:18
Warnings: 5 unchecked decisions!
Exec Total Coverage
Lines: 345 397 86.9%
Functions: 23 30 76.7%
Branches: 445 838 53.1%
Decisions: 154 182 84.6%

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 "CompilerPass.hpp"
16
17 #include <memory>
18 #include <tklog/TketLog.hpp>
19
20 #include "Mapping/RoutingMethodJson.hpp"
21 #include "PassGenerators.hpp"
22 #include "PassLibrary.hpp"
23 #include "Transformations/ContextualReduction.hpp"
24 #include "Transformations/PauliOptimisation.hpp"
25 #include "Utils/Json.hpp"
26 #include "Utils/UnitID.hpp"
27
28 namespace tket {
29
30 898 void trivial_callback(const CompilationUnit&, const nlohmann::json&) {}
31
32 246 PassConditions BasePass::get_conditions() const {
33 246 return {precons_, postcons_};
34 }
35
36 std::string BasePass::to_string() const {
37 std::string str = "Preconditions:\n";
38
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
for (const TypePredicatePair& pp : precons_) {
39 str += (" " + pp.second->to_string() + "\n");
40 }
41 str += "Specific Postconditions:\n";
42
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
for (const TypePredicatePair& pp : postcons_.specific_postcons_) {
43 str += (" " + pp.second->to_string() + "\n");
44 }
45 str += "Generic Postconditions:\n";
46 for (const std::pair<const std::type_index, Guarantee>& pg :
47 postcons_.generic_postcons_) {
48 str += (" " + predicate_name(pg.first) + " ");
49 str += (pg.second == Guarantee::Clear) ? "Clear\n" : "Preserve\n";
50 }
51 str += "Default Postcondition: ";
52 str += (postcons_.default_postcon_ == Guarantee::Clear) ? "Clear\n"
53 : "Preserve\n";
54 return str;
55 };
56
57 359 std::optional<PredicatePtr> BasePass::unsatisfied_precondition(
58 const CompilationUnit& c_unit, SafetyMode safe_mode) const {
59
2/2
✓ Branch 5 taken 278 times.
✓ Branch 6 taken 357 times.
2/2
✓ Decision 'true' taken 278 times.
✓ Decision 'false' taken 357 times.
635 for (const TypePredicatePair& pp : precons_) {
60
1/2
✓ Branch 1 taken 278 times.
✗ Branch 2 not taken.
278 PredicateCache::const_iterator cache_iter = c_unit.cache_.find(pp.first);
61
2/2
✓ Branch 3 taken 135 times.
✓ Branch 4 taken 143 times.
2/2
✓ Decision 'true' taken 135 times.
✓ Decision 'false' taken 143 times.
278 if (cache_iter == c_unit.cache_.end()) { // cache does not contain
62 // predicate
63
3/4
✓ Branch 2 taken 135 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 133 times.
2/2
✓ Decision 'true' taken 133 times.
✓ Decision 'false' taken 2 times.
135 if (!c_unit.calc_predicate(*pp.second)) return pp.second;
64
1/2
✓ Branch 3 taken 133 times.
✗ Branch 4 not taken.
133 c_unit.cache_.insert({pp.first, {pp.second, true}});
65 } else {
66 /* if a Predicate is not `true` in the cache or implied by a set Predicate
67 in the cache then it is assumed to be `false` */
68
2/2
✓ Branch 1 taken 142 times.
✓ Branch 2 taken 1 times.
2/2
✓ Decision 'true' taken 142 times.
✓ Decision 'false' taken 1 times.
143 if (cache_iter->second.second) {
69
3/4
✓ Branch 4 taken 142 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 141 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 141 times.
142 if (!cache_iter->second.first->implies(*pp.second)) {
70
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
1/2
✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
1 if (!c_unit.calc_predicate(*pp.second)) return pp.second;
71 }
72 } else {
73
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
0/1
? Decision couldn't be analyzed.
1 if (!c_unit.calc_predicate(*pp.second)) return pp.second;
74 }
75 }
76 }
77
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 343 times.
2/2
✓ Decision 'true' taken 31 times.
✓ Decision 'false' taken 326 times.
357 if (safe_mode == SafetyMode::Audit) {
78
2/2
✓ Branch 5 taken 17 times.
✓ Branch 6 taken 14 times.
2/2
✓ Decision 'true' taken 17 times.
✓ Decision 'false' taken 14 times.
31 for (const TypePredicatePair& pp : precons_) {
79
2/4
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 17 times.
0/1
? Decision couldn't be analyzed.
17 if (!c_unit.calc_predicate(*pp.second)) return pp.second;
80 }
81 }
82 357 return {};
83 }
84
85 354 void BasePass::update_cache(
86 const CompilationUnit& c_unit, SafetyMode safe_mode) const {
87
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 350 times.
2/2
✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 350 times.
354 if (postcons_.default_postcon_ == Guarantee::Clear) {
88 4 for (PredicateCache::iterator it = c_unit.cache_.begin();
89
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 it != c_unit.cache_.end(); ++it) {
90 it->second.second = false;
91 }
92 }
93 354 for (const std::pair<const std::type_index, Guarantee>& pg :
94
2/2
✓ Branch 5 taken 258 times.
✓ Branch 6 taken 354 times.
966 postcons_.generic_postcons_) {
95
1/2
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 258 times.
✗ Decision 'false' not taken.
258 if (pg.second == Guarantee::Clear) {
96
1/2
✓ Branch 1 taken 258 times.
✗ Branch 2 not taken.
258 PredicateCache::iterator cache_iter = c_unit.cache_.find(pg.first);
97
2/2
✓ Branch 2 taken 61 times.
✓ Branch 3 taken 197 times.
0/1
? Decision couldn't be analyzed.
258 if (cache_iter != c_unit.cache_.end()) cache_iter->second.second = false;
98 }
99 }
100
2/2
✓ Branch 5 taken 400 times.
✓ Branch 6 taken 352 times.
2/2
✓ Decision 'true' taken 400 times.
✓ Decision 'false' taken 352 times.
752 for (const TypePredicatePair& pp : postcons_.specific_postcons_) {
101
7/8
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 380 times.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 18 times.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 398 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 398 times.
400 if (safe_mode == SafetyMode::Audit && !pp.second->verify(c_unit.circ_))
102
2/4
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
2 throw UnsatisfiedPredicate(pp.second->to_string());
103 398 std::pair<PredicatePtr, bool> cache_pair{pp.second, true};
104
1/2
✓ Branch 1 taken 398 times.
✗ Branch 2 not taken.
398 c_unit.cache_[pp.first] = cache_pair;
105 398 }
106 352 }
107
108 Guarantee BasePass::get_guarantee(const std::type_index& ti) const {
109 return get_guarantee(ti, this->get_conditions());
110 }
111
112 241 Guarantee BasePass::get_guarantee(
113 const std::type_index& ti, const PassConditions& conditions) {
114 PredicateClassGuarantees::const_iterator class_guar_iter =
115
1/2
✓ Branch 1 taken 241 times.
✗ Branch 2 not taken.
241 conditions.second.generic_postcons_.find(ti);
116
2/2
✓ Branch 2 taken 229 times.
✓ Branch 3 taken 12 times.
2/2
✓ Decision 'true' taken 229 times.
✓ Decision 'false' taken 12 times.
241 if (class_guar_iter == conditions.second.generic_postcons_.end()) {
117 229 return conditions.second.default_postcon_;
118 } else {
119 12 return class_guar_iter->second;
120 }
121 }
122
123 256 static PredicateClassGuarantees match_class_guarantees(
124 const PassConditions& lhs, const PassConditions& rhs) {
125 256 PredicateClassGuarantees cgs;
126 256 for (const std::pair<const std::type_index, Guarantee>& postcon :
127
2/2
✓ Branch 5 taken 286 times.
✓ Branch 6 taken 256 times.
798 rhs.second.generic_postcons_) {
128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 286 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 286 times.
286 if (postcon.second == Guarantee::Preserve) {
129
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
if (BasePass::get_guarantee(postcon.first, lhs) == Guarantee::Preserve)
130 cgs.insert(postcon);
131 else
132 cgs.insert({postcon.first, Guarantee::Clear});
133 } else
134
1/2
✓ Branch 1 taken 286 times.
✗ Branch 2 not taken.
286 cgs.insert(postcon);
135 }
136 256 return cgs;
137 }
138
139 134 PassConditions BasePass::match_passes(
140 const PassConditions& lhs, const PassConditions& rhs) {
141
1/2
✓ Branch 1 taken 134 times.
✗ Branch 2 not taken.
134 PredicatePtrMap new_precons = lhs.first;
142
2/2
✓ Branch 5 taken 155 times.
✓ Branch 6 taken 128 times.
2/2
✓ Decision 'true' taken 155 times.
✓ Decision 'false' taken 128 times.
283 for (const TypePredicatePair& precon : rhs.first) {
143 PredicatePtrMap::const_iterator data_guar_iter =
144
1/2
✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
155 lhs.second.specific_postcons_.find(precon.first);
145
2/2
✓ Branch 2 taken 71 times.
✓ Branch 3 taken 84 times.
2/2
✓ Decision 'true' taken 71 times.
✓ Decision 'false' taken 84 times.
155 if (data_guar_iter == lhs.second.specific_postcons_.end()) {
146
3/4
✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 70 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 70 times.
71 if (get_guarantee(precon.first, lhs) == Guarantee::Clear) {
147
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 throw IncompatibleCompilerPasses(precon.first);
148 } else {
149
1/2
✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
70 PredicatePtrMap::iterator new_pre_it = new_precons.find(precon.first);
150
2/2
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 58 times.
2/2
✓ Decision 'true' taken 12 times.
✓ Decision 'false' taken 58 times.
70 if (new_pre_it == new_precons.end())
151
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 new_precons.insert(precon);
152 else {
153
1/2
✓ Branch 4 taken 58 times.
✗ Branch 5 not taken.
58 PredicatePtr to_put_in = new_pre_it->second->meet(*precon.second);
154
1/2
✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
58 TypePredicatePair tpp = CompilationUnit::make_type_pair(to_put_in);
155
1/2
✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
58 new_precons[tpp.first] = tpp.second;
156 58 }
157 }
158 } else {
159
3/4
✓ Branch 4 taken 84 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 79 times.
2/2
✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 79 times.
84 if (!data_guar_iter->second->implies(*precon.second)) {
160
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 throw IncompatibleCompilerPasses(precon.first);
161 }
162 }
163 }
164
1/2
✓ Branch 3 taken 128 times.
✗ Branch 4 not taken.
256 PostConditions new_postcons;
165
1/2
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
128 new_postcons.specific_postcons_ = rhs.second.specific_postcons_;
166
2/2
✓ Branch 5 taken 237 times.
✓ Branch 6 taken 128 times.
2/2
✓ Decision 'true' taken 237 times.
✓ Decision 'false' taken 128 times.
365 for (const TypePredicatePair& postcon : lhs.second.specific_postcons_) {
167 PredicatePtrMap::iterator specific_post_it =
168
1/2
✓ Branch 1 taken 237 times.
✗ Branch 2 not taken.
237 new_postcons.specific_postcons_.find(postcon.first);
169
2/2
✓ Branch 2 taken 170 times.
✓ Branch 3 taken 67 times.
2/2
✓ Decision 'true' taken 170 times.
✓ Decision 'false' taken 67 times.
237 if (specific_post_it == new_postcons.specific_postcons_.end()) {
170
3/4
✓ Branch 1 taken 170 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 158 times.
✓ Branch 4 taken 12 times.
2/2
✓ Decision 'true' taken 158 times.
✓ Decision 'false' taken 12 times.
170 if (get_guarantee(postcon.first, rhs) == Guarantee::Preserve)
171
1/2
✓ Branch 1 taken 158 times.
✗ Branch 2 not taken.
158 new_postcons.specific_postcons_.insert(postcon);
172 }
173 }
174
1/2
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
128 new_postcons.generic_postcons_ = match_class_guarantees(lhs, rhs);
175
1/2
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
128 PredicateClassGuarantees others = match_class_guarantees(rhs, lhs);
176
1/2
✓ Branch 3 taken 128 times.
✗ Branch 4 not taken.
128 new_postcons.generic_postcons_.insert(others.begin(), others.end());
177
178
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 126 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 126 times.
128 if (rhs.second.default_postcon_ == Guarantee::Clear)
179 2 new_postcons.default_postcon_ = Guarantee::Clear;
180 else
181 126 new_postcons.default_postcon_ = lhs.second.default_postcon_;
182
183
1/2
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
256 return {new_precons, new_postcons};
184 134 }
185
186 66 PassConditions BasePass::match_passes(const PassPtr& lhs, const PassPtr& rhs) {
187
3/4
✓ Branch 4 taken 66 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 65 times.
✓ Branch 8 taken 1 times.
132 return match_passes(lhs->get_conditions(), rhs->get_conditions());
188 }
189
190 359 bool StandardPass::apply(
191 CompilationUnit& c_unit, SafetyMode safe_mode,
192 const PassCallback& before_apply, const PassCallback& after_apply) const {
193
2/4
✓ Branch 1 taken 359 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 359 times.
✗ Branch 5 not taken.
359 before_apply(c_unit, this->get_config());
194 std::optional<PredicatePtr> unsatisfied_precon =
195
1/2
✓ Branch 1 taken 359 times.
✗ Branch 2 not taken.
359 unsatisfied_precondition(c_unit, safe_mode);
196
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 357 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 357 times.
359 if (unsatisfied_precon)
197
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 throw UnsatisfiedPredicate(
198
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 unsatisfied_precon.value()
199
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
6 ->to_string()); // just raise warning in super-unsafe mode
200 // Allow trans_ to update the initial and final map
201
2/2
✓ Branch 2 taken 354 times.
✓ Branch 3 taken 3 times.
360 bool changed = trans_.apply_fn(c_unit.circ_, c_unit.maps);
202
2/2
✓ Branch 1 taken 352 times.
✓ Branch 2 taken 2 times.
354 update_cache(c_unit, safe_mode);
203
2/4
✓ Branch 1 taken 352 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 352 times.
✗ Branch 5 not taken.
352 after_apply(c_unit, this->get_config());
204 352 return changed;
205 359 }
206
207 std::string StandardPass::to_string() const {
208 std::string str = "***PassType: StandardPass***\n";
209 str += BasePass::to_string();
210 return str;
211 }
212
213 1367 nlohmann::json StandardPass::get_config() const {
214 1367 nlohmann::json j;
215
2/4
✓ Branch 1 taken 1367 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1367 times.
✗ Branch 5 not taken.
1367 j["pass_class"] = "StandardPass";
216
2/4
✓ Branch 1 taken 1367 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1367 times.
✗ Branch 5 not taken.
1367 j["StandardPass"] = pass_config_;
217 1367 return j;
218 }
219
220 60 PassPtr operator>>(const PassPtr& lhs, const PassPtr& rhs) {
221
2/2
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 1 times.
60 PassConditions pre_post_cons = BasePass::match_passes(lhs, rhs);
222
1/2
✓ Branch 1 taken 59 times.
✗ Branch 2 not taken.
59 SequencePass new_pass;
223
1/2
✓ Branch 1 taken 59 times.
✗ Branch 2 not taken.
59 new_pass.precons_ = pre_post_cons.first;
224
1/2
✓ Branch 1 taken 59 times.
✗ Branch 2 not taken.
59 new_pass.postcons_ = pre_post_cons.second;
225
3/6
✓ Branch 3 taken 59 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 118 times.
✓ Branch 6 taken 59 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
177 new_pass.seq_ = {lhs, rhs};
226
1/2
✓ Branch 1 taken 59 times.
✗ Branch 2 not taken.
59 PassPtr sequence = std::make_shared<SequencePass>(new_pass);
227 118 return sequence;
228 59 }
229
230 40 SequencePass::SequencePass(const std::vector<PassPtr>& ptvec) {
231
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 40 times.
40 if (ptvec.size() == 0)
232 throw std::logic_error("Cannot generate CompilerPass from empty list");
233 40 std::vector<PassPtr>::const_iterator iter = ptvec.begin();
234
1/2
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
40 PassConditions conditions = (*iter)->get_conditions();
235
2/2
✓ Branch 4 taken 68 times.
✓ Branch 5 taken 35 times.
2/2
✓ Decision 'true' taken 68 times.
✓ Decision 'false' taken 35 times.
103 for (++iter; iter != ptvec.end(); ++iter) {
236
1/2
✓ Branch 3 taken 68 times.
✗ Branch 4 not taken.
68 const PassConditions next_cons = (*iter)->get_conditions();
237
2/2
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 5 times.
68 conditions = match_passes(conditions, next_cons);
238 68 }
239
1/2
✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
35 this->precons_ = conditions.first;
240
1/2
✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
35 this->postcons_ = conditions.second;
241
1/2
✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
35 this->seq_ = ptvec;
242 50 }
243
244 std::string SequencePass::to_string() const {
245 std::string str = "***PassType: SequencePass***\n";
246 str += BasePass::to_string();
247 return str;
248 }
249
250 285 nlohmann::json SequencePass::get_config() const {
251 285 nlohmann::json j;
252
2/4
✓ Branch 1 taken 285 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 285 times.
✗ Branch 5 not taken.
285 j["pass_class"] = "SequencePass";
253
3/6
✓ Branch 1 taken 285 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 285 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 285 times.
✗ Branch 8 not taken.
285 j["SequencePass"]["sequence"] = seq_;
254 285 return j;
255 }
256
257 3 RepeatPass::RepeatPass(const PassPtr& pass) : pass_(pass) {
258 /* check precons and postcons are compatible for repetition */
259
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 std::tie(precons_, postcons_) = BasePass::match_passes(pass, pass);
260 3 }
261
262 std::string RepeatPass::to_string() const {
263 std::string str = "***PassType: RepeatPass***\n";
264 str += BasePass::to_string();
265 return str;
266 }
267
268 2 nlohmann::json RepeatPass::get_config() const {
269 2 nlohmann::json j;
270
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["pass_class"] = "RepeatPass";
271
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 j["RepeatPass"]["body"] = pass_;
272 2 return j;
273 }
274
275 1 RepeatWithMetricPass::RepeatWithMetricPass(
276 1 const PassPtr& pass, const Transform::Metric& metric)
277
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 : pass_(pass), metric_(metric) {
278
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::tie(precons_, postcons_) = BasePass::match_passes(pass, pass);
279 1 }
280
281 1 bool RepeatWithMetricPass::apply(
282 CompilationUnit& c_unit, SafetyMode safe_mode,
283 const PassCallback& before_apply, const PassCallback& after_apply) const {
284
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 before_apply(c_unit, this->get_config());
285 1 bool success = false;
286
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 unsigned currentVal = metric_(c_unit.get_circ_ref());
287 1 CompilationUnit* c_unit_current = &c_unit;
288
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 CompilationUnit c_unit_new = c_unit;
289
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 pass_->apply(
290 c_unit_new, safe_mode); // I can't make it apply the pass to a copy
291 // without copying the whole CompilationUnit
292
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 unsigned newVal = metric_(c_unit_new.get_circ_ref());
293
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 1 times.
3 while (newVal < currentVal) {
294 2 c_unit_current = &c_unit_new;
295 2 currentVal = newVal;
296 2 success = true;
297
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 pass_->apply(c_unit_new, safe_mode, before_apply, after_apply);
298
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 newVal = metric_(c_unit_new.get_circ_ref());
299 }
300
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1/2
✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
1 if (&c_unit != c_unit_current) c_unit = *c_unit_current;
301
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 after_apply(c_unit, this->get_config());
302 1 return success;
303 1 }
304
305 std::string RepeatWithMetricPass::to_string() const {
306 std::string str = "***PassType: RepeatWithMetricPass***\n";
307 str += BasePass::to_string();
308 return str;
309 }
310
311 2 nlohmann::json RepeatWithMetricPass::get_config() const {
312 2 nlohmann::json j;
313
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["pass_class"] = "RepeatWithMetricPass";
314
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 j["RepeatWithMetricPass"]["body"] = pass_;
315
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["RepeatWithMetricPass"]["metric"] =
316
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 "SERIALIZATION OF METRICS NOT YET IMPLEMENTED";
317 2 return j;
318 }
319
320 2 RepeatUntilSatisfiedPass::RepeatUntilSatisfiedPass(
321 2 const PassPtr& pass, const PredicatePtr& to_satisfy)
322 2 : pass_(pass), pred_(to_satisfy) {
323
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 std::tie(precons_, postcons_) = BasePass::match_passes(pass, pass);
324 2 }
325
326 2 bool RepeatUntilSatisfiedPass::apply(
327 CompilationUnit& c_unit, SafetyMode safe_mode,
328 const PassCallback& before_apply, const PassCallback& after_apply) const {
329
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 before_apply(c_unit, this->get_config());
330 2 bool success = false;
331
2/2
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
2/2
✓ Decision 'true' taken 6 times.
✓ Decision 'false' taken 2 times.
8 while (!pred_->verify(c_unit.get_circ_ref())) {
332 6 pass_->apply(c_unit, safe_mode, before_apply, after_apply);
333 6 success = true;
334 }
335
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 after_apply(c_unit, this->get_config());
336 2 return success;
337 }
338
339 std::string RepeatUntilSatisfiedPass::to_string() const {
340 std::string str = "***PassType: RepeatUntilSatisfiedPass***\n";
341 str += BasePass::to_string();
342 return str;
343 }
344
345 10 nlohmann::json RepeatUntilSatisfiedPass::get_config() const {
346 10 nlohmann::json j;
347
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 j["pass_class"] = "RepeatUntilSatisfiedPass";
348
3/6
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
10 j["RepeatUntilSatisfiedPass"]["body"] = pass_;
349
3/6
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
10 j["RepeatUntilSatisfiedPass"]["predicate"] = pred_;
350 10 return j;
351 }
352
353 768 void to_json(nlohmann::json& j, const PassPtr& pp) { j = pp->get_config(); }
354
355 57 void from_json(const nlohmann::json& j, PassPtr& pp) {
356
2/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
57 std::string classname = j.at("pass_class").get<std::string>();
357
2/2
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 4 times.
2/2
✓ Decision 'true' taken 53 times.
✓ Decision 'false' taken 4 times.
57 if (classname == "StandardPass") {
358
1/2
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
53 const nlohmann::json& content = j.at("StandardPass");
359
2/4
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 53 times.
✗ Branch 5 not taken.
53 std::string passname = content.at("name").get<std::string>();
360
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 52 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 52 times.
53 if (passname == "KAKDecomposition") {
361
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 double cx_fidelity = content.at("fidelity").get<double>();
362
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 OpType target_2qb_gate = content.at("target_2qb_gate").get<OpType>();
363
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 bool allow_swaps = content.at("allow_swaps").get<bool>();
364
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = KAKDecomposition(target_2qb_gate, cx_fidelity, allow_swaps);
365
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 51 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 51 times.
52 } else if (passname == "ThreeQubitSquash") {
366
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 pp = ThreeQubitSquash(content.at("allow_swaps").get<bool>());
367
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 49 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 49 times.
51 } else if (passname == "CommuteThroughMultis") {
368
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 pp = CommuteThroughMultis();
369
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 48 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 48 times.
49 } else if (passname == "DecomposeArbitrarilyControlledGates") {
370
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = DecomposeArbitrarilyControlledGates();
371
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 47 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 47 times.
48 } else if (passname == "DecomposeBoxes") {
372
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = DecomposeBoxes();
373
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 47 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 47 times.
47 } else if (passname == "DecomposeClassicalExp") {
374 throw PassNotSerializable(passname);
375
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 46 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 46 times.
47 } else if (passname == "DecomposeMultiQubitsCX") {
376
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = DecomposeMultiQubitsCX();
377
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 45 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 45 times.
46 } else if (passname == "DecomposeSingleQubitsTK1") {
378
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = DecomposeSingleQubitsTK1();
379
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 44 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 44 times.
45 } else if (passname == "DecomposeTK2") {
380 1 Transforms::TwoQbFidelities fid;
381 fid.CX_fidelity =
382
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 content.at("fidelities").at("CX").get<std::optional<double>>();
383 fid.ZZMax_fidelity =
384
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 content.at("fidelities").at("ZZMax").get<std::optional<double>>();
385 1 fid.ZZPhase_fidelity = std::nullopt;
386
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 bool allow_swaps = content.at("allow_swaps").get<bool>();
387
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = DecomposeTK2(fid, allow_swaps);
388
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 43 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 44 times.
45 } else if (passname == "PeepholeOptimise2Q") {
389
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = PeepholeOptimise2Q();
390
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 42 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 42 times.
43 } else if (passname == "FullPeepholeOptimise") {
391
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 OpType target_2qb_gate = content.at("target_2qb_gate").get<OpType>();
392
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 bool allow_swaps = content.at("allow_swaps").get<bool>();
393
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = FullPeepholeOptimise(allow_swaps, target_2qb_gate);
394
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 40 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 40 times.
42 } else if (passname == "RebaseTket") {
395
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 pp = RebaseTket();
396
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 39 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 39 times.
40 } else if (passname == "RebaseUFR") {
397
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = RebaseUFR();
398
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 37 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 37 times.
39 } else if (passname == "RemoveRedundancies") {
399
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 pp = RemoveRedundancies();
400
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 36 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 36 times.
37 } else if (passname == "SynthesiseHQS") {
401
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = SynthesiseHQS();
402
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 35 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 35 times.
36 } else if (passname == "SynthesiseTK") {
403
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = SynthesiseTK();
404
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 34 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 34 times.
35 } else if (passname == "SynthesiseTket") {
405
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = SynthesiseTket();
406
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 33 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 33 times.
34 } else if (passname == "SynthesiseOQC") {
407
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = SynthesiseOQC();
408
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 32 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 32 times.
33 } else if (passname == "SynthesiseUMD") {
409
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = SynthesiseUMD();
410
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 31 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 31 times.
32 } else if (passname == "SquashTK1") {
411
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = SquashTK1();
412
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 30 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 30 times.
31 } else if (passname == "SquashRzPhasedX") {
413
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = SquashRzPhasedX();
414
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 29 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 29 times.
30 } else if (passname == "FlattenRegisters") {
415
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = FlattenRegisters();
416
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 29 times.
29 } else if (passname == "SquashCustom") {
417 throw PassNotSerializable(passname);
418
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 28 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 28 times.
29 } else if (passname == "DelayMeasures") {
419
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = DelayMeasures();
420
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 27 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 27 times.
28 } else if (passname == "ZZPhaseToRz") {
421
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = ZZPhaseToRz();
422
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 26 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 26 times.
27 } else if (passname == "RemoveDiscarded") {
423
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = RemoveDiscarded();
424
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 25 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 25 times.
26 } else if (passname == "SimplifyMeasured") {
425
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = SimplifyMeasured();
426
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 24 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 24 times.
25 } else if (passname == "RemoveBarriers") {
427
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = RemoveBarriers();
428
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 23 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 23 times.
24 } else if (passname == "ComposePhasePolyBoxes") {
429
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 pp = ComposePhasePolyBoxes(content.at("min_size").get<unsigned>());
430
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 23 times.
23 } else if (passname == "RebaseCustom") {
431 throw PassNotSerializable(passname);
432
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 22 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 22 times.
23 } else if (passname == "EulerAngleReduction") {
433
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 OpType p = content.at("euler_p").get<OpType>();
434
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 OpType q = content.at("euler_q").get<OpType>();
435
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 bool s = content.at("euler_strict").get<bool>();
436
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = gen_euler_pass(q, p, s);
437
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 20 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 20 times.
22 } else if (passname == "RoutingPass") {
438
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 Architecture arc = content.at("architecture").get<Architecture>();
439
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 std::vector<RoutingMethodPtr> con = content.at("routing_config");
440
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 pp = gen_routing_pass(arc, con);
441
442
2/2
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 18 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 20 times.
22 } else if (passname == "PlacementPass") {
443
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 pp = gen_placement_pass(content.at("placement").get<PlacementPtr>());
444
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 17 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 16 times.
18 } else if (passname == "NaivePlacementPass") {
445
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 pp = gen_naive_placement_pass(
446
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
3 content.at("architecture").get<Architecture>());
447
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 16 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 15 times.
17 } else if (passname == "RenameQubitsPass") {
448
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 pp = gen_rename_qubits_pass(
449
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
3 content.at("qubit_map").get<std::map<Qubit, Qubit>>());
450
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 14 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 14 times.
16 } else if (passname == "CliffordSimp") {
451
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 pp = gen_clifford_simp_pass(content.at("allow_swaps").get<bool>());
452
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 13 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 13 times.
14 } else if (passname == "DecomposeSwapsToCXs") {
453
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 Architecture arc = content.at("architecture").get<Architecture>();
454
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 bool d = content.at("directed").get<bool>();
455
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = gen_decompose_routing_gates_to_cxs_pass(arc, d);
456
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 12 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 12 times.
14 } else if (passname == "DecomposeSwapsToCircuit") {
457
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 pp = gen_user_defined_swap_decomp_pass(
458
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
3 content.at("swap_replacement").get<Circuit>());
459
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 11 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 11 times.
12 } else if (passname == "DecomposeBridges") {
460
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = DecomposeBridges();
461
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 9 times.
11 } else if (passname == "OptimisePhaseGadgets") {
462
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 pp = gen_optimise_phase_gadgets(
463
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 content.at("cx_config").get<CXConfigType>());
464
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 9 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 8 times.
10 } else if (passname == "OptimisePairwiseGadgets") {
465
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 pp = gen_pairwise_pauli_gadgets(
466
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 content.at("cx_config").get<CXConfigType>());
467
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 7 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 7 times.
9 } else if (passname == "PauliSimp") {
468 Transforms::PauliSynthStrat pss =
469
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 content.at("pauli_synth_strat").get<Transforms::PauliSynthStrat>();
470
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 CXConfigType cxc = content.at("cx_config").get<CXConfigType>();
471
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 pp = gen_synthesise_pauli_graph(pss, cxc);
472
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 6 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 6 times.
7 } else if (passname == "GuidedPauliSimp") {
473 Transforms::PauliSynthStrat pss =
474
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 content.at("pauli_synth_strat").get<Transforms::PauliSynthStrat>();
475
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 CXConfigType cxc = content.at("cx_config").get<CXConfigType>();
476
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = gen_special_UCC_synthesis(pss, cxc);
477
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 5 times.
6 } else if (passname == "SimplifyInitial") {
478
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 bool acbool = content.at("allow_classical").get<bool>();
479
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 Transforms::AllowClassical ac = (acbool) ? Transforms::AllowClassical::Yes
480 : Transforms::AllowClassical::No;
481
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 bool caqbool = content.at("create_all_qubits").get<bool>();
482 1 Transforms::CreateAllQubits caq = (caqbool)
483
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 ? Transforms::CreateAllQubits::Yes
484 : Transforms::CreateAllQubits::No;
485 1 std::shared_ptr<const Circuit> xc;
486
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
0/1
? Decision couldn't be analyzed.
1 if (content.contains("x_circuit")) {
487
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 xc = std::make_shared<const Circuit>(
488
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
3 content.at("x_circuit").get<Circuit>());
489 }
490
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 pp = gen_simplify_initial(ac, caq, xc);
491
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 5 times.
6 } else if (passname == "FullMappingPass") {
492 // SEQUENCE PASS - DESERIALIZABLE ONLY
493
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 Architecture arc = content.at("architecture").get<Architecture>();
494
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 PlacementPtr place = content.at("placement").get<PlacementPtr>();
495
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 std::vector<RoutingMethodPtr> config = content.at("routing_config");
496
497
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = gen_full_mapping_pass(arc, place, config);
498
2/2
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 3 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 4 times.
5 } else if (passname == "DefaultMappingPass") {
499 // SEQUENCE PASS - DESERIALIZABLE ONLY
500
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 Architecture arc = content.at("architecture").get<Architecture>();
501
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 bool delay_measures = content.at("delay_measures").get<bool>();
502
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = gen_default_mapping_pass(arc, delay_measures);
503
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 3 times.
4 } else if (passname == "CXMappingPass") {
504 // SEQUENCE PASS - DESERIALIZABLE ONLY
505
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 Architecture arc = content.at("architecture").get<Architecture>();
506
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 PlacementPtr place = content.at("placement").get<PlacementPtr>();
507
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 std::vector<RoutingMethodPtr> config = content.at("routing_config");
508
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 bool directed_cx = content.at("directed").get<bool>();
509
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 bool delay_measures = content.at("delay_measures").get<bool>();
510
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = gen_cx_mapping_pass(arc, place, config, directed_cx, delay_measures);
511
2/2
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 2 times.
3 } else if (passname == "PauliSquash") {
512 // SEQUENCE PASS - DESERIALIZABLE ONLY
513 Transforms::PauliSynthStrat strat =
514
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 content.at("pauli_synth_strat").get<Transforms::PauliSynthStrat>();
515
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 CXConfigType cx_config = content.at("cx_config").get<CXConfigType>();
516
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = PauliSquash(strat, cx_config);
517
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1/2
✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
1 } else if (passname == "ContextSimp") {
518 // SEQUENCE PASS - DESERIALIZABLE ONLY
519
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 bool allow_classical = content.at("allow_classical").get<bool>();
520 std::shared_ptr<Circuit> xcirc =
521
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 std::make_shared<Circuit>(content.at("x_circuit").get<Circuit>());
522
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 pp = gen_contextual_pass(
523 allow_classical ? Transforms::AllowClassical::Yes
524 : Transforms::AllowClassical::No,
525 1 xcirc);
526 1 } else {
527 throw JsonError("Cannot load StandardPass of unknown type");
528 }
529
2/2
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
2/2
✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 54 times.
57 } else if (classname == "SequencePass") {
530
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 const nlohmann::json& content = j.at("SequencePass");
531 3 std::vector<PassPtr> seq;
532
5/8
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 9 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 6 times.
✓ Branch 12 taken 3 times.
0/1
? Decision couldn't be analyzed.
9 for (const auto& j_entry : content.at("sequence")) {
533
3/6
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
6 seq.push_back(j_entry.get<PassPtr>());
534 }
535
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 pp = std::make_shared<SequencePass>(seq);
536
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 4 times.
4 } else if (classname == "RepeatPass") {
537 const nlohmann::json& content = j.at("RepeatPass");
538 pp = std::make_shared<RepeatPass>(content.at("body").get<PassPtr>());
539
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 1 times.
1 } else if (classname == "RepeatWithMetricPass") {
540 throw PassNotSerializable(classname);
541
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1/2
✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
1 } else if (classname == "RepeatUntilSatisfiedPass") {
542
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 const nlohmann::json& content = j.at("RepeatUntilSatisfiedPass");
543
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 PassPtr body = content.at("body").get<PassPtr>();
544
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 PredicatePtr pred = content.at("predicate").get<PredicatePtr>();
545
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pp = std::make_shared<RepeatUntilSatisfiedPass>(body, pred);
546 1 } else {
547 throw JsonError("Cannot load PassPtr of unknown type.");
548 }
549 57 }
550
551 } // namespace tket
552