Skip to content
This repository has been archived by the owner on Jul 13, 2022. It is now read-only.

Commit

Permalink
Warning for composite experiment run options (qiskit-community#159)
Browse files Browse the repository at this point in the history
* added warning and test

* addressed comments

* moved base data processor to its own file

* run options

* black

* lint

* changed warning message

* fixed message

* make warning shorter for lint

* broke line in two

* combined FakeExperiment

* changed options checking

* fake experiment name

* fixed default options

* updated default transpile options

* removed import
  • Loading branch information
coruscating committed Jul 18, 2021
1 parent 68a74bd commit 057d79c
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 32 deletions.
7 changes: 3 additions & 4 deletions qiskit_experiments/base_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,6 @@ def __init__(self, qubits: Iterable[int], experiment_type: Optional[str] = None)
self._run_options = self._default_run_options()
self._analysis_options = self._default_analysis_options()

# Set initial layout from qubits
self._transpile_options.initial_layout = list(self._physical_qubits)

def run(
self,
backend: Backend,
Expand Down Expand Up @@ -125,7 +122,9 @@ def run(
run_opts = run_opts.__dict__

# Generate and transpile circuits
circuits = transpile(self.circuits(backend), backend, **self.transpile_options.__dict__)
transpile_opts = self.transpile_options.__dict__
transpile_opts["initial_layout"] = list(self._physical_qubits)
circuits = transpile(self.circuits(backend), backend, **transpile_opts)
self._postprocess_transpiled_circuits(circuits, backend, **run_options)

if isinstance(backend, LegacyBackend):
Expand Down
12 changes: 12 additions & 0 deletions qiskit_experiments/composite/composite_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""

from abc import abstractmethod
import warnings

from qiskit_experiments.base_experiment import BaseExperiment
from .composite_experiment_data import CompositeExperimentData
Expand Down Expand Up @@ -63,6 +64,17 @@ def _add_job_metadata(self, experiment_data, job, **run_options):
# Add sub-experiment options
for i in range(self.num_experiments):
sub_exp = self.component_experiment(i)

# Run and transpile options are always overridden
if (
sub_exp.run_options != sub_exp._default_run_options()
or sub_exp.transpile_options != sub_exp._default_transpile_options()
):

warnings.warn(
"Sub-experiment run and transpile options"
" are overridden by composite experiment options."
)
sub_data = experiment_data.component_experiment_data(i)
sub_exp._add_job_metadata(sub_data, job, **run_options)

Expand Down
13 changes: 2 additions & 11 deletions test/analysis/test_curve_fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,18 @@

from typing import List

from test.fake_experiment import FakeExperiment

import numpy as np
from qiskit.test import QiskitTestCase
from qiskit.qobj.utils import MeasLevel

from qiskit_experiments import ExperimentData
from qiskit_experiments.analysis import CurveAnalysis, SeriesDef, fit_function
from qiskit_experiments.analysis.data_processing import probability
from qiskit_experiments.base_experiment import BaseExperiment
from qiskit_experiments.exceptions import AnalysisError


class FakeExperiment(BaseExperiment):
"""A fake experiment class."""

def __init__(self):
super().__init__(qubits=(0,), experiment_type="fake_experiment")

def circuits(self, backend=None):
return []


def simulate_output_data(func, xvals, param_dict, **metadata):
"""Generate arbitrary fit data."""
__shots = 100000
Expand Down
14 changes: 14 additions & 0 deletions test/data_processing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Data processing tests."""
from .base_data_processor_test import BaseDataProcessorTest
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,10 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""A FakeExperiment for data processor testing."""
"""Base class for data processor tests."""

from qiskit.test import QiskitTestCase
from qiskit.qobj.common import QobjExperimentHeader
from qiskit_experiments.base_experiment import BaseExperiment


class FakeExperiment(BaseExperiment):
"""Fake experiment class for testing."""

def __init__(self):
"""Initialise the fake experiment."""
self._type = None
super().__init__((0,), "fake_test_experiment")

def circuits(self, backend=None):
"""Fake circuits."""
return []


class BaseDataProcessorTest(QiskitTestCase):
Expand Down
5 changes: 4 additions & 1 deletion test/data_processing/test_data_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

# pylint: disable=unbalanced-tuple-unpacking

from test.data_processing.fake_experiment import FakeExperiment, BaseDataProcessorTest
from test.fake_experiment import FakeExperiment

import numpy as np
from qiskit.result.models import ExperimentResultData, ExperimentResult
from qiskit.result import Result
Expand All @@ -31,6 +32,8 @@
MinMaxNormalize,
)

from . import BaseDataProcessorTest


class DataProcessorTest(BaseDataProcessorTest):
"""Class to test DataProcessor."""
Expand Down
4 changes: 3 additions & 1 deletion test/data_processing/test_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

# pylint: disable=unbalanced-tuple-unpacking

from test.data_processing.fake_experiment import FakeExperiment, BaseDataProcessorTest
from test.fake_experiment import FakeExperiment

from typing import Any, List
import numpy as np
Expand All @@ -26,6 +26,8 @@
from qiskit_experiments.data_processing.nodes import SVD, AverageData, MinMaxNormalize
from qiskit_experiments.data_processing.data_processor import DataProcessor

from . import BaseDataProcessorTest


class TestAveraging(QiskitTestCase):
"""Test the averaging nodes."""
Expand Down
58 changes: 58 additions & 0 deletions test/fake_backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Fake backend class for tests."""
from qiskit.providers.backend import BackendV1
from qiskit.providers.models import QasmBackendConfiguration
from qiskit.providers.options import Options

from qiskit.result import Result

from qiskit_experiments.test.mock_job import MockJob


class FakeBackend(BackendV1):
"""
Fake backend for test purposes only.
"""

def __init__(self):
configuration = QasmBackendConfiguration(
backend_name="dummy_backend",
backend_version="0",
n_qubits=int(1e6),
basis_gates=["barrier", "x", "delay", "measure"],
gates=[],
local=True,
simulator=True,
conditional=False,
open_pulse=False,
memory=False,
max_shots=int(1e6),
coupling_map=None,
)
super().__init__(configuration)

@classmethod
def _default_options(cls):
return Options()

def run(self, run_input, **options):
result = {
"backend_name": "Dummmy backend",
"backend_version": "0",
"qobj_id": 0,
"job_id": 0,
"success": True,
"results": [],
}
return MockJob(backend=self, result=Result.from_dict(result))
46 changes: 46 additions & 0 deletions test/fake_experiment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""A FakeExperiment for testing."""

from qiskit.providers.options import Options

from qiskit_experiments.base_experiment import BaseExperiment
from qiskit_experiments.base_analysis import BaseAnalysis


class FakeAnalysis(BaseAnalysis):
"""
Dummy analysis class for test purposes only.
"""

def _run_analysis(self, experiment_data, **options):
return [], None


class FakeExperiment(BaseExperiment):
"""Fake experiment class for testing."""

__analysis_class__ = FakeAnalysis

@classmethod
def _default_experiment_options(cls) -> Options:
return Options(dummyoption=None)

def __init__(self, qubit=0):
"""Initialise the fake experiment."""
self._type = None
super().__init__((qubit,), "fake_test_experiment")

def circuits(self, backend=None):
"""Fake circuits."""
return []
55 changes: 55 additions & 0 deletions test/test_composite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Class to test composite experiments."""

from test.fake_backend import FakeBackend
from test.fake_experiment import FakeExperiment

from qiskit.test import QiskitTestCase
from qiskit.providers.options import Options

from qiskit_experiments.composite.parallel_experiment import ParallelExperiment


class TestComposite(QiskitTestCase):
"""
Test composite experiment behavior.
"""

def test_parallel_options(self):
"""
Test parallel experiments overriding sub-experiment run and transpile options.
"""

# These options will all be overridden
exp0 = FakeExperiment(0)
exp0.set_transpile_options(optimization_level=1)
exp2 = FakeExperiment(2)
exp2.set_experiment_options(dummyoption="test")
exp2.set_run_options(shots=2000)
exp2.set_transpile_options(optimization_level=1)
exp2.set_analysis_options(dummyoption="test")

par_exp = ParallelExperiment([exp0, exp2])

with self.assertWarnsRegex(
Warning,
"Sub-experiment run and transpile options"
" are overridden by composite experiment options.",
):
self.assertEqual(par_exp.experiment_options, Options())
self.assertEqual(par_exp.run_options, Options(meas_level=2))
self.assertEqual(par_exp.transpile_options, Options(optimization_level=0))
self.assertEqual(par_exp.analysis_options, Options())

par_exp.run(FakeBackend())

0 comments on commit 057d79c

Please sign in to comment.