qiskit-experiments icon indicating copy to clipboard operation
qiskit-experiments copied to clipboard

Add job splitting information to the experiment class

Open coruscating opened this issue 1 year ago • 6 comments

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().

coruscating avatar Aug 10 '23 16:08 coruscating

Hey @coruscating I wanna work on this issue.

nayan2167 avatar Aug 10 '23 18:08 nayan2167

@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.

coruscating avatar Aug 10 '23 19:08 coruscating

yup I already joined Qiskit Slack

nayan2167 avatar Aug 10 '23 19:08 nayan2167

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

nayan2167 avatar Aug 10 '23 20:08 nayan2167

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 be len(self.circuits()).
  • The backend logic doesn't quite work right now. job_info() should show an error to the user when self.backend isn't set and the user doesn't provide backend. 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.

coruscating avatar Aug 11 '23 04:08 coruscating

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

nayan2167 avatar Aug 12 '23 06:08 nayan2167