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 "ArchitectureMapping.hpp" | |||
16 | ||||
17 | #include <sstream> | |||
18 | #include <stdexcept> | |||
19 | #include <tkassert/Assert.hpp> | |||
20 | ||||
21 | namespace tket { | |||
22 | ||||
23 | 21 | ArchitectureMapping::ArchitectureMapping(const Architecture& arch) | ||
24 | 21 | : m_arch(arch) { | ||
25 |
1/2✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
|
21 | const auto uids = arch.nodes(); | |
26 |
1/2✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
|
21 | m_vertex_to_node_mapping.reserve(uids.size()); | |
27 |
2/2✓ Branch 4 taken 177 times.
✓ Branch 5 taken 21 times.
|
2/2✓ Decision 'true' taken 177 times.
✓ Decision 'false' taken 21 times.
|
198 | for (const UnitID& uid : uids) { |
28 |
2/4✓ Branch 1 taken 177 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 177 times.
✗ Branch 5 not taken.
|
177 | m_vertex_to_node_mapping.emplace_back(Node(uid)); | |
29 | } | |||
30 | ||||
31 |
2/2✓ Branch 1 taken 177 times.
✓ Branch 2 taken 21 times.
|
2/2✓ Decision 'true' taken 177 times.
✓ Decision 'false' taken 21 times.
|
198 | for (size_t ii = 0; ii < m_vertex_to_node_mapping.size(); ++ii) { |
32 | 177 | const auto& node = m_vertex_to_node_mapping[ii]; | ||
33 | { | |||
34 |
1/2✓ Branch 1 taken 177 times.
✗ Branch 2 not taken.
|
177 | const auto citer = m_node_to_vertex_mapping.find(node); | |
35 | // GCOVR_EXCL_START | |||
36 | TKET_ASSERT( | |||
37 | citer == m_node_to_vertex_mapping.cend() || | |||
38 | AssertMessage() << "Duplicate node " << node.repr() << " at vertices " | |||
39 | << citer->second << ", " << ii); | |||
40 | // GCOVR_EXCL_STOP | |||
41 | } | |||
42 |
1/2✓ Branch 1 taken 177 times.
✗ Branch 2 not taken.
|
177 | m_node_to_vertex_mapping[node] = ii; | |
43 | } | |||
44 | 21 | } | ||
45 | ||||
46 | 2478 | ArchitectureMapping::ArchitectureMapping( | ||
47 | const Architecture& arch, | |||
48 | 2478 | const std::vector<std::pair<unsigned, unsigned>>& edges) | ||
49 | 2478 | : m_arch(arch) { | ||
50 | 2478 | auto& node_to_vertex_mapping = m_node_to_vertex_mapping; | ||
51 | 2478 | auto& vertex_to_node_mapping = m_vertex_to_node_mapping; | ||
52 | ||||
53 | 139516 | const auto add_node = [&node_to_vertex_mapping, | ||
54 | 296131 | &vertex_to_node_mapping](unsigned nn) { | ||
55 |
1/2✓ Branch 1 taken 139516 times.
✗ Branch 2 not taken.
|
139516 | const Node node(nn); | |
56 |
3/4✓ Branch 1 taken 139516 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 52205 times.
✓ Branch 4 taken 87311 times.
|
2/2✓ Decision 'true' taken 52205 times.
✓ Decision 'false' taken 87311 times.
|
139516 | if (node_to_vertex_mapping.count(node) == 0) { |
57 |
1/2✓ Branch 2 taken 52205 times.
✗ Branch 3 not taken.
|
52205 | node_to_vertex_mapping[node] = vertex_to_node_mapping.size(); | |
58 |
1/2✓ Branch 1 taken 52205 times.
✗ Branch 2 not taken.
|
52205 | vertex_to_node_mapping.push_back(node); | |
59 | } | |||
60 | 139516 | }; | ||
61 | ||||
62 | // The nodes are labelled 0,1,2,... in order of appearance. | |||
63 | // Nothing special about this ordering, just for backwards compatibility. | |||
64 |
2/2✓ Branch 5 taken 69758 times.
✓ Branch 6 taken 2478 times.
|
2/2✓ Decision 'true' taken 69758 times.
✓ Decision 'false' taken 2478 times.
|
72236 | for (const auto& entry : edges) { |
65 |
1/2✓ Branch 1 taken 69758 times.
✗ Branch 2 not taken.
|
69758 | add_node(entry.first); | |
66 |
1/2✓ Branch 1 taken 69758 times.
✗ Branch 2 not taken.
|
69758 | add_node(entry.second); | |
67 | } | |||
68 | ||||
69 | // Check that the nodes agree with the architecture object. | |||
70 |
1/2✓ Branch 2 taken 2478 times.
✗ Branch 3 not taken.
|
2478 | const auto uids = arch.nodes(); | |
71 | // GCOVR_EXCL_START | |||
72 | TKET_ASSERT( | |||
73 | uids.size() == m_vertex_to_node_mapping.size() || | |||
74 | AssertMessage() << "passed in " << edges.size() << " edges, giving " | |||
75 | << m_vertex_to_node_mapping.size() | |||
76 | << " vertices; but the architecture object has " | |||
77 | << uids.size() << " vertices"); | |||
78 | // GCOVR_EXCL_STOP | |||
79 | ||||
80 |
2/2✓ Branch 5 taken 52205 times.
✓ Branch 6 taken 2478 times.
|
2/2✓ Decision 'true' taken 52205 times.
✓ Decision 'false' taken 2478 times.
|
54683 | for (const UnitID& uid : uids) { |
81 |
1/2✓ Branch 1 taken 52205 times.
✗ Branch 2 not taken.
|
52205 | const Node node(uid); | |
82 | // GCOVR_EXCL_START | |||
83 | TKET_ASSERT( | |||
84 | m_node_to_vertex_mapping.count(node) != 0 || | |||
85 | AssertMessage() | |||
86 | << "passed in " << edges.size() << " edges, giving " | |||
87 | << m_vertex_to_node_mapping.size() | |||
88 | << " vertices; but the architecture object has an unknown node " | |||
89 | << node.repr()); | |||
90 | // GCOVR_EXCL_STOP | |||
91 | 52205 | } | ||
92 | 2478 | } | ||
93 | ||||
94 | 2199626 | size_t ArchitectureMapping::number_of_vertices() const { | ||
95 | 2199626 | return m_vertex_to_node_mapping.size(); | ||
96 | } | |||
97 | ||||
98 | 756795 | const Node& ArchitectureMapping::get_node(size_t vertex) const { | ||
99 |
1/2✓ Branch 1 taken 756795 times.
✗ Branch 2 not taken.
|
756795 | const auto num_vertices = number_of_vertices(); | |
100 | // GCOVR_EXCL_START | |||
101 | TKET_ASSERT( | |||
102 | vertex < num_vertices || AssertMessage() << "invalid vertex " << vertex | |||
103 | << " (architecture only has " | |||
104 | << num_vertices << " vertices)"); | |||
105 | // GCOVR_EXCL_STOP | |||
106 | ||||
107 | 1513590 | return m_vertex_to_node_mapping[vertex]; | ||
108 | } | |||
109 | ||||
110 | 140896 | size_t ArchitectureMapping::get_vertex(const Node& node) const { | ||
111 |
1/2✓ Branch 1 taken 140896 times.
✗ Branch 2 not taken.
|
140896 | const auto citer = m_node_to_vertex_mapping.find(node); | |
112 | // GCOVR_EXCL_START | |||
113 | TKET_ASSERT( | |||
114 | citer != m_node_to_vertex_mapping.cend() || | |||
115 | AssertMessage() << "node " << node.repr() << " has no vertex number"); | |||
116 | // GCOVR_EXCL_STOP | |||
117 | 140896 | return citer->second; | ||
118 | } | |||
119 | ||||
120 | 404361 | const Architecture& ArchitectureMapping::get_architecture() const { | ||
121 | 404361 | return m_arch; | ||
122 | } | |||
123 | ||||
124 | 7 | std::vector<Swap> ArchitectureMapping::get_edges() const { | ||
125 | 7 | std::vector<Swap> edges; | ||
126 |
3/4✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 11 taken 51 times.
✓ Branch 12 taken 7 times.
|
0/1? Decision couldn't be analyzed.
|
58 | for (auto [node1, node2] : m_arch.get_all_edges_vec()) { |
127 |
4/8✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 51 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 51 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 51 times.
✗ Branch 11 not taken.
|
51 | edges.emplace_back(get_swap(get_vertex(node1), get_vertex(node2))); | |
128 | 58 | } | ||
129 | 7 | return edges; | ||
130 | } | |||
131 | ||||
132 | } // namespace tket | |||
133 |