Skip to content

Commit

Permalink
Update BaseCalibrationExperiment for composite experiment (#1033)
Browse files Browse the repository at this point in the history
* Base calibration update for composite expeirment

* qubits -> physical_qubits

* Update docs and add new test

Co-authored-by: Daniel J. Egger <38065505+eggerdj@users.noreply.github.com>

* Add random init value to the cal table for unittest

---------

Co-authored-by: Daniel J. Egger <38065505+eggerdj@users.noreply.github.com>
  • Loading branch information
nkanazawa1989 and eggerdj authored Feb 14, 2023
1 parent c0cc88c commit 3cb1cda
Show file tree
Hide file tree
Showing 4 changed files with 425 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
"""Base class for calibration-type experiments."""

from abc import ABC, abstractmethod
import functools
import logging
from typing import List, Optional, Sequence, Type, Union
import warnings

from qiskit import QuantumCircuit
from qiskit.providers.backend import Backend
from qiskit.providers.options import Options
from qiskit.pulse import ScheduleBlock
from qiskit.transpiler import StagedPassManager, PassManager, Layout, CouplingMap
Expand Down Expand Up @@ -148,6 +148,43 @@ def calibrations(self) -> Calibrations:
"""Return the calibrations."""
return self._cals

@property
def analysis(self) -> Union[BaseAnalysis, None]:
"""Return the analysis instance for the experiment.
.. note::
Analysis instance set to calibration experiment is implicitly patched to run
calibration updator to update the parameters in the calibration table.
"""
return self._analysis

@analysis.setter
def analysis(self, analysis: Union[BaseAnalysis, None]) -> None:
"""Set the analysis instance for the experiment"""
if analysis is None:
return

# Create direct alias to the original run method to avoid infinite recursion.
# .run method is overruled by the wrapped method
# and thus .run method cannot be called within the wrapper function.
analysis_run = getattr(analysis, "run")

@functools.wraps(analysis_run)
def _wrap_run_analysis(*args, **kwargs):
experiment_data = analysis_run(*args, **kwargs)
if self.auto_update:
experiment_data.add_analysis_callback(self.update_calibrations)
return experiment_data

# Monkey patch run method.
# This calls update_calibrations immediately after standard analysis.
# This mechanism allows a composite experiment to invoke updator.
# Note that the composite experiment only takes circuits from individual experiment
# and the composite analysis calls analysis.run of each experiment.
# This is only place the updator function can be called from the composite experiment.
analysis.run = _wrap_run_analysis
BaseExperiment.analysis.fset(self, analysis)

@classmethod
def _default_experiment_options(cls) -> Options:
"""Default values for a calibration experiment.
Expand Down Expand Up @@ -303,36 +340,3 @@ def _attach_calibrations(self, circuit: QuantumCircuit):
some experiments already attach circuits to the logical circuits and do not needed to run
``_attach_calibrations``. In such experiments a simple ``pass`` statement will suffice.
"""

def run(
self,
backend: Optional[Backend] = None,
analysis: Optional[Union[BaseAnalysis, None]] = "default",
timeout: Optional[float] = None,
**run_options,
) -> ExperimentData:
"""Run an experiment, perform analysis, and update any calibrations.
Args:
backend: Optional, the backend to run the experiment on. This
will override any currently set backends for the single
execution.
analysis: Optional, a custom analysis instance to use for performing
analysis. If None analysis will not be run. If ``"default"``
the experiments :meth:`analysis` instance will be used if
it contains one.
timeout: Time to wait for experiment jobs to finish running before
cancelling.
run_options: backend runtime options used for circuit execution.
Returns:
The experiment data object.
"""
experiment_data = super().run(
backend=backend, analysis=analysis, timeout=timeout, **run_options
)

if self.auto_update and analysis:
experiment_data.add_analysis_callback(self.update_calibrations)

return experiment_data
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---

fixes:
- |
Fixes a bug where :class:`.Calibrations` is not updated when you run any calibration
experiment through composite experiment.
Loading

0 comments on commit 3cb1cda

Please sign in to comment.