From a23b8d4fe67b33f5165717ddb7f840f4dbc79c62 Mon Sep 17 00:00:00 2001 From: Albert Mitjans Date: Mon, 29 May 2023 18:15:32 +0200 Subject: [PATCH] Add save_results flag (#397) * fix: :bug: Add save_results flag. * Small change * Small change * style: :art: Remove unused imports. * Disconnect all instruments after execution. * Small fix * Small fix * style: :art: Improve execute function. --- src/qililab/execute.py | 24 ++++------------ src/qililab/experiment/experiment.py | 42 +++++++++++++++++----------- 2 files changed, 30 insertions(+), 36 deletions(-) diff --git a/src/qililab/execute.py b/src/qililab/execute.py index 4a6763183..e6a14b76d 100644 --- a/src/qililab/execute.py +++ b/src/qililab/execute.py @@ -1,12 +1,9 @@ -import os -from pathlib import Path - from qibo.models import Circuit import qililab as ql -def execute(circuit: Circuit, runcard_name: str): +def execute(circuit: Circuit, runcard_name: str, nshots=1): """Execute a qibo with qililab and native gates Args: @@ -46,21 +43,10 @@ def execute(circuit: Circuit, runcard_name: str): # create platform platform = ql.build_platform(name=runcard_name) - settings = ql.ExperimentSettings( - hardware_average=1, - repetition_duration=0, - software_average=1, - ) - options = ql.ExperimentOptions( - loops=[], # loops to run the experiment - settings=settings, # experiment settings - ) + settings = ql.ExperimentSettings(hardware_average=1, repetition_duration=0, software_average=nshots) + options = ql.ExperimentOptions(settings=settings) # create experiment with options - sample_experiment = ql.Experiment( - platform=platform, # platform to run the experiment - circuits=[circuit], # circuits to run the experiment - options=options, # experiment options - ) + sample_experiment = ql.Experiment(platform=platform, circuits=[circuit], options=options) - return sample_experiment.execute() + return sample_experiment.execute(save_results=False) diff --git a/src/qililab/experiment/experiment.py b/src/qililab/experiment/experiment.py index 7b9adc65b..1996a4435 100644 --- a/src/qililab/experiment/experiment.py +++ b/src/qililab/experiment/experiment.py @@ -7,6 +7,7 @@ from threading import Thread import numpy as np +from qcodes.instrument import Instrument as QcodesInstrument from qibo.models.circuit import Circuit from tqdm.auto import tqdm @@ -33,7 +34,7 @@ class Experiment: # Specify the types of the attributes that are not defined during initialization execution_manager: ExecutionManager results: Results - results_path: Path + results_path: Path | None _plot: LivePlot | None _remote_id: int @@ -66,7 +67,7 @@ def build_execution(self): # Build ``ExecutionManager`` class self.execution_manager = EXECUTION_BUILDER.build(platform=self.platform, pulse_schedules=self.pulse_schedules) - def run(self) -> Results: + def run(self, save_results=True) -> Results: """This method is responsible for: * Creating the live plotting (if connection is provided). * Preparing the `Results` class and the `results.yml` file. @@ -90,13 +91,13 @@ def run(self) -> Results: ) if not hasattr(self, "execution_manager"): raise ValueError("Please build the execution_manager before running an experiment.") + # Prepares the results - self.results, self.results_path = self.prepare_results() - num_schedules = self.execution_manager.num_schedules + self.results, self.results_path = self.prepare_results(save_results=save_results) data_queue: Queue = Queue() # queue used to store the experiment results self._asynchronous_data_handling(queue=data_queue) - + num_schedules = self.execution_manager.num_schedules for idx, _ in itertools.product( tqdm(range(num_schedules), desc="Sequences", leave=False, disable=num_schedules == 1), range(self.software_average), @@ -133,9 +134,11 @@ def _threaded_function(): q = np.array(acq["q"]) amplitude = 20 * np.log10(np.abs(i + 1j * q)).astype(np.float64) self._plot.send_points(value=amplitude[0]) - with open(file=self.results_path / "results.yml", mode="a", encoding="utf8") as data_file: - result_dict = result.to_dict() - yaml.safe_dump(data=[result_dict], stream=data_file, sort_keys=False) + + if self.results_path is not None: + with open(file=self.results_path / "results.yml", mode="a", encoding="utf8") as data_file: + result_dict = result.to_dict() + yaml.safe_dump(data=[result_dict], stream=data_file, sort_keys=False) thread = Thread(target=_threaded_function) thread.start() @@ -171,7 +174,7 @@ def disconnect(self): """Disconnects from the instruments and releases the device.""" self.platform.disconnect() - def execute(self) -> Results: + def execute(self, save_results=True) -> Results: """Runs the whole execution pipeline, which includes the following steps: * Connect to the instruments. @@ -191,9 +194,10 @@ def execute(self) -> Results: self.initial_setup() self.build_execution() self.turn_on_instruments() - results = self.run() + results = self.run(save_results=save_results) self.turn_off_instruments() self.disconnect() + QcodesInstrument.close_all() return results def remote_save_experiment(self) -> None: @@ -434,7 +438,7 @@ def repetition_duration(self): """ return self.options.settings.repetition_duration - def prepare_results(self) -> tuple[Results, Path]: + def prepare_results(self, save_results=True) -> tuple[Results, Path | None]: """Creates the ``Results`` class, creates the ``results.yml`` file where the results will be saved, and dumps the experiment data into this file. @@ -452,13 +456,17 @@ def prepare_results(self) -> tuple[Results, Path]: num_schedules=self.execution_manager.num_schedules, loops=self.options.loops, ) - # Create the folders & files needed to save the results locally - results_path = self._path_to_results_folder() - self._create_results_file(results_path) - # Dump the experiment data into the created file - with open(file=results_path / EXPERIMENT_FILENAME, mode="w", encoding="utf-8") as experiment_file: - yaml.dump(data=self.to_dict(), stream=experiment_file, sort_keys=False) + if save_results: + # Create the folders & files needed to save the results locally + results_path = self._path_to_results_folder() + self._create_results_file(results_path) + + # Dump the experiment data into the created file + with open(file=results_path / EXPERIMENT_FILENAME, mode="w", encoding="utf-8") as experiment_file: + yaml.dump(data=self.to_dict(), stream=experiment_file, sort_keys=False) + else: + results_path = None return results, results_path