Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Use one register per vertex #54

Merged
merged 7 commits into from
Jun 14, 2024
Merged
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: 0 additions & 1 deletion pytket-mbqc-py/pytket_mbqc_py/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@
from .cnot_block import CNOTBlocksGraphCircuit
from .graph_circuit import GraphCircuit
from .qubit_manager import QubitManager
from .random_register_manager import RandomRegisterManager
198 changes: 131 additions & 67 deletions pytket-mbqc-py/pytket_mbqc_py/graph_circuit.py

Large diffs are not rendered by default.

21 changes: 6 additions & 15 deletions pytket-mbqc-py/pytket_mbqc_py/qubit_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import Dict, List

from pytket import Circuit
from pytket.unit_id import BitRegister, Qubit
from pytket.unit_id import Bit, Qubit


class QubitManager(Circuit):
Expand All @@ -20,16 +20,12 @@ class QubitManager(Circuit):
These are those qubits which have either never been used, or have been
used but have been measured and can be reset.
:ivar all_qubit_list: All qubits which could in principle be used.
:ivar qubit_meas_reg: A dictionary mapping qubits to the
classical registers where their measurement results
will be stored.
:ivar physical_qubits_used: A set containing the qubits which
have been made use of at some point.
"""

available_qubit_list: List[Qubit]
all_qubit_list: List[Qubit]
qubit_meas_reg: Dict[Qubit, BitRegister]
physical_qubits_used: set[Qubit]

def __init__(self, n_physical_qubits: int) -> None:
Expand All @@ -41,21 +37,15 @@ def __init__(self, n_physical_qubits: int) -> None:
"""
self.available_qubit_list = [Qubit(index=i) for i in range(n_physical_qubits)]
self.all_qubit_list = [Qubit(index=i) for i in range(n_physical_qubits)]
self.qubit_meas_reg = {
qubit: BitRegister(name=f"meas_{i}", size=1)
for i, qubit in enumerate(self.available_qubit_list)
}
self.qubit_meas_bit: Dict[Qubit, Bit] = dict()
self.physical_qubits_used = set()

super().__init__()

for meas_reg in self.qubit_meas_reg.values():
self.add_c_register(register=meas_reg)

for qubit in self.all_qubit_list:
self.add_qubit(id=qubit)

def get_qubit(self) -> Qubit:
def get_qubit(self, measure_bit: Bit) -> Qubit:
"""Return a qubit which is not in use, and which
is included in the underlying circuit.

Expand All @@ -67,7 +57,8 @@ def get_qubit(self) -> Qubit:

qubit = self.available_qubit_list.pop(0)
self.physical_qubits_used.add(qubit)
self.add_c_setreg(0, self.qubit_meas_reg[qubit])
self.qubit_meas_bit[qubit] = measure_bit
self.add_c_setbits([False], [self.qubit_meas_bit[qubit]])
self.Reset(qubit=qubit)

return qubit
Expand All @@ -93,4 +84,4 @@ def managed_measure(self, qubit: Qubit) -> None:
+ "get_qubit method."
)
self.available_qubit_list.insert(0, qubit)
self.Measure(qubit=qubit, bit=self.qubit_meas_reg[qubit][0])
self.Measure(qubit=qubit, bit=self.qubit_meas_bit[qubit])
133 changes: 0 additions & 133 deletions pytket-mbqc-py/pytket_mbqc_py/random_register_manager.py

This file was deleted.

1 change: 0 additions & 1 deletion pytket-mbqc-py/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ Welcome to pytket-mbqc's documentation!
:caption: Contents:

qubit_manager
random_register_manager
graph_circuit


Expand Down
7 changes: 0 additions & 7 deletions pytket-mbqc-py/source/random_register_manager.rst

This file was deleted.

66 changes: 65 additions & 1 deletion pytket-mbqc-py/tests/test_graph_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ def test_cnot_entangled_output(input_state, output_state):

with pytest.raises(
Exception,
match="Too many initialisation registers, 4, were created. Consider setting n_logical_qubits=3 upon initialising this class.",
match="Too many vertex registers, 4, were created. Consider setting n_logical_qubits=3 upon initialising this class.",
):
graph_circuit.get_outputs()

Expand Down Expand Up @@ -802,3 +802,67 @@ def test_single_unmeasured_vertex():

graph_circuit.add_graph_vertex(measurement_order=None)
assert graph_circuit.get_outputs() == {0: Qubit(1)}


def test_too_few_qubits():
circuit = GraphCircuit(
n_physical_qubits=2,
n_logical_qubits=2,
)
reg = circuit.add_c_register(
name="my_reg",
size=3,
)
circuit.get_qubit(reg[0])
circuit.get_qubit(reg[1])

with pytest.raises(
Exception,
match="You have run out of qubits.",
):
circuit.get_qubit(reg[2])

with pytest.raises(
Exception,
match="There are no unused qubits which can be used to generate randomness.",
):
circuit.populate_random_bits(
bit_list=reg[2],
)


def test_randomness_generation():
circuit = GraphCircuit(
n_physical_qubits=3,
n_logical_qubits=2,
)

reg_one = circuit.add_c_register(
name="my_first_random_reg",
size=16,
)
circuit.populate_random_bits(bit_list=reg_one.to_list())

reg_two = circuit.add_c_register(
name="my_second_random_reg",
size=32,
)
circuit.populate_random_bits(bit_list=reg_two.to_list())

backend = QuantinuumBackend(
device_name="H1-1LE", api_handler=QuantinuumAPIOffline()
)
n_shots = 1000

compiled_circuit = backend.get_compiled_circuit(circuit)
result = backend.run_circuit(
circuit=compiled_circuit,
n_shots=n_shots,
seed=0,
)

for cbits in reg_one:
assert abs(result.get_counts(cbits=[cbits])[(0,)] - n_shots / 2) < 35

for cbits in reg_two:
assert abs(result.get_counts(cbits=[cbits])[(0,)] - n_shots / 2) < 35
7 changes: 6 additions & 1 deletion pytket-mbqc-py/tests/test_qubit_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
def test_simple_measurement():
qubit_mgr = QubitManager(n_physical_qubits=2)

qubit = qubit_mgr.get_qubit()
reg = qubit_mgr.add_c_register(
name="meas_reg",
size=1,
)

qubit = qubit_mgr.get_qubit(measure_bit=reg[0])

assert qubit_mgr.available_qubit_list == [Qubit(1)]
assert qubit_mgr.all_qubit_list == [Qubit(0), Qubit(1)]
Expand Down
74 changes: 0 additions & 74 deletions pytket-mbqc-py/tests/test_random_register_manager.py

This file was deleted.