GCC Code Coverage Report


Directory: ./
File: ArchAwareSynth/include/ArchAwareSynth/SteinerTree.hpp
Date: 2022-10-15 05:10:18
Exec Total Coverage
Lines: 0 4 0.0%
Functions: 0 2 0.0%
Branches: 0 0 -%
Decisions: 0 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 #pragma once
16 #include "Converters/Gauss.hpp"
17 #include "Path.hpp"
18
19 namespace tket {
20 namespace aas {
21
22 typedef std::pair<unsigned, unsigned> Operation;
23 typedef std::list<Operation> OperationList;
24
25 enum class CNotSynthType { SWAP, HamPath, Rec };
26
27 /**
28 * Nodes in a Steiner tree may correspond to different values in the biadjacency
29 * action matrix or phase polynomial
30 */
31 enum class SteinerNodeType {
32 // "in tree" := not a leaf & not disconnected from tree
33 ZeroInTree,
34 OneInTree,
35 // all leaves are 1s by definition
36 Leaf,
37 OutOfTree
38 };
39
40 class InvalidCostCalculation : public std::logic_error {
41 public:
42 explicit InvalidCostCalculation(const std::string &message)
43 : std::logic_error(message) {}
44 };
45
46 class InvalidRowOperation : public std::logic_error {
47 public:
48 explicit InvalidRowOperation(const std::string &message)
49 : std::logic_error(message) {}
50 };
51
52 /**
53 * This clas is creating a steiner tree, which is a mst including all the nodes
54 * of a given phase gadget plus all the nodes which are neede to connect all the
55 * nodes of the gadget. This class also offers the function to reduce this tree
56 * by extracting operations steps by step. This class is designed with
57 * architecture aware synthesis in mind; it may not be suitable for other
58 * generic purposes.
59 */
60 class SteinerTree {
61 public:
62 SteinerTree() {}
63 /**
64 * Construct a Steinertree from given parameters
65 * @param pathhandler giving the included edges
66 * @param nodes_to_add list by ref, will be changed during the construction of
67 * the tree
68 * @param root_node initial node, deleted in the last step
69 */
70 explicit SteinerTree(
71 const PathHandler &pathhandler, std::list<unsigned> &nodes_to_add,
72 unsigned root_node); // N.B. non-const list by ref!
73
74 /**
75 * calculate cost of performing a CNOT between two neighbouring nodes,
76 * dependent on the SteinerNodeTypes.
77 * @param i control index of operation
78 * @param j target index of operation
79 */
80 int cost_of_operation(unsigned i, unsigned j) const;
81
82 /**
83 * initialises the tree
84 * @param pathhandler connectivity for the construction
85 * @param nodes_to_add list of nodes which should be added, the list will be
86 * changes during the process
87 *
88 */
89 void init_tree(
90 const PathHandler &pathhandler, std::list<unsigned> &nodes_to_add);
91
92 /**
93 * adds the closesd nodes to a given list to the tree
94 * @param pathhandler connectivity for the construction
95 * @param nodes_to_add list of nodes which should be added, the list will be
96 */
97 void add_closest_node_to_tree(
98 const PathHandler &pathhandler, std::list<unsigned> &nodes_to_add);
99
100 /**
101 * adds a list of nodes to a given list to the tree
102 * @param pathhandler connectivity for the construction
103 * @param node_in_tree node in tree which is closest to the node to add
104 * @param node_to_add node which should be added
105 */
106 void add_path_to_tree(
107 const PathHandler &pathhandler, unsigned node_in_tree,
108 unsigned node_to_add);
109
110 /**
111 * calculates the available operation in this tree which could be executed
112 * @param pathhandler conections used for the calculation
113 * @return gives the list of all avilable operations
114 */
115 OperationList operations_available(const PathHandler &pathhandler) const;
116
117 /**
118 * Implements a CNOT from node j to node i, updates costs and tree
119 * @param i control index
120 * @param j target index
121 */
122 void add_row(unsigned i, unsigned j);
123
124 /**
125 * checks is the tree is fully reduced
126 * @return true if fully reduced
127 */
128 bool fully_reduced() const;
129
130 /**
131 * gives the cost of the tree
132 * @return cost of the tree
133 */
134 unsigned calculate_cost() const;
135
136 /**
137 * returns the nodes of the tree which has the highest index. only the out of
138 * tree nodes are not taken into consideration
139 * @return index of maximum node
140 */
141 unsigned get_max_element() const;
142
143 /**
144 * gives all nodes of the tree which are leaf, one in or zero in
145 * @return ordered list of all nodes
146 */
147 std::vector<unsigned> nodes() const;
148
149 unsigned tree_cost; // the cost to reduce the Steiner tree alone
150 int last_operation_cost;
151 unsigned root;
152 std::vector<SteinerNodeType> node_types;
153 std::vector<unsigned> num_neighbours;
154 std::list<unsigned> tree_nodes;
155 };
156
157 /**
158 * object to store and perform the swap nased cnot synthesis
159 */
160 class CNotSwapSynth {
161 public:
162 CNotSwapSynth() {}
163 /**
164 * construct the object for the cnot swap synth and perform the reduction
165 * @param pathhandler path for reduction
166 * @param CNOT_mat input of executed cnots which should be reduced
167 */
168 explicit CNotSwapSynth(
169 const PathHandler &pathhandler, const DiagMatrix &CNOT_mat);
170
171 /**
172 * gives the calculated circuit
173 */
174 Circuit get_circuit();
175
176 /**
177 * checks if the matrix is id after reduction
178 * @return true if matrix is id
179 */
180 bool valid_result();
181
182 private:
183 void add_swap(unsigned first, unsigned second);
184 void cleanup_swaps();
185 unsigned swap_to_root(unsigned start_node, unsigned current_row);
186
187 PathHandler paths;
188 DiagMatrix CNOT_matrix;
189 Circuit circ;
190 std::stack<std::pair<unsigned, unsigned>> swaps;
191 };
192
193 /**
194 * This method uses Kissinger & de Meijer's Steiner-Gauss
195 * (https://arxiv.org/abs/1904.00633), and reduces the CNOT_matrix, which is
196 * non-const. This function offers the recursive algorithm and the Hamilton
197 * based algorithm
198 * @param CNOT_matrix input of executed cnots which should be reduced
199 * @param paths pathhandler used for the reduction
200 * @param cnottype type of algorithm which could be CNotSynthType::Rec or
201 * CNotSynthType::HamPath
202 * @return routed circuit
203 */
204 Circuit aas_CNOT_synth(
205 DiagMatrix &CNOT_matrix, const PathHandler &paths,
206 CNotSynthType cnottype = CNotSynthType::Rec);
207
208 /**
209 * this method offers the swap bases cnot synth
210 * @param CNOT_matrix input of executed cnots which should be reduced
211 * @param paths pathhandler used for the reduction
212 * @return routed circuit
213 */
214 Circuit aas_CNOT_synth_SWAP(DiagMatrix &CNOT_matrix, const PathHandler &paths);
215
216 } // namespace aas
217 } // namespace tket
218