Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Qubit out of Bounds Error #496

Merged
merged 25 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
01b94b5
🐛 Fix out of entangling zone bug
ystade Jul 30, 2024
4447bff
🐛 Fix partial order
ystade Jul 31, 2024
c081fa7
🎨 Remove std::cout statements
ystade Jul 31, 2024
215f1d2
Merge remote-tracking branch 'origin/main' into fix-na-out-of-zone
ystade Jul 31, 2024
8e27211
🐛 Fix typo causing type error
ystade Jul 31, 2024
5845c87
⬆️ Update to latest commit of MQT core
ystade Jul 31, 2024
fabcd7d
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 31, 2024
570a224
🐛 Fix tests
ystade Jul 31, 2024
8c070dd
🐛 Fix architecture for patches outside of zones
ystade Jul 31, 2024
69c551a
🚸 Augment test with text output in failing case
ystade Jul 31, 2024
12041c6
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 31, 2024
dad49ca
💚 Satisfy Linter
ystade Aug 1, 2024
d78fbcc
🐛 Fix bug with patches outside of zone
ystade Aug 1, 2024
8dc4dc7
💚 Satisfy Linter
ystade Aug 1, 2024
9bd354c
✅ Increase test covereage
ystade Aug 1, 2024
e72fbed
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 1, 2024
6aafbfb
💚 Satisfy Clang tidy
ystade Aug 1, 2024
b0b8953
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 1, 2024
e81e10b
✏️ Fix typos
ystade Aug 1, 2024
60c8f21
💚 Try to satisfy clang tidy
ystade Aug 1, 2024
b828fe8
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 1, 2024
0e15ee1
🎨 Incorporate feedback from review
ystade Aug 1, 2024
5062a35
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 1, 2024
1d3cddc
💚 Satisfy clang tidy
ystade Aug 1, 2024
15f615e
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmake/ExternalDependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ endif()
# cmake-format: off
set(MQT_CORE_VERSION 2.5.1
ystade marked this conversation as resolved.
Show resolved Hide resolved
CACHE STRING "MQT Core version")
set(MQT_CORE_REV "35e06ca3067ca3cf36bda1f0c38edf5bd7456fb6"
set(MQT_CORE_REV "633915adeece6de3001dd16563bea9d321112b10"
ystade marked this conversation as resolved.
Show resolved Hide resolved
CACHE STRING "MQT Core identifier (tag, branch or commit hash)")
set(MQT_CORE_REPO_OWNER "cda-tum"
CACHE STRING "MQT Core repository owner (change when using a fork)")
Expand Down
3 changes: 2 additions & 1 deletion include/na/NAGraphAlgorithms.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ class NAGraphAlgorithms {
* @return A tuple of vectors containing the moveable vertices, the fixed
* vertices mapped to their relative x-position in every time step.
*/
[[nodiscard]] static auto computeSequence(const InteractionGraph& g)
[[nodiscard]] static auto computeSequence(const InteractionGraph& g,
std::size_t maxSites)
ystade marked this conversation as resolved.
Show resolved Hide resolved
-> std::pair<std::vector<std::unordered_map<qc::Qubit, std::int64_t>>,
std::unordered_map<qc::Qubit, std::int64_t>>;
};
Expand Down
74 changes: 64 additions & 10 deletions src/na/NAGraphAlgorithms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,16 @@
[&](const Edge& a, const Edge& b) {
const auto u = a.first == v ? a.second : a.first;
const auto w = b.first == v ? b.second : b.first;
return partialOrder.isReachable(u, w) or
(!partialOrder.isReachable(w, u) and
(nAdjColors[a] > nAdjColors[b] or
(nAdjColors[a] == nAdjColors[b] and
edgeDegree[a] > edgeDegree[b])));
return u != w &&
(partialOrder.isReachable(u, w) ||
(!partialOrder.isReachable(w, u) &&
(nAdjColors[a] > nAdjColors[b] ||
(nAdjColors[a] == nAdjColors[b] &&
(edgeDegree[a] > edgeDegree[b] ||
(edgeDegree[a] == edgeDegree[b] && u < w))))));
Fixed Show fixed Hide fixed
// the last line together with the first clause (u != w) is
// necessary for a well-defined compare function to handle edges
// that compare equally correctly
});
for (const auto& e : adjacentEdges) {
// color the edge
Expand Down Expand Up @@ -427,7 +432,8 @@
return result;
}

