quil-lang / qvm

The high-performance and featureful Quil simulator.
Other
411 stars 57 forks source link

VQE on QVM with noise model not compatible #269

Open pacobontenbal opened 3 years ago

pacobontenbal commented 3 years ago

I am using Grove's VQE to run on a QVM with a noise model but I get a TypeError when I run it. Below is an example of how one would use the VQE on a QVM with a noise model:


from pyquil import get_qc
from pyquil.quil import Program
from pyquil.gates import *
from pyquil.paulis import PauliTerm, PauliSum
from grove.pyvqe.vqe import VQE
from scipy.optimize import minimize
import numpy as np
from functools import partial 

noisy_qvm = get_qc("Aspen-8", as_qvm=True, noisy=True)

def ansatz(thetas):
    bell_singlet = Program()
    bell_singlet += Program(X(0), XY(thetas[0], 0, 1), RZ(thetas[1], 0))

    return bell_singlet

def hamiltonian():
    pauliTerms = []
    pXX = PauliTerm('X', 0) * PauliTerm ('X', 1)
    pYY = PauliTerm('Y', 0) * PauliTerm ('Y', 1)

    pauliTerms.append(pXX)
    pauliTerms.append(pYY)

    return PauliSum(pauliTerms)

def vqe_run(thetas):
        dispList = []

        vqe_inst = VQE(minimizer=minimize, minimizer_kwargs={'method': "Powell"})
        vqe_run = vqe_inst.vqe_run(partial(ansatz), hamiltonian(), thetas, disp=dispList.append, samples=10000, qvm=noisy_qvm.qam)

        return vqe_run

vqe_run([np.pi/2, -np.pi/2])

However, this results in the following error:


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-19-a5e26cfc1196> in <module>
----> 1 vqe_run([np.pi/2, -np.pi/2])

<ipython-input-18-8e6da3871d03> in vqe_run(thetas)
      3 
      4         vqe_inst = VQE(minimizer=minimize, minimizer_kwargs={'method': "Powell"})
----> 5         vqe_run = vqe_inst.vqe_run(partial(ansatz), hamiltonian(), thetas, disp=dispList.append, samples=10000, qvm=noisy_qvm.qam)
      6 
      7         return vqe_run

/opt/conda/lib/python3.8/site-packages/grove/pyvqe/vqe.py in vqe_run(self, variational_state_evolve, hamiltonian, initial_params, gate_noise, measurement_noise, jacobian, qvm, disp, samples, return_all)
    170             self.minimizer_kwargs['jac'] = jacobian
    171 
--> 172         result = self.minimizer(*args, **self.minimizer_kwargs)
    173 
    174         if hasattr(result, 'status'):

/opt/conda/lib/python3.8/site-packages/scipy/optimize/_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    606         return _minimize_neldermead(fun, x0, args, callback, **options)
    607     elif meth == 'powell':
--> 608         return _minimize_powell(fun, x0, args, callback, bounds, **options)
    609     elif meth == 'cg':
    610         return _minimize_cg(fun, x0, args, jac, callback, **options)

/opt/conda/lib/python3.8/site-packages/scipy/optimize/optimize.py in _minimize_powell(func, x0, args, callback, bounds, xtol, ftol, maxiter, maxfev, disp, direc, return_all, **unknown_options)
   2919                           OptimizeWarning, 3)
   2920 
-> 2921     fval = squeeze(func(x))
   2922     x1 = x.copy()
   2923     iter = 0

/opt/conda/lib/python3.8/site-packages/scipy/optimize/optimize.py in function_wrapper(*wrapper_args)
    425     def function_wrapper(*wrapper_args):
    426         ncalls[0] += 1
--> 427         return function(*(wrapper_args + args))
    428 
    429     return ncalls, function_wrapper

