diff --git a/qwrapper/circuit.py b/qwrapper/circuit.py index d4ae597..ca3abdb 100644 --- a/qwrapper/circuit.py +++ b/qwrapper/circuit.py @@ -9,6 +9,7 @@ try: import cudaq + cudaq.set_target('nvidia') except ImportError: print("cudaq import error") except ModuleNotFoundError: @@ -581,10 +582,13 @@ class CUDAQuantumCircuit(QWrapper): def __init__(self, nqubit): super().__init__(nqubit) self.gatesToApply = [] - # print("Create CUDAQ Circuit") + self.listOfPaulis = [] + self.listOfPaulisCoeff = [] + print("Create CUDAQ Circuit") self.numQubits = nqubit - self.kernel = cudaq.make_kernel() + self.kernel, self.paulisCoeff, self.paulisArg = cudaq.make_kernel(list[float], list[cudaq.pauli_word]) self.qarg = self.kernel.qalloc(self.numQubits) + self.pauliFlag = False def copy(self): raise NotImplementedError('cuda quantum copy - not supported.') @@ -595,7 +599,9 @@ def h(self, index): def x(self, index): # print("x {}".format(index)) - self.gatesToApply.append(lambda qarg: self.kernel.x(qarg[index])) + print ("Adding x gates") + self.kernel.x(self.qarg[index]) + #self.gatesToApply.append(lambda qarg: self.kernel.x(qarg[index])) def y(self, index): # print("y {}".format(index)) diff --git a/qwrapper/obs.py b/qwrapper/obs.py index d4affc5..a31d324 100644 --- a/qwrapper/obs.py +++ b/qwrapper/obs.py @@ -4,15 +4,18 @@ from qwrapper.util import QUtil from qulacs import QuantumState, Observable from qwrapper.circuit import QulacsCircuit, CUDAQuantumCircuit +import time -try: - import cupy as np -except ModuleNotFoundError: - print("cupy not found. numpy is used.") - import numpy as np +#try: +# import cupy as np +#except ModuleNotFoundError: +# print("cupy not found. numpy is used.") +# import numpy as np +import numpy as np try: import cudaq + cudaq.set_target('nvidia') except ImportError: print("cudaq import error") except ModuleNotFoundError: @@ -186,8 +189,13 @@ def exact_value(self, qc: QWrapper, **kwargs): if isinstance(qc, CUDAQuantumCircuit): if self._cudaq_obs is None: self._cudaq_obs = self._build_cudaq_obs() - for op in qc.gatesToApply: - op(qc.qarg) + #pauliIndex = 0 + #for op in qc.gatesToApply: + # if (type(op) == list): + # op[1](qc.qarg, pauliIndex) + # pauliIndex = pauliIndex + 1 + # else: + # op(qc.qarg) if 'parallelObserve' in kwargs and kwargs['parallelObserve']: print("Async exec on qpu {}".format(kwargs['qpu_id'])) @@ -198,12 +206,22 @@ def do_get(): return Future(do_get) - return cudaq.observe(qc.kernel, self._cudaq_obs).expectation_z() + self._identity + #print (qc.kernel) + #print ('Paulis:', qc.listOfPaulis, "Gates:", qc.gatesToApply) + start = time.time() + tmp = cudaq.observe(qc.kernel, self._cudaq_obs, qc.listOfPaulisCoeff, qc.listOfPaulis).expectation_z() + self._identity + print ('obs CUDAQ:', time.time() - start) + return tmp + +# return cudaq.observe(qc.kernel, self._cudaq_obs).expectation_z() + self._identity if isinstance(qc, QulacsCircuit): if self._qulacs_obs is None: self._qulacs_obs = self._build_qulacs_obs() - return self._qulacs_obs.get_expectation_value(qc.get_state()) + self._identity + start = time.time() + tmp = self._qulacs_obs.get_expectation_value(qc.get_state()) + self._identity + print ('obs Qulacs:', time.time() - start) + return tmp if self._matrix is None: matrix = np.diag(np.zeros(pow(2, self.nqubit), dtype=np.complex128)) for h, p in zip(self._hs, self._paulis): diff --git a/qwrapper/operator.py b/qwrapper/operator.py index b1430e5..2dad4eb 100644 --- a/qwrapper/operator.py +++ b/qwrapper/operator.py @@ -4,6 +4,7 @@ try: import cudaq + cudaq.set_target('nvidia') except ImportError: print("cudaq import error") except ModuleNotFoundError: @@ -22,11 +23,19 @@ def __init__(self, pauli: PauliObservable, t, cachable=True): self.cache = None self.cachable = cachable - def add_circuit(self, qc: QWrapper): + def add_circuit(self, qc: QWrapper, sizeOfIndex=0): if isinstance(qc, CUDAQuantumCircuit): + if (qc.pauliFlag == False): + print ('adding pauli loop') + qc.pauliFlag = True + qc.kernel.for_loop(0, qc.paulisArg.size(), + lambda idx: qc.kernel.exp_pauli(qc.paulisCoeff[idx], qc.qarg, qc.paulisArg[idx])) if self.pauli.p_string != len(self.pauli.p_string) * 'I': - qc.gatesToApply.append(lambda qarg: qc.kernel.exp_pauli( - self.pauli.sign * self.t, qarg, self.pauli.p_string)) + #print ('exp_pauli for', self.pauli.p_string, self.t, self.pauli.sign) + qc.listOfPaulis.append(self.pauli.p_string) + qc.listOfPaulisCoeff.append(self.pauli.sign * self.t) + #qc.gatesToApply.append([1, lambda qarg, pArg: qc.kernel.exp_pauli( + # self.pauli.sign * self.t, qarg, qc.paulisArg[pArg])]) return if not isinstance(qc, QulacsCircuit) or not self.cachable: