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 "Rebase.hpp" | |||
16 | ||||
17 | #include <tkassert/Assert.hpp> | |||
18 | #include <tklog/TketLog.hpp> | |||
19 | ||||
20 | #include "BasicOptimisation.hpp" | |||
21 | #include "Circuit/CircPool.hpp" | |||
22 | #include "Circuit/CircUtils.hpp" | |||
23 | #include "Circuit/Circuit.hpp" | |||
24 | #include "Gate/GatePtr.hpp" | |||
25 | #include "OpType/OpType.hpp" | |||
26 | #include "OpType/OpTypeFunctions.hpp" | |||
27 | #include "Ops/Op.hpp" | |||
28 | #include "Replacement.hpp" | |||
29 | #include "Transform.hpp" | |||
30 | ||||
31 | namespace tket { | |||
32 | ||||
33 | namespace Transforms { | |||
34 | ||||
35 | // Rebase a 0- or 1-qubit unitary operation | |||
36 | 992 | static Circuit rebase_op( | ||
37 | Gate_ptr op, | |||
38 | const std::function<Circuit(const Expr&, const Expr&, const Expr&)>& | |||
39 | tk1_replacement) { | |||
40 | 992 | OpType type = op->get_type(); | ||
41 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 991 times.
|
2/2✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 991 times.
|
992 | if (type == OpType::Phase) { |
42 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | Circuit replacement(0); | |
43 |
3/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
|
1 | replacement.add_phase(op->get_params()[0]); | |
44 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | return replacement; | |
45 | 1 | } else { | ||
46 |
1/2✓ Branch 2 taken 991 times.
✗ Branch 3 not taken.
|
991 | std::vector<Expr> tk1_angles = op->get_tk1_angles(); | |
47 | Circuit replacement = | |||
48 |
1/2✓ Branch 4 taken 991 times.
✗ Branch 5 not taken.
|
991 | tk1_replacement(tk1_angles[0], tk1_angles[1], tk1_angles[2]); | |
49 |
2/4✓ Branch 1 taken 991 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 991 times.
✗ Branch 5 not taken.
|
991 | remove_redundancies().apply(replacement); | |
50 |
2/4✓ Branch 2 taken 991 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 991 times.
✗ Branch 6 not taken.
|
991 | replacement.add_phase(tk1_angles[3]); | |
51 |
1/2✓ Branch 1 taken 991 times.
✗ Branch 2 not taken.
|
991 | return replacement; | |
52 | 991 | } | ||
53 | } | |||
54 | ||||
55 | 279 | static bool standard_rebase( | ||
56 | Circuit& circ, const OpTypeSet& allowed_gates, | |||
57 | const Circuit& cx_replacement, | |||
58 | const std::function<Circuit(const Expr&, const Expr&, const Expr&)>& | |||
59 | tk1_replacement) { | |||
60 | 279 | bool success = false; | ||
61 | 279 | VertexSet bin; | ||
62 |
7/8✓ Branch 1 taken 279 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 11798 times.
✓ Branch 6 taken 279 times.
✓ Branch 8 taken 11798 times.
✓ Branch 9 taken 279 times.
✓ Branch 11 taken 279 times.
✓ Branch 12 taken 279 times.
|
12356 | BGL_FORALL_VERTICES(v, circ.dag, DAG) { | |
63 |
1/2✓ Branch 1 taken 11798 times.
✗ Branch 2 not taken.
|
11798 | Op_ptr op = circ.get_Op_ptr_from_Vertex(v); | |
64 |
1/2✓ Branch 1 taken 11798 times.
✗ Branch 2 not taken.
|
11798 | unsigned n_qubits = circ.n_in_edges_of_type(v, EdgeType::Quantum); | |
65 |
2/2✓ Branch 0 taken 7556 times.
✓ Branch 1 taken 4242 times.
|
2/2✓ Decision 'true' taken 4242 times.
✓ Decision 'false' taken 7556 times.
|
11798 | if (n_qubits <= 1) continue; |
66 | 4242 | bool conditional = op->get_type() == OpType::Conditional; | ||
67 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 4182 times.
|
2/2✓ Decision 'true' taken 60 times.
✓ Decision 'false' taken 4182 times.
|
4242 | if (conditional) { |
68 | 60 | const Conditional& cond = static_cast<const Conditional&>(*op); | ||
69 |
1/2✓ Branch 1 taken 60 times.
✗ Branch 2 not taken.
|
60 | op = cond.get_op(); | |
70 | } | |||
71 | 4242 | OpType type = op->get_type(); | ||
72 |
7/8✓ Branch 2 taken 4242 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 132 times.
✓ Branch 6 taken 4110 times.
✓ Branch 7 taken 94 times.
✓ Branch 8 taken 38 times.
✓ Branch 9 taken 4148 times.
✓ Branch 10 taken 94 times.
|
2/2✓ Decision 'true' taken 4148 times.
✓ Decision 'false' taken 188 times.
|
4336 | if (allowed_gates.find(type) != allowed_gates.end() || type == OpType::CX || |
73 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
|
94 | type == OpType::Barrier) | |
74 | 4148 | continue; | ||
75 | // need to convert | |||
76 |
1/2✓ Branch 2 taken 94 times.
✗ Branch 3 not taken.
|
94 | Circuit replacement = CX_circ_from_multiq(op); | |
77 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 88 times.
|
2/2✓ Decision 'true' taken 6 times.
✓ Decision 'false' taken 88 times.
|
94 | if (conditional) { |
78 |
2/4✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
|
6 | circ.substitute_conditional(replacement, v, Circuit::VertexDeletion::No); | |
79 | } else { | |||
80 |
1/2✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
|
88 | circ.substitute(replacement, v, Circuit::VertexDeletion::No); | |
81 | } | |||
82 |
1/2✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
|
94 | bin.insert(v); | |
83 | 94 | success = true; | ||
84 |
2/2✓ Branch 2 taken 94 times.
✓ Branch 3 taken 11704 times.
|
11798 | } | |
85 |
3/4✓ Branch 2 taken 279 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 67 times.
✓ Branch 6 taken 212 times.
|
2/2✓ Decision 'true' taken 67 times.
✓ Decision 'false' taken 212 times.
|
279 | if (allowed_gates.find(OpType::CX) == allowed_gates.end()) { |
86 |
1/2✓ Branch 2 taken 67 times.
✗ Branch 3 not taken.
|
67 | const Op_ptr cx_op = get_op_ptr(OpType::CX); | |
87 |
1/2✓ Branch 2 taken 67 times.
✗ Branch 3 not taken.
|
67 | success = circ.substitute_all(cx_replacement, cx_op) | success; | |
88 | 67 | } | ||
89 |
7/8✓ Branch 1 taken 279 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 13512 times.
✓ Branch 6 taken 279 times.
✓ Branch 8 taken 13512 times.
✓ Branch 9 taken 279 times.
✓ Branch 11 taken 279 times.
✓ Branch 12 taken 279 times.
|
14070 | BGL_FORALL_VERTICES(v, circ.dag, DAG) { | |
90 |
3/4✓ Branch 1 taken 13512 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 94 times.
✓ Branch 4 taken 13418 times.
|
2/2✓ Decision 'true' taken 13418 times.
✓ Decision 'false' taken 12525 times.
|
25943 | if (bin.contains(v)) continue; |
91 |
3/4✓ Branch 1 taken 13418 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4148 times.
✓ Branch 4 taken 9270 times.
|
2/2✓ Decision 'true' taken 9270 times.
✓ Decision 'false' taken 4148 times.
|
13418 | if (circ.n_in_edges_of_type(v, EdgeType::Quantum) > 1) continue; |
92 |
1/2✓ Branch 1 taken 9270 times.
✗ Branch 2 not taken.
|
9270 | Op_ptr op = circ.get_Op_ptr_from_Vertex(v); | |
93 | 9270 | bool conditional = op->get_type() == OpType::Conditional; | ||
94 |
2/2✓ Branch 0 taken 399 times.
✓ Branch 1 taken 8871 times.
|
2/2✓ Decision 'true' taken 399 times.
✓ Decision 'false' taken 8871 times.
|
9270 | if (conditional) { |
95 | 399 | const Conditional& cond = static_cast<const Conditional&>(*op); | ||
96 |
1/2✓ Branch 1 taken 399 times.
✗ Branch 2 not taken.
|
399 | op = cond.get_op(); | |
97 | } | |||
98 | 9270 | OpType type = op->get_type(); | ||
99 |
6/8✓ Branch 1 taken 9270 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7393 times.
✓ Branch 4 taken 1877 times.
✓ Branch 6 taken 7393 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7353 times.
✓ Branch 9 taken 40 times.
|
2/2✓ Decision 'true' taken 8283 times.
✓ Decision 'false' taken 8340 times.
|
16623 | if (!is_gate_type(type) || is_projective_type(type) || |
100 |
5/6✓ Branch 2 taken 7353 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6366 times.
✓ Branch 6 taken 987 times.
✓ Branch 7 taken 8283 times.
✓ Branch 8 taken 987 times.
|
16623 | allowed_gates.find(type) != allowed_gates.end()) | |
101 | 8283 | continue; | ||
102 | // need to convert | |||
103 |
2/4✓ Branch 2 taken 987 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 987 times.
✗ Branch 6 not taken.
|
1974 | Circuit replacement = rebase_op(as_gate_ptr(op), tk1_replacement); | |
104 |
2/2✓ Branch 0 taken 163 times.
✓ Branch 1 taken 824 times.
|
2/2✓ Decision 'true' taken 163 times.
✓ Decision 'false' taken 824 times.
|
987 | if (conditional) { |
105 |
2/4✓ Branch 1 taken 163 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 163 times.
✗ Branch 5 not taken.
|
163 | circ.substitute_conditional(replacement, v, Circuit::VertexDeletion::No); | |
106 | } else { | |||
107 |
1/2✓ Branch 1 taken 824 times.
✗ Branch 2 not taken.
|
824 | circ.substitute(replacement, v, Circuit::VertexDeletion::No); | |
108 | } | |||
109 |
1/2✓ Branch 1 taken 987 times.
✗ Branch 2 not taken.
|
987 | bin.insert(v); | |
110 | 987 | success = true; | ||
111 |
2/2✓ Branch 2 taken 987 times.
✓ Branch 3 taken 8283 times.
|
9270 | } | |
112 |
1/2✓ Branch 1 taken 279 times.
✗ Branch 2 not taken.
|
279 | circ.remove_vertices( | |
113 | bin, Circuit::GraphRewiring::No, Circuit::VertexDeletion::Yes); | |||
114 | 279 | return success; | ||
115 | 279 | } | ||
116 | ||||
117 | 1 | static bool standard_rebase_via_tk2( | ||
118 | Circuit& circ, const OpTypeSet& allowed_gates, | |||
119 | const std::function<Circuit(const Expr&, const Expr&, const Expr&)>& | |||
120 | tk1_replacement, | |||
121 | const std::function<Circuit(const Expr&, const Expr&, const Expr&)>& | |||
122 | tk2_replacement) { | |||
123 | 1 | bool success = false; | ||
124 | 1 | VertexSet bin; | ||
125 | ||||
126 | // 1. Replace all multi-qubit gates outside the target gateset to TK2. | |||
127 |
7/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 11 times.
✓ Branch 6 taken 1 times.
✓ Branch 8 taken 11 times.
✓ Branch 9 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 1 times.
|
13 | BGL_FORALL_VERTICES(v, circ.dag, DAG) { | |
128 |
1/2✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
|
11 | Op_ptr op = circ.get_Op_ptr_from_Vertex(v); | |
129 |
1/2✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
|
11 | unsigned n_qubits = circ.n_in_edges_of_type(v, EdgeType::Quantum); | |
130 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 9 times.
|
11 | if (n_qubits <= 1) continue; |
131 | 2 | bool conditional = op->get_type() == OpType::Conditional; | ||
132 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 2 times.
|
2 | if (conditional) { |
133 | ✗ | const Conditional& cond = static_cast<const Conditional&>(*op); | ||
134 | ✗ | op = cond.get_op(); | ||
135 | } | |||
136 | 2 | OpType type = op->get_type(); | ||
137 |
6/8✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
|
2/2✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 2 times.
|
3 | if (allowed_gates.contains(type) || type == OpType::TK2 || |
138 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | type == OpType::Barrier) | |
139 | 1 | continue; | ||
140 | // need to convert | |||
141 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | Circuit replacement = TK2_circ_from_multiq(op); | |
142 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1 times.
|
1 | if (conditional) { |
143 | ✗ | circ.substitute_conditional(replacement, v, Circuit::VertexDeletion::No); | ||
144 | } else { | |||
145 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | circ.substitute(replacement, v, Circuit::VertexDeletion::No); | |
146 | } | |||
147 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | bin.insert(v); | |
148 | 1 | success = true; | ||
149 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 3 taken 10 times.
|
11 | } | |
150 | ||||
151 | // 2. If TK2 is not in the target gateset, decompose TK2 gates. | |||
152 |
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 (!allowed_gates.contains(OpType::TK2)) { |
153 |
7/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 1 times.
✓ Branch 8 taken 12 times.
✓ Branch 9 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 1 times.
|
14 | BGL_FORALL_VERTICES(v, circ.dag, DAG) { | |
154 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | Op_ptr op = circ.get_Op_ptr_from_Vertex(v); | |
155 | 12 | bool conditional = op->get_type() == OpType::Conditional; | ||
156 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 12 times.
|
12 | if (conditional) { |
157 | ✗ | const Conditional& cond = static_cast<const Conditional&>(*op); | ||
158 | ✗ | op = cond.get_op(); | ||
159 | } | |||
160 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 3 taken 11 times.
|
2/2✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 11 times.
|
12 | if (op->get_type() == OpType::TK2) { |
161 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | std::vector<Expr> params = op->get_params(); | |
162 | TKET_ASSERT(params.size() == 3); | |||
163 |
1/2✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | Circuit replacement = tk2_replacement(params[0], params[1], params[2]); | |
164 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | remove_redundancies().apply(replacement); | |
165 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1 times.
|
1 | if (conditional) { |
166 | ✗ | circ.substitute_conditional( | ||
167 | replacement, v, Circuit::VertexDeletion::No); | |||
168 | } else { | |||
169 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | circ.substitute(replacement, v, Circuit::VertexDeletion::No); | |
170 | } | |||
171 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | bin.insert(v); | |
172 | 1 | success = true; | ||
173 | 1 | } | ||
174 | 12 | } | ||
175 | } | |||
176 | ||||
177 | // 3. Replace 0- and 1-qubit gates by converting to TK1 and replacing. | |||
178 |
7/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 24 times.
✓ Branch 6 taken 1 times.
✓ Branch 8 taken 24 times.
✓ Branch 9 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 1 times.
|
26 | BGL_FORALL_VERTICES(v, circ.dag, DAG) { | |
179 |
3/4✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 22 times.
|
2/2✓ Decision 'true' taken 22 times.
✓ Decision 'false' taken 19 times.
|
41 | if (bin.contains(v)) continue; |
180 |
3/4✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 21 times.
|
2/2✓ Decision 'true' taken 21 times.
✓ Decision 'false' taken 1 times.
|
22 | if (circ.n_in_edges_of_type(v, EdgeType::Quantum) > 1) continue; |
181 |
1/2✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
|
21 | Op_ptr op = circ.get_Op_ptr_from_Vertex(v); | |
182 | 21 | bool conditional = op->get_type() == OpType::Conditional; | ||
183 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 21 times.
|
21 | if (conditional) { |
184 | ✗ | const Conditional& cond = static_cast<const Conditional&>(*op); | ||
185 | ✗ | op = cond.get_op(); | ||
186 | } | |||
187 | 21 | OpType type = op->get_type(); | ||
188 |
7/10✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
✓ Branch 4 taken 4 times.
✓ Branch 6 taken 17 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 17 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 5 times.
|
2/2✓ Decision 'true' taken 16 times.
✓ Decision 'false' taken 22 times.
|
38 | if (!is_gate_type(type) || is_projective_type(type) || |
189 |
3/4✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 5 times.
|
17 | allowed_gates.contains(type)) | |
190 | 16 | continue; | ||
191 | // need to convert | |||
192 |
2/4✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
|
10 | Circuit replacement = rebase_op(as_gate_ptr(op), tk1_replacement); | |
193 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 5 times.
|
5 | if (conditional) { |
194 | ✗ | circ.substitute_conditional(replacement, v, Circuit::VertexDeletion::No); | ||
195 | } else { | |||
196 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | circ.substitute(replacement, v, Circuit::VertexDeletion::No); | |
197 | } | |||
198 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | bin.insert(v); | |
199 | 5 | success = true; | ||
200 |
2/2✓ Branch 2 taken 5 times.
✓ Branch 3 taken 16 times.
|
21 | } | |
201 | ||||
202 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | circ.remove_vertices( | |
203 | bin, Circuit::GraphRewiring::No, Circuit::VertexDeletion::Yes); | |||
204 | 1 | return success; | ||
205 | 1 | } | ||
206 | ||||
207 | 246 | Transform rebase_factory( | ||
208 | const OpTypeSet& allowed_gates, const Circuit& cx_replacement, | |||
209 | const std::function<Circuit(const Expr&, const Expr&, const Expr&)>& | |||
210 | tk1_replacement) { | |||
211 | 279 | return Transform([=](Circuit& circ) { | ||
212 | 558 | return standard_rebase( | ||
213 | 279 | circ, allowed_gates, cx_replacement, tk1_replacement); | ||
214 |
2/4✓ Branch 4 taken 246 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 246 times.
✗ Branch 8 not taken.
|
246 | }); | |
215 | } | |||
216 | ||||
217 | 1 | Transform rebase_factory_via_tk2( | ||
218 | const OpTypeSet& allowed_gates, | |||
219 | const std::function<Circuit(const Expr&, const Expr&, const Expr&)>& | |||
220 | tk1_replacement, | |||
221 | const std::function<Circuit(const Expr&, const Expr&, const Expr&)>& | |||
222 | tk2_replacement) { | |||
223 | 1 | return Transform([=](Circuit& circ) { | ||
224 | 2 | return standard_rebase_via_tk2( | ||
225 | 1 | circ, allowed_gates, tk1_replacement, tk2_replacement); | ||
226 |
2/4✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
1 | }); | |
227 | } | |||
228 | ||||
229 | 145 | Transform rebase_tket() { | ||
230 | std::function<Circuit(const Expr&, const Expr&, const Expr&)> tk1_to_tk1 = | |||
231 | 426 | [](const Expr& alpha, const Expr& beta, const Expr& gamma) { | ||
232 |
1/2✓ Branch 2 taken 426 times.
✗ Branch 3 not taken.
|
426 | Circuit c(1); | |
233 |
8/16✓ Branch 3 taken 426 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 426 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 426 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 426 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 426 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 426 times.
✗ Branch 20 not taken.
✓ Branch 23 taken 1278 times.
✓ Branch 24 taken 426 times.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
|
1704 | c.add_op<unsigned>(OpType::TK1, {alpha, beta, gamma}, {0}); | |
234 | 426 | return c; | ||
235 | 145 | }; | ||
236 |
3/6✓ Branch 1 taken 145 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 145 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 145 times.
✗ Branch 9 not taken.
|
290 | return rebase_factory({OpType::CX, OpType::TK1}, CircPool::CX(), tk1_to_tk1); | |
237 | 145 | } | ||
238 | ||||
239 | ✗ | Transform rebase_cirq() { | ||
240 | return rebase_factory( | |||
241 | {OpType::CZ, OpType::PhasedX, OpType::Rz}, CircPool::H_CZ_H(), | |||
242 | ✗ | CircPool::tk1_to_PhasedXRz); | ||
243 | } | |||
244 | ||||
245 | ✗ | Transform rebase_quil() { | ||
246 | return rebase_factory( | |||
247 | {OpType::CZ, OpType::Rx, OpType::Rz}, CircPool::H_CZ_H(), | |||
248 | ✗ | CircPool::tk1_to_rzrx); | ||
249 | } | |||
250 | ||||
251 | 1 | Transform rebase_pyzx() { | ||
252 | OpTypeSet pyzx_gates = {OpType::SWAP, OpType::CX, OpType::CZ, OpType::H, | |||
253 | OpType::X, OpType::Z, OpType::S, OpType::T, | |||
254 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | OpType::Rx, OpType::Rz}; | |
255 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
2 | return rebase_factory(pyzx_gates, CircPool::CX(), CircPool::tk1_to_rzrx); | |
256 | 1 | } | ||
257 | ||||
258 | 1 | Transform rebase_projectq() { | ||
259 | OpTypeSet projectq_gates = {OpType::SWAP, OpType::CRz, OpType::CX, OpType::CZ, | |||
260 | OpType::H, OpType::X, OpType::Y, OpType::Z, | |||
261 | OpType::S, OpType::T, OpType::V, OpType::Rx, | |||
262 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | OpType::Ry, OpType::Rz}; | |
263 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
2 | return rebase_factory(projectq_gates, CircPool::CX(), CircPool::tk1_to_rzrx); | |
264 | 1 | } | ||
265 | ||||
266 | 29 | Transform rebase_UFR() { | ||
267 | return rebase_factory( | |||
268 | {OpType::CX, OpType::Rz, OpType::H}, CircPool::CX(), | |||
269 |
3/6✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 29 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 29 times.
✗ Branch 10 not taken.
|
29 | CircPool::tk1_to_rzh); | |
270 | } | |||
271 | ||||
272 | 15 | Transform rebase_OQC() { | ||
273 | return rebase_factory( | |||
274 | {OpType::ECR, OpType::Rz, OpType::SX}, CircPool::CX_using_ECR(), | |||
275 |
3/6✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 15 times.
✗ Branch 10 not taken.
|
15 | CircPool::tk1_to_rzsx); | |
276 | } | |||
277 | ||||
278 | // Multiqs: ZZMax | |||
279 | // Singleqs: Rz, PhasedX | |||
280 | 12 | Transform rebase_HQS() { | ||
281 | return rebase_factory( | |||
282 | {OpType::ZZMax, OpType::Rz, OpType::PhasedX}, CircPool::CX_using_ZZMax(), | |||
283 |
3/6✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 12 times.
✗ Branch 10 not taken.
|
12 | CircPool::tk1_to_PhasedXRz); | |
284 | } | |||
285 | ||||
286 | // Multiqs: TK2 | |||
287 | // Singleqs: TK1 | |||
288 | 15 | Transform rebase_TK() { | ||
289 | return rebase_factory( | |||
290 | {OpType::TK2, OpType::TK1}, CircPool::CX_using_TK2(), | |||
291 |
3/6✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 15 times.
✗ Branch 10 not taken.
|
15 | CircPool::tk1_to_tk1); | |
292 | } | |||
293 | ||||
294 | // Multiqs: XXPhase | |||
295 | // Singleqs: Rz, PhasedX | |||
296 | 5 | Transform rebase_UMD() { | ||
297 | return rebase_factory( | |||
298 | {OpType::XXPhase, OpType::Rz, OpType::PhasedX}, | |||
299 |
3/6✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 5 times.
✗ Branch 10 not taken.
|
5 | CircPool::CX_using_XXPhase_0(), CircPool::tk1_to_PhasedXRz); | |
300 | } | |||
301 | ||||
302 | } // namespace Transforms | |||
303 | ||||
304 | } // namespace tket | |||
305 |