-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Copy TokenSwapping CodeBase, update CMakeLists.txt * Add TokenSwapping tests * Update GraphTests to use TokenSwapping RNG * Remove "class RNG;" * Add cpp files to compilation
- Loading branch information
Showing
119 changed files
with
18,727 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#include "ArchitectureMapping.hpp" | ||
|
||
#include <sstream> | ||
#include <stdexcept> | ||
|
||
namespace tket { | ||
namespace tsa_internal { | ||
|
||
ArchitectureMapping::ArchitectureMapping(const Architecture& arch) | ||
: m_arch(arch) { | ||
const auto uids = arch.get_all_uids(); | ||
m_vertex_to_node_mapping.reserve(uids.size()); | ||
for (const UnitID& uid : uids) { | ||
m_vertex_to_node_mapping.emplace_back(Node(uid)); | ||
} | ||
|
||
for (size_t ii = 0; ii < m_vertex_to_node_mapping.size(); ++ii) { | ||
const auto& node = m_vertex_to_node_mapping[ii]; | ||
{ | ||
const auto citer = m_node_to_vertex_mapping.find(node); | ||
if (citer != m_node_to_vertex_mapping.cend()) { | ||
std::stringstream ss; | ||
ss << "Duplicate node " << node.repr() << " at vertices " | ||
<< citer->second << ", " << ii; | ||
throw std::runtime_error(ss.str()); | ||
} | ||
} | ||
m_node_to_vertex_mapping[node] = ii; | ||
} | ||
} | ||
|
||
size_t ArchitectureMapping::number_of_vertices() const { | ||
return m_vertex_to_node_mapping.size(); | ||
} | ||
|
||
const Node& ArchitectureMapping::get_node(size_t vertex) const { | ||
const auto num_vertices = number_of_vertices(); | ||
if (vertex >= num_vertices) { | ||
std::stringstream ss; | ||
ss << "get_node: invalid vertex " << vertex << " (architecture only has " | ||
<< num_vertices << " vertices)"; | ||
throw std::runtime_error(ss.str()); | ||
} | ||
return m_vertex_to_node_mapping[vertex]; | ||
} | ||
|
||
size_t ArchitectureMapping::get_vertex(const Node& node) const { | ||
const auto citer = m_node_to_vertex_mapping.find(node); | ||
if (citer == m_node_to_vertex_mapping.cend()) { | ||
std::stringstream ss; | ||
ss << "get_vertex: node " << node.repr() << " has no vertex number"; | ||
throw std::runtime_error(ss.str()); | ||
} | ||
return citer->second; | ||
} | ||
|
||
const Architecture& ArchitectureMapping::get_architecture() const { | ||
return m_arch; | ||
} | ||
|
||
std::vector<Swap> ArchitectureMapping::get_edges() const { | ||
std::vector<Swap> edges; | ||
for (auto [node1, node2] : m_arch.get_connections_vec()) { | ||
edges.emplace_back(get_swap(get_vertex(node1), get_vertex(node2))); | ||
} | ||
return edges; | ||
} | ||
|
||
} // namespace tsa_internal | ||
} // namespace tket |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
#ifndef _TKET_TokenSwapping_ArchitectureMapping_H_ | ||
#define _TKET_TokenSwapping_ArchitectureMapping_H_ | ||
|
||
#include "Architecture/Architectures.hpp" | ||
#include "TSAUtils/SwapFunctions.hpp" | ||
|
||
namespace tket { | ||
namespace tsa_internal { | ||
|
||
/** For mapping between nodes in an architecture and size_t vertex numbers. | ||
* The vertex numbers are merely the indices of each Node | ||
* within the vector returned by the get_all_uids() function. | ||
* | ||
* For now, we don't want to use Node objects as (1) this would make | ||
* TokenSwapping dependent on other parts of Tket and hence less modular, | ||
* (2) it would probably slow things down significantly because Nodes | ||
* contain extra data, like vectors and strings, which are relatively | ||
* expensive to copy; vertices get copied and moved around many times | ||
* by any TSA. | ||
* | ||
* TODO: it would be better to use a Vertex wrapper class | ||
* instead of raw size_t. (Also, might change to unsigned instead of size_t). | ||
*/ | ||
class ArchitectureMapping { | ||
public: | ||
/** The object must remain valid and unchanged | ||
* throughout the life of this object. | ||
* @param arch The finished Architecture object, must remain valid | ||
* for the lifetime of this object. | ||
*/ | ||
explicit ArchitectureMapping(const Architecture& arch); | ||
|
||
/** Convenient reference to the Architecture object we used | ||
* to construct this ArchitectureMapping. | ||
*/ | ||
const Architecture& get_architecture() const; | ||
|
||
/** The number of vertices in the Architecture. | ||
* @return The number of vertices | ||
*/ | ||
size_t number_of_vertices() const; | ||
|
||
/** Get the newly created vertex assigned to the node. | ||
* Throws if the node is invalid. | ||
* @param node The node within the original Architecture object | ||
* @return The newly created vertex representing this node | ||
*/ | ||
size_t get_vertex(const Node& node) const; | ||
|
||
/** Reverse of "get_vertex", throws if the vertex is invalid. | ||
* @param vertex The vertex created by this ArchitectureMapping object. | ||
* @return The node corresponding to this vertex. | ||
*/ | ||
const Node& get_node(size_t vertex) const; | ||
|
||
/** Get the edges using the vertices created by this ArchitectureMapping | ||
* object. The vertex numbers, of course, do not necessarily match with | ||
* the Node uids of the underlying architecture object | ||
* (that's why we have a mapping). | ||
* @return The vector of edges in the architecture, using the new | ||
* vertex numbers. | ||
*/ | ||
std::vector<Swap> get_edges() const; | ||
|
||
private: | ||
/// Store a reference to the Architecture passed into the constructor. | ||
const Architecture& m_arch; | ||
|
||
/// Element i is simply the node corresponding to vertex i. | ||
node_vector_t m_vertex_to_node_mapping; | ||
|
||
/// Reverse of m_vertex_to_node_mapping; look up the index of a node. | ||
std::map<Node, size_t> m_node_to_vertex_mapping; | ||
}; | ||
|
||
} // namespace tsa_internal | ||
} // namespace tket | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#include "BestFullTsa.hpp" | ||
|
||
#include "DistancesFromArchitecture.hpp" | ||
#include "NeighboursFromArchitecture.hpp" | ||
#include "RiverFlowPathFinder.hpp" | ||
#include "TableLookup/VertexMapResizing.hpp" | ||
|
||
namespace tket { | ||
namespace tsa_internal { | ||
|
||
BestFullTsa::BestFullTsa() { m_name = "BestFullTsa"; } | ||
|
||
HybridTsa00& BestFullTsa::get_hybrid_tsa_for_testing() { return m_hybrid_tsa; } | ||
|
||
void BestFullTsa::append_partial_solution( | ||
SwapList& swaps, VertexMapping& vertex_mapping, | ||
const ArchitectureMapping& arch_mapping) { | ||
DistancesFromArchitecture distances(arch_mapping); | ||
NeighboursFromArchitecture neighbours(arch_mapping); | ||
RiverFlowPathFinder path_finder(distances, neighbours, m_rng); | ||
m_rng.set_seed(); | ||
append_partial_solution( | ||
swaps, vertex_mapping, distances, neighbours, path_finder); | ||
} | ||
|
||
void BestFullTsa::append_partial_solution( | ||
SwapList& swaps, VertexMapping& vertex_mapping, | ||
DistancesInterface& distances, NeighboursInterface& neighbours, | ||
PathFinderInterface& path_finder) { | ||
auto vm_copy = vertex_mapping; | ||
|
||
m_hybrid_tsa.append_partial_solution( | ||
swaps, vm_copy, distances, neighbours, path_finder); | ||
|
||
// Still subject to experimentation, but this seems the best | ||
m_swap_list_optimiser.optimise_pass_with_zero_travel(swaps); | ||
m_swap_list_optimiser.optimise_pass_with_token_tracking(swaps); | ||
m_swap_list_optimiser.optimise_pass_remove_empty_swaps(swaps, vertex_mapping); | ||
m_swap_list_optimiser.full_optimise(swaps, vertex_mapping); | ||
|
||
VertexMapResizing map_resizing(neighbours); | ||
std::set<size_t> vertices_with_tokens_at_start; | ||
for (const auto& entry : vertex_mapping) { | ||
vertices_with_tokens_at_start.insert(entry.first); | ||
} | ||
m_table_optimiser.optimise( | ||
vertices_with_tokens_at_start, map_resizing, swaps, | ||
m_swap_list_optimiser); | ||
} | ||
|
||
} // namespace tsa_internal | ||
} // namespace tket |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#ifndef _TKET_TokenSwapping_BestFullTsa_H_ | ||
#define _TKET_TokenSwapping_BestFullTsa_H_ | ||
#include "ArchitectureMapping.hpp" | ||
#include "HybridTsa00.hpp" | ||
#include "RNG.hpp" | ||
#include "SwapListOptimiser.hpp" | ||
#include "TableLookup/SwapListTableOptimiser.hpp" | ||
|
||
namespace tket { | ||
namespace tsa_internal { | ||
|
||
/** To enable easier experimentation, keep this up-to-date with the best | ||
* end-to-end known default options, but also make it possible to change | ||
* the options. | ||
* Also include the best known postprocessing swap list optimisations. | ||
*/ | ||
class BestFullTsa : public PartialTsaInterface { | ||
public: | ||
BestFullTsa(); | ||
|
||
/** We emphasise that, unlike the general PartialTsaInterface, the solution | ||
* returned is complete, AND includes all known swap list optimisations. | ||
* Warning: unlike most PartialTsaInterface objects, the vertex_mapping | ||
* is NOT updated. (There's no point for a full TSA). | ||
* @param swaps The list of swaps to append to (does not clear first). | ||
* @param vertex_mapping The current desired mapping, giving (current source | ||
* vertex)->(target vertex) mappings. NOT updated at the end. | ||
* @param distances An object to calculate distances between vertices. | ||
* @param neighbours An object to calculate adjacent vertices to any given | ||
* vertex. | ||
* @param path_finder An object to calculate a shortest path between any | ||
* pair of vertices. (Of course, paths might not be unique if the graph | ||
* is not a tree). | ||
*/ | ||
virtual void append_partial_solution( | ||
SwapList& swaps, VertexMapping& vertex_mapping, | ||
DistancesInterface& distances, NeighboursInterface& neighbours, | ||
PathFinderInterface& path_finder) override; | ||
|
||
/** Wrapper around the main append_partial_solution function, but constructing | ||
* and using the best known PathFinderInterface object. The DistancesInterface | ||
* and NeighboursInterface objects will automatically be constructed. | ||
* @param swaps The list of swaps to append to. | ||
* @param vertex_mapping The current desired mapping. Will be updated with | ||
* the new added swaps. | ||
* @param arch_mapping An ArchitectureMapping object, which knows the graph, | ||
* how to do Node <-> vertex size_t conversions, etc. | ||
*/ | ||
void append_partial_solution( | ||
SwapList& swaps, VertexMapping& vertex_mapping, | ||
const ArchitectureMapping& arch_mapping); | ||
|
||
/** For experiments, provide access to the internal stored TSA object. This | ||
* function may be deleted later! | ||
* @return Reference to the internal stored TSA object. | ||
*/ | ||
HybridTsa00& get_hybrid_tsa_for_testing(); | ||
|
||
private: | ||
HybridTsa00 m_hybrid_tsa; | ||
SwapListOptimiser m_swap_list_optimiser; | ||
SwapListTableOptimiser m_table_optimiser; | ||
RNG m_rng; | ||
}; | ||
|
||
} // namespace tsa_internal | ||
} // namespace tket | ||
#endif |
Oops, something went wrong.