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

✨ OpenQASM 3.0 support #309

Merged
merged 116 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
ef86fb2
Add OpenQASM 3.0 parser
martin-fink Oct 21, 2023
0ecaffb
🎨 pre-commit fixes
pre-commit-ci[bot] Oct 24, 2023
bcec8e2
cleanup code
martin-fink Nov 2, 2023
58fdfde
Rename constructor params to fix shadowing warnings
martin-fink Nov 2, 2023
d7c6335
Update code
martin-fink Nov 2, 2023
66b04ac
Add unit tests
martin-fink Nov 6, 2023
0e3c435
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 6, 2023
c5cf9de
Merge remote-tracking branch 'upstream/main'
martin-fink Nov 6, 2023
25b57fd
Add support for if statements
martin-fink Nov 10, 2023
bc4bf8d
Implicitly include stdgates.inc
martin-fink Nov 10, 2023
e3baeb7
Add dumpOpenQASM3
martin-fink Nov 11, 2023
62c1092
Add support for teleport/opaque gates
martin-fink Nov 14, 2023
f346500
Warn user if old-style designator is encountered.
martin-fink Nov 14, 2023
d4ffa56
Merge remote-tracking branch 'upstream/main'
martin-fink Nov 14, 2023
b93e8f5
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 14, 2023
b7ebfcb
Apply suggestions from code review
martin-fink Nov 25, 2023
52be091
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 25, 2023
4c37b9b
Return false in CompoundOperation::isControlled
martin-fink Nov 14, 2023
0538944
In OpenQASM 2.0 mode, set MaxControls to 2
martin-fink Nov 14, 2023
6ad0fc1
Fix formatting of operations with controls but no targets.
martin-fink Nov 14, 2023
ff1bf7e
Use native gates for p, swap, iswap
martin-fink Nov 14, 2023
0341b6c
If encountering a compound gate with only one op, inline the gate.
martin-fink Nov 14, 2023
323a795
zx: Handle nested compound ops
martin-fink Nov 16, 2023
248022b
Throw an error for duplicate qubits in controls/targets
martin-fink Nov 16, 2023
970d02f
Fix parsing floats
martin-fink Nov 16, 2023
4ad1da9
Fix dumpOpenQASM3
martin-fink Nov 16, 2023
2423847
Support reset, barrier in gate declarations
martin-fink Nov 16, 2023
f1783e3
Support if statements with single statement as body
martin-fink Nov 16, 2023
4aefcf8
Format code
martin-fink Nov 16, 2023
f688a39
Switch tests to OpenQASM 3.0 parser
martin-fink Nov 16, 2023
9733088
Move import tests to own test suite
martin-fink Nov 25, 2023
f979139
Replace default argument `dumpOpenQASM` with overloads
martin-fink Nov 26, 2023
b60eb6a
Remove reference to istream in scanner
martin-fink Nov 26, 2023
27b9627
Implement review suggestions
martin-fink Nov 26, 2023
9f1f834
Use natively supported gates instead of parsing stdgates
martin-fink Nov 26, 2023
3768a40
Remove relative imports
martin-fink Nov 26, 2023
a997b03
Enable time-unit keywords.
martin-fink Nov 26, 2023
8db2aed
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 26, 2023
022b10e
Merge remote-tracking branch 'upstream/main'
martin-fink Nov 26, 2023
0627bd3
Fix io tests
martin-fink Nov 26, 2023
5c5fa58
Refactor dumping to OpenQASM2/3 to reduce code duplication
martin-fink Nov 26, 2023
e6bd29c
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 26, 2023
70de345
Fixed typos
martin-fink Nov 26, 2023
657120f
Add #ifdef for call to __builtin_unreachable
martin-fink Nov 26, 2023
069dfb3
Make var const
martin-fink Nov 26, 2023
96aee66
Add test to parse control modifiers
martin-fink Nov 26, 2023
20f35fb
Fix typo
martin-fink Nov 26, 2023
c0a7b4b
Fix some warnings
martin-fink Nov 26, 2023
1ed0b2d
Remove main
martin-fink Nov 26, 2023
b7f8796
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 26, 2023
873e405
Fix some warnings
martin-fink Nov 26, 2023
4d74d67
Include math header
martin-fink Nov 26, 2023
f06039c
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 26, 2023
23ac9fb
Fix warnings
martin-fink Nov 26, 2023
86a07f0
Fixed clang-tidy warnings
martin-fink Nov 26, 2023
dd11140
Fix build on windows
martin-fink Nov 26, 2023
c62d0ab
fixed clang-tidy warnings
martin-fink Nov 26, 2023
1fa3151
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 26, 2023
d8e4de3
Add tests to increase coverage
martin-fink Nov 26, 2023
640297e
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 26, 2023
027a7fc
Fix warnings
martin-fink Nov 29, 2023
135dff0
Fix build on windows
martin-fink Nov 29, 2023
bb616f6
Add expet include
martin-fink Nov 29, 2023
40e10fd
Merge remote-tracking branch 'upstream/main'
martin-fink Nov 29, 2023
5fa2b29
Add error handling tests
martin-fink Nov 29, 2023
510dea4
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 29, 2023
99f59dd
Add constant eval tests
martin-fink Nov 29, 2023
e205cff
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 29, 2023
13c17ca
Fix some warnings
martin-fink Nov 29, 2023
264e5ff
Replace duplicate types with template class
martin-fink Nov 30, 2023
0850bd7
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 30, 2023
9248106
Implement support for mc* gates
martin-fink Dec 4, 2023
f2f825b
Add iswapdg gate
martin-fink Dec 4, 2023
d93a300
Remove QASMParser
martin-fink Dec 4, 2023
250893e
Factor out mc* gate definition method
martin-fink Dec 4, 2023
def5881
fix windows build
martin-fink Dec 4, 2023
b3fcacc
🎨 pre-commit fixes
pre-commit-ci[bot] Dec 4, 2023
58f869b
fix build
martin-fink Dec 4, 2023
ba535eb
🎨 pre-commit fixes
pre-commit-ci[bot] Dec 4, 2023
03e4897
Add more tests
martin-fink Dec 4, 2023
fafcdae
Fix code warnings
martin-fink Dec 4, 2023
a72f72d
🎨 pre-commit fixes
pre-commit-ci[bot] Dec 4, 2023
46eed04
Fix test
martin-fink Dec 4, 2023
8979412
Fix code warnings
martin-fink Dec 4, 2023
bb30fd5
Add some more tests
martin-fink Dec 4, 2023
44de01b
Merge remote-tracking branch 'upstream/main'
martin-fink Dec 6, 2023
e44f8c6
Rename dumpOpenQASM to dumpOpenQASM2
martin-fink Dec 6, 2023
acd5ebe
Introduce constant for indent size
martin-fink Dec 6, 2023
d6d9f2a
Fix CompoundOperation::isControlled
martin-fink Dec 6, 2023
cc1a14c
Rename dumpOpenQASM to dumpOpenQASM2
martin-fink Dec 6, 2023
836175e
Use `U` gate when dumping OpenQASM 2
martin-fink Dec 6, 2023
fac2019
Refactor StandardOperation::dumpOpenQASM
martin-fink Dec 7, 2023
cdaf723
Remove comments
martin-fink Dec 7, 2023
a42b62f
Handle gphase in zx construction
martin-fink Dec 7, 2023
98aa8c5
Fix dumpOpenQASM python interface
martin-fink Dec 7, 2023
ebdcbde
🎨 pre-commit fixes
pre-commit-ci[bot] Dec 7, 2023
4ac244d
Fix dumpOpenQASM python interface
martin-fink Dec 7, 2023
83c0089
Remove faulty test
martin-fink Dec 7, 2023
7139215
Update include/operations/CompoundOperation.hpp
burgholzer Dec 11, 2023
2429703
Fix codeql warnings
martin-fink Dec 11, 2023
18d6074
Merge branch 'main' into main
burgholzer Dec 11, 2023
a57666a
Update src/parsers/QASM3Parser.cpp
burgholzer Dec 12, 2023
4cf0eb7
Update src/parsers/QASM3Parser.cpp
burgholzer Dec 12, 2023
f6d4eea
🎨 pre-commit fixes
pre-commit-ci[bot] Dec 12, 2023
9cd5d35
Update failing test
martin-fink Dec 13, 2023
fb5c507
Use natively supported gates instead of parsing stdgates.inc
martin-fink Dec 13, 2023
7c486ca
Ignore redeclaration of standard gates
martin-fink Dec 13, 2023
72ceb3c
Introduce OpenQASM 2.0 compat mode
martin-fink Dec 13, 2023
3300ede
In OpenQASM 2.0 compat mode, ignore gate redefinitions with `c` prefixes
martin-fink Dec 13, 2023
a7897d5
Remove Comment token, add separate tokens for InitialLayout and Outpu…
martin-fink Dec 13, 2023
22ca99c
🚨 fix a couple of clang-tidy warnings
burgholzer Dec 13, 2023
4d0973f
Merge branch 'main' into oq3
burgholzer Dec 13, 2023
c0217f6
♻️ also allow `mcx_*` and `mcphase` definitions in `openQASM2CompatMo…
burgholzer Dec 13, 2023
386cb14
🔥 remove `maxControls`
burgholzer Dec 13, 2023
29734f3
♻️ move `QASM2_COMPAT_GATES` to `STANDARD_GATES`. There is no real re…
burgholzer Dec 13, 2023
eb7a097
✏️ adjust std gates documentation
burgholzer Dec 13, 2023
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
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,7 @@ if(BUILD_MQT_CORE_TESTS)
include(GoogleTest)
add_subdirectory(test)
endif()

# TODO: remove before merging
add_executable(main-test src/main.cpp)
target_link_libraries(main-test PUBLIC MQT::qfr)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The MQT Core library forms the backbone of the quantum software tools developed
- [MQT DDVis](https://github.com/cda-tum/mqt-ddvis): A Web-Application visualizing Decision Diagrams for Quantum Computing.
- [MQT SyReC](https://github.com/cda-tum/mqt-syrec): A Tool for Synthesis of Reversible Circuits/Quantum Computing Oracles.

For a full list of tools and libraries, please visit the [MQT website](https://mqt.readthedocs.io/).
For a full list of tools and libraries, please run the [MQT website](https://mqt.readthedocs.io/).
martin-fink marked this conversation as resolved.
Show resolved Hide resolved

<p align="center">
<a href="https://mqt.readthedocs.io/projects/core">
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The MQT Core library forms the backbone of the quantum software tools developed
- [MQT DDVis](https://github.com/cda-tum/mqt-ddvis): A Web-Application visualizing Decision Diagrams for Quantum Computing.
- {doc}`MQT SyReC <syrec:index>`: A Tool for Synthesis of Reversible Circuits/Quantum Computing Oracles.

For a full list of tools and libraries, please visit the {doc}`MQT website <mqt:index>`.
For a full list of tools and libraries, please run the {doc}`MQT website <mqt:index>`.
martin-fink marked this conversation as resolved.
Show resolved Hide resolved

```{include} ../README.md
:start-after: <!-- SPHINX-START -->
Expand Down
6 changes: 5 additions & 1 deletion include/Definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,16 @@ static constexpr fp PI_2 = static_cast<fp>(
1.570796326794896619231321691639751442098584699687552910487L);
static constexpr fp PI_4 = static_cast<fp>(
0.785398163397448309615660845819875721049292349843776455243L);
static constexpr fp TAU = static_cast<fp>(
6.283185307179586476925286766559005768394338798750211641950L);
static constexpr fp E = static_cast<fp>(
2.718281828459045235360287471352662497757247093699959574967L);

