Skip to content

Commit

Permalink
add hypothesis test and smallest failing example
Browse files Browse the repository at this point in the history
  • Loading branch information
ss2165 committed Dec 15, 2023
1 parent a779511 commit e8c9c65
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ devenv.local.nix
.coverage
coverage.xml
lcov.info

# python hypothesis testing
.hypothesis
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ packages = [{ include = "tket2-py" }]
[tool.poetry.dependencies]
python = ">=3.10"

[tool.poetry.dev-dependencies]
[tool.poetry.group.dev.dependencies]
maturin = "^1.3.0"
pytket = "*"
pytest = "^7.1.2"
pytest-cov = "^4.1.0"
ruff = "^0.1.3"
hypothesis = "^6.91.1"

[build-system]
requires = ["maturin~=1.3"]
Expand Down
57 changes: 56 additions & 1 deletion tket2-py/test/test_pass.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,43 @@
from pytket import Circuit, OpType
from dataclasses import dataclass

from typing import Callable, Any
from tket2.passes import badger_pass, greedy_depth_reduce, chunks
from tket2.circuit import Tk2Circuit
from tket2.pattern import Rule, RuleMatcher
import hypothesis.strategies as st
from hypothesis.strategies._internal import SearchStrategy
from hypothesis import given, settings


@st.composite
def circuits(
draw: Callable[[SearchStrategy[Any]], Any],
n_qubits: SearchStrategy[int] = st.integers(min_value=0, max_value=8),
depth: SearchStrategy[int] = st.integers(min_value=5, max_value=50),
) -> Circuit:
total_qubits = draw(n_qubits)
circuit = Circuit(total_qubits)
if total_qubits == 0:
return circuit
for _ in range(draw(depth)):
gates = [circuit.Rz, circuit.H]
if total_qubits > 1:
gates.extend([circuit.CX])
gate = draw(st.sampled_from(gates))
control = draw(st.integers(min_value=0, max_value=total_qubits - 1))
if gate in (circuit.CX,):
target = draw(
st.integers(min_value=0, max_value=total_qubits - 1).filter(
lambda x: x != control
)
)
gate(control, target)
if gate == circuit.Rz:
angle = draw(st.floats(min_value=-2.0, max_value=2.0))
gate(angle, control)
if gate == circuit.H:
gate(control)
return circuit


def test_simple_badger_pass_no_opt():
Expand All @@ -30,6 +64,27 @@ def test_depth_optimise():
assert c.depth() == 2


def test_depth_optimise_buggy():
# bug https://github.com/CQCL/tket2/issues/253
c = Circuit(3).H(2).CX(2, 1).CX(0, 2).CX(0, 1)

assert c.depth() == 4

c, moves = greedy_depth_reduce(c)
assert moves == 1
assert c == Circuit(3).H(2).CX(0, 1).CX(2, 1).CX(0, 2)
assert c.depth() == 3


@given(circ=circuits())
@settings(print_blob=True, deadline=30)
def test_depth_hyp(circ: Circuit) -> None:
new, _ = greedy_depth_reduce(circ)

assert circ.n_gates == new.n_gates
assert new.depth() <= circ.depth()


def test_chunks():
c = Circuit(4).CX(0, 2).CX(1, 3).CX(1, 2).CX(0, 3).CX(1, 3)

Expand Down

0 comments on commit e8c9c65

Please sign in to comment.