auto NAGraphAlgorithms::computeSequence(const InteractionGraph& g)
auto NAGraphAlgorithms::computeSequence(const InteractionGraph& g,
const std::size_t maxSites)
-> std::pair<std::vector<std::unordered_map<qc::Qubit, std::int64_t>>,
std::unordered_map<qc::Qubit, std::int64_t>> {
const auto& maxIndepSet = getMaxIndependentSet(g);
Expand All @@ -437,11 +443,14 @@
[&](const auto& u, const auto& v) {
return g.getDegree(u) > g.getDegree(v);
});
const auto& sequence = groupByConnectedComponent(g, sequenceUngrouped);
const auto& [coloring, partialOrder] =
auto sequence = groupByConnectedComponent(g, sequenceUngrouped);
const auto& colorEdgesResult =
colorEdges(g, coveredEdges(g, maxIndepSet), sequence);
const auto& fixed = partialOrder.orderTopologically();
const auto& resting = computeRestingPositions(sequence, fixed, coloring);
std::unordered_map<Edge, Color, qc::PairHash<qc::Qubit, qc::Qubit>> coloring =
colorEdgesResult.first;
ystade marked this conversation as resolved.
Show resolved Hide resolved
auto partialOrder = colorEdgesResult.second;
auto fixed = partialOrder.orderTopologically();
auto resting = computeRestingPositions(sequence, fixed, coloring);
// compute relative x positions of fixed vertices
std::unordered_map<qc::Qubit, std::int64_t> fixedPositions{};
for (std::uint32_t x = 0, i = 0; x < fixed.size(); ++x) {
Expand All @@ -450,6 +459,51 @@
++i;
}
}

const auto maxSiteUsed =
std::max_element(
fixedPositions.cbegin(), fixedPositions.cend(),
[](const auto& a, const auto& b) { return a.second < b.second; })
->second;
const auto maxSitesSigned = static_cast<std::int64_t>(maxSites);
if (maxSiteUsed >= maxSitesSigned) {
// Handle the situation when the entangling zone is not big enough to fit
// all fixed qubits
for (auto it = fixedPositions.begin(); it != fixedPositions.end();) {
if (it->second >= maxSitesSigned) {
it = fixedPositions.erase(it); // erase returns the next iterator
} else {
++it; // move to the next element
}
}
fixed.erase(std::remove_if(fixed.begin(), fixed.end(),
[&fixedPositions](const auto& q) {
return fixedPositions.find(q) ==
fixedPositions.end();
}),
fixed.end());
for (auto it = coloring.begin(); it != coloring.end();) {
if (fixedPositions.find(it->first.first) == fixedPositions.end() &&
fixedPositions.find(it->first.second) == fixedPositions.end()) {
it = coloring.erase(it); // erase returns the next iterator
} else {
++it; // move to the next element
}
}
sequence.erase(std::remove_if(sequence.begin(), sequence.end(),
[&coloring](const auto& q) {
return !std::any_of(
coloring.cbegin(), coloring.cend(),
[q](const auto& elem) {
return elem.first.first == q ||
elem.first.second == q;
});
}),
sequence.end());
// recalculate resting positions
resting = computeRestingPositions(sequence, fixed, coloring);
}

