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 option to run MLAE circuits separately #7428

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions qiskit/algorithms/amplitude_estimators/mlae.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def __init__(
evaluation_schedule: Union[List[int], int],
minimizer: Optional[MINIMIZER] = None,
quantum_instance: Optional[Union[QuantumInstance, BaseBackend, Backend]] = None,
run_circuits_as_one_job: bool = True,
) -> None:
r"""
Args:
Expand All @@ -66,6 +67,9 @@ def __init__(
argument and a list of (float, float) tuples (as bounds) as second argument and
returns a single float which is the found minimum.
quantum_instance: Quantum Instance or Backend
run_circuits_as_one_job: If set to True, the necessary circuits will be submitted as
one job. Otherwise, each circuit will be run separately. This is useful for
backends that don't support multi-circuit experiments.
Comment on lines +70 to +72
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps use_separate_jobs=False? (I have very little preference here - just suggesting alternatives.)

A minor wording nitpick: "If set to True" implies to me that that's not the default. It'd perhaps be best to use the words "If set to ..." to talk about the non-default setting.


Raises:
ValueError: If the number of oracle circuits is smaller than 1.
Expand Down Expand Up @@ -99,6 +103,8 @@ def default_minimizer(objective_fn, bounds):
else:
self._minimizer = minimizer

self._run_circuits_as_one_job = run_circuits_as_one_job

Comment on lines +106 to +107
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that backend can be changed after object instantiation, you may want to make this a public attribute so it can be set if the value of the switch isn't known til later.

@property
def quantum_instance(self) -> Optional[QuantumInstance]:
"""Get the quantum instance.
Expand Down Expand Up @@ -286,12 +292,18 @@ def estimate(
result.shots = 1

else:
# run circuit on QASM simulator
# construct circuits
circuits = self.construct_circuits(estimation_problem, measurement=True)
ret = self._quantum_instance.execute(circuits)

# get counts and construct MLE input
result.circuit_results = [ret.get_counts(circuit) for circuit in circuits]
# run circuit on QASM simulator, get counts, and construct MLE input
if self._run_circuits_as_one_job:
ret = self._quantum_instance.execute(circuits)
result.circuit_results = [ret.get_counts(circuit) for circuit in circuits]
else:
rets = [self._quantum_instance.execute(circuit) for circuit in circuits]
result.circuit_results = [
ret.get_counts(circuit) for ret, circuit in zip(rets, circuits)
]

# to count the number of Q-oracle calls
result.shots = self._quantum_instance._run_config.shots
Expand Down
30 changes: 30 additions & 0 deletions test/python/algorithms/test_amplitude_estimators.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,5 +547,35 @@ def is_good_state(bitstr):
self.assertAlmostEqual(result.estimation, expect, places=5)


@ddt
class TestMaximumLikelihoodAmplitudeEstimation(QiskitAlgorithmsTestCase):
"""Specific tests for Maximum Likelihood AE."""

def test_sequential_circuit_submission(self):
"""Test that the results are correct when circuits are submitted separately."""
prob = 0.2
a_op = BernoulliStateIn(prob)
q_op = BernoulliGrover(prob)
problem = EstimationProblem(a_op, objective_qubits=[0], grover_operator=q_op)

# construct algo
quantum_instance = QuantumInstance(
backend=BasicAer.get_backend("qasm_simulator"),
shots=1000,
seed_simulator=2,
seed_transpiler=2,
)
mlae = MaximumLikelihoodAmplitudeEstimation(
evaluation_schedule=5,
quantum_instance=quantum_instance,
run_circuits_as_one_job=False,
)

# run the algo
result = mlae.estimate(problem)
Comment on lines +568 to +575
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be good to use a mock object to wrap your quantum_instance's execute method, and ensure that it's called the number of times you expect - as it stands, this test only ensures that the option is valid, not that it actually separates the circuits.


self.assertAlmostEqual(prob, result.estimation, places=3, msg="estimate failed")


if __name__ == "__main__":
unittest.main()