From be9db80537ed6b4bcecdb09d95fafd43c8b9127c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= Date: Tue, 16 Jun 2026 16:46:31 +0100 Subject: [PATCH 1/7] Limit benchmark runs --- .github/workflows/benchmarks_pr.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/benchmarks_pr.yml b/.github/workflows/benchmarks_pr.yml index 984b25b2a..147249966 100644 --- a/.github/workflows/benchmarks_pr.yml +++ b/.github/workflows/benchmarks_pr.yml @@ -11,6 +11,12 @@ permissions: contents: read id-token: write # required for OIDC auth with Codspeed +# Limits the number of concurrent runs of this workflow for branches to one. Runs caused by newly pushed commits thus +# cancel any in-progress runs for the same branch. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: benchmark_pr_branch: name: Benchmark PR From 5d65554d3d96af1d525915065e6d1639d7010444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= Date: Wed, 17 Jun 2026 12:10:57 +0100 Subject: [PATCH 2/7] Test tracing --- tests/benchmarks/test_tracing.py | 87 ++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 tests/benchmarks/test_tracing.py diff --git a/tests/benchmarks/test_tracing.py b/tests/benchmarks/test_tracing.py new file mode 100644 index 000000000..a5041ff90 --- /dev/null +++ b/tests/benchmarks/test_tracing.py @@ -0,0 +1,87 @@ +from typing import no_type_check + +import numpy as np +import pytest +from guppylang import guppy +from guppylang.defs import GuppyFunctionDefinition +from guppylang.std.angles import angle +from guppylang.std.builtins import array, comptime +from guppylang.std.qsystem import random, rz, utils +from guppylang.std.quantum import cx, discard_array, qubit, x, y, z +from pytket import Circuit, OpType + + +def random_layered_circuit(n_qubits: int, depth: int, seed: int) -> Circuit: + rng = np.random.default_rng(seed=seed) + circuit = Circuit(n_qubits=n_qubits) + + for _ in range(depth): + for q in range(circuit.n_qubits): + circuit.Rz(rng.uniform(0, 4), q) + qubits = rng.permutation(circuit.n_qubits) + for i in range(0, circuit.n_qubits - 1, 2): + circuit.CX(qubits[i], qubits[i + 1]) + + return circuit + + +n = guppy.nat_var("n") + + +@guppy +@no_type_check +def apply_pauli_frame(qs: array[qubit, n], frame_ints: array[int, n]) -> None: + for idx in range(n): + if frame_ints[idx] == 1: + x(qs[idx]) + elif frame_ints[idx] == 2: + y(qs[idx]) + elif frame_ints[idx] == 3: + z(qs[idx]) + + +def build_guppy_circuit_comptime(circ: Circuit, seed: int) -> GuppyFunctionDefinition: + gate_map: dict[OpType, GuppyFunctionDefinition] = {OpType.Rz: rz} + + @guppy.comptime + @no_type_check + def comptime_circuit() -> None: + rng = random.RNG(seed + utils.get_current_shot()) + frame_ints = array( + rng.random_int_bounded(4) for _ in range(comptime(circ.n_qubits)) + ) + rng.discard() + + q = array(qubit() for _ in range(comptime(circ.n_qubits))) + apply_pauli_frame(q, frame_ints) + + for com in circ.get_commands(): + if (op_type := com.op.type) in gate_map: + gate_map[op_type]( + q[com.qubits[0].index[0]], + *[angle(float(ang)) for ang in com.op.params], + ) + elif op_type == OpType.CX: + cx(q[com.qubits[0].index[0]], q[com.qubits[1].index[0]]) + + apply_pauli_frame(q, frame_ints) + discard_array(q) + + return comptime_circuit + + +@pytest.fixture +def circuit_seed(): + seed = int(np.random.SeedSequence().generate_state(1)[0]) + circ = random_layered_circuit(n_qubits=32, depth=24, seed=seed) + + return circ, seed + + +def test_circuit_comptime_compile(benchmark, circuit_seed): + def circuit_comptime_compile(): + circ, seed = circuit_seed + guppy_func = build_guppy_circuit_comptime(circ, seed) + guppy_func.compile() + + benchmark.pedantic(circuit_comptime_compile, rounds=25) From 5d9601700ab8fb0517f43be0370611e3157801c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= Date: Wed, 17 Jun 2026 13:43:05 +0100 Subject: [PATCH 3/7] Also check test --- tests/benchmarks/test_tracing.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/benchmarks/test_tracing.py b/tests/benchmarks/test_tracing.py index a5041ff90..56d33e8c6 100644 --- a/tests/benchmarks/test_tracing.py +++ b/tests/benchmarks/test_tracing.py @@ -78,10 +78,15 @@ def circuit_seed(): return circ, seed +def test_circuit_comptime_check(benchmark, circuit_seed): + def circuit_comptime_check(): + build_guppy_circuit_comptime(*circuit_seed).check() + + benchmark.pedantic(circuit_comptime_check(), rounds=25) + + def test_circuit_comptime_compile(benchmark, circuit_seed): def circuit_comptime_compile(): - circ, seed = circuit_seed - guppy_func = build_guppy_circuit_comptime(circ, seed) - guppy_func.compile() + build_guppy_circuit_comptime(*circuit_seed).compile() benchmark.pedantic(circuit_comptime_compile, rounds=25) From bc5f716a49bf1c4fdb9e945133573300d8466e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= Date: Wed, 17 Jun 2026 13:43:36 +0100 Subject: [PATCH 4/7] Also check test --- tests/benchmarks/test_tracing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/benchmarks/test_tracing.py b/tests/benchmarks/test_tracing.py index 56d33e8c6..4781cc6f8 100644 --- a/tests/benchmarks/test_tracing.py +++ b/tests/benchmarks/test_tracing.py @@ -82,7 +82,7 @@ def test_circuit_comptime_check(benchmark, circuit_seed): def circuit_comptime_check(): build_guppy_circuit_comptime(*circuit_seed).check() - benchmark.pedantic(circuit_comptime_check(), rounds=25) + benchmark.pedantic(circuit_comptime_check, rounds=25) def test_circuit_comptime_compile(benchmark, circuit_seed): From fad0fdd05e4d226539e4426df04905d6899a29d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= Date: Wed, 17 Jun 2026 13:46:19 +0100 Subject: [PATCH 5/7] Inline a bit --- tests/benchmarks/test_tracing.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/tests/benchmarks/test_tracing.py b/tests/benchmarks/test_tracing.py index 4781cc6f8..6f3f3c1ac 100644 --- a/tests/benchmarks/test_tracing.py +++ b/tests/benchmarks/test_tracing.py @@ -25,24 +25,22 @@ def random_layered_circuit(n_qubits: int, depth: int, seed: int) -> Circuit: return circuit -n = guppy.nat_var("n") - - -@guppy -@no_type_check -def apply_pauli_frame(qs: array[qubit, n], frame_ints: array[int, n]) -> None: - for idx in range(n): - if frame_ints[idx] == 1: - x(qs[idx]) - elif frame_ints[idx] == 2: - y(qs[idx]) - elif frame_ints[idx] == 3: - z(qs[idx]) - - def build_guppy_circuit_comptime(circ: Circuit, seed: int) -> GuppyFunctionDefinition: gate_map: dict[OpType, GuppyFunctionDefinition] = {OpType.Rz: rz} + n = guppy.nat_var("n") + + @guppy + @no_type_check + def apply_pauli_frame(qs: array[qubit, n], frame_ints: array[int, n]) -> None: + for idx in range(n): + if frame_ints[idx] == 1: + x(qs[idx]) + elif frame_ints[idx] == 2: + y(qs[idx]) + elif frame_ints[idx] == 3: + z(qs[idx]) + @guppy.comptime @no_type_check def comptime_circuit() -> None: @@ -82,7 +80,7 @@ def test_circuit_comptime_check(benchmark, circuit_seed): def circuit_comptime_check(): build_guppy_circuit_comptime(*circuit_seed).check() - benchmark.pedantic(circuit_comptime_check, rounds=25) + benchmark(circuit_comptime_check) def test_circuit_comptime_compile(benchmark, circuit_seed): From 3adfeb5e1c07a47231d936abeb3062447dd69055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= Date: Wed, 17 Jun 2026 14:44:00 +0100 Subject: [PATCH 6/7] Reduce size --- tests/benchmarks/test_tracing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/benchmarks/test_tracing.py b/tests/benchmarks/test_tracing.py index 6f3f3c1ac..e207bde95 100644 --- a/tests/benchmarks/test_tracing.py +++ b/tests/benchmarks/test_tracing.py @@ -71,7 +71,7 @@ def comptime_circuit() -> None: @pytest.fixture def circuit_seed(): seed = int(np.random.SeedSequence().generate_state(1)[0]) - circ = random_layered_circuit(n_qubits=32, depth=24, seed=seed) + circ = random_layered_circuit(n_qubits=16, depth=10, seed=seed) return circ, seed From bbc834163198848fd71e4c81dcdf4c2bdcc455aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= Date: Wed, 17 Jun 2026 16:06:45 +0100 Subject: [PATCH 7/7] Remove pedantic mode --- tests/benchmarks/test_tracing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/benchmarks/test_tracing.py b/tests/benchmarks/test_tracing.py index e207bde95..1effbdfba 100644 --- a/tests/benchmarks/test_tracing.py +++ b/tests/benchmarks/test_tracing.py @@ -87,4 +87,4 @@ def test_circuit_comptime_compile(benchmark, circuit_seed): def circuit_comptime_compile(): build_guppy_circuit_comptime(*circuit_seed).compile() - benchmark.pedantic(circuit_comptime_compile, rounds=25) + benchmark(circuit_comptime_compile)