// forward declaration
class Operation;

// supported file formats
enum class Format { Real, OpenQASM, GRCS, TFC, QC, Tensor };
enum class Format { Real, OpenQASM, OpenQASM3, GRCS, TFC, QC, Tensor };

using DAG = std::vector<std::deque<std::unique_ptr<Operation>*>>;
using DAGIterator = std::deque<std::unique_ptr<Operation>*>::iterator;
Expand Down
14 changes: 10 additions & 4 deletions include/QuantumComputation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
std::unordered_set<sym::Variable> occuringVariables;

void importOpenQASM(std::istream& is);
void importOpenQASM3(std::istream& is);
void importReal(std::istream& is);
int readRealHeader(std::istream& is);
void readRealGateDescriptions(std::istream& is, int line);
Expand All @@ -70,7 +71,7 @@
template <class RegisterType>
static void printSortedRegisters(const RegisterMap<RegisterType>& regmap,
const std::string& identifier,
std::ostream& of) {
std::ostream& of, bool openQASM3 = false) {
// sort regs by start index
std::map<decltype(RegisterType::first),
std::pair<std::string, RegisterType>>
Expand All @@ -80,8 +81,13 @@
}

for (const auto& reg : sortedRegs) {
of << identifier << " " << reg.second.first << "["
<< reg.second.second.second << "];" << std::endl;
if (openQASM3) {
of << identifier << "[" << reg.second.second.second << "] "
<< reg.second.first << ";" << std::endl;
} else {
of << identifier << " " << reg.second.first << "["
<< reg.second.second.second << "];" << std::endl;
}
}
}
template <class RegisterType>
Expand Down Expand Up @@ -746,7 +752,7 @@
dump(std::move(of), format);
}
virtual void dump(std::ostream&& of, Format format);
virtual void dumpOpenQASM(std::ostream& of);
virtual void dumpOpenQASM(std::ostream& of, bool openQASM3 = false);

