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

measured_clbit_indices to classical_bit_mapping #923

Merged
merged 2 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions qiskit-superstaq/qiskit_superstaq/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from . import compiler_output, custom_gates, serialization, validation
from ._version import __version__
from .compiler_output import active_qubit_indices, measured_clbit_indices, measured_qubit_indices
from .compiler_output import active_qubit_indices, classical_bit_mapping, measured_qubit_indices
from .custom_gates import (
AceCR,
AQTiCCXGate,
Expand All @@ -19,11 +19,11 @@
"AceCR",
"AQTiCCXGate",
"AQTiToffoliGate",
"classical_bit_mapping",
"compiler_output",
"custom_gates",
"deserialize_circuits",
"measured_qubit_indices",
"measured_clbit_indices",
"ParallelGates",
"serialization",
"serialize_circuits",
Expand Down
31 changes: 18 additions & 13 deletions qiskit-superstaq/qiskit_superstaq/compiler_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,28 +59,33 @@ def measured_qubit_indices(circuit: qiskit.QuantumCircuit) -> list[int]:
return sorted(circuit.find_bit(qubit).index for qubit in measured_qubits)


def measured_clbit_indices(circuit: qiskit.QuantumCircuit) -> list[int]:
"""Returns the indices of the classical bits in the input quantum circuit.
def classical_bit_mapping(circuit: qiskit.QuantumCircuit) -> dict[int, int]:
"""Returns the index of the (final) measured qubit associated with each classical bit.

If more than one measurements are assigned to the same classical bit, only the final measurement
is considered.
richrines1 marked this conversation as resolved.
Show resolved Hide resolved

Args:
circuit: A `qiskit.QuantumCircuit` circuit.

Returns:
A list containing the indices of the classical bits.
A dictionary mapping classical bit indices to the indices of the measured qubits.
"""
measured_clbits: set[qiskit.circuit.Clbit] = set()

for items in circuit:
inst = items[0]
clbits = items[2]
if isinstance(inst, qiskit.circuit.Measure):
measured_clbits.update(clbits)
clbit_map: dict[qiskit.circuit.Clbit, qiskit.circuit.Qubit] = {}

# Recurse into definition
elif clbits and inst.definition is not None:
measured_clbits.update(clbits[i] for i in measured_clbit_indices(inst.definition))
for inst in circuit:
if isinstance(inst.operation, qiskit.circuit.Measure):
clbit_map[inst.clbits[0]] = inst.qubits[0]

# Recurse into definition if it involves classical bits
elif inst.clbits and inst.operation.definition is not None:
inst_clbit_map = classical_bit_mapping(inst.operation.definition)
clbit_map.update(
{inst.clbits[ci]: inst.qubits[qi] for ci, qi in inst_clbit_map.items()}
)

return sorted(circuit.find_bit(bit).index for bit in measured_clbits)
return {circuit.find_bit(c).index: circuit.find_bit(q).index for c, q in clbit_map.items()}


class CompilerOutput:
Expand Down
20 changes: 12 additions & 8 deletions qiskit-superstaq/qiskit_superstaq/compiler_output_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ def test_measured_clbit_indices() -> None:
circuit.measure([6, 5], [0, 1])
circuit.measure([1, 3], [0, 1])
circuit.measure([5, 1], [0, 1])
assert qss.measured_clbit_indices(circuit) == [0, 1]
assert qss.classical_bit_mapping(circuit) == {0: 5, 1: 1}

# Test len(qiskit.ClassicalRegister()) > len(qiskit.QuantumRegister())
circuit = qiskit.QuantumCircuit(3, 5)
circuit.h(1)
circuit.x(2)
circuit.measure([0, 1, 2], [2, 4, 1])
assert qss.measured_clbit_indices(circuit) == [1, 2, 4]
assert qss.classical_bit_mapping(circuit) == {2: 0, 4: 1, 1: 2}

# Test len(qiskit.ClassicalRegister()) = len(qiskit.QuantumRegister())
circuit = qiskit.QuantumCircuit(9, 9)
Expand All @@ -81,9 +81,10 @@ def test_measured_clbit_indices() -> None:
circuit.s(1)
circuit.cx(1, 0)
circuit.measure([0, 1, 4], [0, 1, 2])
assert qss.measured_clbit_indices(circuit) == [0, 1, 2]
circuit.measure([0, 1, 4, 2, 3, 5, 6, 7, 8], [0, 1, 2, 8, 7, 6, 5, 3, 4])
assert qss.measured_clbit_indices(circuit) == [0, 1, 2, 3, 4, 5, 6, 7, 8]
assert qss.classical_bit_mapping(circuit) == {0: 0, 1: 1, 2: 4}

circuit.measure([0, 1, 4, 2, 3, 5, 6, 7], [0, 1, 2, 8, 7, 6, 5, 3])
assert qss.classical_bit_mapping(circuit) == {0: 0, 1: 1, 2: 4, 8: 2, 7: 3, 6: 5, 5: 6, 3: 7}

# Custom instruction with measurements test
circuit_instr = qiskit.QuantumCircuit(2, 2)
Expand All @@ -92,10 +93,13 @@ def test_measured_clbit_indices() -> None:
circuit_instr.measure([0, 1], [0, 1])
custom_instruction = circuit_instr.to_instruction()

qc = qiskit.QuantumCircuit(2, 2)
qc.append(custom_instruction, [0, 1], [0, 1])
circuit = qiskit.QuantumCircuit(4, 4)
circuit.append(custom_instruction, [1, 2], [2, 3])

assert qss.classical_bit_mapping(circuit) == {2: 1, 3: 2}

assert qss.measured_clbit_indices(qc) == [0, 1]
circuit.append(custom_instruction, [2, 1], [2, 3])
assert qss.classical_bit_mapping(circuit) == {2: 2, 3: 1}


def test_compiler_output_repr() -> None:
Expand Down
2 changes: 1 addition & 1 deletion qiskit-superstaq/qiskit_superstaq/superstaq_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def _get_clbit_indices(self, index: int) -> list[int]:
the job.
"""
input_circuit = self.input_circuits(index)
return qss.compiler_output.measured_clbit_indices(input_circuit)
return sorted(qss.classical_bit_mapping(input_circuit))

def _get_num_clbits(self, index: int) -> int:
"""Helper to get number of classical bits in the classical register of the input circuit.
Expand Down