qiskit-experiments
qiskit-experiments copied to clipboard
Add job splitting information to the experiment class
Suggested feature
Users often want to know how many circuits are in the experiment and whether the experiment will be split into multiple jobs if run on a specific backend. This logic is currently handled in _run_jobs()
, but we would like there to be a public method that provides the user with this information.
I propose the following change:
- Add
experiment._max_circuits()
which splits out the logic in_run_jobs()
that calculates the maximum number of circuits per job - Add a public interface
experiment.job_info(backend)
which uses_max_circuits()
to tell the user how many circuits and how many jobs their experiment will consist of on a particular backend. If the backend is not provided in the run parameters, the experiment must already have a backend specified. - Refactor
_run_jobs()
to use_max_circuits()
.
Hey @coruscating I wanna work on this issue.
@nayan2167 Great! If you're on the Qiskit Slack, I can add you to the experiments-dev channel where we discuss development on Qiskit Experiments.
yup I already joined Qiskit Slack
Hi @coruscating can you review it please
def _max_circuits(self):
"""Calculate the maximum number of circuits per job for the experiment."""
# Get max circuits for job splitting
max_circuits_option = getattr(self.experiment_options, "max_circuits", None)
max_circuits_backend = self._backend_data.max_circuits
if max_circuits_option and max_circuits_backend:
return min(max_circuits_option, max_circuits_backend)
elif max_circuits_option:
return max_circuits_option
else:
return max_circuits_backend
def job_info(self, backend=None):
"""Get information about job distribution for the experiment on a specific backend."""
if backend is None:
backend = self.backend
max_circuits = self._max_circuits()
total_circuits = len(self.circuits)
if total_circuits <= max_circuits:
return {
"circuits_per_job": total_circuits,
"num_jobs": 1
}
else:
num_jobs = (total_circuits + max_circuits - 1) // max_circuits
return {
"circuits_per_job": max_circuits,
"num_jobs": num_jobs
}
def _run_jobs(self, circuits: List[QuantumCircuit], **run_options) -> List[Job]:
"""Run circuits on backend as 1 or more jobs."""
max_circuits = self._max_circuits()
if len(circuits) <= max_circuits:
job_circuits = [circuits]
else:
job_circuits = [
circuits[i:i + max_circuits] for i in range(0, len(circuits), max_circuits)
]
jobs = [self.backend.run(circs, **run_options) for circs in job_circuits]
return jobs
This is a good start, thanks @nayan2167. A few comments:
- It looks like you've defined
circuits_per_job
as the total number of circuits in the experiment, so this variable isn't accurately named (each experiment can have many jobs).len(self.circuits)
should belen(self.circuits())
. - The backend logic doesn't quite work right now.
job_info()
should show an error to the user whenself.backend
isn't set and the user doesn't providebackend
. It also does nothing with the backend provided by the user. That should be passed to_max_circuits
so it can calculate correctly. - A test should be added to check that
job_info()
produces the correct information, and the job splitting how-to should be updated with this method so users know how to use it.
Please open a pull request after making these changes so it will be easier to make comments.
Hi @coruscating I am not quite understanding A test should be added to check that job_info()
can you explain a bit more?
However, I made a few changes please review PR #1248