Skip to content
This repository has been archived by the owner on Dec 7, 2021. It is now read-only.

Commit

Permalink
VQE change backends
Browse files Browse the repository at this point in the history
  • Loading branch information
manoelmarques committed Jul 31, 2020
1 parent 358874b commit 4c66cba
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 14 deletions.
31 changes: 17 additions & 14 deletions qiskit/aqua/algorithms/minimum_eigen_solvers/vqe.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ def __init__(self,
self._max_evals_grouped = max_evals_grouped
self._circuit_sampler = None # type: Optional[CircuitSampler]
self._expectation = expectation
self._user_passed_expectation = self._expectation is not None
self._include_custom = include_custom
self._expect_op = None
self._operator = None
Expand Down Expand Up @@ -184,26 +185,28 @@ def operator(self, operator: Union[OperatorBase, LegacyBaseOperator]) -> None:
self._operator = operator
self._expect_op = None
self._check_operator_varform()
# Expectation was never created, try to create one
if self._expectation is None:
self._try_set_expectation_value_from_factory()

def _try_set_expectation_value_from_factory(self):
def _try_set_expectation_value_from_factory(self) -> None:
if self.operator and self.quantum_instance:
self.expectation = ExpectationFactory.build(operator=self.operator,
backend=self.quantum_instance,
include_custom=self._include_custom)
self._set_expectation(ExpectationFactory.build(operator=self.operator,
backend=self.quantum_instance,
include_custom=self._include_custom))

def _set_expectation(self, exp: ExpectationBase) -> None:
self._expectation = exp
self._expect_op = None

@QuantumAlgorithm.quantum_instance.setter
def quantum_instance(self, quantum_instance: Union[QuantumInstance, BaseBackend]) -> None:
""" set quantum_instance """
super(VQE, self.__class__).quantum_instance.__set__(self, quantum_instance)

if self._circuit_sampler is None:
self._circuit_sampler = CircuitSampler(self._quantum_instance)
else:
self._circuit_sampler.quantum_instance = self._quantum_instance

if self._expectation is None:
self._circuit_sampler = CircuitSampler(self._quantum_instance)
# Expectation was never created or it was not passed by user, try to create one
if self._expectation is None or not self._user_passed_expectation:
self._try_set_expectation_value_from_factory()

@property
Expand All @@ -214,8 +217,8 @@ def expectation(self) -> ExpectationBase:

@expectation.setter
def expectation(self, exp: ExpectationBase) -> None:
self._expectation = exp
self._expect_op = None
self._set_expectation(exp)
self._user_passed_expectation = self._expectation is not None

@property
def aux_operators(self) -> Optional[List[Optional[OperatorBase]]]:
Expand Down Expand Up @@ -328,8 +331,8 @@ def construct_expectation(self,
else:
wave_function = self.var_form.construct_circuit(parameter)

# If ExpectationValue was never created, create one now.
if self.expectation is None:
# Expectation was never created, try to create one
if self._expectation is None:
self._try_set_expectation_value_from_factory()

# If setting the expectation failed, raise an Error:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
fixes:
- |
Changing backends in VQE from statevector to qasm_simulator or real device
was causing an error due to CircuitSampler incompatible reuse. VQE was changed
to always create a new CircuitSampler and create a new expectation in case not
entered by user.
Refer to
`#1153 <https://github.com/Qiskit/qiskit-aqua/issues/1153>` for more details.
16 changes: 16 additions & 0 deletions test/aqua/test_vqe.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,22 @@ def test_ibmq(self):
self.assertIsNotNone(result.cost_function_evals)
self.assertIsNotNone(result.optimizer_time)

def test_backend_change(self):
"""Test that VQE works when backend changes."""
vqe = VQE(operator=self.h2_op,
var_form=TwoLocal(rotation_blocks=['ry', 'rz'], entanglement_blocks='cz'),
optimizer=SLSQP(maxiter=2),
quantum_instance=BasicAer.get_backend('statevector_simulator'))
result0 = vqe.run()
try:
vqe.set_backend(BasicAer.get_backend('qasm_simulator'))
except Exception as ex: # pylint: disable=broad-except
self.fail("Failed to change backend. Error: '{}'".format(str(ex)))
return

result1 = vqe.run()
self.assertEqual(len(result0.optimal_point), len(result1.optimal_point))


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

0 comments on commit 4c66cba

Please sign in to comment.