-
Notifications
You must be signed in to change notification settings - Fork 26
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
Delayed Phase Correction #397
base: main
Are you sure you want to change the base?
Changes from all commits
c81eb40
5eb3747
8c9d539
1cd55fd
256f588
d218f42
af8ee8f
eb35989
b2e3a92
848e9d7
7690afa
d334f58
267c2b1
f58a738
3b3f028
e6c3348
f45ac80
cad2a04
c02c8ed
0608ae9
e8d4794
b8423cc
995ed9d
6a3bafa
dac77bb
60f64ca
4291548
245f55c
a0652f0
aaeb22f
4b48b48
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
+4 −4 | .pre-commit-config.yaml | |
+1 −1 | extern/googletest | |
+1 −1 | extern/plog |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please revert these unrelated submodule change |
+64 −10 | README.md | |
+1 −2 | docs/DevelopmentGuide.md | |
+22 −0 | docs/_static/custom.css | |
+1,120 −0 | docs/_static/erc_dark.svg | |
+1,125 −0 | docs/_static/erc_light.svg | |
+60 −0 | docs/_static/logo-bavaria.svg | |
+2 −0 | docs/_static/logo-mqv.svg | |
+130 −0 | docs/_static/tum_dark.svg | |
+130 −0 | docs/_static/tum_light.svg | |
+61 −0 | docs/_templates/page.html | |
+3 −0 | docs/conf.py | |
+2 −0 | docs/index.md | |
+ − | extern/mqt_dark.png | |
+ − | extern/mqt_light.png | |
+8 −3 | src/python/operations/register_operation.cpp |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -5,13 +5,16 @@ | |||
|
||||
#pragma once | ||||
|
||||
#include "GateSet.hpp" | ||||
#include "TargetMetric.hpp" | ||||
#include "nlohmann/json.hpp" | ||||
#include "operations/OpType.hpp" | ||||
|
||||
#include <plog/Log.h> | ||||
#include <thread> | ||||
#include <unordered_map> | ||||
#include <variant> | ||||
#include <vector> | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Seems unnecessary |
||||
|
||||
namespace cs { | ||||
|
||||
|
@@ -48,6 +51,12 @@ struct Configuration { | |||
std::size_t splitSize = 5U; | ||||
std::size_t nThreadsHeuristic = std::thread::hardware_concurrency(); | ||||
|
||||
GateSet gateSet = {qc::OpType::None, qc::OpType::S, qc::OpType::Sdg, | ||||
qc::OpType::H, qc::OpType::X, qc::OpType::Y, | ||||
qc::OpType::Z}; | ||||
Comment on lines
+54
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I am missing something, but I believe this is missing the SX and SXdg gates. (and potentially the |
||||
|
||||
bool delayPaulis = false; | ||||
|
||||
[[nodiscard]] nlohmann::json json() const { | ||||
nlohmann::json j; | ||||
j["initial_timestep_limit"] = initialTimestepLimit; | ||||
|
@@ -66,6 +75,8 @@ struct Configuration { | |||
j["heuristic"] = heuristic; | ||||
j["split_size"] = splitSize; | ||||
j["n_threads_heuristic"] = nThreadsHeuristic; | ||||
j["gate_set"] = gateSet.toString(); | ||||
j["delay_paulis"] = delayPaulis; | ||||
if (!solverParameters.empty()) { | ||||
nlohmann::json solverParametersJson; | ||||
for (const auto& entry : solverParameters) { | ||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have two general points here:
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,237 @@ | ||||||
// | ||||||
// This file is part of the MQT QMAP library released under the MIT license. | ||||||
// See README.md or go to https://github.com/cda-tum/qmap for more information. | ||||||
// | ||||||
|
||||||
#pragma once | ||||||
|
||||||
#include "operations/OpType.hpp" | ||||||
|
||||||
#include <algorithm> | ||||||
#include <array> | ||||||
#include <initializer_list> | ||||||
#include <vector> | ||||||
|
||||||
namespace cs { | ||||||
class GateSet { | ||||||
static constexpr std::array<qc::OpType, 10> SINGLE_QUBIT_CLIFFORDS = { | ||||||
qc::OpType::I, qc::OpType::H, qc::OpType::X, qc::OpType::Y, | ||||||
qc::OpType::Z, qc::OpType::S, qc::OpType::Sdg, qc::OpType::SX, | ||||||
qc::OpType::SXdg, qc::OpType::None}; | ||||||
|
||||||
using iterator = typename std::vector<qc::OpType>::iterator; | ||||||
using const_iterator = typename std::vector<qc::OpType>::const_iterator; | ||||||
|
||||||
private: | ||||||
// Check if None is already contained and if not, append it | ||||||
void appendNone() { | ||||||
if (!containsGate(qc::OpType::None)) { | ||||||
gates.push_back(qc::OpType::None); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
} | ||||||
std::vector<qc::OpType> gates{}; | ||||||
|
||||||
public: | ||||||
GateSet() { appendNone(); }; | ||||||
|
||||||
explicit GateSet(std::vector<qc::OpType> gateSet) | ||||||
: gates(std::move(gateSet)) { | ||||||
appendNone(); | ||||||
}; | ||||||
|
||||||
GateSet(const GateSet& gateSet) : gates(gateSet.gates) { appendNone(); }; | ||||||
|
||||||
GateSet(GateSet&& gateSet) noexcept : gates(std::move(gateSet.gates)) { | ||||||
appendNone(); | ||||||
}; | ||||||
|
||||||
GateSet(std::initializer_list<qc::OpType> gateSet) : gates(gateSet) { | ||||||
appendNone(); | ||||||
} | ||||||
|
||||||
GateSet& operator=(const GateSet& other) { | ||||||
gates = other.gates; | ||||||
appendNone(); | ||||||
return *this; | ||||||
} | ||||||
|
||||||
GateSet& operator=(GateSet&& other) noexcept { | ||||||
gates = std::move(other.gates); | ||||||
appendNone(); | ||||||
return *this; | ||||||
} | ||||||
|
||||||
GateSet& operator=(std::initializer_list<qc::OpType> other) { | ||||||
gates = other; | ||||||
appendNone(); | ||||||
return *this; | ||||||
} | ||||||
Comment on lines
+42
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a strong feeling that all of these methods could be removed. |
||||||
|
||||||
void removeGate(const qc::OpType& gate) { | ||||||
gates.erase(std::remove(gates.begin(), gates.end(), gate), gates.end()); | ||||||
} | ||||||
|
||||||
void removePaulis() { | ||||||
gates.erase(std::remove_if(gates.begin(), gates.end(), | ||||||
[](qc::OpType gate) { | ||||||
return gate == qc::OpType::X || | ||||||
gate == qc::OpType::Y || | ||||||
gate == qc::OpType::Z || | ||||||
gate == qc::OpType::None; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just for my understanding: Do you really want to remove |
||||||
}), | ||||||
gates.end()); | ||||||
} | ||||||
[[nodiscard]] bool containsGate(qc::OpType gate) const { | ||||||
for (const auto& g : // NOLINT(readability-use-anyofallof) | ||||||
gates) { | ||||||
if (g == gate) { | ||||||
return true; | ||||||
} | ||||||
} | ||||||
return false; | ||||||
} | ||||||
[[nodiscard]] bool containsX() const { return containsGate(qc::OpType::X); } | ||||||
[[nodiscard]] bool containsY() const { return containsGate(qc::OpType::Y); } | ||||||
[[nodiscard]] bool containsZ() const { return containsGate(qc::OpType::Z); } | ||||||
[[nodiscard]] bool containsH() const { return containsGate(qc::OpType::H); } | ||||||
[[nodiscard]] bool containsS() const { return containsGate(qc::OpType::S); } | ||||||
[[nodiscard]] bool containsSdg() const { | ||||||
return containsGate(qc::OpType::Sdg); | ||||||
} | ||||||
[[nodiscard]] bool containsSX() const { return containsGate(qc::OpType::SX); } | ||||||
[[nodiscard]] bool containsSXdg() const { | ||||||
return containsGate(qc::OpType::SXdg); | ||||||
} | ||||||
[[nodiscard]] std::size_t gateToIndex(const qc::OpType type) const { | ||||||
for (std::size_t i = 0; i < gates.size(); ++i) { | ||||||
if (gates.at(i) == type) { | ||||||
return i; | ||||||
} | ||||||
} | ||||||
return 0; | ||||||
} | ||||||
|
||||||
[[nodiscard]] GateSet paulis() const { | ||||||
std::vector<qc::OpType> result; | ||||||
for (const auto& g : gates) { | ||||||
if (g == qc::OpType::X || g == qc::OpType::Y || g == qc::OpType::Z || | ||||||
g == qc::OpType::I) { | ||||||
result.push_back(g); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
} | ||||||
return GateSet(result); | ||||||
} | ||||||
|
||||||
[[nodiscard]] bool isValidGateSet() const { | ||||||
return std::all_of(gates.begin(), gates.end(), [](const auto& g) { | ||||||
return std::find(SINGLE_QUBIT_CLIFFORDS.begin(), | ||||||
SINGLE_QUBIT_CLIFFORDS.end(), | ||||||
g) != SINGLE_QUBIT_CLIFFORDS.end(); | ||||||
}); | ||||||
} | ||||||
|
||||||
// Any single-qubit Clifford gate can be obtained from a product of PI/2 | ||||||
// rotations around different axes. | ||||||
[[nodiscard]] bool isComplete() const { | ||||||
if (containsS() || containsSdg()) { | ||||||
if (containsSX() || containsSXdg() || containsH()) { | ||||||
return true; | ||||||
} | ||||||
} | ||||||
|
||||||
if (containsSX() || containsSXdg()) { | ||||||
if (containsH()) { | ||||||
return true; | ||||||
} | ||||||
} | ||||||
return false; | ||||||
} | ||||||
|
||||||
[[nodiscard]] std::string toString() const { | ||||||
std::string result = "{"; | ||||||
for (const auto& g : gates) { | ||||||
result += qc::toString(g) + ", "; | ||||||
} | ||||||
result += "}"; | ||||||
return result; | ||||||
} | ||||||
|
||||||
const qc::OpType& operator[](std::size_t index) const { return gates[index]; } | ||||||
/** | ||||||
* Pass-Through | ||||||
*/ | ||||||
|
||||||
// Iterators (pass-through) | ||||||
auto begin() noexcept { return gates.begin(); } | ||||||
[[nodiscard]] auto begin() const noexcept { return gates.begin(); } | ||||||
[[nodiscard]] auto cbegin() const noexcept { return gates.cbegin(); } | ||||||
auto end() noexcept { return gates.end(); } | ||||||
[[nodiscard]] auto end() const noexcept { return gates.end(); } | ||||||
[[nodiscard]] auto cend() const noexcept { return gates.cend(); } | ||||||
auto rbegin() noexcept { return gates.rbegin(); } | ||||||
[[nodiscard]] auto rbegin() const noexcept { return gates.rbegin(); } | ||||||
[[nodiscard]] auto crbegin() const noexcept { return gates.crbegin(); } | ||||||
auto rend() noexcept { return gates.rend(); } | ||||||
[[nodiscard]] auto rend() const noexcept { return gates.rend(); } | ||||||
[[nodiscard]] auto crend() const noexcept { return gates.crend(); } | ||||||
|
||||||
// Capacity (pass-through) | ||||||
[[nodiscard]] bool empty() const noexcept { return gates.empty(); } | ||||||
[[nodiscard]] std::size_t size() const noexcept { return gates.size(); } | ||||||
// NOLINTNEXTLINE(readability-identifier-naming) | ||||||
[[nodiscard]] std::size_t max_size() const noexcept { | ||||||
return gates.max_size(); | ||||||
} | ||||||
[[nodiscard]] std::size_t capacity() const noexcept { | ||||||
return gates.capacity(); | ||||||
} | ||||||
|
||||||
void reserve(const std::size_t newCap) { gates.reserve(newCap); } | ||||||
// NOLINTNEXTLINE(readability-identifier-naming) | ||||||
void shrink_to_fit() { gates.shrink_to_fit(); } | ||||||
|
||||||
// Modifiers (pass-through) | ||||||
void clear() noexcept { gates.clear(); } | ||||||
// NOLINTNEXTLINE(readability-identifier-naming) | ||||||
void pop_back() { return gates.pop_back(); } | ||||||
void resize(std::size_t count) { gates.resize(count); } | ||||||
iterator erase(const_iterator pos) { return gates.erase(pos); } | ||||||
iterator erase(const_iterator first, const_iterator last) { | ||||||
return gates.erase(first, last); | ||||||
} | ||||||
|
||||||
// NOLINTNEXTLINE(readability-identifier-naming) | ||||||
void push_back(const qc::OpType& gate) { | ||||||
if (!containsGate(gate)) { | ||||||
gates.push_back(gate); | ||||||
} | ||||||
} | ||||||
|
||||||
// NOLINTNEXTLINE(readability-identifier-naming) | ||||||
template <class T, class... Args> void emplace_back(Args&&... args) { | ||||||
gates.emplace_back(args...); | ||||||
} | ||||||
|
||||||
// NOLINTNEXTLINE(readability-identifier-naming) | ||||||
void emplace_back(qc::OpType& gate) { | ||||||
if (!containsGate(gate)) { | ||||||
gates.emplace_back(gate); | ||||||
} | ||||||
} | ||||||
|
||||||
// NOLINTNEXTLINE(readability-identifier-naming) | ||||||
void emplace_back(qc::OpType&& gate) { | ||||||
if (!containsGate(gate)) { | ||||||
gates.emplace_back(gate); | ||||||
} | ||||||
} | ||||||
|
||||||
[[nodiscard]] const auto& at(const std::size_t i) const { | ||||||
return gates.at(i); | ||||||
} | ||||||
[[nodiscard]] auto& at(const std::size_t i) { return gates.at(i); } | ||||||
[[nodiscard]] const auto& front() const { return gates.front(); } | ||||||
[[nodiscard]] const auto& back() const { return gates.back(); } | ||||||
}; | ||||||
Comment on lines
+160
to
+235
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's quite a long list of pass-through methods. Are all of these really necessary/helpful? |
||||||
|
||||||
} // namespace cs |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -6,6 +6,7 @@ | |||||
#pragma once | ||||||
|
||||||
#include "QuantumComputation.hpp" | ||||||
#include "operations/OpType.hpp" | ||||||
#include "utils/logging.hpp" | ||||||
|
||||||
#include <cstdint> | ||||||
|
@@ -50,7 +51,7 @@ class Tableau { | |||||
nQubits = tableau.size() / 2U; | ||||||
} | ||||||
|
||||||
[[nodiscard]] RowType operator[](const std::size_t index) { | ||||||
[[nodiscard]] RowType& operator[](const std::size_t index) { | ||||||
return tableau[index]; | ||||||
} | ||||||
[[nodiscard]] RowType operator[](const std::size_t index) const { | ||||||
|
@@ -98,6 +99,7 @@ class Tableau { | |||||
} | ||||||
|
||||||
void applyGate(const qc::Operation* gate); | ||||||
void applySingleQGate(const qc::OpType& gate, std::size_t target); | ||||||
void applyH(std::size_t target); | ||||||
void applyS(std::size_t target); | ||||||
void applySdag(std::size_t target); | ||||||
|
@@ -121,6 +123,19 @@ class Tableau { | |||||
return !(lhs == rhs); | ||||||
} | ||||||
|
||||||
[[nodiscard]] bool equalUpToPhase(const Tableau& rhs) const { | ||||||
const auto& lhsTab = this->getTableau(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
const auto& rhsTab = rhs.getTableau(); | ||||||
for (std::size_t i = 0; i < lhsTab.size(); ++i) { | ||||||
for (std::size_t j = 0; j < lhsTab[i].size() - 1; ++j) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might be stupid, but what is the |
||||||
if (lhsTab[i][j] != rhsTab[i][j]) { | ||||||
return false; | ||||||
} | ||||||
} | ||||||
} | ||||||
return true; | ||||||
} | ||||||
|
||||||
[[nodiscard]] bool isIdentityTableau() const; | ||||||
|
||||||
void createDiagonalTableau(std::size_t nQ, bool includeDestabilizers = false); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Heads-up: I personally despise |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// | ||
// This file is part of the MQT QMAP library released under the MIT license. | ||
// See README.md or go to https://github.com/cda-tum/qmap for more information. | ||
// | ||
|
||
#pragma once | ||
|
||
#include "cliffordsynthesis/GateSet.hpp" | ||
#include "operations/OpType.hpp" | ||
|
||
namespace cs { | ||
|
||
const GateSet PAULIS{ | ||
qc::OpType::None, | ||
qc::OpType::X, | ||
qc::OpType::Y, | ||
qc::OpType::Z, | ||
}; | ||
|
||
inline bool isPauli(const qc::OpType& gate) { | ||
return PAULIS.containsGate(gate); | ||
} | ||
|
||
qc::OpType multiplyPaulis(const GateSet& paulis); | ||
|
||
} // namespace cs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert these unrelated submodule change