From 0a26f59d303476aa0d8830394d69704d65be29ed Mon Sep 17 00:00:00 2001 From: Yao Tang Date: Fri, 28 Jan 2022 15:08:37 +0000 Subject: [PATCH 1/3] Add sequenced_bimap_t --- tket/src/Utils/SequencedContainers.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tket/src/Utils/SequencedContainers.hpp b/tket/src/Utils/SequencedContainers.hpp index 76edfd3de2..71a25595fd 100644 --- a/tket/src/Utils/SequencedContainers.hpp +++ b/tket/src/Utils/SequencedContainers.hpp @@ -23,7 +23,23 @@ namespace tket { struct TagKey {}; +struct TagValue {}; struct TagSeq {}; + +template +using sequenced_bimap_t = boost::multi_index::multi_index_container< + std::pair, + boost::multi_index::indexed_by< + boost::multi_index::ordered_unique< + boost::multi_index::tag, + boost::multi_index::member< + std::pair, A, &std::pair::first>>, + boost::multi_index::ordered_unique< + boost::multi_index::tag, + boost::multi_index::member< + std::pair, B, &std::pair::second>>, + boost::multi_index::sequenced>>>; + template using sequenced_map_t = boost::multi_index::multi_index_container< std::pair, From 6afec719e223afb092c6d2f2ae74f21f4cddcae9 Mon Sep 17 00:00:00 2001 From: Yao Tang Date: Fri, 28 Jan 2022 15:09:16 +0000 Subject: [PATCH 2/3] Use sequenced_bimap_t for unit_vertport_frontier_t --- tket/src/Mapping/MappingFrontier.cpp | 8 ++------ tket/src/Mapping/MappingFrontier.hpp | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/tket/src/Mapping/MappingFrontier.cpp b/tket/src/Mapping/MappingFrontier.cpp index 9b2650da1e..b38aefd7ac 100644 --- a/tket/src/Mapping/MappingFrontier.cpp +++ b/tket/src/Mapping/MappingFrontier.cpp @@ -10,12 +10,8 @@ namespace tket { UnitID get_unitid_from_unit_frontier( const std::shared_ptr& u_frontier, const VertPort& vp) { - for (auto it = u_frontier->get().begin(); - it != u_frontier->get().end(); ++it) { - if (it->second == vp) { - return it->first; - } - } + auto it = u_frontier->get().find(vp); + if (it != u_frontier->get().end()) return it->first; throw MappingFrontierError( std::string("Edge provided not in unit_frontier_t object.")); } diff --git a/tket/src/Mapping/MappingFrontier.hpp b/tket/src/Mapping/MappingFrontier.hpp index afc4128e58..02c404869b 100644 --- a/tket/src/Mapping/MappingFrontier.hpp +++ b/tket/src/Mapping/MappingFrontier.hpp @@ -8,7 +8,7 @@ namespace tket { -typedef sequenced_map_t unit_vertport_frontier_t; +typedef sequenced_bimap_t unit_vertport_frontier_t; // list of error types to throw out class MappingFrontierError : public std::logic_error { From e4ac5149bb138002dabaf1b9d574c2a2d7515bb7 Mon Sep 17 00:00:00 2001 From: Yao Tang Date: Fri, 28 Jan 2022 15:09:30 +0000 Subject: [PATCH 3/3] Update MultiGateReorder --- tket/src/Mapping/MultiGateReorder.cpp | 50 +++++++++------------------ 1 file changed, 17 insertions(+), 33 deletions(-) diff --git a/tket/src/Mapping/MultiGateReorder.cpp b/tket/src/Mapping/MultiGateReorder.cpp index a7216a2b3a..548ac8b218 100644 --- a/tket/src/Mapping/MultiGateReorder.cpp +++ b/tket/src/Mapping/MultiGateReorder.cpp @@ -14,24 +14,25 @@ MultiGateReorder::MultiGateReorder( _mapping_frontier->circuit_, _mapping_frontier->quantum_boundary)); } -// Traverse the DAG to the quantum frontier encoded in q_boundary_map +// Traverse the DAG to the quantum frontier // to find the UnitID associated with an VertPort UnitID get_unitid_from_vertex_port( - const Circuit &circ, const VertPort &vert_port, - const std::map &q_boundary_map) { + const std::shared_ptr &frontier, + const VertPort &vert_port) { VertPort current_vert_port = vert_port; while (true) { - auto it = q_boundary_map.find(current_vert_port); - if (it != q_boundary_map.end()) { - return it->second; + auto it = + frontier->quantum_boundary->get().find(current_vert_port); + if (it != frontier->quantum_boundary->get().end()) { + return it->first; } - Edge current_e = circ.get_nth_out_edge( + Edge current_e = frontier->circuit_.get_nth_out_edge( current_vert_port.first, current_vert_port.second); Vertex prev_vert; Edge prev_e; std::tie(prev_vert, prev_e) = - circ.get_prev_pair(current_vert_port.first, current_e); - current_vert_port = {prev_vert, circ.get_source_port(prev_e)}; + frontier->circuit_.get_prev_pair(current_vert_port.first, current_e); + current_vert_port = {prev_vert, frontier->circuit_.get_source_port(prev_e)}; } } @@ -46,12 +47,11 @@ bool is_multiq_quantum_gate(const Circuit &circ, const Vertex &vert) { } bool is_physically_permitted( - const Circuit &circ, const ArchitecturePtr &arc_ptr, const Vertex &vert, - const std::map &q_boundary_map) { + const std::shared_ptr &frontier, + const ArchitecturePtr &arc_ptr, const Vertex &vert) { std::vector nodes; - for (port_t port = 0; port < circ.n_ports(vert); ++port) { - nodes.push_back( - Node(get_unitid_from_vertex_port(circ, {vert, port}, q_boundary_map))); + for (port_t port = 0; port < frontier->circuit_.n_ports(vert); ++port) { + nodes.push_back(Node(get_unitid_from_vertex_port(frontier, {vert, port}))); } return arc_ptr->valid_operation(nodes); @@ -176,14 +176,11 @@ void MultiGateReorder::solve(unsigned max_depth, unsigned max_size) { // store a copy of the original this->mapping_frontier_->quantum_boundray // this object will be updated and reset throughout the procedure - // so need to return it to original setting at end - // also create a map for getting UnitID from VertPort - std::map q_boundary_map; + // so need to return it to original setting at end. unit_vertport_frontier_t copy; for (const std::pair &pair : this->mapping_frontier_->quantum_boundary->get()) { copy.insert({pair.first, pair.second}); - q_boundary_map.insert({pair.second, pair.first}); } // Get a subcircuit only for iterating vertices Subcircuit circ = @@ -196,8 +193,7 @@ void MultiGateReorder::solve(unsigned max_depth, unsigned max_size) { // 2. is a multi qubit quantum operation without classical controls if (is_multiq_quantum_gate(this->mapping_frontier_->circuit_, vert) && is_physically_permitted( - this->mapping_frontier_->circuit_, this->architecture_, vert, - q_boundary_map)) { + this->mapping_frontier_, this->architecture_, vert)) { std::optional> commute_pairs = try_find_commute_edges( this->mapping_frontier_->circuit_, this->u_frontier_edges_, vert); @@ -212,12 +208,6 @@ void MultiGateReorder::solve(unsigned max_depth, unsigned max_size) { convert_u_frontier_to_edges(*frontier_convert_vertport_to_edge( this->mapping_frontier_->circuit_, this->mapping_frontier_->quantum_boundary)); - // Update the map - q_boundary_map.clear(); - for (const std::pair &pair : - this->mapping_frontier_->quantum_boundary->get()) { - q_boundary_map.insert({pair.second, pair.first}); - } } } } @@ -235,11 +225,6 @@ bool MultiGateReorderRoutingMethod::check_method( const EdgeVec u_frontier_edges = convert_u_frontier_to_edges(*frontier_convert_vertport_to_edge( mapping_frontier->circuit_, mapping_frontier->quantum_boundary)); - std::map q_boundary_map; - for (const std::pair &pair : - mapping_frontier->quantum_boundary->get()) { - q_boundary_map.insert({pair.second, pair.first}); - } Subcircuit circ = mapping_frontier->get_frontier_subcircuit( this->max_depth_, this->max_size_); @@ -247,8 +232,7 @@ bool MultiGateReorderRoutingMethod::check_method( // we are certain that any multi-q vert lies after the frontier for (const Vertex &vert : circ.verts) { if (is_multiq_quantum_gate(mapping_frontier->circuit_, vert) && - is_physically_permitted( - mapping_frontier->circuit_, architecture, vert, q_boundary_map)) { + is_physically_permitted(mapping_frontier, architecture, vert)) { std::optional> commute_pairs = try_find_commute_edges( mapping_frontier->circuit_, u_frontier_edges, vert);