qiskit-community / qiskit-aqua

Quantum Algorithms & Applications (**DEPRECATED** since April 2021 - see readme for more info)
https://qiskit.org/aqua
Apache License 2.0
574 stars 376 forks source link

Problem while executing HHL on qasm simulator #918

Closed skanderkaz closed 4 years ago

skanderkaz commented 4 years ago

Hi,

I have a problem when executing the HHL algorithm on the backends and on the qasm simulator (it works fine with the statevector simulator). I receive the following error :

SolverError: The solver CVXOPT is not installed.

Steps to reproduce the problem :

provider = IBMQ.get_provider(group='open') backend = provider.get_backend('ibmq_qasm_simulator')

woodsp-ibm commented 4 years ago

Hi, as far as I can see the exception is something that cvxpy would raise. cvxpy is used in Terra and Ignis but not in Aqua. Can you provide the output from the exception that shows the call stack so we can see better where this is coming from. I tried to see if I could get the issue by running the HHL code I have but it works fine - and I ensured cvxopt was not installed, was was using BasicAer wasm simulator. What version of qiskit do you have installed? If your code sample is short that can reproduce the issue with a local qasm simulator maybe you can post that here as well.

skanderkaz commented 4 years ago

I'm using qiskit version 0.12.0

Here is the full output for the exception

---------------------------------------------------------------------------
SolverError                               Traceback (most recent call last)
<ipython-input-40-7a51cf906997> in <module>
      6     mat = np.diag([i for i in range(1, i+1)]).tolist()
      7     b = [i for i in range(1, i+1)]
----> 8     _, _, fid, width, depth = find_solution(mat, b, backend, ancillae=3)
      9     d['Simulator'] = False
     10     d['Diagonal'] = True

<ipython-input-9-5ee74c83f1af> in find_solution(mat, b, backend, ancillae)
     20            orig_size = orig_size)
     21 
---> 22     result = algo.run(QuantumInstance(backend, skip_qobj_validation=False))
     23 
     24     quantum_result = np.round(result['solution'], 5)

/opt/conda/lib/python3.7/site-packages/qiskit/aqua/algorithms/quantum_algorithm.py in run(self, quantum_instance, **kwargs)
     65                 quantum_instance.set_config(**kwargs)
     66             self._quantum_instance = quantum_instance
---> 67         return self._run()
     68 
     69     @abstractmethod

/opt/conda/lib/python3.7/site-packages/qiskit/aqua/algorithms/single_sample/hhl/hhl.py in _run(self)
    488         else:
    489             self.construct_circuit(measurement=False)
--> 490             self._state_tomography()
    491         # Adding a bit of general result information
    492         self._ret["matrix"] = self._resize_matrix(self._matrix)

/opt/conda/lib/python3.7/site-packages/qiskit/aqua/algorithms/single_sample/hhl/hhl.py in _state_tomography(self)
    440         results_noanc = self._tomo_postselect(results)
    441         tomo_data = StateTomographyFitter(results_noanc, tomo_circuits_noanc)
--> 442         rho_fit = tomo_data.fit()
    443         vec = np.sqrt(np.diag(rho_fit))
    444         self._hhl_results(vec)

/opt/conda/lib/python3.7/site-packages/qiskit/ignis/verification/tomography/fitters/state_fitter.py in fit(self, method, standard_weights, beta, **kwargs)
    117         """
    118         return super().fit(method, standard_weights, beta,
--> 119                            trace=1, PSD=True, **kwargs)

/opt/conda/lib/python3.7/site-packages/qiskit/ignis/verification/tomography/fitters/base_fitter.py in fit(self, method, standard_weights, beta, **kwargs)
    211 
    212         if method == 'cvx':
--> 213             return cvx_fit(data, basis_matrix, weights=weights, **kwargs)
    214 
    215         raise QiskitError('Unrecognised fit method {}'.format(method))

/opt/conda/lib/python3.7/site-packages/qiskit/ignis/verification/tomography/fitters/cvx_fit.py in cvx_fit(data, basis_matrix, weights, PSD, trace, trace_preserving, **kwargs)
    203     while not problem_solved:
    204         kwargs['max_iters'] = iters
--> 205         prob.solve(**kwargs)
    206         if prob.status in ["optimal_inaccurate", "optimal"]:
    207             problem_solved = True

/opt/conda/lib/python3.7/site-packages/cvxpy/problems/problem.py in solve(self, *args, **kwargs)
    288         const_dict = {id(constant): constant for constant in constants_}
    289         return list(const_dict.values())
--> 290 
    291     def atoms(self):
    292         """Accessor method for atoms.

/opt/conda/lib/python3.7/site-packages/cvxpy/problems/problem.py in _solve(self, solver, warm_start, verbose, parallel, gp, qcp, **kwargs)
    566         cvxpy.error.DGPError
    567             Raised if the problem is not DGP and `gp` is True.
