Skip to content

Commit

Permalink
add support TI dac flux bias
Browse files Browse the repository at this point in the history
  • Loading branch information
aorgazf committed Jul 17, 2024
1 parent 7a5ad0b commit 7a727d2
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 54 deletions.
8 changes: 4 additions & 4 deletions src/qibosoq/programs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def __init__(

self.relax_delay = self.us2cycles(qpcfg.relaxation_time)
self.syncdelay = self.us2cycles(0)
self.wait_initialize = self.us2cycles(2.0)
self.wait_initialize = self.us2cycles(5.0)

self.pulses_registered = False
self.registered_waveforms: Dict[int, list] = {}
Expand Down Expand Up @@ -320,16 +320,16 @@ def declare_gen_mux_ro(self):
self.declare_gen(
ch=ro_ch,
nqz=zone,
mixer_freq=0,
# mixer_freq=0,
mux_freqs=mux_freqs,
mux_gains=mux_gains,
ro_ch=adc_ch_added[0],
# ro_ch=adc_ch_added[0],
)

def add_muxed_readout_to_register(self, ro_pulses: List[Rectangular]):
"""Register multiplexed pulse before firing it."""
# readout amplitude gets divided by len(mask), we are here fixing the values
mask = [0, 1, 2]
mask = [0, 1, 2, 3]

pulse = ro_pulses[0]
gen_ch = pulse.dac
Expand Down
94 changes: 52 additions & 42 deletions src/qibosoq/programs/flux.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
Rectangular,
)
from qibosoq.programs.base import BaseProgram
from ..TIDAC80508 import TIDAC80508

logger = logging.getLogger(qibosoq_cfg.MAIN_LOGGER_NAME)

Expand All @@ -25,10 +26,11 @@ class FluxProgram(BaseProgram):
"""Abstract class for flux-tunable qubits programs."""

def __init__(
self, soc: QickSoc, qpcfg: Config, sequence: List[Element], qubits: List[Qubit]
self, soc: QickSoc, tidac: TIDAC80508, qpcfg: Config, sequence: List[Element], qubits: List[Qubit]
):
"""Define an empty dictionary for bias sweepers and call super().__init__."""
self.bias_sweep_registers: Dict[int, Tuple[QickRegister, QickRegister]] = {}
self.tidac = tidac
super().__init__(soc, qpcfg, sequence, qubits)