Check warning on line 755 in include/QuantumComputation.hpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

/include/QuantumComputation.hpp:755:16 [google-default-arguments]

default arguments on virtual or override methods are prohibited
martin-fink marked this conversation as resolved.
Show resolved Hide resolved

// this convenience method allows to turn a circuit into a compound operation.
std::unique_ptr<CompoundOperation> asCompoundOperation() {
Expand Down
35 changes: 31 additions & 4 deletions include/operations/ClassicControlledOperation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,33 @@

namespace qc {

enum ComparisonKind {
Eq,
Neq,
Lt,
Leq,
Gt,
Geq,
};

std::ostream& operator<<(std::ostream& os, const ComparisonKind& kind);

class ClassicControlledOperation final : public Operation {
private:
std::unique_ptr<Operation> op;
ClassicalRegister controlRegister{};
std::uint64_t expectedValue = 1U;
ComparisonKind comparisonKind = ComparisonKind::Eq;

public:
// Applies operation `_op` if the creg starting at index `control` has the
// expected value
ClassicControlledOperation(std::unique_ptr<qc::Operation>& operation,
ClassicalRegister controlReg,
std::uint64_t expectedVal = 1U)
std::uint64_t expectedVal = 1U,
ComparisonKind kind = ComparisonKind::Eq)
: op(std::move(operation)), controlRegister(std::move(controlReg)),
expectedValue(expectedVal) {
expectedValue(expectedVal), comparisonKind(kind) {
nqubits = op->getNqubits();
name = "c_" + shortName(op->getType());
parameter.reserve(3);
Expand Down Expand Up @@ -108,7 +121,8 @@
return false;
}

if (expectedValue != classic->expectedValue) {
if (expectedValue != classic->expectedValue ||
comparisonKind != classic->comparisonKind) {
return false;
}

Expand All @@ -124,10 +138,23 @@
const RegisterNames& creg) const override {
of << "if(";
of << creg[controlRegister.first].first;
of << " == " << expectedValue << ") ";
of << " " << comparisonKind << " " << expectedValue << ") ";
op->dumpOpenQASM(of, qreg, creg);
}

void dumpOpenQASM3(std::ostream& of, const RegisterNames& qreg,

Check warning on line 145 in include/operations/ClassicControlledOperation.hpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

/include/operations/ClassicControlledOperation.hpp:145:8 [google-default-arguments]

default arguments on virtual or override methods are prohibited
const RegisterNames& creg,
uint32_t indent = 0) const override {
martin-fink marked this conversation as resolved.
Show resolved Hide resolved
for (uint32_t i = 0; i < indent; ++i) {
of << " ";
}
martin-fink marked this conversation as resolved.
Show resolved Hide resolved
of << "if (";
of << creg[controlRegister.first].first;
of << " " << comparisonKind << " " << expectedValue << ") {\n";
op->dumpOpenQASM3(of, qreg, creg, indent + 1);
of << "}\n";
}

void invert() override { op->invert(); }
};
} // namespace qc
Expand Down
8 changes: 8 additions & 0 deletions include/operations/CompoundOperation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,14 @@
}
}

