Skip to content

Commit

Permalink
Dijkstra arbitrary weights (#269)
Browse files Browse the repository at this point in the history
  • Loading branch information
EliasLF authored Mar 19, 2023
1 parent 6e8ab7a commit 7f38148
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 30 deletions.
23 changes: 10 additions & 13 deletions include/Architecture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,21 +364,18 @@ class Architecture {
void createDistanceTable();
void createFidelityTable();

static double costHeuristicBidirectional(const Dijkstra::Node& node) {
auto length = node.cost - 1;
static double dijkstraNodeToCost(const Dijkstra::Node& node) {
// Dijkstra determines the minimal path cost from one physical qubit to
// another. In the non-fidelity case we are only interested in swapping 2
// logical qubits next to each other. Therefore the last swap cost has to
// be ignored. That cost is stored in the field `node.prevCost` of each
// node.
if (node.containsCorrectEdge) {
return length * COST_BIDIRECTIONAL_SWAP;
return node.prevCost;
}
throw QMAPException("In a bidrectional architecture it should not happen "
"that a node does not contain the right edge.");
}

static double costHeuristicUnidirectional(const Dijkstra::Node& node) {
auto length = node.cost - 1;
if (node.containsCorrectEdge) {
return length * COST_UNIDIRECTIONAL_SWAP;
}
return length * COST_UNIDIRECTIONAL_SWAP + COST_DIRECTION_REVERSE;
// in case the last edge is a back-edge, we will need to reverse the CNOT,
// executed on that edge
return node.prevCost + COST_DIRECTION_REVERSE;
}

// added for teleportation
Expand Down
5 changes: 3 additions & 2 deletions include/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,16 @@ class Dijkstra {
bool visited = false;
std::optional<std::uint16_t> pos = std::nullopt;
double cost = -1.;
double prevCost = -1.;
};

static void buildTable(std::uint16_t n, const CouplingMap& couplingMap,
Matrix& distanceTable,
Matrix& distanceTable, const Matrix& edgeWeights,
const std::function<double(const Node&)>& cost);

protected:
static void dijkstra(const CouplingMap& couplingMap, std::vector<Node>& nodes,
std::uint16_t start);
std::uint16_t start, const Matrix& edgeWeights);

struct NodeComparator {
bool operator()(const Node* x, const Node* y) {
Expand Down
19 changes: 10 additions & 9 deletions src/Architecture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,20 +185,21 @@ Architecture::Architecture(const std::uint16_t nQ, const CouplingMap& cm,
}

void Architecture::createDistanceTable() {
isBidirectional = true;
Matrix edgeWeights(nqubits, std::vector<double>(
nqubits, std::numeric_limits<double>::max()));
for (const auto& edge : couplingMap) {
if (couplingMap.find({edge.second, edge.first}) == couplingMap.end()) {
isBidirectional = false;
break;
isBidirectional = false;
edgeWeights.at(edge.second).at(edge.first) = COST_UNIDIRECTIONAL_SWAP;
edgeWeights.at(edge.first).at(edge.second) = COST_UNIDIRECTIONAL_SWAP;
} else {
edgeWeights.at(edge.first).at(edge.second) = COST_BIDIRECTIONAL_SWAP;
}
}

if (isBidirectional) {
Dijkstra::buildTable(nqubits, couplingMap, distanceTable,
Architecture::costHeuristicBidirectional);
} else {
Dijkstra::buildTable(nqubits, couplingMap, distanceTable,
Architecture::costHeuristicUnidirectional);
}
Dijkstra::buildTable(nqubits, couplingMap, distanceTable, edgeWeights,
Architecture::dijkstraNodeToCost);
}

void Architecture::createFidelityTable() {
Expand Down
16 changes: 10 additions & 6 deletions src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <cassert>

void Dijkstra::buildTable(const std::uint16_t n, const CouplingMap& couplingMap,
Matrix& distanceTable,
Matrix& distanceTable, const Matrix& edgeWeights,
const std::function<double(const Node&)>& cost) {
distanceTable.clear();
distanceTable.resize(n, std::vector<double>(n, -1.));
Expand All @@ -20,11 +20,13 @@ void Dijkstra::buildTable(const std::uint16_t n, const CouplingMap& couplingMap,
nodes.at(j).visited = false;
nodes.at(j).pos = j;
nodes.at(j).cost = -1.;
nodes.at(j).prevCost = -1.;
}

nodes.at(i).cost = 0.;
nodes.at(i).cost = 0.;
nodes.at(i).prevCost = 0.;

dijkstra(couplingMap, nodes, i);
dijkstra(couplingMap, nodes, i, edgeWeights);

for (std::uint16_t j = 0; j < n; ++j) {
if (i == j) {
Expand All @@ -37,7 +39,8 @@ void Dijkstra::buildTable(const std::uint16_t n, const CouplingMap& couplingMap,
}

void Dijkstra::dijkstra(const CouplingMap& couplingMap,
std::vector<Node>& nodes, std::uint16_t start) {
std::vector<Node>& nodes, std::uint16_t start,
const Matrix& edgeWeights) {
std::priority_queue<Node*, std::vector<Node*>, NodeComparator> queue{};
queue.push(&nodes.at(start));
while (!queue.empty()) {
Expand All @@ -61,8 +64,9 @@ void Dijkstra::dijkstra(const CouplingMap& couplingMap,
}

Node newNode;
newNode.cost = current->cost + 1.0;
newNode.pos = to;
newNode.cost = current->cost + edgeWeights.at(*pos).at(*to);
newNode.prevCost = current->cost;
newNode.pos = to;
newNode.containsCorrectEdge = correctEdge;
if (nodes.at(*to).cost < 0 || newNode < nodes.at(*to)) {
nodes.at(*to) = newNode;
Expand Down
31 changes: 31 additions & 0 deletions test/test_general.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//

#include "Architecture.hpp"
#include "utils.hpp"

#include "gtest/gtest.h"
#include <iostream>
Expand Down Expand Up @@ -52,3 +53,33 @@ TEST(General, TestLineParsing) {
EXPECT_EQ(data[1], "Entry2");
EXPECT_EQ(data[2], "EscapedEntry1;EscapedEntry2");
}

TEST(General, Dijkstra) {
/*
(6)
.----------.
\/ \/
0 <-> 1 --> 2 <-> 3
(1) (2) (3)
*/

const CouplingMap cm = {{0, 1}, {1, 0}, {1, 2}, {2, 3},
{3, 2}, {1, 3}, {3, 1}};

const Matrix edgeWeights = {
{0, 1, 0, 0}, {1, 0, 2, 6}, {0, 15, 0, 3}, {0, 6, 3, 0}};

const Matrix targetTable1 = {
{0, 1, 3, 6}, {1, 0, 2, 5}, {10, 9, 0, 3}, {7, 6, 3, 0}};
Matrix distanceTable{};
Dijkstra::buildTable(4, cm, distanceTable, edgeWeights,
[](const Dijkstra::Node& n) { return n.cost; });
EXPECT_EQ(distanceTable, targetTable1);

const Matrix targetTable2 = {
{0, 0, 1, 3}, {0, 0, 0, 2}, {9, 3, 0, 0}, {6, 0, 0, 0}};
distanceTable = {};
Dijkstra::buildTable(4, cm, distanceTable, edgeWeights,
[](const Dijkstra::Node& n) { return n.prevCost; });
EXPECT_EQ(distanceTable, targetTable2);
}

0 comments on commit 7f38148

Please sign in to comment.