Skip to content

Commit bccc324

Browse files
Merge remote-tracking branch 'upstream/main'
2 parents d93cec0 + 714d682 commit bccc324

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+2618
-5591
lines changed

.pre-commit-config.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,15 @@ repos:
5959

6060
# Python linting using ruff
6161
- repo: https://github.com/astral-sh/ruff-pre-commit
62-
rev: v0.9.4
62+
rev: v0.9.5
6363
hooks:
6464
- id: ruff
6565
args: ["--fix", "--show-fixes"]
6666
- id: ruff-format
6767

6868
# Static type checking using mypy
6969
- repo: https://github.com/pre-commit/mirrors-mypy
70-
rev: v1.14.1
70+
rev: v1.15.0
7171
hooks:
7272
- id: mypy
7373
files: ^(src/mqt|test/python|noxfile.py)

docs/mqt_core_ir.md

+28-5
Original file line numberDiff line numberDiff line change
@@ -298,16 +298,37 @@ qc.append(classic_controlled)
298298
print(qc)
299299
```
300300

301-
## Interfacing with other SDKs
301+
## Interfacing with other SDKs and Formats
302302

303-
Since a {py:class}`~mqt.core.ir.QuantumComputation` can be imported from and exported to an OpenQASM 3.0 (or OpenQASM 2.0) string, any library that can work with OpenQASM is easy to use in conjunction with the {py:class}`~mqt.core.ir.QuantumComputation` class.
303+
### OpenQASM
304304

305-
In addition, `mqt-core` can import [Qiskit](https://qiskit.org/) {py:class}`~qiskit.circuit.QuantumCircuit` objects directly.
305+
OpenQASM is a widely used format for representing quantum circuits.
306+
Its latest version, [OpenQASM 3](https://openqasm.com/index.html), is a powerful language that can express a wide range of quantum circuits.
307+
MQT Core supports the full functionality of OpenQASM 2.0 (including classically controlled operations) and a growing subset of OpenQASM 3.
306308

307309
```{code-cell} ipython3
308-
from qiskit import QuantumCircuit
310+
from mqt.core.ir import QuantumComputation
309311
310-
from mqt.core.plugins.qiskit import qiskit_to_mqt
312+
qasm_str = """
313+
OPENQASM 3.0;
314+
include "stdgates.inc";
315+
qubit[3] q;
316+
h q[0];
317+
cx q[0], q[1];
318+
cx q[0], q[2];
319+
"""
320+
321+
qc = QuantumComputation.from_qasm_str(qasm_str)
322+
323+
print(qc)
324+
```
325+
326+
### Qiskit
327+
328+
In addition to OpenQASM, `mqt-core` can natively import [Qiskit](https://qiskit.org/) {py:class}`~qiskit.circuit.QuantumCircuit` objects.
329+
330+
```{code-cell} ipython3
331+
from qiskit import QuantumCircuit
311332
312333
# GHZ circuit in qiskit
313334
qiskit_qc = QuantumCircuit(3)
@@ -319,6 +340,8 @@ qiskit_qc.draw(output="mpl", style="iqp")
319340
```
320341

321342
```{code-cell} ipython3
343+
from mqt.core.plugins.qiskit import qiskit_to_mqt
344+
322345
mqt_qc = qiskit_to_mqt(qiskit_qc)
323346
print(mqt_qc)
324347
```

include/mqt-core/Definitions.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ static constexpr fp E = static_cast<fp>(
5050
2.718281828459045235360287471352662497757247093699959574967L);
5151

5252
// supported file formats
53-
enum class Format : uint8_t { Real, OpenQASM2, OpenQASM3, TFC, QC, Tensor };
53+
enum class Format : uint8_t { OpenQASM2, OpenQASM3 };
5454

5555
/**
5656
* @brief 64bit mixing hash (from MurmurHash3)

include/mqt-core/ir/QuantumComputation.hpp

+8-36
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include <cstddef>
2323
#include <cstdint>
2424
#include <iostream>
25-
#include <map>
2625
#include <memory>
2726
#include <optional>
2827
#include <random>
@@ -68,10 +67,8 @@ class QuantumComputation {
6867
std::unordered_set<sym::Variable> occurringVariables;
6968

7069
public:
71-
QuantumComputation() = default;
72-
explicit QuantumComputation(std::size_t nq, std::size_t nc = 0U,
70+
explicit QuantumComputation(std::size_t nq = 0, std::size_t nc = 0U,
7371
std::size_t s = 0);
74-
explicit QuantumComputation(const std::string& filename, std::size_t s = 0U);
7572
QuantumComputation(QuantumComputation&& qc) noexcept = default;
7673
QuantumComputation& operator=(QuantumComputation&& qc) noexcept = default;
7774
QuantumComputation(const QuantumComputation& qc);
@@ -82,13 +79,6 @@ class QuantumComputation {
8279
Permutation initialLayout{};
8380
Permutation outputPermutation{};
8481

85-
/**
86-
* @brief Construct a QuantumComputation from an OpenQASM string
87-
* @param qasm The OpenQASM 2.0 or 3.0 string
88-
* @return The constructed QuantumComputation
89-
*/
90-
[[nodiscard]] static QuantumComputation fromQASM(const std::string& qasm);
91-
9282
/**
9383
* @brief Construct a QuantumComputation from CompoundOperation object
9484
* @details The function creates a copy of each operation in the compound
@@ -114,9 +104,11 @@ class QuantumComputation {
114104
[[nodiscard]] const std::vector<bool>& getAncillary() const noexcept {
115105
return ancillary;
116106
}
107+
[[nodiscard]] std::vector<bool>& getAncillary() noexcept { return ancillary; }
117108
[[nodiscard]] const std::vector<bool>& getGarbage() const noexcept {
118109
return garbage;
119110
}
111+
[[nodiscard]] std::vector<bool>& getGarbage() noexcept { return garbage; }
120112
[[nodiscard]] std::size_t getNcbits() const noexcept { return nclassics; }
121113
[[nodiscard]] std::string getName() const noexcept { return name; }
122114
[[nodiscard]] const auto& getQuantumRegisters() const noexcept {
@@ -372,9 +364,6 @@ class QuantumComputation {
372364
/// qubits occurring in the output permutation
373365
void stripIdleQubits(bool force = false);
374366

375-
void import(const std::string& filename);
376-
void import(const std::string& filename, Format format);
377-
void import(std::istream& is, Format format);
378367
void initializeIOMapping();
379368
// append measurements to the end of the circuit according to the tracked
380369
// output permutation
@@ -408,7 +397,8 @@ class QuantumComputation {
408397
void addQubit(Qubit logicalQubitIndex, Qubit physicalQubitIndex,
409398
std::optional<Qubit> outputQubitIndex);
410399

411-
QuantumComputation instantiate(const VariableAssignment& assignment) const;
400+
[[nodiscard]] QuantumComputation
401+
instantiate(const VariableAssignment& assignment) const;
412402
void instantiateInplace(const VariableAssignment& assignment);
413403

414404
void addVariable(const SymbolOrNumber& expr);
@@ -449,20 +439,15 @@ class QuantumComputation {
449439
static std::ostream& printPermutation(const Permutation& permutation,
450440
std::ostream& os = std::cout);
451441

452-
void dump(const std::string& filename, Format format) const;
453-
void dump(const std::string& filename) const;
454-
void dump(std::ostream& of, Format format) const;
455-
void dumpOpenQASM2(std::ostream& of) const { dumpOpenQASM(of, false); }
456-
void dumpOpenQASM3(std::ostream& of) const { dumpOpenQASM(of, true); }
442+
void dump(const std::string& filename,
443+
Format format = Format::OpenQASM3) const;
457444

458445
/**
459446
* @brief Dumps the circuit in OpenQASM format to the given output stream
460-
* @details One might want to call `ensureContiguousInitialLayout` before
461-
* calling this function to ensure full layout information is available.
462447
* @param of The output stream to write the OpenQASM representation to
463448
* @param openQasm3 Whether to use OpenQASM 3.0 or 2.0
464449
*/
465-
void dumpOpenQASM(std::ostream& of, bool openQasm3) const;
450+
void dumpOpenQASM(std::ostream& of, bool openQasm3 = true) const;
466451

467452
/**
468453
* @brief Returns the OpenQASM representation of the circuit
@@ -500,19 +485,6 @@ class QuantumComputation {
500485
[[nodiscard]] bool isDynamic() const;
501486

502487
protected:
503-
void importOpenQASM3(std::istream& is);
504-
void importReal(std::istream& is);
505-
int readRealHeader(std::istream& is);
506-
void readRealGateDescriptions(std::istream& is, int line);
507-
void importTFC(std::istream& is);
508-
int readTFCHeader(std::istream& is, std::map<std::string, Qubit>& varMap);
509-
void readTFCGateDescriptions(std::istream& is, int line,
510-
std::map<std::string, Qubit>& varMap);
511-
void importQC(std::istream& is);
512-
int readQCHeader(std::istream& is, std::map<std::string, Qubit>& varMap);
513-
void readQCGateDescriptions(std::istream& is, int line,
514-
std::map<std::string, Qubit>& varMap);
515-
516488
[[nodiscard]] std::size_t getSmallestAncillary() const {
517489
for (std::size_t i = 0; i < ancillary.size(); ++i) {
518490
if (ancillary[i]) {

0 commit comments

Comments
 (0)