// compute relative x positions of moveable vertices at every timestamp
const Color maxColor = std::accumulate(
coloring.cbegin(), coloring.cend(), static_cast<Color>(0),
Expand Down
9 changes: 5 additions & 4 deletions src/na/NAMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,11 @@ auto NAMapper::map(const qc::QuantumComputation& qc) -> void {
"Other gates than cz are not supported for mapping yet.");
// TODO: support other gates than cz
}
const auto& sequence = NAGraphAlgorithms::computeSequence(graph);
const Zone interactionZone =
*arch.getPropertiesOfOperation({qc::OpType::Z, 1}).zones.begin();
const auto sites = arch.getSitesInRow(interactionZone, 0);
const auto& sequence =
NAGraphAlgorithms::computeSequence(graph, sites.size());
const auto& moveable = sequence.first;
const auto& fixed = sequence.second;
// 3. move the atoms accordingly and execute the gates
Expand All @@ -982,9 +986,6 @@ auto NAMapper::map(const qc::QuantumComputation& qc) -> void {
assert(q.second >= 0);
return std::max(max, static_cast<std::size_t>(q.second));
});
const Zone interactionZone =
*arch.getPropertiesOfOperation({qc::OpType::Z, 1}).zones.begin();
const auto sites = arch.getSitesInRow(interactionZone, 0);
if (sites.size() < maxSeqWidth) {
std::stringstream ss;
ss << "Target site in " << arch.getZoneLabel(interactionZone);
Expand Down
6 changes: 3 additions & 3 deletions test/na/test_nagraphalgorithms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "gtest/gtest.h"
#include <algorithm>
#include <iterator>
#include <memory>

Check warning on line 14 in test/na/test_nagraphalgorithms.cpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

test/na/test_nagraphalgorithms.cpp:14:1 [misc-include-cleaner]

included header memory is not used directly
#include <numeric>

class TestNAGraph : public testing::Test {
Expand Down Expand Up @@ -45,7 +45,7 @@
EXPECT_EQ(graph.getDegree(5), 3);
EXPECT_EQ(graph.getDegree(6), 2);
EXPECT_EQ(graph.getDegree(7), 4);
EXPECT_THROW(std::ignore = graph.getDegree(0), std::invalid_argument);

Check warning on line 48 in test/na/test_nagraphalgorithms.cpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

test/na/test_nagraphalgorithms.cpp:48:21 [misc-include-cleaner]

no header providing "std::ignore" is directly included

Check warning on line 48 in test/na/test_nagraphalgorithms.cpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

test/na/test_nagraphalgorithms.cpp:48:55 [misc-include-cleaner]

no header providing "std::invalid_argument" is directly included
EXPECT_TRUE(graph.isAdjacent(1, 2));
EXPECT_FALSE(graph.isAdjacent(1, 3));
EXPECT_FALSE(graph.isAdjacent(1, 4));
Expand Down Expand Up @@ -100,13 +100,13 @@

TEST_F(TestNAGraph, CoveredEdges) {
EXPECT_THROW(std::ignore = na::NAGraphAlgorithms::coveredEdges(
graph, std::unordered_set<qc::Qubit>{8}),

Check warning on line 103 in test/na/test_nagraphalgorithms.cpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

test/na/test_nagraphalgorithms.cpp:103:32 [misc-include-cleaner]

no header providing "std::unordered_set" is directly included

Check warning on line 103 in test/na/test_nagraphalgorithms.cpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

test/na/test_nagraphalgorithms.cpp:103:50 [misc-include-cleaner]

no header providing "qc::Qubit" is directly included
std::invalid_argument);
}

TEST_F(TestNAGraph, Coloring) {
const auto& maxIndepSet = na::NAGraphAlgorithms::getMaxIndependentSet(graph);
std::vector queue(maxIndepSet.cbegin(), maxIndepSet.cend());

Check warning on line 109 in test/na/test_nagraphalgorithms.cpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

test/na/test_nagraphalgorithms.cpp:109:8 [misc-include-cleaner]

no header providing "std::vector" is directly included
// sort the vertices by degree in descending order
std::sort(queue.begin(), queue.end(), [&](const auto& u, const auto& v) {
return graph.getDegree(u) > graph.getDegree(v);
Expand Down Expand Up @@ -159,12 +159,12 @@
}

TEST_F(TestNAGraph, SequenceOrdering) {
const auto& sequence = na::NAGraphAlgorithms::computeSequence(graph);
const auto& sequence = na::NAGraphAlgorithms::computeSequence(graph, 20);
const auto& moveable = sequence.first;
// check that the order of moveable qubits is consistent
auto order =
std::accumulate(moveable[0].cbegin(), moveable[0].cend(),
std::vector<qc::Qubit>{}, [](auto& acc, const auto& p) {

Check warning on line 167 in test/na/test_nagraphalgorithms.cpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

test/na/test_nagraphalgorithms.cpp:167:28 [misc-include-cleaner]

no header providing "std::vector" is directly included
acc.push_back(p.first);
return acc;
});
Expand All @@ -173,7 +173,7 @@
});
for (const auto& t : moveable) {
EXPECT_EQ(t.size(), order.size());
for (std::size_t i = 1; i < order.size(); ++i) {

Check warning on line 176 in test/na/test_nagraphalgorithms.cpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

test/na/test_nagraphalgorithms.cpp:176:15 [misc-include-cleaner]

no header providing "std::size_t" is directly included
const auto& x1It = t.find(order[i - 1]);
const auto& x2It = t.find(order[i]);
EXPECT_NE(x1It, t.cend());
Expand All @@ -184,7 +184,7 @@
}

TEST_F(TestNAGraph, InteractionExists) {
const auto& sequence = na::NAGraphAlgorithms::computeSequence(graph);
const auto& sequence = na::NAGraphAlgorithms::computeSequence(graph, 20);
const auto& moveable = sequence.first;
const auto& fixed = sequence.second;
// check that all interactions are part of the interaction graph
Expand All @@ -208,7 +208,7 @@
na::NAGraphAlgorithms::coveredEdges(graph, maxIndepSet);
// TODO for some reason this must be a vector, set gives an error
std::vector coveredEdgesVec(coveredEdges.cbegin(), coveredEdges.cend());
const auto& sequence = na::NAGraphAlgorithms::computeSequence(graph);
const auto& sequence = na::NAGraphAlgorithms::computeSequence(graph, 20);
const auto& moveable = sequence.first;
const auto& fixed = sequence.second;
// check that all interactions that are covered by the independent set are
Expand Down
Loading