void dumpOpenQASM3(std::ostream& of, const RegisterNames& qreg,

Check warning on line 159 in include/operations/CompoundOperation.hpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

/include/operations/CompoundOperation.hpp:159:8 [google-default-arguments]

default arguments on virtual or override methods are prohibited
const RegisterNames& creg,
uint32_t indent = 0) const override {
martin-fink marked this conversation as resolved.
Show resolved Hide resolved
for (const auto& op : ops) {
op->dumpOpenQASM3(of, qreg, creg, indent);
}
}

/**
* Pass-Through
*/
Expand Down
3 changes: 3 additions & 0 deletions include/operations/NonUnitaryOperation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ class NonUnitaryOperation final : public Operation {
void dumpOpenQASM(std::ostream& of, const RegisterNames& qreg,
const RegisterNames& creg) const override;

void dumpOpenQASM3(std::ostream& of, const RegisterNames& qreg,
const RegisterNames& creg, uint32_t indent) const override;

void invert() override {
throw QFRException("Inverting a non-unitary operation is not supported.");
}
Expand Down
4 changes: 4 additions & 0 deletions include/operations/Operation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@
virtual void dumpOpenQASM(std::ostream& of, const RegisterNames& qreg,
const RegisterNames& creg) const = 0;

virtual void dumpOpenQASM3(std::ostream& of, const RegisterNames& qreg,

Check warning on line 182 in include/operations/Operation.hpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

/include/operations/Operation.hpp:182:16 [google-default-arguments]

default arguments on virtual or override methods are prohibited
const RegisterNames& creg,
uint32_t indent = 0) const = 0;
martin-fink marked this conversation as resolved.
Show resolved Hide resolved

virtual void invert() = 0;

virtual bool operator==(const Operation& rhs) const { return equals(rhs); }
Expand Down
4 changes: 3 additions & 1 deletion include/operations/StandardOperation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@

void dumpOpenQASM(std::ostream& of, const RegisterNames& qreg,
const RegisterNames& creg) const override;

void dumpOpenQASM3(std::ostream& of, const RegisterNames& qreg,

Check warning on line 107 in include/operations/StandardOperation.hpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

/include/operations/StandardOperation.hpp:107:8 [google-default-arguments]

default arguments on virtual or override methods are prohibited
const RegisterNames& creg,
uint32_t indent = 0) const override;
martin-fink marked this conversation as resolved.
Show resolved Hide resolved
void invert() override;
};

