Skip to content

Commit

Permalink
fix: removing support for register append
Browse files Browse the repository at this point in the history
  • Loading branch information
BrunoLiegiBastonLiegi committed Apr 2, 2024
1 parent e4f35f0 commit bcaebac
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 15 deletions.
30 changes: 22 additions & 8 deletions src/qibo/models/_openqasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,7 @@ def to_circuit(
density_matrix,
wire_names=self._construct_wire_names(),
)
for gate in gates:
circ.add(gate)
self._reorder_registers(circ.measurements)
circ.add(self._merge_measurements(gates))
return circ

def _get_measurement(self, measurement):
Expand Down Expand Up @@ -267,11 +265,27 @@ def _def_gate(self, definition):
gates = [self._get_gate(gate) for gate in definition.body]
self.defined_gates.update({name: CustomQASMGate(name, gates, qubits, args)})

def _reorder_registers(self, measurements):
"""Reorders the registers of the provided :class:`qibo.gates.measurements.M`
gates according to the classical registers order defined in the QASM program."""
for meas in measurements:
meas.target_qubits = [self.c_registers[meas.register_name].pop(0)]
def _merge_measurements(self, gates):
"""Merges separated measurements of a same register into a single one.
This is needed because qibo doesn't allow to separetely define two measurements in a same register:
# not allowed
c.add(gates.M(0, register="m0"))
c.add(gates.M(1, register="m0"))
"""
updated_queue = []
for gate in gates:
if isinstance(gate, qibo.gates.M):
if gate.register_name in self.c_registers:
updated_queue.append(
qibo.gates.M(
*self.c_registers.pop(gate.register_name),
register_name=gate.register_name,
)
)
else:
updated_queue.append(gate)
return updated_queue

def _construct_wire_names(self):
"""Builds the wires names from the declared quantum registers."""
Expand Down
8 changes: 8 additions & 0 deletions src/qibo/models/circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,13 @@ def add(self, gate):
nreg = self.queue.nmeasurements - 1
gate.register_name = f"register{nreg}"
else:
name = gate.register_name
for mgate in self.measurements:
if name == mgate.register_name:
raise_error(
KeyError, f"Register {name} already exists in circuit."
)
"""
registers = self.measurement_tuples
for register, qubits in registers.items():
intersection = set(qubits).intersection(set(gate.target_qubits))
Expand All @@ -675,6 +682,7 @@ def add(self, gate):
KeyError,
f"Qubits {tuple(intersection)} already measured in register `{register}`.",
)
"""

gate.result.circuit = self
if gate.collapse:
Expand Down
4 changes: 2 additions & 2 deletions src/qibo/quantum_info/clifford.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,8 @@ def samples(self, binary: bool = True, registers: bool = False):

if registers:
return {
gate.register_name: gate.result.samples(binary)
for gate in self.measurements
register: gate.result.samples(binary)
for register, gate in self._measurement_registers
}

if binary:
Expand Down
21 changes: 17 additions & 4 deletions src/qibo/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ def __init__(
self.nshots = nshots

self._measurement_gate = None
self._measurement_registers = None
self._probs = probabilities
self._samples = samples
self._frequencies = None
Expand Down Expand Up @@ -255,8 +256,8 @@ def frequencies(self, binary: bool = True, registers: bool = False):

if registers:
return {
gate.register_name: gate.result.frequencies(binary)
for gate in self.measurements
register: gate.result.frequencies(binary)
for register, gate in self._measurement_registers
}

if binary:
Expand Down Expand Up @@ -362,8 +363,8 @@ def samples(self, binary: bool = True, registers: bool = False):

if registers:
return {
gate.register_name: gate.result.samples(binary)
for gate in self.measurements
register: gate.result.samples(binary)
for register, gate in self._measurement_registers
}

if binary:
Expand All @@ -388,6 +389,18 @@ def measurement_gate(self):

return self._measurement_gate

def measurement_registers(self):
if self._measurement_registers is None:
registers = {}
for gate in self.measurements:
if gate.register_name in registers:
registers[gate.register_name].add(gate)
else:
registers[gate.register_name] = gate
self._measurement_registers = registers

return self._measurement_registers

def apply_bitflips(self, p0: float, p1: Optional[float] = None):
"""Apply bitflips to the measurements with probabilities `p0` and `p1`
Expand Down
1 change: 0 additions & 1 deletion tests/test_models_circuit_qasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ def test_crotations():
"measurements",
[
[gates.M(0, 1)],
[gates.M(0, register_name="register0"), gates.M(1, register_name="register0")],
],
)
def test_measurements(measurements):
Expand Down
13 changes: 13 additions & 0 deletions tests/test_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,19 @@ def test_measurementoutcomes_probabilities(backend, qubits):
backend.assert_allclose(result.probabilities(qubits), probabilities, atol=1e-1)


def test_measurementoutcomes_measurement_registers(backend):
c = Circuit(3)
c.add(gates.H(0))
c_copy = c.copy()
c.add(gates.M(0, register_name="m0"))
c.add(gates.M(2, register_name="m0"))
c_copy.add(gates.M(0, 2, register_name="m0"))
res = backend.execute_circuit(c)
res_copy = backend.execute_circuit(c_copy)
samples = res.samples(registers=True)
samples_copy = res_copy.samples(registers=True)


def test_circuit_result_error(backend):
c = models.Circuit(1)
state = np.array([1, 0])
Expand Down

0 comments on commit bcaebac

Please sign in to comment.