Skip to content

Commit

Permalink
Add CliffordCircuitPredicate if we're using the stabilizer simulator (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
isobelhooper authored Feb 11, 2025
1 parent 73693ba commit 07a4367
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 12 deletions.
5 changes: 5 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

# Changelog

## Unreleased

- Add CliffordCircuitPredicate for circuit compilation and processing
when using the stabilizer simulator.

## 0.44.0 (February 2025)

- Remove `noise_specs` from local-emulator backends.
Expand Down
3 changes: 3 additions & 0 deletions pytket/extensions/quantinuum/backends/quantinuum.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
scratch_reg_resize_pass,
)
from pytket.predicates import (
CliffordCircuitPredicate,
GateSetPredicate,
MaxNClRegPredicate,
MaxNQubitsPredicate,
Expand Down Expand Up @@ -621,6 +622,8 @@ def required_predicates(self) -> list[Predicate]:
assert self.backend_info is not None
preds.append(MaxNQubitsPredicate(self.backend_info.n_nodes))
preds.append(MaxNClRegPredicate(cast(int, self.backend_info.n_cl_reg)))
if self.simulator_type == "stabilizer":
preds.append(CliffordCircuitPredicate())

return preds

Expand Down
19 changes: 9 additions & 10 deletions tests/integration/backend_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
QuantinuumAPI,
QuantinuumAPIError,
)
from pytket.extensions.quantinuum.backends.quantinuum import _ALL_GATES, GetResultFailed
from pytket.extensions.quantinuum.backends.quantinuum import _ALL_GATES
from pytket.predicates import CompilationUnit
from pytket.wasm import WasmFileHandler

Expand Down Expand Up @@ -530,11 +530,11 @@ def test_leakage_detection(


@given(
n_shots=st.integers(min_value=1, max_value=10), # type: ignore
n_shots=st.integers(min_value=1, max_value=10),
n_bits=st.integers(min_value=0, max_value=10),
)
@pytest.mark.timeout(120)
def test_shots_bits_edgecases(n_shots, n_bits) -> None:
def test_shots_bits_edgecases(n_shots: int, n_bits: int) -> None:
quantinuum_backend = QuantinuumBackend("H1-1SC", machine_debug=True)
c = Circuit(n_bits, n_bits)

Expand Down Expand Up @@ -597,18 +597,17 @@ def test_simulator(
assert sum(stab_counts.values()) == n_shots
assert len(stab_counts) == 2

# test non-clifford circuit fails on stabilizer backend
# unfortunately the job is accepted, then fails, so have to check get_result
# test non-clifford circuit fails predicate check
# when run on stabilizer backend
non_stab_circ = (
Circuit(2, name="non_stab_circ").H(0).Rx(0.1, 0).CX(0, 1).measure_all()
)
non_stab_circ = stabilizer_backend.get_compiled_circuit(non_stab_circ)
broken_handle = stabilizer_backend.process_circuit(
non_stab_circ, n_shots, language=language
)

with pytest.raises(GetResultFailed) as _:
_ = stabilizer_backend.get_result(broken_handle)
with pytest.raises(CircuitNotValidError):
_ = stabilizer_backend.process_circuit(
non_stab_circ, n_shots, noisy_simulation=False, language=language
)


@pytest.mark.skipif(skip_remote_tests, reason=REASON)
Expand Down
29 changes: 29 additions & 0 deletions tests/unit/backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import pytest

from pytket.extensions.quantinuum import QuantinuumAPIOffline, QuantinuumBackend
from pytket.predicates import CliffordCircuitPredicate


@pytest.mark.parametrize(
"simulator_type,should_have_clifford_predicate",
[
("state-vector", False),
("stabilizer", True),
],
)
def test_clifford_circuits_for_stabilizer(
simulator_type: str,
should_have_clifford_predicate: bool,
) -> None:
"""Check that the stabilizer simulator restricts circuits to be Clifford circuits,
and the statevector simulator does not."""
qapi_offline = QuantinuumAPIOffline()
backend = QuantinuumBackend(
"H1-1E",
api_handler=qapi_offline, # type: ignore
simulator=simulator_type,
)
required_predicates = backend.required_predicates
assert should_have_clifford_predicate == any(
isinstance(pred, CliffordCircuitPredicate) for pred in required_predicates
)
4 changes: 2 additions & 2 deletions tests/unit/offline_backend_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def test_tket_pass_submission(language: Language) -> None:


@given(
n_shots=strategies.integers(min_value=1, max_value=10), # type: ignore
n_shots=strategies.integers(min_value=1, max_value=10),
n_bits=strategies.integers(min_value=0, max_value=10),
)
@pytest.mark.parametrize(
Expand All @@ -128,7 +128,7 @@ def test_tket_pass_submission(language: Language) -> None:
Language.PQIR,
],
)
def test_shots_bits_edgecases(n_shots, n_bits, language: Language) -> None:
def test_shots_bits_edgecases(n_shots: int, n_bits: int, language: Language) -> None:
quantinuum_backend = QuantinuumBackend("H1-1SC", machine_debug=True)
c = Circuit(n_bits, n_bits)

Expand Down

0 comments on commit 07a4367

Please sign in to comment.