GCC Code Coverage Report


Directory: ./
File: MeasurementSetup/MeasurementSetup.cpp
Date: 2022-10-15 05:10:18
Warnings: 5 unchecked decisions!
Exec Total Coverage
Lines: 71 98 72.4%
Functions: 9 11 81.8%
Branches: 90 204 44.1%
Decisions: 10 28 35.7%

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 "MeasurementSetup.hpp"
16
17 #include "Converters/Converters.hpp"
18
19 namespace tket {
20
21 std::string MeasurementSetup::MeasurementBitMap::to_str() const {
22 std::stringstream ss;
23 ss << "Circuit index: ";
24 ss << circ_index;
25 ss << "\nBits: ";
26
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
for (unsigned i : bits) {
27 ss << i;
28 ss << " ";
29 }
30 ss << "\nInvert: ";
31
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
if (invert)
32 ss << "True";
33 else
34 ss << "False";
35 return ss.str();
36 }
37
38 46 void MeasurementSetup::add_measurement_circuit(const Circuit &circ) {
39 46 measurement_circs.push_back(circ);
40 46 }
41
42 177 void MeasurementSetup::add_result_for_term(
43 const QubitPauliString &term, const MeasurementBitMap &result) {
44 177 result_map[term].push_back(result);
45 177 }
46
47 113 void MeasurementSetup::add_result_for_term(
48 const QubitPauliTensor &term, const MeasurementBitMap &result) {
49 113 add_result_for_term(term.string, result);
50 113 }
51
52 15 bool MeasurementSetup::verify() const {
53 15 std::map<std::pair<unsigned, unsigned>, QubitPauliTensor> pauli_map;
54 // Identify Paulis measured onto each bit
55
2/2
✓ Branch 1 taken 42 times.
✓ Branch 2 taken 15 times.
2/2
✓ Decision 'true' taken 42 times.
✓ Decision 'false' taken 15 times.
57 for (unsigned circ_id = 0; circ_id < measurement_circs.size(); ++circ_id) {
56
1/2
✓ Branch 2 taken 42 times.
✗ Branch 3 not taken.
42 Circuit circ = measurement_circs[circ_id];
57
1/2
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
42 std::map<Qubit, unsigned> readout = circ.qubit_readout();
58 // Remove Measures from circuit to allow CliffordTableau generation
59
3/4
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 153 times.
✓ Branch 9 taken 42 times.
0/1
? Decision couldn't be analyzed.
195 for (const Vertex &out : circ.q_outputs()) {
60
1/2
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
153 Vertex pred = circ.get_predecessors(out).front();
61
2/4
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 153 times.
✗ Branch 4 not taken.
1/2
✓ Decision 'true' taken 153 times.
✗ Decision 'false' not taken.
153 if (circ.get_OpType_from_Vertex(pred) == OpType::Measure) {
62
1/2
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
153 circ.remove_vertex(
63 pred, Circuit::GraphRewiring::Yes, Circuit::VertexDeletion::Yes);
64 }
65 42 }
66
1/2
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
42 CliffTableau tab = circuit_to_tableau(circ);
67
3/4
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 153 times.
✓ Branch 8 taken 42 times.
0/1
? Decision couldn't be analyzed.
195 for (const Qubit &qb : tab.get_qubits()) {
68
3/6
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 153 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 153 times.
✗ Branch 10 not taken.
153 pauli_map.insert({{circ_id, readout[qb]}, tab.get_zpauli(qb)});
69 42 }
70 42 }
71 15 for (const std::pair<const QubitPauliString, std::vector<MeasurementBitMap>>
72
2/2
✓ Branch 5 taken 156 times.
✓ Branch 6 taken 12 times.
183 &term : result_map) {
73
2/2
✓ Branch 5 taken 163 times.
✓ Branch 6 taken 153 times.
2/2
✓ Decision 'true' taken 163 times.
✓ Decision 'false' taken 153 times.
316 for (const MeasurementBitMap &bits : term.second) {
74 163 QubitPauliTensor total;
75
2/2
✓ Branch 4 taken 367 times.
✓ Branch 5 taken 163 times.
2/2
✓ Decision 'true' taken 367 times.
✓ Decision 'false' taken 163 times.
530 for (unsigned bit : bits.bits) {
76
2/4
✓ Branch 2 taken 367 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 367 times.
✗ Branch 6 not taken.
367 total = total * pauli_map[{bits.circ_index, bit}];
77 }
78
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 134 times.
1/2
✓ Decision 'true' taken 163 times.
✗ Decision 'false' not taken.
163 if (bits.invert) total.coeff *= -1.;
79
1/2
✓ Branch 1 taken 163 times.
✗ Branch 2 not taken.
163 QubitPauliTensor term_tensor(term.first);
80
3/4
✓ Branch 1 taken 163 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 160 times.
2/2
✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 160 times.
163 if (total != term_tensor) {
81
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 std::stringstream out;
82 out << "Invalid MeasurementSetup: expecting to measure "
83
6/12
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3 times.
✗ Branch 17 not taken.
3 << term_tensor.to_str() << "; actually measured " << total.to_str();
84
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
3 tket_log()->error(out.str());
85 3 return false;
86 3 }
87
4/4
✓ Branch 1 taken 160 times.
✓ Branch 2 taken 3 times.
✓ Branch 4 taken 160 times.
✓ Branch 5 taken 3 times.
166 }
88 }
89 12 return true;
90 15 }
91
92 std::string MeasurementSetup::to_str() const {
93 std::stringstream ss;
94 ss << "Circuits: ";
95 ss << measurement_circs.size();
96 ss << "\n";
97 for (const std::pair<const QubitPauliString, std::vector<MeasurementBitMap>>
98 &tensor_map : result_map) {
99 ss << "|| ";
100 ss << tensor_map.first.to_str();
101 ss << " ||\n";
102
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
for (const MeasurementBitMap &mbm : tensor_map.second) {
103 ss << mbm.to_str();
104 ss << "\n";
105 }
106 }
107 return ss.str();
108 }
109
110 18 void to_json(
111 nlohmann::json &j, const MeasurementSetup::MeasurementBitMap &result) {
112
1/2
✓ Branch 3 taken 18 times.
✗ Branch 4 not taken.
18 j["circ_index"] = result.get_circ_index();
113
1/2
✓ Branch 3 taken 18 times.
✗ Branch 4 not taken.
18 j["bits"] = result.get_bits();
114
1/2
✓ Branch 3 taken 18 times.
✗ Branch 4 not taken.
18 j["invert"] = result.get_invert();
115 18 }
116
117 9 void from_json(
118 const nlohmann::json &j, MeasurementSetup::MeasurementBitMap &result) {
119
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
18 result = MeasurementSetup::MeasurementBitMap(
120
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
9 j.at("circ_index").get<unsigned>(),
121 27 j.at("bits").get<std::vector<unsigned>>(), j.at("invert").get<bool>());
122 9 }
123
124 4 void to_json(nlohmann::json &j, const MeasurementSetup &setup) {
125 std::vector<std::pair<
126 QubitPauliString, std::vector<MeasurementSetup::MeasurementBitMap>>>
127 4 map_list;
128 4 for (const std::pair<
129 const QubitPauliString,
130 std::vector<MeasurementSetup::MeasurementBitMap>> &tensor_map :
131
2/2
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 4 times.
20 setup.get_result_map()) {
132
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 map_list.push_back(tensor_map);
133 }
134 // sort the list for consistent serialisation
135
1/2
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
4 std::sort(map_list.begin(), map_list.end(), [](auto pair1, auto pair2) {
136 13 return pair1.first < pair2.first;
137 });
138
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 j["result_map"] = map_list;
139
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 j["circs"] = setup.get_circs();
140 4 }
141
142 2 void from_json(const nlohmann::json &j, MeasurementSetup &setup) {
143
5/8
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✓ Branch 12 taken 2 times.
0/1
? Decision couldn't be analyzed.
4 for (auto it = j["circs"].begin(); it != j["circs"].end(); ++it) {
144
4/8
✓ 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.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
2 setup.add_measurement_circuit(it->get<Circuit>());
145 }
146
6/10
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 8 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 6 times.
✓ Branch 15 taken 2 times.
0/1
? Decision couldn't be analyzed.
8 for (auto it = j["result_map"].begin(); it != j["result_map"].end(); ++it) {
147
7/12
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 13 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 7 times.
✓ Branch 18 taken 6 times.
0/1
? Decision couldn't be analyzed.
13 for (auto second_it = it->at(1).begin(); second_it != it->at(1).end();
148 7 ++second_it) {
149
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 setup.add_result_for_term(
150
3/6
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
14 it->at(0).get<QubitPauliString>(),
151
3/6
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 7 times.
✗ Branch 9 not taken.
14 second_it->get<MeasurementSetup::MeasurementBitMap>());
152 }
153 }
154 2 }
155
156 } // namespace tket
157