-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MPS circuit apply_gate
implementation & performance
#232
Comments
Maybe you could quantify "so much time"? This code takes about 10ms for me, possibly what you are seeing is some For the specific questions:
These are the main two functions of an MPS simulator, you would expect them to take close to 100% of the time, especially as the bond dimensions become large (in fact this example has bond dimension 1 throughout, so in fact the time is almost all overhead, rather than linear algebra that will eventually dominate).
For low bond (i.e. very cheap) simulations, acceleration is hard because so little time is spent on the actual numeric operations. This is one area where you expect python to be slower. Once the bond dimensions are big however, it should already be pretty optimized. You can further use a GPU or alternative array backend like
I am open to suggestions here, especially if you have a comparison point for a MPS simulator that is much faster and how they achieved that, but there is nothing specific planned! |
One particular point we had in mind was to use Vidal's form (see eq. (156) in 4.6 Notations and conversions in https://arxiv.org/abs/1008.3477) to represent an MPS. This would allow us to avoid re-canonization and should bring some noticable speed-ups. This is for example what TeNPy are doing, keeping track of both right-orthogonal With that description you can apply local gates cheaply. For example, applying a 2-qubit gate at sites If I understand correctly, in the example above we are re-canonicalizing all sites I understand that this is quite a significant feature request changing the structure of the MPS in quimb. I would be curious to hear your thoughts on this! I also have a question: Is there a way to do eager contractions in |
Sorry, poor wording choice here. I meant as a percentage of the entire calculation, but since you mentioned this is expected, I would say it's understood and hence all good.
I was trying to come up with the simplest example, but that one may be a bit too simple indeed. Cheating even :) I'll post the following example for those who might want to play with
@Qottmann mentioned Vidal's form might be a good way to reduce overheads and lower the cost of canonicalization.
After further investigation, I think the above doesn't apply. |
Thanks for the various clarifications! Regarding canonicalization and Vidal gauge. Currently You can monitor it directly with: print(circ.gate_opts["info"]["cur_orthog"]) For the Vidal form, this is the same as Simple Update, so you could in fact adapt the Regarding eager contractions - And yes regarding the CNOT splitting - that happens only in the non-MPS case, as it seems you found out! As a side note, |
Here's a implementation using import quimb.tensor as qtn
import numpy as np
n = 40
n_layers = 20
params = np.random.rand(n_layers, n, 3) * 2 * np.pi
psi = qtn.MPS_computational_state("0" * n)
gauges = {}
contract_opts = dict(
max_bond=64,
cutoff=1e-10,
)
gates = []
for l in range(n_layers):
for i in range(n):
for j, label in enumerate(["rz", "ry", "rz"]):
gates.append(
qtn.Gate(label, params=(params[l, i, j],), qubits=[i])
)
for i in range(l % 2, n - 1, 2):
gates.append(
qtn.Gate("cnot", params=(), qubits=[i, i + 1])
)
for gate in gates:
psi.gate_simple_(
G=gate.array,
where=gate.qubits,
gauges=gauges,
renorm=False,
**contract_opts,
)
# re-insert gauges
psi.gauge_simple_insert(gauges, remove=True)
# approx fidelity
psi.H @ psi
# 0.3917061075190 |
What is your issue?
I would like to use Quimb as a backend for an MPS-based quantum circuit simulator. When running a circuit such as
with cProfile (
python -m cProfile -o 01-prof mps.py
) and visualizing withsnakeviz
, I see that mostly all the time is spent betweencanonicalize
andgate_split
. I'm wondering:canonicalize
andgate_split
take so much time in this example?The text was updated successfully, but these errors were encountered: