diff --git a/qiskit_experiments/framework/base_experiment.py b/qiskit_experiments/framework/base_experiment.py index bb14cdc610..024911a0e4 100644 --- a/qiskit_experiments/framework/base_experiment.py +++ b/qiskit_experiments/framework/base_experiment.py @@ -85,6 +85,9 @@ def __init__( if isinstance(backend, Backend): self._set_backend(backend) + # Optional user-defined custom transpiled circuits + self._custom_transpiled_circuits = None + @property def experiment_type(self) -> str: """Return experiment type.""" @@ -133,6 +136,26 @@ def _set_backend(self, backend: Backend): self._backend = backend self._backend_data = BackendData(backend) + @property + def custom_transpiled_circuits(self): + """Custom transpiled circuits as defined by the user. The user is responsible for providing + the circuit metadata expected by experiment analysis.""" + return self._custom_transpiled_circuits + + @custom_transpiled_circuits.setter + def custom_transpiled_circuits(self, circuits: List[QuantumCircuit]): + """Set custom transpiled circuits.""" + if not isinstance(circuits, List) and all(isinstance(i, QuantumCircuit) for i in circuits): + raise TypeError("Custom transpiled circuits must be a list of QuantumCircuit objects.") + self._set_custom_transpiled_circuits(circuits) + + def _set_custom_transpiled_circuits(self, circuits: List[QuantumCircuit]): + """Set custom transpiled circuits. + + Subclasses can override this method to add circuit verification or modify + the user-provided circuit and/or its metadata.""" + self._custom_transpiled_circuits = circuits + def copy(self) -> "BaseExperiment": """Return a copy of the experiment""" # We want to avoid a deep copy be default for performance so we @@ -233,8 +256,11 @@ def run( # Finalize experiment before executions experiment._finalize() - # Generate and transpile circuits - transpiled_circuits = experiment._transpiled_circuits() + if self.custom_transpiled_circuits: + transpiled_circuits = self.custom_transpiled_circuits + else: + # Generate and transpile circuits + transpiled_circuits = experiment._transpiled_circuits() # Initialize result container experiment_data = experiment._initialize_experiment_data() diff --git a/test/framework/test_framework.py b/test/framework/test_framework.py index 265630371e..07f6a28f19 100644 --- a/test/framework/test_framework.py +++ b/test/framework/test_framework.py @@ -15,6 +15,7 @@ from test.fake_experiment import FakeExperiment, FakeAnalysis from test.base import QiskitExperimentsTestCase from itertools import product +import unittest import ddt from qiskit import QuantumCircuit @@ -116,6 +117,16 @@ def circuits(self): num_jobs += 1 self.assertEqual(len(job_ids), num_jobs) + def test_custom_transpiled_circuits(self): + """Test that custom transpiled circuits can be injected.""" + exp = FakeExperiment((0,)) + backend = FakeBackend() + exp._transpiled_circuits = unittest.mock.Mock() + exp.custom_transpiled_circuits = [QuantumCircuit(0)] + expdata = exp.run(backend) + self.assertExperimentDone(expdata) + exp._transpiled_circuits.assert_not_called() + def test_analysis_replace_results_true(self): """Test running analysis with replace_results=True""" analysis = FakeAnalysis()