def set_bias(self, mode: str = "sweetspot"):
Expand All @@ -38,46 +40,54 @@ def set_bias(self, mode: str = "sweetspot"):
Args:
mode (str): can be 'sweetspot' or 'zero'
"""
duration = 48 # minimum len

for qubit in self.qubits:
# if bias is zero, just skip the qubit
if qubit.bias is None or qubit.dac is None or qubit.bias == 0:
continue

flux_ch = qubit.dac
max_gain = int(self.soccfg["gens"][flux_ch]["maxv"])

if mode == "sweetspot":
value = max_gain
elif mode == "zero":
value = 0
else:
raise NotImplementedError(f"Mode {mode} not supported")

i_wf = np.full(duration, value)
q_wf = np.zeros(len(i_wf))
self.add_pulse(flux_ch, f"const_{value}_{flux_ch}", i_wf, q_wf)
self.set_pulse_registers(
ch=flux_ch,
waveform=f"const_{value}_{flux_ch}",
style="arb",
outsel="input",
stdysel="last",
freq=0,
phase=0,
gain=np.trunc(max_gain * qubit.bias).astype(int),
)

if flux_ch in self.bias_sweep_registers:
swept_reg, non_swept_reg = self.bias_sweep_registers[flux_ch]
if mode == "sweetspot":
non_swept_reg.set_to(swept_reg)
elif mode == "zero":
non_swept_reg.set_to(0)

self.pulse(ch=flux_ch)
self.sync_all(50) # wait all pulses are fired + 50 clks
# if mode == "sweetspot":
# for qubit in self.qubits:
# self.tidac.set_bias(qubit.dac, bias_value=qubit.bias)
# elif mode == "zero":
# for qubit in self.qubits:
# self.tidac.set_bias(qubit.dac, bias_value=0)

# duration = 48 # minimum len
# for qubit in self.qubits:
# # if bias is zero, just skip the qubit
# # continue
# if qubit.bias is None or qubit.dac is None or qubit.bias == 0:
# continue

# flux_ch = qubit.dac
# max_gain = int(self.soccfg["gens"][flux_ch]["maxv"])

# if mode == "sweetspot":
# value = max_gain
# elif mode == "zero":
# value = 0
# else:
# raise NotImplementedError(f"Mode {mode} not supported")

# i_wf = np.full(duration, value)
# q_wf = np.zeros(len(i_wf))
# self.add_pulse(flux_ch, f"const_{value}_{flux_ch}", i_wf, q_wf)
# self.set_pulse_registers(
# ch=flux_ch,
# waveform=f"const_{value}_{flux_ch}",
# style="arb",
# outsel="input",
# stdysel="last",
# freq=0,
# phase=0,
# gain=np.trunc(max_gain * qubit.bias).astype(int),
# )

# if flux_ch in self.bias_sweep_registers:
# swept_reg, non_swept_reg = self.bias_sweep_registers[flux_ch]
# if mode == "sweetspot":
# non_swept_reg.set_to(swept_reg)
# elif mode == "zero":
# non_swept_reg.set_to(0)

# self.pulse(ch=flux_ch)
# self.sync_all(50) # wait all pulses are fired + 50 clks

def find_qubit_sweetspot(self, pulse: Pulse) -> float:
"""Return bias of a qubit from flux pulse."""
Expand Down Expand Up @@ -149,7 +159,7 @@ def body(self):
muxed_pulses_executed = []
muxed_ro_executed_indexes = []

self.set_bias("sweetspot")
# self.set_bias("sweetspot")

for elem in self.sequence:
# wait the needed wait time so that the start is timed correctly
Expand All @@ -172,7 +182,7 @@ def body(self):
self.execute_flux_pulse(elem)

self.wait_all()
self.set_bias("zero")
# self.set_bias("zero")
self.sync_all(self.relax_delay)

def declare_zones_and_ro(self, sequence: List[Pulse]):
Expand Down
5 changes: 3 additions & 2 deletions src/qibosoq/programs/pulse_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from qibosoq.components.base import Config, Qubit
from qibosoq.components.pulses import Element
from qibosoq.programs.flux import FluxProgram

from ..TIDAC80508 import TIDAC80508
logger = logging.getLogger(qibosoq_cfg.MAIN_LOGGER_NAME)


Expand All @@ -19,12 +19,13 @@ class ExecutePulseSequence(FluxProgram, AveragerProgram):
def __init__(
self,
soc: QickSoc,
tidac: TIDAC80508,
qpcfg: Config,
sequence: List[Element],
qubits: List[Qubit],
):
"""Init function, call super.__init__."""
super().__init__(soc, qpcfg, sequence, qubits)
super().__init__(soc, tidac, qpcfg, sequence, qubits)

self.reps = qpcfg.reps # must be done after AveragerProgram init
self.soft_avgs = qpcfg.soft_avgs
Expand Down
5 changes: 3 additions & 2 deletions src/qibosoq/programs/sweepers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from qibosoq.components.base import Config, Parameter, Qubit, Sweeper
from qibosoq.components.pulses import Element
from qibosoq.programs.flux import FluxProgram

from ..TIDAC80508 import TIDAC80508
logger = logging.getLogger(qibosoq_cfg.MAIN_LOGGER_NAME)


Expand All @@ -30,14 +30,15 @@ class ExecuteSweeps(FluxProgram, NDAveragerProgram):
def __init__(
self,
soc: QickSoc,
tidac: TIDAC80508,
qpcfg: Config,
sequence: List[Element],
qubits: List[Qubit],
*sweepers: Sweeper,
):
"""Init function, sets sweepers parameters before calling super.__init__."""
self.sweepers = reversed_sweepers(sweepers)
super().__init__(soc, qpcfg, sequence, qubits)
super().__init__(soc, tidac, qpcfg, sequence, qubits)

self.reps = qpcfg.reps # must be done after NDAveragerProgram init
self.soft_avgs = qpcfg.soft_avgs
Expand Down
22 changes: 18 additions & 4 deletions src/qibosoq/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
logger = logging.getLogger(cfg.MAIN_LOGGER_NAME)
qick_logger = logging.getLogger(cfg.PROGRAM_LOGGER_NAME)

# import sys
# sys.path.append('/home/xilinx/jupyter_notebooks/qick/qick_demos/custom/drivers')
from .TIDAC80508 import TIDAC80508


def load_elements(list_sequence: List[Dict]) -> List[Element]:
"""Convert a list of elements in dict form to a list of Pulse objects."""
Expand Down Expand Up @@ -49,7 +53,7 @@ def load_sweeps(list_sweepers: List[Dict]) -> List[Sweeper]:
return sweepers


def execute_program(data: dict, qick_soc: QickSoc) -> dict:
def execute_program(data: dict, qick_soc: QickSoc, tidac: TIDAC80508) -> dict:
"""Create and execute qick programs.
Returns:
Expand All @@ -70,14 +74,18 @@ def execute_program(data: dict, qick_soc: QickSoc) -> dict:
raise NotImplementedError(
f"Operation code {data['operation_code']} not supported"
)

program = programcls(
qick_soc,
tidac,
Config(**data["cfg"]),
load_elements(data["sequence"]),
[Qubit(**qubit) for qubit in data["qubits"]],
*args,
)
# program.set_bias("sweetspot")
for qubit in program.qubits:
tidac.set_bias(qubit.dac, bias_value=qubit.bias)

asm_prog = program.asm()
qick_logger.handlers[0].doRollover() # type: ignore
Expand All @@ -104,10 +112,13 @@ def execute_program(data: dict, qick_soc: QickSoc) -> dict:
qick_soc,
average=data["cfg"]["average"],
)
# program.set_bias("zero")
for qubit in program.qubits:
tidac.set_bias(qubit.dac, bias_value=0)

# return {"i": (np.array(toti)+0.5).tolist(), "q": (np.array(totq)+0.5).tolist()} # ZCU111?
return {"i": toti, "q": totq}


class ConnectionHandler(BaseRequestHandler):
"""Handle requests to the server."""

Expand Down Expand Up @@ -137,7 +148,9 @@ def handle(self):

try:
data = self.receive_command()
results = execute_program(data, self.server.qick_soc)

results = execute_program(data, self.server.qick_soc, self.server.tidac)

except Exception: # pylint: disable=W0612,W0718
logger.exception("")
logger.error("Faling command: %s", data)
Expand All @@ -160,5 +173,6 @@ def serve(host, port):
TCPServer.allow_reuse_address = True
with TCPServer((host, port), ConnectionHandler) as server:
server.qick_soc = QickSoc(bitfile=cfg.QICKSOC_LOCATION)
server.tidac = TIDAC80508()
log_initial_info()
server.serve_forever()

0 comments on commit 7a727d2

Please sign in to comment.