Expand Down
4 changes: 4 additions & 0 deletions include/operations/SymbolicOperation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@
[[noreturn]] void dumpOpenQASM(std::ostream& of, const RegisterNames& qreg,
const RegisterNames& creg) const override;

[[noreturn]] void dumpOpenQASM3(std::ostream& of, const RegisterNames& qreg,

Check warning on line 140 in include/operations/SymbolicOperation.hpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

/include/operations/SymbolicOperation.hpp:140:21 [google-default-arguments]

default arguments on virtual or override methods are prohibited
const RegisterNames& creg,
uint32_t indent = 0) const override;
martin-fink marked this conversation as resolved.
Show resolved Hide resolved

[[nodiscard]] StandardOperation
getInstantiatedOperation(const VariableAssignment& assignment) const;

Expand Down
54 changes: 54 additions & 0 deletions include/parsers/qasm3_parser/Gate.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#pragma once

#include "NestedEnvironment.hpp"
#include "QuantumComputation.hpp"
#include "Statement.hpp"

namespace qasm3 {
struct GateInfo {
public:
size_t nControls;
size_t nTargets;
size_t nParameters;
qc::OpType type;
};

struct Gate {
public:
virtual ~Gate() = default;

virtual size_t getNControls() = 0;
virtual size_t getNTargets() = 0;
virtual size_t getNParameters() = 0;
};

struct StandardGate : public Gate {
public:
GateInfo info;

explicit StandardGate(GateInfo gateInfo) : info(gateInfo) {}

size_t getNControls() override { return info.nControls; }

size_t getNTargets() override { return info.nTargets; }
size_t getNParameters() override { return info.nParameters; }
};

struct CompoundGate : public Gate {
public:
std::vector<std::string> parameterNames;
std::vector<std::string> targetNames;
std::vector<std::shared_ptr<GateCallStatement>> body;

explicit CompoundGate(
std::vector<std::string> parameters, std::vector<std::string> targets,
std::vector<std::shared_ptr<GateCallStatement>> bodyStatements)
: parameterNames(std::move(parameters)), targetNames(std::move(targets)),
body(std::move(bodyStatements)) {}

size_t getNControls() override { return 0; }

size_t getNTargets() override { return targetNames.size(); }
size_t getNParameters() override { return parameterNames.size(); }
};
} // namespace qasm3
Loading
Loading