Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions src/mqt/bench/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
!*.qasm
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Negation won’t catch nested .qasm files

!*.qasm only re-includes files directly under this folder, not nested ones (e.g., benchmarks/structured/**). If the parent .gitignore ignores *.qasm, nested files remain ignored. Use a recursive pattern.

-!*.qasm
+!*.qasm
+!**/*.qasm

If the parent doesn’t ignore *.qasm, consider removing this file altogether to avoid confusion.


🏁 Script executed:

#!/usr/bin/env bash
# Search for qasm ignore patterns in all .gitignore files
rg -n '\*\.qasm' -g '*.gitignore'

Length of output: 54


Include nested .qasm files
Root .gitignore ignores *.qasm, so !*.qasm here only re-includes files directly under this folder. Add a recursive pattern:

 !*.qasm
+!**/*.qasm
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
!*.qasm
!*.qasm
!**/*.qasm
🤖 Prompt for AI Agents
In src/mqt/bench/.gitignore around lines 1 to 1, the file currently re-includes
only top-level .qasm files with "!*.qasm" but the repo root ignores "*.qasm"
recursively; update this file to re-include nested .qasm files by using a
recursive negation pattern (e.g., "!**/*.qasm") so that .qasm files in
subdirectories beneath src/mqt/bench are not excluded.

11 changes: 11 additions & 0 deletions src/mqt/bench/benchmarks/structured/ghz/ghz.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
OPENQASM 3.0;
include "qelib1.inc";

input int n;

qubit[n] q;

h q[0];
for int i in [1:n-1] {
cx q[i - 1], q[i];
}
Comment on lines +4 to +11
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Guard against n == 0 (q[0] access)

Program assumes n ≥ 1 due to h q[0]. Add a precondition note or a runtime guard to avoid invalid indexing for n == 0.

Example guard:

 input int n;
 
 qubit[n] q;
 
+// Require n >= 1
+if (n == 0) {
+    // no-op or raise, depending on your bench conventions
+}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/mqt/bench/benchmarks/structured/ghz/ghz.qasm around lines 4 to 11, the
code unconditionally accesses q[0] and will fail when n == 0; add a guard so the
circuit and operations are only emitted when n >= 1 (for example, conditionally
declare/operate on qubits or return early if n == 0), or document a precondition
explicitly that n must be >= 1; ensure both the h q[0] and the for-loop body are
skipped when n == 0 to avoid invalid indexing.

24 changes: 24 additions & 0 deletions src/mqt/bench/benchmarks/structured/grover/grover.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
OPENQASM 3.0;
include "qelib1.inc";

input int n;

qubit[n-1] q;
qubit flag;

h q;
x flag;

int num_iterations = int(pi / 4 * 2**(n-1)**0.5);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix the operator precedence in the Grover iteration formula.

The expression 2**(n-1)**0.5 evaluates as 2^(sqrt(n-1)) due to operator precedence (exponentiation is right-associative), but the correct Grover formula requires sqrt(2^(n-1)) or 2^((n-1)/2).

For example, with n=5 (4 search qubits):

  • Current: 2^(sqrt(4)) = 2^2 = 4 iterations
  • Correct: sqrt(2^4) = sqrt(16) = 4 iterations

While these happen to match for n=5, they diverge for other values:

  • n=9: Current gives 2^(sqrt(8)) ≈ 5.66, Correct gives sqrt(2^8) = 16

Apply this diff to fix the formula:

-int num_iterations = int(pi / 4 * 2**(n-1)**0.5);
+int num_iterations = int(pi / 4 * sqrt(2**(n-1)));

Or equivalently:

-int num_iterations = int(pi / 4 * 2**(n-1)**0.5);
+int num_iterations = int(pi / 4 * 2**((n-1)/2.0));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
int num_iterations = int(pi / 4 * 2**(n-1)**0.5);
int num_iterations = int(pi / 4 * sqrt(2**(n-1)));
🤖 Prompt for AI Agents
In src/mqt/bench/benchmarks/structured/grover/grover.qasm around line 12, the
Grover iteration formula uses wrong operator precedence: replace int
num_iterations = int(pi / 4 * 2**(n-1)**0.5); with an expression that computes
the square root of 2^(n-1) — e.g., use int num_iterations = int(pi / 4 *
(2**(n-1))**0.5); or int num_iterations = int(pi / 4 * 2**((n-1)/2)); so the
exponentiation groups correctly and yields sqrt(2^(n-1)).


for int i in [1:num_iterations] {
// oracle
ctrl(n-1) @ z q[0:n-1], flag;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Out-of-bounds array access on line 16.

The register q is declared as qubit[n-1] on line 6, which creates a register with indices 0 through n-2. Accessing q[0:n-1] attempts to access index n-1, which is out of bounds.

Apply this diff to fix the indexing:

-    ctrl(n-1) @ z q[0:n-1], flag;
+    ctrl(n-1) @ z q, flag;

Note: In OpenQASM 3.0, using the register name q without explicit indices applies the gate to all qubits in the register.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ctrl(n-1) @ z q[0:n-1], flag;
ctrl(n-1) @ z q, flag;
🤖 Prompt for AI Agents
In src/mqt/bench/benchmarks/structured/grover/grover.qasm around line 16, the
slice q[0:n-1] is out-of-bounds because q is declared qubit[n-1] (indices
0..n-2); replace the indexed slice with the register name q (or use q[0:n-2] if
an explicit range is desired) so the controlled Z gate applies to the valid
qubits of the register.


// diffusion
h q;
x q;
ctrl(n-2) @ z q[0:n-2], q[n-1];
x q;
h q;
}
17 changes: 17 additions & 0 deletions src/mqt/bench/benchmarks/structured/iqft/iqft.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
OPENQASM 3.0;
include "qelib1.inc";

input int n;

qubit q;
bit[n] res;

for int i in [0:n-1] {
for int j in [0:i-1] {
if (res[n - 1 - j]) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use explicit comparison for bit conditions

Make bit checks explicit for broader parser compatibility.

-        if (res[n - 1 - j]) {
+        if (res[n - 1 - j] == 1) {
🤖 Prompt for AI Agents
In src/mqt/bench/benchmarks/structured/iqft/iqft.qasm around line 11, the
conditional if (res[n - 1 - j]) relies on truthiness; change it to an explicit
comparison (e.g., compare to 1) so the bit check is unambiguous and compatible
with stricter parsers — replace the truthy check with an explicit equality check
against the bit value.

p(2*pi/2**(i-j+1)) q;
}
}
h q;
res[n - 1 - i] = measure q;
}
Comment on lines +15 to +17
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Reset after measurement to avoid state carryover

Unlike iqpe, this program doesn’t reset q after measuring. Add reset q; to make iterations independent and consistent across backends.

-    res[n - 1 - i] = measure q;
+    res[n - 1 - i] = measure q;
+    reset q;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
h q;
res[n - 1 - i] = measure q;
}
h q;
res[n - 1 - i] = measure q;
reset q;
}
🤖 Prompt for AI Agents
In src/mqt/bench/benchmarks/structured/iqft/iqft.qasm around lines 15 to 17, the
code measures qubit q but does not reset it, causing state carryover between
iterations; after the line with "res[n - 1 - i] = measure q;" add a "reset q;"
statement immediately following the measurement (inside the same loop scope) so
each iteration starts with q in the |0> state and backends produce consistent,
independent results.

