Skip to content

Commit

Permalink
Deprecates Opflow and QuantumInstance (#499)
Browse files Browse the repository at this point in the history
* reduce deprecation warnings of opflow

* update

* update

* update

* suppress opflow deprecation of a legacy test

* suppress opflow deprecations in tests

* Update qiskit_optimization/translators/ising.py

Co-authored-by: Steve Wood <40241007+woodsp-ibm@users.noreply.github.com>

* update test_ising and add reno

---------

Co-authored-by: Steve Wood <40241007+woodsp-ibm@users.noreply.github.com>
  • Loading branch information
t-imamichi and woodsp-ibm committed Apr 28, 2023
1 parent fc9a86a commit 75d9898
Show file tree
Hide file tree
Showing 13 changed files with 273 additions and 195 deletions.
54 changes: 21 additions & 33 deletions qiskit_optimization/algorithms/grover_optimizer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2020, 2022.
# (C) Copyright IBM 2020, 2023.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand All @@ -14,7 +14,6 @@

import logging
import math
import warnings
from copy import deepcopy
from typing import Dict, List, Optional, Union, cast

Expand All @@ -28,16 +27,21 @@
from qiskit.quantum_info import partial_trace
from qiskit.utils import QuantumInstance, algorithm_globals

from ..converters.quadratic_program_to_qubo import QuadraticProgramConverter, QuadraticProgramToQubo
from ..exceptions import QiskitOptimizationError
from ..problems import Variable
from ..problems.quadratic_program import QuadraticProgram
from .optimization_algorithm import (
from qiskit_optimization.algorithms.optimization_algorithm import (
OptimizationAlgorithm,
OptimizationResult,
OptimizationResultStatus,
SolutionSample,
)
from qiskit_optimization.converters import QuadraticProgramConverter, QuadraticProgramToQubo
from qiskit_optimization.deprecation import (
DeprecatedType,
deprecate_method,
deprecate_property,
warn_deprecated,
)
from qiskit_optimization.exceptions import QiskitOptimizationError
from qiskit_optimization.problems import QuadraticProgram, Variable

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -82,51 +86,35 @@ def __init__(
if quantum_instance is not None and sampler is not None:
raise ValueError("Only one of quantum_instance or sampler can be passed, not both!")

self._quantum_instance = None # type: Optional[QuantumInstance]
if quantum_instance is not None:
warnings.warn(
"The quantum_instance argument has been superseded by the sampler argument. "
"This argument will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
stacklevel=2,
if quantum_instance:
warn_deprecated(
"0.6.0",
old_type=DeprecatedType.ARGUMENT,
old_name="quantum_instance",
new_type=DeprecatedType.ARGUMENT,
new_name="sampler",
)
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=PendingDeprecationWarning)
self.quantum_instance = quantum_instance

self._quantum_instance = quantum_instance # type: Optional[QuantumInstance]
self._sampler = sampler

@property
@deprecate_property("0.6.0")
def quantum_instance(self) -> QuantumInstance:
"""The quantum instance to run the circuits.
Returns:
The quantum instance used in the algorithm.
"""
warnings.warn(
"The quantum_instance argument has been superseded by the sampler argument. "
"This argument will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
stacklevel=2,
)
return self._quantum_instance

@quantum_instance.setter
@deprecate_method("0.6.0")
def quantum_instance(self, quantum_instance: Union[Backend, QuantumInstance]) -> None:
"""Set the quantum instance used to run the circuits.
Args:
quantum_instance: The quantum instance to be used in the algorithm.
"""
warnings.warn(
"The GroverOptimizer.quantum_instance setter is pending deprecation. "
"This property will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
stacklevel=2,
)
if isinstance(quantum_instance, Backend):
self._quantum_instance = QuantumInstance(quantum_instance)
else:
Expand Down
20 changes: 12 additions & 8 deletions qiskit_optimization/algorithms/minimum_eigen_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
MinimumEigensolverResult as LegacyMinimumEigensolverResult,
)
from qiskit.algorithms.minimum_eigensolvers import (
VQE,
NumPyMinimumEigensolver,
NumPyMinimumEigensolverResult,
SamplingMinimumEigensolver,
SamplingMinimumEigensolverResult,
VQE,
)
from qiskit.opflow import OperatorBase, PauliOp, PauliSumOp
from qiskit.quantum_info import SparsePauliOp

from ..converters.quadratic_program_to_qubo import QuadraticProgramConverter, QuadraticProgramToQubo
from ..exceptions import QiskitOptimizationError
Expand Down Expand Up @@ -222,25 +222,29 @@ def solve(self, problem: QuadraticProgram) -> MinimumEigenOptimizationResult:
problem_ = self._convert(problem, self._converters)

# construct operator and offset
operator, offset = problem_.to_ising(opflow=True)
operator, offset = problem_.to_ising(opflow=False)

return self._solve_internal(operator, offset, problem_, problem)

def _solve_internal(
self,
operator: OperatorBase,
operator: SparsePauliOp,
offset: float,
converted_problem: QuadraticProgram,
original_problem: QuadraticProgram,
):
# only try to solve non-empty Ising Hamiltonians
eigen_result: Optional[MinimumEigensolverResult] = None
if operator.num_qubits > 0:
# NumPyEigensolver does not accept PauliOp but PauliSumOp
if isinstance(operator, PauliOp):
operator = PauliSumOp.from_list([(operator.primitive.to_label(), operator.coeff)])
# approximate ground state of operator using min eigen solver
eigen_result = self._min_eigen_solver.compute_minimum_eigenvalue(operator)
if isinstance(self._min_eigen_solver, LegacyMinimumEigensolver):
from qiskit.opflow import PauliSumOp

eigen_result = self._min_eigen_solver.compute_minimum_eigenvalue(
PauliSumOp(operator)
)
else:
eigen_result = self._min_eigen_solver.compute_minimum_eigenvalue(operator)
# analyze results
raw_samples = None
if eigen_result.eigenstate is not None:
Expand Down
2 changes: 1 addition & 1 deletion qiskit_optimization/algorithms/optimization_algorithm.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2020, 2022.
# (C) Copyright IBM 2020, 2023.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def solve(self, problem: QuadraticProgram) -> MinimumEigenOptimizationResult:
pre_solutions = opt_result.samples[:num_pre_solutions]

# construct operator and offset
operator, offset = converted_problem.to_ising(opflow=True)
operator, offset = converted_problem.to_ising(opflow=False)

results: List[MinimumEigenOptimizationResult] = []
for pre_solution in pre_solutions:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2018, 2022.
# (C) Copyright IBM 2018, 2023.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand Down
4 changes: 2 additions & 2 deletions qiskit_optimization/translators/ising.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,9 @@ def from_ising(
warn(
"The `qubit_op` argument can currently accept Opflow operators (`OperatorBase` type), "
"but have been superseded by Qiskit Terra quantum_info `BaseOperators` such as "
"`SparsePauliOp`. Opflow operator support will be deprecated in a future release "
"`SparsePauliOp`. Opflow operators have been deprecated in Qiskit Terra 0.24.0 "
"and subsequently removed after that.",
category=PendingDeprecationWarning,
category=DeprecationWarning,
stacklevel=2,
)
if isinstance(qubit_op, PauliSumOp):
Expand Down
13 changes: 13 additions & 0 deletions releasenotes/notes/deprecate-opflow-0c472adf38939a5c.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
deprecations:
- |
The ``quantum_instance`` argument of :class:`~qiskit_optimization.algorithms.GroverOptimizer`'s constructor
and :meth:`~qiskit_optimization.algorithms.GroverOptimizer.quantum_instance` property have been deprecated
and will be removed in a future release.
Using ``QuantumInstance`` is superseded by ``Sampler``.
See `QuantumInstance Migration <https://qisk.it/qi_migration>`__.
- |
The ``qubit_op`` argument of :func:`~qiskit_optimization.translators.from_ising`
can currently accept Opflow operators.
But they have been deprecated in Qiskit Terra 0.24.0 and will be removed in a future release.
See `Opflow Migration <https://qisk.it/opflow_migration>`__.
36 changes: 20 additions & 16 deletions test/algorithms/legacy/test_min_eigen_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ def test_min_eigen_optimizer(self, config):
# get minimum eigen solver
min_eigen_solver = self.min_eigen_solvers[min_eigen_solver_name]
if backend:
min_eigen_solver.quantum_instance = BasicAer.get_backend(backend)
with self.assertWarns(DeprecationWarning):
min_eigen_solver.quantum_instance = BasicAer.get_backend(backend)

# construct minimum eigen optimizer
min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver)
Expand Down Expand Up @@ -379,26 +380,29 @@ def test_runtime(self, subroutine):
if subroutine == "vqe":
ry_ansatz = TwoLocal(5, "ry", "cz", reps=3, entanglement="full")
initial_point = np.random.default_rng(42).random(ry_ansatz.num_parameters)
solver = VQEClient(
ansatz=ry_ansatz,
optimizer=optimizer,
initial_point=initial_point,
backend=backend,
provider=FakeVQERuntimeProvider(),
)
with self.assertWarns(DeprecationWarning):
solver = VQEClient(
ansatz=ry_ansatz,
optimizer=optimizer,
initial_point=initial_point,
backend=backend,
provider=FakeVQERuntimeProvider(),
)
else:
reps = 2
initial_point = np.random.default_rng(42).random(2 * reps)
solver = QAOAClient(
optimizer=optimizer,
reps=reps,
initial_point=initial_point,
backend=backend,
provider=FakeQAOARuntimeProvider(),
)
with self.assertWarns(DeprecationWarning):
solver = QAOAClient(
optimizer=optimizer,
reps=reps,
initial_point=initial_point,
backend=backend,
provider=FakeQAOARuntimeProvider(),
)

opt = MinimumEigenOptimizer(solver)
result = opt.solve(self.op_ordering)
with self.assertWarns(DeprecationWarning):
result = opt.solve(self.op_ordering)
self.assertIsInstance(result, MinimumEigenOptimizationResult)


Expand Down
Loading

0 comments on commit 75d9898

Please sign in to comment.