Skip to content

Commit 8c1afbe

Browse files
committed
add qpu engine
1 parent 3404845 commit 8c1afbe

File tree

7 files changed

+160
-38
lines changed

7 files changed

+160
-38
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,6 @@ which is also a good introduction to the software.
9898
## Research and Applications
9999

100100
### Variational basis state encoder
101-
An efficient algorithm to encoder phonon states in electron-phonon systems for quantum computation.
101+
An efficient algorithm to encode phonon states in electron-phonon systems for quantum computation.
102102
See [examples](https://github.com/tencent-quantum-lab/TenCirChem/tree/master/example).
103103
Reference paper: https://arxiv.org/pdf/2301.01442.pdf (published in PRR).

docs/source/tutorial_jupyter/marcus.ipynb

Lines changed: 91 additions & 19 deletions
Large diffs are not rendered by default.

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ pandas
44
jax
55
jaxlib
66
pyscf
7-
tensorcircuit-nightly
7+
tensorcircuit
88
openfermion
99
qiskit
1010
pylatexenc
1111
SciencePlots
1212
noisyopt
13-
renormalizer==0.0.9
13+
renormalizer==0.0.10

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"numpy",
2121
"scipy",
2222
"pandas",
23-
"tensorcircuit-nightly",
23+
"tensorcircuit",
2424
"pyscf",
2525
"openfermion",
2626
"qiskit",

tencirchem/static/engine_hea.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88

99
import numpy as np
1010
import tensorcircuit as tc
11-
from tensorcircuit import DMCircuit
11+
from tensorcircuit import Circuit, DMCircuit
1212
from tensorcircuit.noisemodel import circuit_with_noise
1313
from tensorcircuit.experimental import parameter_shift_grad
14+
from tensorcircuit.cloud.wrapper import batch_expectation_ps
1415

1516
from tencirchem.utils.backend import jit
1617

@@ -72,6 +73,23 @@ def get_energy_tensornetwork_noise_shot(params, paulis, coeffs, get_dmcircuit, n
7273
return sample_expectation_pauli(c, paulis, coeffs, shots, noise_conf)
7374

7475

76+
def get_energy_qpu(params, paulis, coeffs, get_circuit, shots: int):
77+
c: Circuit = get_circuit(params)
78+
pss = []
79+
symbol_mapping = {"X": 1, "Y": 2, "Z": 3}
80+
for pauli in paulis:
81+
ps = [0] * c.circuit_param["nqubits"]
82+
for idx, symbol in pauli:
83+
ps[idx] = symbol_mapping[symbol]
84+
pss.append(ps)
85+
es = []
86+
for _ in range((shots - 1) // 8192 + 1):
87+
e = batch_expectation_ps(c, pss, device="tianxuan_s1", ws=coeffs, shots=8192)
88+
es.append(e)
89+
print(es)
90+
return np.mean(es)
91+
92+
7593
def _get_energy_and_grad(partial_get_energy, params, grad):
7694
if grad == "param-shift":
7795
e = partial_get_energy(params)
@@ -120,3 +138,14 @@ def get_energy_and_grad_tensornetwork_noise_shot(params, paulis, coeffs, get_dmc
120138
shots=shots,
121139
)
122140
return _get_energy_and_grad(partial_get_energy, params, grad)
141+
142+
143+
def get_energy_and_grad_qpu(params, paulis, coeffs, get_circuit, shots: int, grad):
144+
partial_get_energy = partial(
145+
get_energy_qpu,
146+
paulis=paulis,
147+
coeffs=coeffs,
148+
get_circuit=get_circuit,
149+
shots=shots,
150+
)
151+
return _get_energy_and_grad(partial_get_energy, params, grad)

tencirchem/static/hea.py

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@
3535
get_energy_tensornetwork_noise,
3636
get_energy_tensornetwork_shot,
3737
get_energy_tensornetwork_noise_shot,
38+
get_energy_qpu,
3839
get_energy_and_grad_tensornetwork,
3940
get_energy_and_grad_tensornetwork_noise,
4041
get_energy_and_grad_tensornetwork_shot,
4142
get_energy_and_grad_tensornetwork_noise_shot,
43+
get_energy_and_grad_qpu,
4244
)
4345
from tencirchem.static.hamiltonian import get_hop_from_integral
4446
from tencirchem.utils.misc import reverse_fop_idx, scipy_opt_wrap, reverse_qop_idx
@@ -361,6 +363,7 @@ def get_circuit(params):
361363
self.shots = 4096
362364
self._grad = "param-shift"
363365

366+
self.scipy_minimize_options = None
364367
self._params = None
365368
self.opt_res = None
366369

@@ -585,8 +588,14 @@ def energy(self, params: Tensor = None, engine: str = None) -> float:
585588
self.shots,
586589
)
587590
else:
588-
assert self.engine == "qpu"
589-
assert False
591+
assert engine == "qpu"
592+
e = get_energy_qpu(
593+
params,
594+
tuple(self.h_qubit_op.terms.keys()),
595+
list(self.h_qubit_op.terms.values()),
596+
self.get_circuit,
597+
self.shots,
598+
)
590599
return e
591600

592601
def energy_and_grad(self, params: Tensor = None, engine: str = None, grad: str = None) -> Tuple[float, Tensor]:
@@ -633,15 +642,15 @@ def energy_and_grad(self, params: Tensor = None, engine: str = None, grad: str =
633642
raise ValueError("Must provide a gradient algorithm")
634643

635644
if engine == "tensornetwork":
636-
e, grad = get_energy_and_grad_tensornetwork(params, self.h_array, self.get_circuit, grad)
645+
e, grad_array = get_energy_and_grad_tensornetwork(params, self.h_array, self.get_circuit, grad)
637646
elif engine == "tensornetwork-noise":
638-
e, grad = get_energy_and_grad_tensornetwork_noise(
647+
e, grad_array = get_energy_and_grad_tensornetwork_noise(
639648
params, self.h_array, self.get_dmcircuit_no_noise, self.engine_conf, grad
640649
)
641650
elif engine == "tensornetwork-shot":
642651
if grad == "autodiff":
643652
raise ValueError(f"Engine {engine} is incompatible with grad method {grad}")
644-
e, grad = get_energy_and_grad_tensornetwork_shot(
653+
e, grad_array = get_energy_and_grad_tensornetwork_shot(
645654
params,
646655
tuple(self.h_qubit_op.terms.keys()),
647656
list(self.h_qubit_op.terms.values()),
@@ -652,7 +661,7 @@ def energy_and_grad(self, params: Tensor = None, engine: str = None, grad: str =
652661
elif engine == "tensornetwork-noise&shot":
653662
if grad == "autodiff":
654663
raise ValueError(f"Engine {engine} is incompatible with grad method {grad}")
655-
e, grad = get_energy_and_grad_tensornetwork_noise_shot(
664+
e, grad_array = get_energy_and_grad_tensornetwork_noise_shot(
656665
params,
657666
tuple(self.h_qubit_op.terms.keys()),
658667
list(self.h_qubit_op.terms.values()),
@@ -662,23 +671,35 @@ def energy_and_grad(self, params: Tensor = None, engine: str = None, grad: str =
662671
grad,
663672
)
664673
else:
665-
assert self.engine == "qpu"
666-
assert False
667-
return e, grad
674+
assert engine == "qpu"
675+
if grad == "autodiff":
676+
raise ValueError(f"Engine {engine} is incompatible with grad method {grad}")
677+
e, grad_array = get_energy_and_grad_qpu(
678+
params,
679+
tuple(self.h_qubit_op.terms.keys()),
680+
list(self.h_qubit_op.terms.values()),
681+
self.get_circuit,
682+
self.shots,
683+
grad,
684+
)
685+
return e, grad_array
668686

669687
def kernel(self):
670688
logger.info("Begin optimization")
671689

672690
func, stating_time = self.get_opt_function(with_time=True)
691+
673692
time1 = time()
674693
if self.grad == "free":
675-
if self.engine in ["tensornetwork", "tensornetwork-noise"]:
676-
opt_res = minimize(func, x0=self.init_guess, method="COBYLA")
694+
if self.engine in ["tensornetwork", "tensornetwork-noise", "qpu"]:
695+
opt_res = minimize(func, x0=self.init_guess, method="COBYLA", options=self.scipy_minimize_options)
677696
else:
678697
assert self.engine in ["tensornetwork-shot", "tensornetwork-noise&shot"]
679-
opt_res = minimizeSPSA(func, x0=self.init_guess, paired=False, niter=125)
698+
opt_res = minimizeSPSA(func, x0=self.init_guess, paired=False, niter=100, disp=True)
680699
else:
681-
opt_res = minimize(func, x0=self.init_guess, jac=True, method="L-BFGS-B")
700+
opt_res = minimize(
701+
func, x0=self.init_guess, jac=True, method="L-BFGS-B", options=self.scipy_minimize_options
702+
)
682703

683704
time2 = time()
684705

tencirchem/static/ucc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ def energy_and_grad(self, params: Tensor = None, engine: str = None) -> Tuple[fl
704704

705705
def apply_excitation(self, state: Tensor, ex_op: Tuple, engine: str = None) -> Tensor:
706706
"""
707-
Apply a given excitation operator to a give state.
707+
Apply a given excitation operator to a given state.
708708
709709
Parameters
710710
----------

0 commit comments

Comments
 (0)