GCC Code Coverage Report


Directory: ./
File: Characterisation/include/Characterisation/Cycles.hpp
Date: 2022-10-15 05:10:18
Exec Total Coverage
Lines: 3 5 60.0%
Functions: 2 3 66.7%
Branches: 0 2 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
17 #include "Circuit/Circuit.hpp"
18
19 namespace tket {
20
21 typedef std::pair<Edge, Edge> edge_pair_t;
22
23 // CycleCom stores minimum command information required for FrameRandomisation
24 struct CycleCom {
25 OpType type;
26 std::vector<unsigned> indices;
27 Vertex address;
28
29 bool operator==(const CycleCom& other) const {
30 return this->type == other.type && this->indices == other.indices;
31 }
32 };
33
34 // Cycle stores minimum subcircuit information requried for FrameRandomisation
35 class Cycle {
36 public:
37 372 Cycle() {}
38 Cycle(
39 const std::vector<edge_pair_t>& _boundary_edges,
40 const std::vector<CycleCom>& _coms)
41 : boundary_edges_(_boundary_edges), coms_(_coms) {}
42
43 // Returns size of boundary_edges_
44 unsigned size() const;
45
46 // For edge_pair_t ep in boundary_edges_, if ep.first == source_edge,
47 // ep.second = replacement_edge
48 void update_boundary(const Edge& source_edge, const Edge& replacement_edge);
49
50 // Adds coms_ from new_cycle to end of this->coms_
51 // Extends this->boundary_edges_ with new_cycles.boundary_edges_
52 void merge(Cycle& new_cycle);
53
54 // if CycleCom.indices has unsigned equal to key in new_indices, change to
55 // value
56 void update_coms_indices(const std::map<unsigned, unsigned>& new_indices);
57
58 // Cycle has noop vertices wired into edges in _boundary_edges for purpose of
59 // Frame Randomisation This method these vertices in frame_vertices
60 void add_vertex_pair(const std::pair<Vertex, Vertex>& verts);
61
62 // Returns frame_vertices
63 std::vector<std::pair<Vertex, Vertex>> get_frame() const;
64
65 bool operator==(const Cycle& other) const {
66 return this->size() == other.size() && this->coms_ == other.coms_;
67 }
68
69 std::vector<edge_pair_t> boundary_edges_;
70 std::vector<CycleCom> coms_;
71
72 private:
73 std::vector<std::pair<Vertex, Vertex>> frame_vertices;
74 };
75
76 // CycleHistory stores information used to find minimal number of boundaries
77 struct CycleHistory {
78 // Every time a new cycle is made it's assigned a key of type unsigned
79 // The size of key is used to track the causal ordering of cycles
80 unsigned key;
81 // history.size() == key always
82 // Tracks which UnitID were in which Cycle
83 std::vector<std::vector<UnitID>> history;
84 // Map from UnitID to key, where key maps in key_to_cycle to "active" Cycle
85 std::map<UnitID, unsigned> uid_to_key;
86 // Map from key to cycle, where a key n refers to the nth cycle made
87 std::map<unsigned, Cycle> key_to_cycle;
88 };
89
90 class CycleFinder {
91 public:
92 19 CycleFinder(const Circuit& _circ, const OpTypeSet& _cycle_types)
93 19 : circ(_circ), cycle_types_(_cycle_types){};
94
95 // Cycles are sub-circuits of circ where every gate has OpType in cycle_types_
96 // get_cycles() returns the minimum number of cycles such that every
97 // cycle_types_ gate in circ is in one cycle
98 std::vector<Cycle> get_cycles();
99
100 private:
101 // Circuit cycles are found in
102 const Circuit& circ;
103 // OpType cycle gates have
104 const OpTypeSet cycle_types_;
105
106 // CycleFinder uses SliceIterator to find get circ gates in cycle_types_
107 // In Edges to a new slice are checked for equality with the last boundary out
108 // edge stored for their UnitID If equal a cycle may be extended, if not equal
109 std::map<Edge, UnitID> cycle_out_edges;
110
111 // Stores data structures for tracking created Cycles and associated UnitID's
112 CycleHistory bt;
113
114 // Given a new CutFrontier object, creates new cycles from interior vertices
115 // and merges them with previous cycles where possible
116 void extend_cycles(const CutFrontier& cut);
117
118 // Makes a new Cycle object from given dag information
119 // Return type used to identify whether cycle should be merged with previous
120 // cycles
121 std::pair<unsigned, std::set<unsigned>> make_cycle(
122 const Vertex& v, const EdgeVec& out_edges, const CutFrontier& cut);
123
124 // Uses CycleHistory to merge Cycle attributed to new_key with Cycles
125 // attributed to old_keys Cycles are merged in to Cycle with smallest key
126 void merge_cycles(unsigned new_key, std::set<unsigned>& old_keys);
127
128 // Updates cycle_out_edges with new Edge
129 // UnitID should not be new, so error thrown if not found
130 void update_cycle_out_edges(const UnitID& uid, const Edge& e);
131
132 // Getter for UnitID from unit_frontier_t in Cut
133 UnitID unitid_from_unit_frontier(
134 const std::shared_ptr<unit_frontier_t>& u_frontier, const Edge& e) const;
135
136 // if unsigned in erase_from is <= to_erase, removes from erase_from
137 void erase_keys(
138 const unsigned& to_erase, std::set<unsigned>& erase_from) const;
139
140 // removes unsigned from old_keys that have cycles that can't merge with
141 // new_key adds new_key to old_keys
142 void order_keys(unsigned& new_key, std::set<unsigned>& old_keys) const;
143 };
144 } // namespace tket
145