diff --git a/src/qibolab/instruments/qblox/controller.py b/src/qibolab/instruments/qblox/controller.py index f657756c0a..8cb41d87e3 100644 --- a/src/qibolab/instruments/qblox/controller.py +++ b/src/qibolab/instruments/qblox/controller.py @@ -16,7 +16,20 @@ from qibolab.sweeper import Parameter, Sweeper, SweeperType from qibolab.unrolling import Bounds -SEQUENCER_MEMORY = 2**17 +MAX_NUM_BINS = 98304 +"""Maximum number of bins that should be used per sequencer in a readout +module. + +If only one sequencer is used, it can have up to 2 ** 17 bins, however +the 6 sequencer in module allocate bins from a shared memory, and this +memory is smaller than 6 * 2 ** 17, hence, if all sequencers are used at +once they cannot support 2 ** 17 bins. In fact, the total bin memory for +the module is 3 * (2 ** 17 + 2 ** 16). This means up to three sequencers +used at once can support 2 ** 17 bins each, but four or more sequencers +cannot. So the limitation on the number of bins technically depends on +the number of sequencers used, but to keep things simple we limit +ourselves to max number of bins that works regardless of situation. +""" class QbloxController(Controller): @@ -455,7 +468,7 @@ def _sweep_recursion( num_bins *= len(sweeper.values) # split the sweep if the number of bins is larget than the memory of the sequencer (2**17) - if num_bins < SEQUENCER_MEMORY: + if num_bins < MAX_NUM_BINS: # for sweeper in sweepers: # if sweeper.parameter is Parameter.amplitude: # # qblox cannot sweep amplitude in real time, but sweeping gain is quivalent @@ -480,13 +493,13 @@ def _sweep_recursion( sweepers_repetitions = 1 for sweeper in sweepers: sweepers_repetitions *= len(sweeper.values) - if sweepers_repetitions > SEQUENCER_MEMORY: + if sweepers_repetitions > MAX_NUM_BINS: raise ValueError( f"Requested sweep has {sweepers_repetitions} total number of sweep points. " - f"Maximum supported is {SEQUENCER_MEMORY}" + f"Maximum supported is {MAX_NUM_BINS}" ) - max_rt_nshots = SEQUENCER_MEMORY // sweepers_repetitions + max_rt_nshots = MAX_NUM_BINS // sweepers_repetitions num_full_sft_iterations = nshots // max_rt_nshots result_chunks = [] for sft_iteration in range(num_full_sft_iterations + 1): diff --git a/tests/test_instruments_qblox_controller.py b/tests/test_instruments_qblox_controller.py index 3b47daef1b..fde3682f07 100644 --- a/tests/test_instruments_qblox_controller.py +++ b/tests/test_instruments_qblox_controller.py @@ -4,7 +4,7 @@ import pytest from qibolab import AveragingMode, ExecutionParameters -from qibolab.instruments.qblox.controller import SEQUENCER_MEMORY, QbloxController +from qibolab.instruments.qblox.controller import MAX_NUM_BINS, QbloxController from qibolab.pulses import Gaussian, Pulse, PulseSequence, ReadoutPulse, Rectangular from qibolab.result import IntegratedResults from qibolab.sweeper import Parameter, Sweeper @@ -31,7 +31,7 @@ def test_sweep_too_many_bins(platform, controller): # These values shall result into execution in two rounds shots = 128 - sweep_len = (SEQUENCER_MEMORY + 431) // shots + sweep_len = (MAX_NUM_BINS + 431) // shots mock_data = np.array([1, 2, 3, 4]) sweep_ampl = Sweeper(Parameter.amplitude, np.random.rand(sweep_len), pulses=[pulse]) @@ -54,7 +54,7 @@ def test_sweep_too_many_sweep_points(platform, controller): qubit = platform.qubits[0] pulse = Pulse(0, 40, 0.05, int(3e9), 0.0, Gaussian(5), qubit.drive.name, qubit=0) sweep = Sweeper( - Parameter.amplitude, np.random.rand(SEQUENCER_MEMORY + 17), pulses=[pulse] + Parameter.amplitude, np.random.rand(MAX_NUM_BINS + 17), pulses=[pulse] ) params = ExecutionParameters(nshots=12, relaxation_time=10) with pytest.raises(ValueError, match="total number of sweep points"):