In-place functions for contractions and factorizations

I noticed that the absence of many in-place implementations of most functions, like apply(MPO,MPS), If I’m performing an evolution of the state in time it would be very useful to have a function that modifies the MPS in-place. Also the factorizations aren’t implemented in-place, even though it would be the most natural think to do in a mps, and LAPACK functions naturally supports the overwriting of the initial matrix. Is there a particular reason that has led to don’t implement this in-place functions?

Often in MPS calculations (such as in apply) we dynamically adjust the bond dimension based on the truncation/entanglement, so it isn’t so easy to reuse the data that was input. In principle it would be possible, for example by pre-allocating a large chunk of memory (say enough that we think the calculation won’t exceed that amount) and overwriting it during the calculation, but that is a bit more advanced to implement properly. It is definitely something we have in mind to try at some point. Some Julia packages like GitHub - MasonProtter/Bumper.jl: Bring Your Own Stack may be beneficial for that.

There are cases where we know the dimension or that the size doesn’t change, like when we perform a truncation, we first left orthogonalize the MPS, but orthogonalize! uses factorization which is going to perform a QR decomposition, but in such case we already know that the size of each tensor is not going to change so why don’t us a qr! implementation?
In apply is impossible to know the size beforehand, but, taking for example the naive implementation, by changing

  ψ_out = typeof(ψ)(N)
  for j in 1:N
    ψ_out[j] = A[j] * ψ[j]

To

    update!(ψ[j], A[j] * ψ[j])  # Overwrite the location of ψ[j]

where

function update!(ψ_old::ITensor, ψ_new::ITensor)
  setstorage!(ψ_old, storage(ψ_new))
  setinds!(ψ_old, inds(ψ_new))
end

(Probably already ψ[j]=A[j] * ψ[j] is enough) would make the old location of \psi[j] unreachable so that the GC could collect that memory already on exit from the function

1 Like