--> 568         """
    569         candidates = {'qp_solvers': [],
    570                       'conic_solvers': []}

/opt/conda/lib/python3.7/site-packages/cvxpy/problems/problem.py in _construct_chains(self, solver, gp)
    509                 dgp2dcp = self._cache.solving_chain.get(Dgp2Dcp)
    510                 # Parameters in the param cone prog are the logs
--> 511                 # of parameters in the original problem (with one exception:
    512                 # parameters appearing as exponents (in power and gmatmul
    513                 # atoms) are unchanged.

/opt/conda/lib/python3.7/site-packages/cvxpy/problems/problem.py in _construct_chains(self, solver, gp)
    495         key = self._cache.make_key(solver, gp)
    496         if key != self._cache.key:
--> 497             self._cache.invalidate()
    498             solving_chain = self._construct_chain(
    499                 solver=solver, gp=gp, enforce_dpp=enforce_dpp)

/opt/conda/lib/python3.7/site-packages/cvxpy/problems/problem.py in _find_candidate_solvers(self, solver, gp)
    432 
    433         ::
--> 434 
    435             objective = ...
    436             constraints = ...

SolverError: The solver CVXOPT is not installed.

And here is the full code that I used

def fidelity(hhl, ref):
    solution_hhl_normed = hhl / np.linalg.norm(hhl)
    solution_ref_normed = ref / np.linalg.norm(ref)
    fidelity = state_fidelity(solution_hhl_normed, solution_ref_normed)
    return fidelity

def create_eigs(matrix, num_ancillae, negative_evals):
    ne_qfts = [None, None]
    if negative_evals:
        num_ancillae += 1
        ne_qfts = [StandardQFTS(num_ancillae - 1), StandardIQFTS(num_ancillae - 1)]

    return EigsQPE(MatrixOperator(matrix=matrix),
                   StandardIQFTS(num_ancillae),
                   num_time_slices=1,
                   num_ancillae=num_ancillae,
                   expansion_mode='suzuki',
                   expansion_order=2,
                   evo_time=None,
                   negative_evals=negative_evals,
                   ne_qfts=ne_qfts)

def find_solution(mat, b, backend, ancillae):

    orig_size = len(b)
    mat, b, truncate_powerdim, truncate_hermitian = HHL.matrix_resize(mat, b)

    eigs = create_eigs(mat, num_ancillae=ancillae, negative_evals=False)
    num_q, num_a = eigs.get_register_sizes()
    init_state = Custom(num_q, state_vector=b)
    rot = LookupRotation(negative_evals=eigs._negative_evals, evo_time=eigs._evo_time, scale=0.5)

    algo = HHL(matrix = mat, 
           vector = b, 
           truncate_powerdim=truncate_powerdim, 
           truncate_hermitian = truncate_hermitian, 
           eigs = eigs,
           init_state= init_state, 
           reciprocal = rot, 
           num_q = num_q, 
           num_a = num_a, 
           orig_size = orig_size)

    result = algo.run(QuantumInstance(backend, skip_qobj_validation=False))

    return result

fidelities = []
list_N = [2, 4, 8, 16]
dicts_results = []

for i in list_N:
    d = {}
    mat = np.diag([i for i in range(1, i+1)]).tolist()
    b = [i for i in range(1, i+1)]
    _, _, fid, width, depth = find_solution(mat, b, backend, ancillae=3)
    d['Simulator'] = False
    d['Diagonal'] = True
    d['N'] = i
    d['Fidelity'] = fid
    d['Circuit width'] = width
    d['Circuit depth'] = depth
    dicts_results.append(d)
    fidelities.append(fid)
woodsp-ibm commented 4 years ago

I am not sure what version you have. You say qiskit 0.12.0 which was released in Aug 2019. Yet in the issue you say qiskit-aqua 0.6.5 and the former has 0.6.0 for Aqua. I tried 0.12.0 and your code will not run because HHL does not have a matrix_resize property. On newer versions the find_solution you provide would not unpack and failed. I just printed the result from BasicAer qasm_simulator as a backend. I saw no failures at all. What I might suggest is to do pip install qiskit -U which will update your installation to the latest version. Then try that. (I see there are some deprecation warnings as Terra was updated in the qiskit meta package and Aqua is still using some now deprecated method - this will be fixed in the next release which should be very soon)

skanderkaz commented 4 years ago

I updated qiskit and my algorithm works now, thanks a lot. 👍

I now get this Deprecation warning btw:

/opt/conda/lib/python3.7/site-packages/qiskit/aqua/operators/common.py:273: DeprecationWarning: The Pauli.numberofqubits method is deprecated as of 0.13.0, and will be removed no earlier than 3 months after that release date. You should use the Pauli.num_qubits method instead.
  n_qubits = pauli[1].numberofqubits
woodsp-ibm commented 4 years ago

Great!, Yes, Terra deprecated a method in the latest release and an updated Aqua to correct that has not yet been released. A new version, which will correct that, will be released shortly. Since it works for you now I will close this off.