diff --git a/src/qibolab/platform.py b/src/qibolab/platform.py index 71f8de983..a10400cd5 100644 --- a/src/qibolab/platform.py +++ b/src/qibolab/platform.py @@ -230,14 +230,14 @@ def _controller(self): assert len(controllers) == 1 return controllers[0] - def _execute(self, sequence, options, **kwargs): + def _execute(self, sequence, options, *sweepers, **kwargs): """Executes sequence on the controllers.""" result = {} for instrument in self.instruments.values(): if isinstance(instrument, Controller): new_result = instrument.play( - self.qubits, self.couplers, sequence, options + self.qubits, self.couplers, sequence, options, *sweepers ) if isinstance(new_result, dict): result.update(new_result) @@ -245,9 +245,35 @@ def _execute(self, sequence, options, **kwargs): return result def execute( - self, sequences: List[PulseSequence], options: ExecutionParameters, **kwargs + self, + sequences: List[PulseSequence], + options: ExecutionParameters, + *sweepers: Sweeper, + **kwargs, ): - """ + """Executes a pulse sequences. + + If any sweeper is passed, the execution is performed for the different values of sweeped parameters. + + Example: + .. testcode:: + + import numpy as np + from qibolab.dummy import create_dummy + from qibolab.sweeper import Sweeper, Parameter + from qibolab.pulses import PulseSequence + from qibolab.execution_parameters import ExecutionParameters + + + platform = create_dummy() + sequence = PulseSequence() + parameter = Parameter.frequency + pulse = platform.create_qubit_readout_pulse(qubit=0) + sequence.append(pulse) + parameter_range = np.random.randint(10, size=10) + sweeper = Sweeper(parameter, parameter_range, [pulse]) + platform.execute([sequence], ExecutionParameters(), sweeper) + Args: sequence (List[:class:`qibolab.pulses.PulseSequence`]): Pulse sequences to execute. options (:class:`qibolab.platforms.platform.ExecutionParameters`): Object holding the execution options. @@ -263,7 +289,9 @@ def execute( * options.nshots * NS_TO_SEC ) - log.info(f"Minimal execution time (unrolling): {time}") + for sweep in sweepers: + time *= len(sweep.values) + log.info(f"Minimal execution time: {time}") # find readout pulses ro_pulses = { @@ -276,7 +304,7 @@ def execute( bounds = kwargs.get("bounds", self._controller.bounds) for b in batch(sequences, bounds): sequence, readouts = unroll_sequences(b, options.relaxation_time) - result = self._execute(sequence, options, **kwargs) + result = self._execute(sequence, options, *sweepers, **kwargs) for serial, new_serials in readouts.items(): results[serial].extend(result[ser] for ser in new_serials) @@ -285,59 +313,6 @@ def execute( return results - def sweep( - self, sequence: PulseSequence, options: ExecutionParameters, *sweepers: Sweeper - ): - """Executes a pulse sequence for different values of sweeped - parameters. - - Useful for performing chip characterization. - - Example: - .. testcode:: - - import numpy as np - from qibolab.dummy import create_dummy - from qibolab.sweeper import Sweeper, Parameter - from qibolab.pulses import PulseSequence - from qibolab.execution_parameters import ExecutionParameters - - - platform = create_dummy() - sequence = PulseSequence() - parameter = Parameter.frequency - pulse = platform.create_qubit_readout_pulse(qubit=0) - sequence.append(pulse) - parameter_range = np.random.randint(10, size=10) - sweeper = Sweeper(parameter, parameter_range, [pulse]) - platform.sweep(sequence, ExecutionParameters(), sweeper) - - Returns: - Readout results acquired by after execution. - """ - if options.nshots is None: - options = replace(options, nshots=self.settings.nshots) - - if options.relaxation_time is None: - options = replace(options, relaxation_time=self.settings.relaxation_time) - - time = ( - (sequence.duration + options.relaxation_time) * options.nshots * NS_TO_SEC - ) - for sweep in sweepers: - time *= len(sweep.values) - log.info(f"Minimal execution time (sweep): {time}") - - result = {} - for instrument in self.instruments.values(): - if isinstance(instrument, Controller): - new_result = instrument.sweep( - self.qubits, self.couplers, sequence, options, *sweepers - ) - if isinstance(new_result, dict): - result.update(new_result) - return result - def get_qubit(self, qubit): """Return the name of the physical qubit corresponding to a logical qubit.