GCC Code Coverage Report


Directory: ./
File: Simulation/CircuitSimulator.cpp
Date: 2022-10-15 05:10:18
Exec Total Coverage
Lines: 35 44 79.5%
Functions: 4 4 100.0%
Branches: 48 108 44.4%
Decisions: 4 10 40.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 "CircuitSimulator.hpp"
16
17 #include <sstream>
18
19 #include "Circuit/Circuit.hpp"
20 #include "DecomposeCircuit.hpp"
21 #include "Gate/GateUnitaryMatrixError.hpp"
22 #include "GateNodesBuffer.hpp"
23 #include "Utils/Expression.hpp"
24
25 namespace tket {
26 namespace tket_sim {
27
28 5269 Eigen::MatrixXcd get_unitary(
29 const Circuit& circ, double abs_epsilon, unsigned max_number_of_qubits) {
30 5269 const auto matr_size = get_matrix_size(circ.n_qubits());
31
1/2
✓ Branch 2 taken 5269 times.
✗ Branch 3 not taken.
5269 Eigen::MatrixXcd result = Eigen::MatrixXcd::Identity(matr_size, matr_size);
32
2/2
✓ Branch 1 taken 5266 times.
✓ Branch 2 taken 3 times.
5269 apply_unitary(circ, result, abs_epsilon, max_number_of_qubits);
33 5266 return result;
34 3 }
35
36 5871 static void apply_unitary_may_throw(
37 const Circuit& circ, Eigen::MatrixXcd& matr, double abs_epsilon,
38 unsigned max_number_of_qubits) {
39
2/4
✓ Branch 1 taken 5871 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 5871 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 5871 times.
5871 if (circ.n_qubits() > max_number_of_qubits) {
40 throw GateUnitaryMatrixError(
41 "Circuit to simulate has too many qubits",
42 GateUnitaryMatrixError::Cause::TOO_MANY_QUBITS);
43 }
44
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5871 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 5871 times.
5871 if (matr.cols() <= 0) {
45 throw GateUnitaryMatrixError(
46 "M has no columns", GateUnitaryMatrixError::Cause::INPUT_ERROR);
47 }
48
2/4
✓ Branch 1 taken 5871 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5871 times.
✗ Branch 5 not taken.
5871 const auto full_matr_size = get_matrix_size(circ.n_qubits());
49
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5871 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 5871 times.
5871 if (matr.rows() != full_matr_size) {
50 throw GateUnitaryMatrixError(
51 "M has wrong number of rows",
52 GateUnitaryMatrixError::Cause::INPUT_ERROR);
53 }
54
1/2
✓ Branch 1 taken 5871 times.
✗ Branch 2 not taken.
5871 internal::GateNodesBuffer buffer(matr, abs_epsilon);
55
2/2
✓ Branch 1 taken 5868 times.
✓ Branch 2 taken 3 times.
5871 internal::decompose_circuit(circ, buffer, abs_epsilon);
56
2/4
✓ Branch 1 taken 5868 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5868 times.
✗ Branch 5 not taken.
5868 matr = apply_qubit_permutation(matr, circ.implicit_qubit_permutation());
57 5871 }
58
59 5871 void apply_unitary(
60 const Circuit& circ, Eigen::MatrixXcd& matr, double abs_epsilon,
61 unsigned max_number_of_qubits) {
62 try {
63
2/2
✓ Branch 1 taken 5868 times.
✓ Branch 2 taken 3 times.
5871 apply_unitary_may_throw(circ, matr, abs_epsilon, max_number_of_qubits);
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 } catch (const GateUnitaryMatrixError& e) {
65
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 const auto full_matr_size = get_matrix_size(circ.n_qubits());
66
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 std::stringstream ss;
67
3/6
✓ 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.
3 ss << "Error trying to simulate circuit " << circ << " with "
68
5/10
✓ 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 14 taken 3 times.
✗ Branch 15 not taken.
6 << circ.n_qubits() << " qubits, " << circ.get_commands().size()
69
4/8
✓ 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.
3 << " commands; U is size " << full_matr_size << "x" << full_matr_size
70
4/8
✓ 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.
✓ Branch 12 taken 3 times.
✗ Branch 13 not taken.
3 << ", premultiplying M with " << matr.rows() << " rows, " << matr.cols()
71
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
3 << " cols: " << e.what();
72
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 3 times.
✗ Decision 'false' not taken.
3 if (e.cause == GateUnitaryMatrixError::Cause::GATE_NOT_IMPLEMENTED) {
73
2/4
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
3 throw Unsupported(ss.str());
74
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
} else if (e.cause == GateUnitaryMatrixError::Cause::SYMBOLIC_PARAMETERS) {
75 throw SymbolsNotSupported(ss.str());
76 } else {
77 throw e;
78 }
79 6 }
80 5868 }
81
82 598 Eigen::VectorXcd get_statevector(
83 const Circuit& circ, double abs_epsilon, unsigned max_number_of_qubits) {
84 Eigen::MatrixXcd result =
85
4/8
✓ Branch 1 taken 598 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 598 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 598 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 598 times.
✗ Branch 11 not taken.
598 Eigen::MatrixXcd::Zero(get_matrix_size(circ.n_qubits()), 1);
86
1/2
✓ Branch 1 taken 598 times.
✗ Branch 2 not taken.
598 result(0, 0) = 1.0;
87
1/2
✓ Branch 1 taken 598 times.
✗ Branch 2 not taken.
598 apply_unitary(circ, result, abs_epsilon, max_number_of_qubits);
88
1/2
✓ Branch 1 taken 598 times.
✗ Branch 2 not taken.
1196 return result;
89 598 }
90
91 } // namespace tket_sim
92 } // namespace tket
93