23 changes: 23 additions & 0 deletions src/mqt/bench/benchmarks/structured/iqpe/iqpe.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
OPENQASM 3.0;
include "qelib1.inc";

input int precision;

qubit q;
qubit anc;
bit[precision] res;

x anc;

for int i in [precision - 1:0:-1] {
h q;
pow(2**i) @ cp(3*pi/8) q, anc;
for int j in [i + 1:precision - 1] {
Comment on lines +12 to +15
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Verify support for pow(2**i) @ with non-constant exponent

Some parsers (e.g., current Qiskit) may not support pow with a loop variable. If compatibility is required, unroll explicitly:

-    pow(2**i) @ cp(3*pi/8) q, anc;
+    // Fallback for parsers without pow(@) support:
+    for int k in [0:2**i-1] {
+        cp(3*pi/8) q, anc;
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for int i in [precision - 1:0:-1] {
h q;
pow(2**i) @ cp(3*pi/8) q, anc;
for int j in [i + 1:precision - 1] {
for int i in [precision - 1:0:-1] {
h q;
// Fallback for parsers without pow(@) support:
for int k in [0:2**i-1] {
cp(3*pi/8) q, anc;
}
for int j in [i + 1:precision - 1] {
🤖 Prompt for AI Agents
In src/mqt/bench/benchmarks/structured/iqpe/iqpe.qasm around lines 12–15, the
use of pow(2**i) with a loop variable may not be accepted by some parsers;
replace it with a form that uses a constant exponent per emitted instruction by
either unrolling the outer loop so each iteration emits pow with a literal
integer exponent (e.g., pow(1), pow(2), pow(4), ...) or convert the construct to
apply the base gate repeated by a loop that multiplies/accumulates a constant
exponent per iteration (for example emit pow(2) repeated i times or compute the
integer value before emitting), ensuring every emitted pow(...) has a
compile-time constant exponent.

if (res[j]) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use explicit comparison for bit conditions

Many toolchains require bit to be compared explicitly rather than used as a boolean.

-        if (res[j]) {
+        if (res[j] == 1) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (res[j]) {
if (res[j] == 1) {
🤖 Prompt for AI Agents
In src/mqt/bench/benchmarks/structured/iqpe/iqpe.qasm around line 16, the
condition uses the bit value directly ("if (res[j])"); change it to an explicit
comparison (e.g., "if (res[j] == 1)") so the bit is compared to 0/1 explicitly
to satisfy toolchains that disallow implicit boolean coercion; ensure you
compare to the correct numeric value (1) and keep the rest of the logic
unchanged.

p(2*pi/2**(j-i+1)) q;
}
}
h q;
res[i] = measure q;
reset q;
}
41 changes: 41 additions & 0 deletions src/mqt/bench/benchmarks/structured/multiplexer/multiplexer.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
OPENQASM 3.0;

// Quantum Multiplexer (Uniformly Controlled RY Gates)
// Applies 2^n different RY rotations based on n control qubits

input int n;
int num_controls = n - 1;
input angle[2**num_controls] angles;
Comment on lines +7 to +8
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify OpenQASM 3.0 support for runtime-sized array declarations.

Line 8 declares an input array with size 2**num_controls, where num_controls is computed at runtime from the input parameter n. OpenQASM 3.0 typically requires array dimensions to be compile-time constants. This may cause parsing errors when the benchmark is compiled.

Run the following verification to check OpenQASM 3.0 specification and test with available parsers:


🌐 Web query:

Does OpenQASM 3.0 support array declarations with runtime-computed sizes like "input angle[2**num_controls] angles" where num_controls is derived from an input parameter?

💡 Result:

Short answer: No — OpenQASM 3.0 requires array/register sizes to be compile‑time constants. You cannot declare a global array with a size computed only at runtime (e.g. input angle[2**num_controls] where num_controls is a non-const input). See the specification passages that sizes must be compile‑time const and examples showing invalid runtime-sized declarations. [1][2]

References

  • Types & compile‑time constants (array / qubit sizes must be const). [1]
  • Subroutines: array parameters can have unspecified runtime lengths for passing slices/references, but that does not allow runtime-sized declarations at global scope. [2]

Require compile-time constant for array dimensions
Lines 7–8: num_controls = n - 1 isn’t constant, so input angle[2**num_controls] angles; violates OpenQASM 3.0. Either make n a const parameter or refactor to use an unsized array (input angle[] angles;) inside a subroutine.

🤖 Prompt for AI Agents
In src/mqt/bench/benchmarks/structured/multiplexer/multiplexer.qasm around lines
7–8, the dimension expression `2**num_controls` uses `num_controls = n - 1`
which is not a compile-time constant and violates OpenQASM 3.0; either change
`n` to a const parameter so `num_controls` becomes a compile-time constant
(e.g., declare `const int n = ...` or `const int num_controls = ...`) and keep
the sized input, or refactor to accept an unsized input array and use a
subroutine signature like `input angle[] angles;` and pass a properly sized
array at call site so the file no longer requires non-constant array dimensions.



qubit[num_controls] controls;
qubit target;
bit[num_controls + 1] c;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Remove unused classical bit register.

The classical bit register c is declared but never used in the program. Consider removing it to improve code clarity.

Apply this diff:

 qubit[num_controls] controls;
 qubit target;
-bit[num_controls + 1] c;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
bit[num_controls + 1] c;
qubit[num_controls] controls;
qubit target;
🤖 Prompt for AI Agents
In src/mqt/bench/benchmarks/structured/multiplexer/multiplexer.qasm around line
13, the classical bit register `c` (bit[num_controls + 1] c;) is declared but
never referenced; remove this unused declaration from the QASM file to eliminate
the unused register and improve clarity, ensuring no other code depends on `c`
before committing the change.


int num_states = 2**num_controls;

for int state in [0:num_states-1] {
// We want to apply angles[state] when controls equal 'state'
// State is a binary number: e.g., state=5 = 0b101 for 3 controls
// means control[0]=1, control[1]=0, control[2]=1

// Extract each bit: if 0, we need to flip the corresponding qubit
// Bit i is: (state >> i) & 1
for int bit_pos in [0:num_controls-1] {
int bit_value = (state >> bit_pos) & 1;
if (bit_value == 0) {
x controls[bit_pos]; // Flip this control
}
}

// Apply fully-controlled gate (all controls must be |1⟩)
ctrl(num_controls) @ ry(angles[state]) controls[0:num_controls-1], target;

// Flip controls back
for int bit_pos in [0:num_controls-1] {
int bit_value = (state >> bit_pos) & 1;
if (bit_value == 0) {
x controls[bit_pos]; // Flip back
}
}
}
16 changes: 16 additions & 0 deletions src/mqt/bench/benchmarks/structured/qft/qft.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
OPENQASM 3.0;
include "qelib1.inc";

input int n;

qubit[n] q;

for int i in [0:n-1] {
h q[i];
for int j in [i+1:n-1] {
cp(2*pi/2**(j-i+1)) q[j], q[i];
}
}
for int i in [0:(n-1)/2] {
swap q[i], q[n - 1 - i];
}
Comment on lines +14 to +16
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix swap loop bound to avoid non-integer/end-inclusive pitfalls

(n-1)/2 can be non-integer; inclusivity may overrun. Prefer a bound that clearly iterates floor(n/2) swaps.

-for int i in [0:(n-1)/2] {
+for int i in [0:n/2 - 1] {
     swap q[i], q[n - 1 - i];
 }

Alternatively (more robust to integer semantics):

-for int i in [0:(n-1)/2] {
-    swap q[i], q[n - 1 - i];
-}
+for int i in [0:n-1] {
+    if (i < n - 1 - i) {
+        swap q[i], q[n - 1 - i];
+    }
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for int i in [0:(n-1)/2] {
swap q[i], q[n - 1 - i];
}
for int i in [0:n/2 - 1] {
swap q[i], q[n - 1 - i];
}
Suggested change
for int i in [0:(n-1)/2] {
swap q[i], q[n - 1 - i];
}
for int i in [0:n-1] {
if (i < n - 1 - i) {
swap q[i], q[n - 1 - i];
}
}
🤖 Prompt for AI Agents
In src/mqt/bench/benchmarks/structured/qft/qft.qasm around lines 14 to 16, the
swap loop uses the bound (n-1)/2 which can be non-integer and may be interpreted
inclusively, risking wrong swap count or out-of-range indices; change the loop
to iterate exactly floor(n/2) times — e.g. use an explicit integer upper bound
like [0:floor(n/2)-1] or rewrite as a half-open form using i < n/2 so the loop
runs for i = 0 .. floor(n/2)-1 and performs exactly floor(n/2) swaps without
overrun.

26 changes: 26 additions & 0 deletions src/mqt/bench/benchmarks/structured/qpe/qpe.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
OPENQASM 3.0;
include "qelib1.inc";

input int n;

qubit[n-1] q;
qubit anc;

h q;
x anc;

// Iteratively apply gates
for int i in [0:n-2] {
pow(2**i) @ cp(3*pi/8) q[i], anc;
}

// Apply reverse QFT
for int i in [0:(n-2)/2] {
swap q[i], q[n - 2 - i];
}
for int i in [0:n-2] {
h q[i];
for int j in [i+1:n-2] {
cp(2*pi/2**(j-i+1)) q[j], q[i];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
OPENQASM 3.0;
include "qelib1.inc";

qubit psi;
qubit q1;
qubit q2;

// Alice has a qubit in an unknown state.
h psi;

// Alice and Bob share an entangled Bell pair.
h q1;
cx q1, q2;

// Alice prepares the teleport operation.
cx psi, q1;
h psi;

// Alice then measures her qubits.
bit a = measure psi;
bit b1 = measure q1;

// Bob applies corrections based on the measurement result.
if (b1) {
x q2;
}
if (a) {
z q2;
}
Comment on lines +24 to +29
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use explicit comparisons for bit-controlled corrections

Ensure conditionals on measured bits are explicit.

-if (b1) {
+if (b1 == 1) {
   x q2;
 }
-if (a) {
+if (a == 1) {
   z q2;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (b1) {
x q2;
}
if (a) {
z q2;
}
if (b1 == 1) {
x q2;
}
if (a == 1) {
z q2;
}
🤖 Prompt for AI Agents
In src/mqt/bench/benchmarks/structured/teleportation/teleportation.qasm around
lines 24 to 29, the conditionals use implicit truthiness (if (b1) and if (a));
change them to explicit comparisons against the measured-bit value (for example
if (b1 == 1) { x q2; } and if (a == 1) { z q2; }) so the bit-controlled
corrections are unambiguous and robust.


// Now q2 is in the previous state of a.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Comment nit: variable name

“previous state of a” should be “previous state of psi”.

-// Now q2 is in the previous state of a.
+// Now q2 is in the previous state of psi.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Now q2 is in the previous state of a.
// Now q2 is in the previous state of psi.
🤖 Prompt for AI Agents
In src/mqt/bench/benchmarks/structured/teleportation/teleportation.qasm around
line 31, the inline comment uses “previous state of a” which is incorrect;
update the comment to read “previous state of psi” so it accurately refers to
the state variable psi.

Loading