Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add job splitting information to the experiment class #1247

Open
coruscating opened this issue Aug 10, 2023 · 6 comments
Open

Add job splitting information to the experiment class #1247

coruscating opened this issue Aug 10, 2023 · 6 comments
Assignees
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@coruscating
Copy link
Collaborator

coruscating commented Aug 10, 2023

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 coruscating added enhancement New feature or request good first issue Good for newcomers labels Aug 10, 2023
@nayan2167
Copy link
Contributor

Hey @coruscating I wanna work on this issue.

@coruscating
Copy link
Collaborator Author

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

@nayan2167
Copy link
Contributor

yup I already joined Qiskit Slack

@nayan2167
Copy link
Contributor

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

@coruscating
Copy link
Collaborator Author

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.

@nayan2167
Copy link
Contributor

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

github-merge-queue bot pushed a commit that referenced this issue Oct 23, 2023
This PR aims to solve issue #1247 als the changes are similar to PR
#1248
### Summary:
This pull request aims to enhance the user experience by providing
clearer insights into the structure of experiments and their
distribution across backends. It introduces two new public methods,
`_max_circuits()` and `job_info(backend)`, while also refactoring the
existing `_run_jobs()` method for better code organization and reuse of
logic.

### Proposed Changes:

Add` _max_circuits()` Method:
This method will calculate the maximum number of circuits that can be
included in a single job. This method will encapsulate the logic
previously present in the ` _run_jobs()` method to determine the maximum
circuits per job.

Add `job_info(backend)` Method:
This method will utilize the `_max_circuits()` method to provide users
with information about the experiment's configuration for a specific
backend. If the backend argument is provided, the method will return the
number of circuits and the number of jobs the experiment will be split
into on that backend. If the backend argument is not provided, the
method will rely on the backend already specified in the experiment.

Refactor `_run_jobs()` Method:
The existing `_run_jobs()` method will be refactored to make use of the
`_max_circuits()` method. This change will enhance code readability and
maintainability by segregating the logic related to job distribution
from the actual job execution logic.

### Testing 
Added `test_max_circuits` for testing of `_max_circuits()` and
`test_job_info` for testing of `job_info(backend)` these tests ensure
that methods functioning correctly

---------

Co-authored-by: Helena Zhang <[email protected]>
nkanazawa1989 pushed a commit to nkanazawa1989/qiskit-experiments that referenced this issue Jan 10, 2024
…kit-community#1281)

This PR aims to solve issue qiskit-community#1247 als the changes are similar to PR
qiskit-community#1248
### Summary:
This pull request aims to enhance the user experience by providing
clearer insights into the structure of experiments and their
distribution across backends. It introduces two new public methods,
`_max_circuits()` and `job_info(backend)`, while also refactoring the
existing `_run_jobs()` method for better code organization and reuse of
logic.

### Proposed Changes:

Add` _max_circuits()` Method:
This method will calculate the maximum number of circuits that can be
included in a single job. This method will encapsulate the logic
previously present in the ` _run_jobs()` method to determine the maximum
circuits per job.

Add `job_info(backend)` Method:
This method will utilize the `_max_circuits()` method to provide users
with information about the experiment's configuration for a specific
backend. If the backend argument is provided, the method will return the
number of circuits and the number of jobs the experiment will be split
into on that backend. If the backend argument is not provided, the
method will rely on the backend already specified in the experiment.

Refactor `_run_jobs()` Method:
The existing `_run_jobs()` method will be refactored to make use of the
`_max_circuits()` method. This change will enhance code readability and
maintainability by segregating the logic related to job distribution
from the actual job execution logic.

### Testing 
Added `test_max_circuits` for testing of `_max_circuits()` and
`test_job_info` for testing of `job_info(backend)` these tests ensure
that methods functioning correctly

---------

Co-authored-by: Helena Zhang <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants