GCC Code Coverage Report


Directory: ./
File: Transformations/RzPhasedXSquash.cpp
Date: 2022-10-15 05:10:18
Warnings: 1 unchecked decisions!
Exec Total Coverage
Lines: 43 44 97.7%
Functions: 4 4 100.0%
Branches: 85 158 53.8%
Decisions: 17 20 85.0%

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 "RzPhasedXSquash.hpp"
16
17 #include <memory>
18
19 #include "BasicOptimisation.hpp"
20 #include "Decomposition.hpp"
21 #include "PQPSquash.hpp"
22 #include "Transform.hpp"
23 #include "Utils/Expression.hpp"
24
25 namespace tket {
26
27 namespace Transforms {
28
29 11 RzPhasedXSquasher::RzPhasedXSquasher(bool reversed)
30 11 : PQPSquasher(OpType::Rz, OpType::Rx, false, reversed) {}
31
32 61 std::pair<Circuit, Gate_ptr> RzPhasedXSquasher::flush(
33 std::optional<Pauli> commutation_colour) const {
34 // For Quantinuum gate set, commutation_colour can only be Z or nullopt (e.g.
35 // Measure)
36
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 std::pair<Circuit, Gate_ptr> pair = PQPSquasher::flush(commutation_colour);
37
38 // Setting smart_squash to false should guarantee that only Rzs can commute
39 // through.
40 TKET_ASSERT(pair.second == nullptr || pair.second->get_type() == OpType::Rz);
41
1/2
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
61 Circuit replacement(1);
42
2/4
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 61 times.
✗ Branch 5 not taken.
61 replacement.add_phase(pair.first.get_phase());
43
44 // 1. Recover the angles of RzRxRz and the leftover Rz from PQPSquasher
45
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 std::vector<Command> coms = pair.first.get_commands();
46 // pqp
47
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 Expr rz1_angle = 0;
48
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 Expr rx_angle = 0;
49
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 Expr rz2_angle = 0;
50 // left over Rz
51
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 Expr rz3_angle = 0;
52
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 5 times.
2/2
✓ Decision 'true' taken 56 times.
✓ Decision 'false' taken 5 times.
61 if (coms.size() > 0) {
53
2/2
✓ Branch 5 taken 41 times.
✓ Branch 6 taken 15 times.
2/2
✓ Decision 'true' taken 41 times.
✓ Decision 'false' taken 15 times.
56 if (coms[0].get_op_ptr()->get_type() == OpType::Rz) {
54
2/4
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 41 times.
✗ Branch 9 not taken.
41 rz1_angle = coms[0].get_op_ptr()->get_params()[0];
55 } else {
56
2/4
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 15 times.
✗ Branch 9 not taken.
15 rx_angle = coms[0].get_op_ptr()->get_params()[0];
57 }
58 }
59
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 47 times.
2/2
✓ Decision 'true' taken 14 times.
✓ Decision 'false' taken 47 times.
61 if (coms.size() > 1) {
60
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 12 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 12 times.
14 if (coms[1].get_op_ptr()->get_type() == OpType::Rz) {
61
2/4
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
2 rz2_angle = coms[1].get_op_ptr()->get_params()[0];
62 } else {
63
2/4
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
12 rx_angle = coms[1].get_op_ptr()->get_params()[0];
64 }
65 }
66
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 51 times.
2/2
✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 51 times.
61 if (coms.size() > 2) {
67
2/4
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 10 times.
✗ Branch 9 not taken.
10 rz2_angle = coms[2].get_op_ptr()->get_params()[0];
68 }
69
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 61 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 61 times.
61 if (pair.second != nullptr) {
70 rz3_angle = pair.second->get_params()[0];
71 }
72
73 // 2. Rebase (Rz Rx Rz | Rz) into (PhasedX Rz | Rz)
74
5/6
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 24 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 37 times.
✓ Branch 6 taken 24 times.
✓ Branch 7 taken 37 times.
2/2
✓ Decision 'true' taken 24 times.
✓ Decision 'false' taken 37 times.
61 if (commutation_colour == Pauli::Z || commutation_colour == Pauli::I) {
75
3/4
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 17 times.
2/2
✓ Decision 'true' taken 21 times.
✓ Decision 'false' taken 3 times.
24 if (!equiv_0(rx_angle, 4)) {
76
7/14
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 17 not taken.
✓ Branch 20 taken 14 times.
✓ Branch 21 taken 7 times.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
21 replacement.add_op<unsigned>(
77 OpType::PhasedX, {rx_angle, -rz1_angle}, {0});
78 }
79
2/4
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
24 rz3_angle += rz1_angle + rz2_angle;
80 } else {
81
3/4
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 17 times.
0/1
? Decision couldn't be analyzed.
37 if (!equiv_0(rx_angle, 4)) {
82
7/14
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 20 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 20 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 20 times.
✗ Branch 17 not taken.
✓ Branch 20 taken 40 times.
✓ Branch 21 taken 20 times.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
60 replacement.add_op<unsigned>(
83 OpType::PhasedX, {rx_angle, -rz1_angle}, {0});
84 }
85
4/6
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 22 times.
✓ Branch 8 taken 15 times.
2/2
✓ Decision 'true' taken 22 times.
✓ Decision 'false' taken 15 times.
37 if (!equiv_0(rz1_angle + rz2_angle, 4)) {
86
3/6
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 22 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 22 times.
✗ Branch 10 not taken.
22 replacement.add_op<unsigned>(OpType::Rz, {rz1_angle + rz2_angle}, {0});
87 }
88 }
89 Gate_ptr rz3_gate =
90
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 equiv_0(rz3_angle, 4)
91
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 20 times.
122 ? nullptr
92
9/18
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 20 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 20 times.
✓ Branch 12 taken 41 times.
✓ Branch 13 taken 20 times.
✓ Branch 14 taken 41 times.
✓ Branch 15 taken 20 times.
✓ Branch 16 taken 41 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
202 : std::make_shared<Gate>(OpType::Rz, std::vector<Expr>{rz3_angle}, 1);
93
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
122 return {replacement, rz3_gate};
94 61 }
95
96 7 Transform squash_1qb_to_Rz_PhasedX() {
97 9 return Transform([](Circuit &circ) {
98 9 bool reverse = false;
99
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
9 bool success = decompose_ZX().apply(circ);
100
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 auto squasher = std::make_unique<RzPhasedXSquasher>(reverse);
101
3/12
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 9 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
18 return SingleQubitSquash(std::move(squasher), circ, reverse).squash() ||
102
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
18 success;
103
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
16 });
104 }
105
106 } // namespace Transforms
107
108 } // namespace tket
109