From 8f0780c7fea175306a932545fe25b2360b46cc1b Mon Sep 17 00:00:00 2001 From: Will Shanks Date: Sun, 7 Jan 2024 14:13:52 -0500 Subject: [PATCH] Update tests to avoid empty ExperimentData warning (#1349) Update fake backend to generate fake results for each circuit and update tests to run at least one circuit so that some results are generated. These changes avoid generating many instances of the recently added warning about running analysis on an empty experiment data object and also make the tests a little more realistic. --- qiskit_experiments/test/fake_backend.py | 15 ++++++++- .../test_base_calibration_experiment.py | 7 ++++ test/fake_experiment.py | 3 +- test/framework/test_composite.py | 24 +++++++------- test/framework/test_framework.py | 33 +++++++++++++++---- 5 files changed, 62 insertions(+), 20 deletions(-) diff --git a/qiskit_experiments/test/fake_backend.py b/qiskit_experiments/test/fake_backend.py index d9f4772350..3918cca70b 100644 --- a/qiskit_experiments/test/fake_backend.py +++ b/qiskit_experiments/test/fake_backend.py @@ -55,12 +55,25 @@ def target(self) -> Target: return self._target def run(self, run_input, **options): + if not isinstance(run_input, list): + run_input = [run_input] + results = [ + { + "data": {"0": 100}, + "shots": 100, + "success": True, + "header": {"metadata": circ.metadata}, + "meas_level": 2, + } + for circ in run_input + ] + result = { "backend_name": "fake_backend", "backend_version": "0", "qobj_id": uuid.uuid4().hex, "job_id": uuid.uuid4().hex, "success": True, - "results": [], + "results": results, } return FakeJob(backend=self, result=Result.from_dict(result)) diff --git a/test/calibration/test_base_calibration_experiment.py b/test/calibration/test_base_calibration_experiment.py index 8227e89eee..e924ff3992 100644 --- a/test/calibration/test_base_calibration_experiment.py +++ b/test/calibration/test_base_calibration_experiment.py @@ -87,6 +87,7 @@ def test_update_calibration(self): new_value=ref_new_value, param_name="to_calibrate", sched_name="test", + circuits=[QuantumCircuit(1)], ) self.assertExperimentDone(exp.run(backend)) @@ -131,6 +132,7 @@ def test_update_calibration_update_analysis(self): new_value=999999, param_name="to_calibrate", sched_name="test", + circuits=[QuantumCircuit(1)], ) exp.analysis.set_options(return_value=ref_new_value) # Update analysis option here self.assertExperimentDone(exp.run(backend)) @@ -176,6 +178,7 @@ def test_update_calibration_custom_analysis(self): new_value=99999, param_name="to_calibrate", sched_name="test", + circuits=[QuantumCircuit(1)], ) user_analysis = DoNothingAnalysis() @@ -231,6 +234,7 @@ def test_update_calibration_batch(self): new_value=ref_new_value1, param_name="to_calibrate1", sched_name="test", + circuits=[QuantumCircuit(1)], ) exp2 = MockCalExperiment( physical_qubits=(0,), @@ -238,6 +242,7 @@ def test_update_calibration_batch(self): new_value=ref_new_value2, param_name="to_calibrate2", sched_name="test", + circuits=[QuantumCircuit(1)], ) batch_exp = BatchExperiment([exp1, exp2], flatten_results=False, backend=backend) self.assertExperimentDone(batch_exp.run(backend)) @@ -301,6 +306,7 @@ def test_update_calibration_parallel(self): new_value=ref_new_value1, param_name="to_calibrate1", sched_name="test1", + circuits=[QuantumCircuit(1)], ) exp2 = MockCalExperiment( physical_qubits=(1,), @@ -308,6 +314,7 @@ def test_update_calibration_parallel(self): new_value=ref_new_value2, param_name="to_calibrate2", sched_name="test2", + circuits=[QuantumCircuit(1)], ) batch_exp = ParallelExperiment([exp1, exp2], flatten_results=False, backend=backend) self.assertExperimentDone(batch_exp.run(backend)) diff --git a/test/fake_experiment.py b/test/fake_experiment.py index f904a7f4c4..52a18f2940 100644 --- a/test/fake_experiment.py +++ b/test/fake_experiment.py @@ -14,6 +14,7 @@ import numpy as np from matplotlib.figure import Figure as MatplotlibFigure +from qiskit import QuantumCircuit from qiskit_experiments.framework import BaseExperiment, BaseAnalysis, Options, AnalysisResultData @@ -61,4 +62,4 @@ def __init__(self, physical_qubits=None, backend=None, experiment_type=None): def circuits(self): """Fake circuits.""" - return [] + return [QuantumCircuit(len(self.physical_qubits))] diff --git a/test/framework/test_composite.py b/test/framework/test_composite.py index b006d9f7c0..a25dcea966 100644 --- a/test/framework/test_composite.py +++ b/test/framework/test_composite.py @@ -70,7 +70,7 @@ def test_parallel_options(self): self.assertEqual(par_exp.analysis.options, par_exp.analysis._default_options()) with self.assertWarns(UserWarning): - expdata = par_exp.run(FakeBackend()) + expdata = par_exp.run(FakeBackend(num_qubits=3)) self.assertExperimentDone(expdata) def test_flatten_results_nested(self): @@ -92,7 +92,7 @@ def test_flatten_results_nested(self): ], flatten_results=True, ) - expdata = comp_exp.run(FakeBackend()) + expdata = comp_exp.run(FakeBackend(num_qubits=4)) self.assertExperimentDone(expdata) # Check no child data was saved self.assertEqual(len(expdata.child_data()), 0) @@ -112,7 +112,7 @@ def test_flatten_results_partial(self): ], flatten_results=False, ) - expdata = comp_exp.run(FakeBackend()) + expdata = comp_exp.run(FakeBackend(num_qubits=4)) self.assertExperimentDone(expdata) # Check out experiment wasn't flattened self.assertEqual(len(expdata.child_data()), 2) @@ -176,7 +176,7 @@ class TestCompositeExperimentData(QiskitExperimentsTestCase): def setUp(self): super().setUp() - self.backend = FakeBackend() + self.backend = FakeBackend(num_qubits=4) self.share_level = "public" exp1 = FakeExperiment([0, 2]) @@ -302,7 +302,7 @@ def test_nested_composite(self): exp4 = BatchExperiment([exp3, exp1], flatten_results=False) exp5 = ParallelExperiment([exp4, FakeExperiment([4])], flatten_results=False) nested_exp = BatchExperiment([exp5, exp3], flatten_results=False) - expdata = nested_exp.run(FakeBackend()) + expdata = nested_exp.run(FakeBackend(num_qubits=4)) self.assertExperimentDone(expdata) def test_analysis_replace_results_true(self): @@ -312,12 +312,12 @@ def test_analysis_replace_results_true(self): exp1 = FakeExperiment([0, 2]) exp2 = FakeExperiment([1, 3]) par_exp = ParallelExperiment([exp1, exp2], flatten_results=False) - data1 = par_exp.run(FakeBackend()) + data1 = par_exp.run(FakeBackend(num_qubits=4)) self.assertExperimentDone(data1) # Additional data not part of composite experiment exp3 = FakeExperiment([0, 1]) - extra_data = exp3.run(FakeBackend()) + extra_data = exp3.run(FakeBackend(num_qubits=2)) self.assertExperimentDone(extra_data) data1.add_child_data(extra_data) @@ -336,12 +336,12 @@ def test_analysis_replace_results_false(self): exp1 = FakeExperiment([0, 2]) exp2 = FakeExperiment([1, 3]) par_exp = BatchExperiment([exp1, exp2], flatten_results=False) - data1 = par_exp.run(FakeBackend()) + data1 = par_exp.run(FakeBackend(num_qubits=4)) self.assertExperimentDone(data1) # Additional data not part of composite experiment exp3 = FakeExperiment([0, 1]) - extra_data = exp3.run(FakeBackend()) + extra_data = exp3.run(FakeBackend(num_qubits=2)) self.assertExperimentDone(extra_data) data1.add_child_data(extra_data) @@ -360,7 +360,7 @@ def test_composite_tags(self): exp1 = FakeExperiment([0, 2]) exp2 = FakeExperiment([1, 3]) par_exp = BatchExperiment([exp1, exp2], flatten_results=False) - expdata = par_exp.run(FakeBackend()) + expdata = par_exp.run(FakeBackend(num_qubits=4)) self.assertExperimentDone(expdata) data1 = expdata.child_data(0) data2 = expdata.child_data(1) @@ -390,7 +390,7 @@ def test_composite_figures(self): exp1.analysis.set_options(add_figures=True) exp2.analysis.set_options(add_figures=True) par_exp = BatchExperiment([exp1, exp2], flatten_results=False) - expdata = par_exp.run(FakeBackend()) + expdata = par_exp.run(FakeBackend(num_qubits=4)) self.assertExperimentDone(expdata) expdata.service = IBMExperimentService(local=True, local_save=False) expdata.auto_save = True @@ -405,7 +405,7 @@ def test_composite_auto_save(self): exp1 = FakeExperiment([0, 2]) exp2 = FakeExperiment([1, 3]) par_exp = BatchExperiment([exp1, exp2], flatten_results=False) - expdata = par_exp.run(FakeBackend()) + expdata = par_exp.run(FakeBackend(num_qubits=4)) expdata.service = service self.assertExperimentDone(expdata) expdata.auto_save = True diff --git a/test/framework/test_framework.py b/test/framework/test_framework.py index 16488a38f7..7e05097e69 100644 --- a/test/framework/test_framework.py +++ b/test/framework/test_framework.py @@ -38,9 +38,20 @@ class TestFramework(QiskitExperimentsTestCase): """Test Base Experiment""" + def fake_job_data(self): + """Generate fake job data for tests""" + return { + "job_id": "123", + "metadata": {}, + "shots": 100, + "meas_level": 2, + "success": True, + "data": {"0": 100}, + } + def test_metadata(self): """Test the metadata of a basic experiment.""" - backend = FakeBackend() + backend = FakeBackend(num_qubits=2) exp = FakeExperiment((0, 2)) expdata = exp.run(backend) self.assertExperimentDone(expdata) @@ -119,7 +130,9 @@ def circuits(self): def test_analysis_replace_results_true(self): """Test running analysis with replace_results=True""" analysis = FakeAnalysis() - expdata1 = analysis.run(ExperimentData(), seed=54321) + expdata1 = ExperimentData() + expdata1.add_data(self.fake_job_data()) + expdata1 = analysis.run(expdata1, seed=54321) self.assertExperimentDone(expdata1) result_ids = [res.result_id for res in expdata1.analysis_results()] expdata2 = analysis.run(expdata1, replace_results=True, seed=12345) @@ -132,7 +145,9 @@ def test_analysis_replace_results_true(self): def test_analysis_replace_results_false(self): """Test running analysis with replace_results=False""" analysis = FakeAnalysis() - expdata1 = analysis.run(ExperimentData(), seed=54321) + expdata1 = ExperimentData() + expdata1.add_data(self.fake_job_data()) + expdata1 = analysis.run(expdata1, seed=54321) self.assertExperimentDone(expdata1) expdata2 = analysis.run(expdata1, replace_results=False, seed=12345) self.assertExperimentDone(expdata2) @@ -172,7 +187,9 @@ def test_analysis_runtime_opts(self): run_opts = {"opt1": True, "opt2": True, "opt3": True} analysis = FakeAnalysis() analysis.set_options(**opts) - analysis.run(ExperimentData(), **run_opts) + expdata = ExperimentData() + expdata.add_data(self.fake_job_data()) + analysis.run(expdata, **run_opts) # add also the default 'figure_names' option target_opts = opts.copy() target_opts["figure_names"] = None @@ -190,7 +207,9 @@ def _run_analysis(self, experiment_data, **options): analysis = FakeAnalysis() failed_analysis = FakeFailedAnalysis() - expdata1 = analysis.run(ExperimentData(), seed=54321) + expdata1 = ExperimentData() + expdata1.add_data(self.fake_job_data()) + expdata1 = analysis.run(expdata1, seed=54321) self.assertExperimentDone(expdata1) expdata2 = failed_analysis.run( expdata1, replace_results=True, seed=12345 @@ -211,7 +230,9 @@ def _run_analysis(self, experiment_data, **options): analysis = FakeAnalysis() failed_analysis = FakeFailedAnalysis() - expdata1 = analysis.run(ExperimentData(), seed=54321) + expdata1 = ExperimentData() + expdata1.add_data(self.fake_job_data()) + expdata1 = analysis.run(expdata1, seed=54321) self.assertExperimentDone(expdata1) expdata2 = failed_analysis.run(expdata1, replace_results=False, seed=12345)