Skip to content

Commit

Permalink
Cleanup.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ville Bergholm committed Dec 18, 2024
1 parent 8d20230 commit 2254c04
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 45 deletions.
36 changes: 14 additions & 22 deletions src/iqm/iqm_client/transpile.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

from collections.abc import Iterable
from enum import Enum
from typing import Any, Optional
from typing import Optional
import warnings

from iqm.iqm_client import (
Expand Down Expand Up @@ -163,39 +163,30 @@ def create_move_instructions(
self,
qubit: str,
resonator: str,
*,
apply_move: Optional[bool] = True,
reverse_qubit_mapping: Optional[dict[str, str]] = None,
) -> Iterable[Instruction]:
"""MOVE instruction(s) to move the state of the given resonator into the
resonator if needed and then move resonator state to the given qubit.
qubit that owns it if needed, and then move the state of the given qubit to the resonator.
Args:
qubit: The qubit
resonator: The resonator
apply_move: Whether the moves should be applied to the resonator tracking state.
reverse_qubit_mapping: Mapping of physical qubit names to logical qubit names.
Yields:
The one or two MOVE instructions needed.
"""
res_state_owner = self.res_state_owner[resonator]
if res_state_owner not in [qubit, resonator]:
other = res_state_owner
if apply_move:
self.apply_move(other, resonator)
qbs = tuple(reverse_qubit_mapping[q] if reverse_qubit_mapping else q for q in [other, resonator])
yield Instruction(name=self.move_gate, qubits=qbs, args={})
if apply_move:
self.apply_move(qubit, resonator)
qbs = tuple(reverse_qubit_mapping[q] if reverse_qubit_mapping else q for q in [qubit, resonator])
yield Instruction(name=self.move_gate, qubits=qbs, args={})
locus = (res_state_owner, resonator)
self.apply_move(*locus)
yield Instruction(name=self.move_gate, qubits=locus, args={})

locus = (qubit, resonator)
self.apply_move(*locus)
yield Instruction(name=self.move_gate, qubits=locus, args={})

def reset_as_move_instructions(
self,
resonators: Optional[Iterable[str]] = None,
*,
reverse_qubit_mapping: Optional[dict[str, str]] = None,
) -> list[Instruction]:
"""MOVE instructions that move all the states held in the given resonators back to their qubits.
Expand All @@ -204,7 +195,6 @@ def reset_as_move_instructions(
Args:
resonators: Resonators that hold qubit states that should be moved back to the qubits.
If ``None``, the states in any resonators will be returned to the qubits.
reverse_qubit_mapping: Mapping of physical qubit names to logical qubit names.
Returns:
Instructions needed to move all qubit states out of the resonators.
Expand All @@ -215,9 +205,9 @@ def reset_as_move_instructions(
instructions: list[Instruction] = []
for r, q in self.res_state_owner.items():
if r != q and r in resonators:
locus = tuple(reverse_qubit_mapping[q] if reverse_qubit_mapping else q for q in [q, r])
locus = (q, r)
instructions.append(Instruction(name=self.move_gate, qubits=locus, args={}))
self.apply_move(q, r)
self.apply_move(*locus)
return instructions

def available_resonators_to_move(self, qubits: Iterable[str]) -> dict[str, list[str]]:
Expand All @@ -242,7 +232,9 @@ def resonators_holding_qubits(self, qubits: Iterable[str]) -> list[str]:
"""
return [r for r, q in self.res_state_owner.items() if q in qubits and q not in self.resonators]

def choose_move_pair(self, qubits: list[str], remaining_instructions: Iterable[Instruction]) -> list[tuple[str, str]]:
def choose_move_pair(
self, qubits: list[str], remaining_instructions: Iterable[Instruction]
) -> list[tuple[str, str]]:
"""Choose which of the given qubits to move into which resonator.
The choice is made using a heuristic based on the given lookahead sequence
Expand Down
30 changes: 7 additions & 23 deletions tests/test_transpiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,6 @@ def test_unavailable_cz(self):


class TestResonatorStateTracker:
reverse_qubit_mapping = {'COMP_R': 'A', 'QB1': 'B', 'QB3': 'C'}

def test_apply_move(self, sample_dynamic_architecture, sample_move_architecture):
# Check handling of an architecture without a resonator
Expand Down Expand Up @@ -462,30 +461,21 @@ def test_create_move_instructions(self, sample_move_architecture):
sample_move_architecture.gates['move'].implementations[default_move_impl].loci += (('QB1', 'COMP_R'),)
status = ResonatorStateTracker.from_dynamic_architecture(sample_move_architecture)
instr = Instruction(name='move', qubits=('QB3', 'COMP_R'), args={})
# Check insertion without and with apply_move
gen_instr = tuple(status.create_move_instructions('QB3', 'COMP_R', apply_move=False))
# Check insertion
gen_instr = tuple(status.create_move_instructions('QB3', 'COMP_R'))
assert len(gen_instr) == 1
assert gen_instr[0] == instr
assert status.res_state_owner['COMP_R'] == 'COMP_R'
gen_instr = tuple(status.create_move_instructions('QB3', 'COMP_R', apply_move=True))
assert status.res_state_owner['COMP_R'] == 'QB3'
gen_instr = tuple(status.create_move_instructions('QB3', 'COMP_R'))
assert len(gen_instr) == 1
assert gen_instr[0] == instr
assert status.res_state_owner['COMP_R'] == 'QB3'
assert status.res_state_owner['COMP_R'] == 'COMP_R'
status.res_state_owner['COMP_R'] = 'QB1'
# Check removal without and with apply_move
gen_instr = tuple(status.create_move_instructions('QB3', 'COMP_R', apply_move=False))
# Check removal
gen_instr = tuple(status.create_move_instructions('QB3', 'COMP_R'))
assert len(gen_instr) == 2
assert gen_instr[0] == Instruction(name='move', qubits=('QB1', 'COMP_R'), args={})
assert gen_instr[1] == instr
# Check with a qubit mapping
gen_instr = tuple(
status.create_move_instructions(
'QB3', 'COMP_R', apply_move=True, reverse_qubit_mapping=self.reverse_qubit_mapping
)
)
assert len(gen_instr) == 2
assert gen_instr[0] == Instruction(name='move', qubits=('B', 'A'), args={})
assert gen_instr[1] == Instruction(name='move', qubits=('C', 'A'), args={})
assert status.res_state_owner['COMP_R'] == 'QB3'

def test_reset_as_move_instructions(self, sample_move_architecture):
Expand All @@ -499,12 +489,6 @@ def test_reset_as_move_instructions(self, sample_move_architecture):
assert len(gen_instr) == 1
assert gen_instr[0] == Instruction(name='move', qubits=('QB3', 'COMP_R'), args={})
assert status.res_state_owner['COMP_R'] == 'COMP_R'
# Reset without argument, with qubit mapping
status.apply_move('QB3', 'COMP_R')
gen_instr = tuple(status.reset_as_move_instructions(reverse_qubit_mapping=self.reverse_qubit_mapping))
assert len(gen_instr) == 1
assert gen_instr[0] == Instruction(name='move', qubits=('C', 'A'), args={})
assert status.res_state_owner['COMP_R'] == 'COMP_R'
# Reset without arguments
status.apply_move('QB3', 'COMP_R')
gen_instr = tuple(status.reset_as_move_instructions())
Expand Down

0 comments on commit 2254c04

Please sign in to comment.