/opt/conda/lib/python3.8/site-packages/grove/pyvqe/vqe.py in objective_function(params)
    143             """
    144             pyquil_prog = variational_state_evolve(params)
--> 145             mean_value = self.expectation(pyquil_prog, hamiltonian, samples, qvm)
    146             self._current_expectation = mean_value  # store for printing
    147             return mean_value

/opt/conda/lib/python3.8/site-packages/grove/pyvqe/vqe.py in expectation(pyquil_prog, pauli_sum, samples, qvm)
    265 
    266                             meas_outcome = \
--> 267                                 expectation_from_sampling(pyquil_prog + meas_basis_change,
    268                                                           qubits_to_measure,
    269                                                           qvm,

/opt/conda/lib/python3.8/site-packages/grove/pyvqe/vqe.py in expectation_from_sampling(pyquil_program, marked_qubits, qvm, samples)
    313         pyquil_program.measure(qindex, qindex)
    314 
--> 315     bitstring_samples = qvm.run(pyquil_program, range(max(marked_qubits) + 1), trials=samples)
    316     bitstring_tuples = list(map(tuple, bitstring_samples))
    317 

/opt/conda/lib/python3.8/site-packages/pyquil/api/_error_reporting.py in wrapper(*args, **kwargs)
    249             global_error_context.log[key] = pre_entry
    250 
--> 251         val = func(*args, **kwargs)
    252 
    253         # poke the return value of that call in

TypeError: run() got an unexpected keyword argument 'trials'

Is there a way to run a VQE on a QVM with a noise model ?

erichulburd commented 3 years ago

Hi @pacobontenbal , could you try updating to the beta version of quantum-grove and let me know what errors you get?

pacobontenbal commented 3 years ago

Hi, i tried running the same code snippet, but with the beta version of Grove and it seems like ik get the following error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-7f8c673d38ae> in <module>
     34         return vqe_run
     35 
---> 36 vqe_run([np.pi/2, -np.pi/2])

<ipython-input-4-7f8c673d38ae> in vqe_run(thetas)
     30 
     31         vqe_inst = VQE(minimizer=minimize, minimizer_kwargs={'method': "Powell"})
---> 32         vqe_run = vqe_inst.vqe_run(partial(ansatz), hamiltonian(), thetas, disp=dispList.append, samples=10000, qc=noisy_qvm.qam)
     33 
     34         return vqe_run

~\anaconda3\lib\site-packages\grove\pyvqe\vqe.py in vqe_run(self, variational_state_evolve, hamiltonian, initial_params, gate_noise, measurement_noise, jacobian, qc, disp, samples, return_all)
    173             self.minimizer_kwargs['jac'] = jacobian
    174 
--> 175         result = self.minimizer(*args, **self.minimizer_kwargs)
    176 
    177         if hasattr(result, 'status'):

~\anaconda3\lib\site-packages\scipy\optimize\_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    606         return _minimize_neldermead(fun, x0, args, callback, **options)
    607     elif meth == 'powell':
--> 608         return _minimize_powell(fun, x0, args, callback, bounds, **options)
    609     elif meth == 'cg':
    610         return _minimize_cg(fun, x0, args, jac, callback, **options)

~\anaconda3\lib\site-packages\scipy\optimize\optimize.py in _minimize_powell(func, x0, args, callback, bounds, xtol, ftol, maxiter, maxfev, disp, direc, return_all, **unknown_options)
   2919                           OptimizeWarning, 3)
   2920 
-> 2921     fval = squeeze(func(x))
   2922     x1 = x.copy()
   2923     iter = 0

~\anaconda3\lib\site-packages\scipy\optimize\optimize.py in function_wrapper(*wrapper_args)
    425     def function_wrapper(*wrapper_args):
    426         ncalls[0] += 1
--> 427         return function(*(wrapper_args + args))
    428 
    429     return ncalls, function_wrapper

~\anaconda3\lib\site-packages\grove\pyvqe\vqe.py in objective_function(params)
    146             """
    147             pyquil_prog = variational_state_evolve(params)
--> 148             mean_value = self.expectation(pyquil_prog, hamiltonian, samples, qc)
    149             self._current_expectation = mean_value  # store for printing
    150             return mean_value

~\anaconda3\lib\site-packages\grove\pyvqe\vqe.py in expectation(pyquil_prog, pauli_sum, samples, qc)
    265 
    266                             meas_outcome = \
--> 267                                 expectation_from_sampling(pyquil_prog + meas_basis_change,
    268                                                           qubits_to_measure,
    269                                                           qc,

~\anaconda3\lib\site-packages\grove\pyvqe\vqe.py in expectation_from_sampling(pyquil_program, marked_qubits, qc, samples)
    316     program += [MEASURE(qubit, r) for qubit, r in zip(list(range(max(marked_qubits) + 1)), ro)]
    317     program.wrap_in_numshots_loop(samples)
--> 318     executable = qc.compile(program)
    319     bitstring_samples = qc.run(executable)
    320     bitstring_tuples = list(map(tuple, bitstring_samples))

AttributeError: 'QVM' object has no attribute 'compile'
notmgsk commented 3 years ago

@pacobontenbal can you share the pyquil script you're running?

pacobontenbal commented 3 years ago

@notmgsk It's the same pyquil script as in the initial issue report, so:

from pyquil import get_qc
from pyquil.quil import Program
from pyquil.gates import *
from pyquil.paulis import PauliTerm, PauliSum
from grove.pyvqe.vqe import VQE
from scipy.optimize import minimize
import numpy as np
from functools import partial 

noisy_qvm = get_qc("Aspen-8", as_qvm=True, noisy=True)

def ansatz(thetas):
    bell_singlet = Program()
    bell_singlet += Program(X(0), XY(thetas[0], 0, 1), RZ(thetas[1], 0))

    return bell_singlet

def hamiltonian():
    pauliTerms = []
    pXX = PauliTerm('X', 0) * PauliTerm ('X', 1)
    pYY = PauliTerm('Y', 0) * PauliTerm ('Y', 1)

    pauliTerms.append(pXX)
    pauliTerms.append(pYY)

    return PauliSum(pauliTerms)

def vqe_run(thetas):
        dispList = []

        vqe_inst = VQE(minimizer=minimize, minimizer_kwargs={'method': "Powell"})
        vqe_run = vqe_inst.vqe_run(partial(ansatz), hamiltonian(), thetas, disp=dispList.append, samples=10000, qvm=noisy_qvm.qam)

        return vqe_run

vqe_run([np.pi/2, -np.pi/2])
notmgsk commented 3 years ago

@pacobontenbal Sorry for missing that. The issue is where you pass qvm=noisy_qvm.qam to vqe_run() -- it should be qc=qc. (Be sure to update to the recent 2.0.0b version of grove: https://pypi.org/project/quantum-grove/2.0.0b0/)

pacobontenbal commented 3 years ago

I'm sorry I used the same pyquil script but i did update to the beta version you referred to and changed the variables accordingly, so my previous script should be disregarded, I actually ran:

from pyquil import get_qc
from pyquil.quil import Program
from pyquil.gates import *
from pyquil.paulis import PauliTerm, PauliSum
from grove.pyvqe.vqe import VQE
from scipy.optimize import minimize
import numpy as np
from functools import partial 

noisy_qvm = get_qc("Aspen-9", as_qvm=True, noisy=True)

def ansatz(thetas):
    bell_singlet = Program()
    bell_singlet += Program(X(0), XY(thetas[0], 0, 1), RZ(thetas[1], 0))

    return bell_singlet

def hamiltonian():
    pauliTerms = []
    pXX = PauliTerm('X', 0) * PauliTerm ('X', 1)
    pYY = PauliTerm('Y', 0) * PauliTerm ('Y', 1)

    pauliTerms.append(pXX)
    pauliTerms.append(pYY)

    return PauliSum(pauliTerms)

def vqe_run(thetas):
        dispList = []

        vqe_inst = VQE(minimizer=minimize, minimizer_kwargs={'method': "Nelder-Mead"})
        vqe_run = vqe_inst.vqe_run(partial(ansatz), hamiltonian(), thetas, disp=dispList.append, samples=10000, qc=noisy_qvm.qam)

        return vqe_run

vqe_run([np.pi/2, -np.pi/2])
notmgsk commented 3 years ago

Same issue. In vqe_run() you should be passing qc=noisy_qvm not qc=noisy_qvm.qam

On Mar 31, 2021, at 9:43 PM, Paco Bontenbal @.***> wrote:

 I'm sorry I used the same pyquil script but i did update to the beta version you referred to and changed the variables accordingly, so my previous script should be disregarded, I actually ran:

from pyquil import get_qc from pyquil.quil import Program from pyquil.gates import * from pyquil.paulis import PauliTerm, PauliSum from grove.pyvqe.vqe import VQE from scipy.optimize import minimize import numpy as np from functools import partial

noisy_qvm = get_qc("Aspen-9", as_qvm=True, noisy=True)

def ansatz(thetas): bell_singlet = Program() bell_singlet += Program(X(0), XY(thetas[0], 0, 1), RZ(thetas[1], 0))

return bell_singlet

def hamiltonian(): pauliTerms = [] pXX = PauliTerm('X', 0) PauliTerm ('X', 1) pYY = PauliTerm('Y', 0) PauliTerm ('Y', 1)

pauliTerms.append(pXX)
pauliTerms.append(pYY)

return PauliSum(pauliTerms)

def vqe_run(thetas): dispList = []

    vqe_inst = VQE(minimizer=minimize, minimizer_kwargs={'method': "Nelder-Mead"})
    vqe_run = vqe_inst.vqe_run(partial(ansatz), hamiltonian(), thetas, disp=dispList.append, samples=10000, qc=noisy_qvm.qam)

    return vqe_run

vqe_run([np.pi/2, -np.pi/2]) — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

pacobontenbal commented 3 years ago

@notmgsk Yeah i've tried that before too, but it seems that it says quilc is not running while I do have a server running, giving me the following error:

---------------------------------------------------------------------------
TimeoutError                              Traceback (most recent call last)
~\anaconda3\lib\site-packages\pyquil\api\_compiler.py in connect(self)
    409         try:
--> 410             version_dict = self.get_version_info()
    411             check_quilc_version(version_dict)

~\anaconda3\lib\site-packages\pyquil\api\_compiler.py in get_version_info(self)
    419     def get_version_info(self) -> Dict[str, Any]:
--> 420         return cast(Dict[str, Any], self.client.call("get_version_info"))
    421 

~\anaconda3\lib\site-packages\rpcq\_client.py in call(self, method_name, rpc_timeout, *args, **kwargs)
    186             if self._socket.poll(timeout) == 0:
--> 187                 raise TimeoutError(f"Timeout on client {self.endpoint}, method name {method_name}, class info: {self}")
    188 

TimeoutError: Timeout on client tcp://127.0.0.1:5555, method name get_version_info, class info: <rpcq._client.Client object at 0x0000023C14EE9EE0>

During handling of the above exception, another exception occurred:

QuilcNotRunning                           Traceback (most recent call last)
<ipython-input-12-28ccd99fcfdc> in <module>
     34         return vqe_run
     35 
---> 36 vqe_run([np.pi/2, -np.pi/2])

<ipython-input-12-28ccd99fcfdc> in vqe_run(thetas)
     30 
     31         vqe_inst = VQE(minimizer=minimize, minimizer_kwargs={'method': "Nelder-Mead"})
---> 32         vqe_run = vqe_inst.vqe_run(partial(ansatz), hamiltonian(), thetas, disp=dispList.append, samples=10000, qc=noisy_qvm)
     33 
     34         return vqe_run

~\anaconda3\lib\site-packages\grove\pyvqe\vqe.py in vqe_run(self, variational_state_evolve, hamiltonian, initial_params, gate_noise, measurement_noise, jacobian, qc, disp, samples, return_all)
    173             self.minimizer_kwargs['jac'] = jacobian
    174 
--> 175         result = self.minimizer(*args, **self.minimizer_kwargs)
    176 
    177         if hasattr(result, 'status'):

~\anaconda3\lib\site-packages\scipy\optimize\_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    604 
    605     if meth == 'nelder-mead':
--> 606         return _minimize_neldermead(fun, x0, args, callback, **options)
    607     elif meth == 'powell':
    608         return _minimize_powell(fun, x0, args, callback, bounds, **options)

~\anaconda3\lib\site-packages\scipy\optimize\optimize.py in _minimize_neldermead(func, x0, args, callback, maxiter, maxfev, disp, return_all, initial_simplex, xatol, fatol, adaptive, **unknown_options)
    687 
    688     for k in range(N + 1):
--> 689         fsim[k] = func(sim[k])
    690 
    691     ind = np.argsort(fsim)

~\anaconda3\lib\site-packages\scipy\optimize\optimize.py in function_wrapper(*wrapper_args)
    425     def function_wrapper(*wrapper_args):
    426         ncalls[0] += 1
--> 427         return function(*(wrapper_args + args))
    428 
    429     return ncalls, function_wrapper

~\anaconda3\lib\site-packages\grove\pyvqe\vqe.py in objective_function(params)
    146             """
    147             pyquil_prog = variational_state_evolve(params)
--> 148             mean_value = self.expectation(pyquil_prog, hamiltonian, samples, qc)
    149             self._current_expectation = mean_value  # store for printing
    150             return mean_value

~\anaconda3\lib\site-packages\grove\pyvqe\vqe.py in expectation(pyquil_prog, pauli_sum, samples, qc)
    265 
    266                             meas_outcome = \
--> 267                                 expectation_from_sampling(pyquil_prog + meas_basis_change,
    268                                                           qubits_to_measure,
    269                                                           qc,

~\anaconda3\lib\site-packages\grove\pyvqe\vqe.py in expectation_from_sampling(pyquil_program, marked_qubits, qc, samples)
    316     program += [MEASURE(qubit, r) for qubit, r in zip(list(range(max(marked_qubits) + 1)), ro)]
    317     program.wrap_in_numshots_loop(samples)
--> 318     executable = qc.compile(program)
    319     bitstring_samples = qc.run(executable)
    320     bitstring_tuples = list(map(tuple, bitstring_samples))

~\anaconda3\lib\site-packages\pyquil\api\_error_reporting.py in wrapper(*args, **kwargs)
    249             global_error_context.log[key] = pre_entry
    250 
--> 251         val = func(*args, **kwargs)
    252 
    253         # poke the return value of that call in

~\anaconda3\lib\site-packages\pyquil\api\_quantum_computer.py in compile(self, program, to_native_gates, optimize, protoquil_positional, protoquil)
    491 
    492         if quilc:
--> 493             nq_program = self.compiler.quil_to_native_quil(program, protoquil=protoquil)
    494         else:
    495             nq_program = program

~\anaconda3\lib\site-packages\pyquil\api\_error_reporting.py in wrapper(*args, **kwargs)
    249             global_error_context.log[key] = pre_entry
    250 
--> 251         val = func(*args, **kwargs)
    252 
    253         # poke the return value of that call in

~\anaconda3\lib\site-packages\pyquil\api\_compiler.py in quil_to_native_quil(self, program, protoquil)
    422     @_record_call
    423     def quil_to_native_quil(self, program: Program, *, protoquil: Optional[bool] = None) -> Program:
--> 424         self.connect()
    425         request = NativeQuilRequest(quil=program.out(), target_device=self.target_device)
    426         response = self.client.call("quil_to_native_quil", request, protoquil=protoquil).asdict()

~\anaconda3\lib\site-packages\pyquil\api\_compiler.py in connect(self)
    411             check_quilc_version(version_dict)
    412         except TimeoutError:
--> 413             raise QuilcNotRunning(
    414                 f"Request to quilc at {self.client.endpoint} timed out. "
    415                 "This could mean that quilc is not running, is not reachable, or is "

QuilcNotRunning: Request to quilc at tcp://127.0.0.1:5555 timed out. This could mean that quilc is not running, is not reachable, or is responding slowly.

With this error in the console:

<131>1 2021-04-01T10:06:49Z LAPTOP-KU4O3GSE qvm - - - [2021-04-01 12:06:49 [ERROR]] Error while processing connection: The condition The condition end of file on #<SB-SYS:FD-STREAM for "socket 127.0.0.1:5555, peer: 127.0.0.1:52574" {100BEAAC83}> occurred with errno: 0. occurred with errno: 0.
notmgsk commented 3 years ago

You may have the qvm server running, but it looks like the compiler server is not running. Issue quilc -R -P at your terminal.