Tensor and tensor network decomposition¶
Introduction¶
Decomposition methods such as QR and SVD are prevalent in tensor network algorithms, as they allow one to exploit the sparsity of the network and thus reduce the computational cost.
Starting with cuQuantum Python v23.03, we provide these functionalities at both the tensor and tensor network levels.
The tensor level decomposition routines are implemented inside the module cuquantum.cutensornet.tensor
with the following features:
QR decomposition can be performed using
cuquantum.cutensornet.tensor.decompose()
withcuquantum.cutensornet.tensor.QRMethod
.Both exact and truncated SVD can be performed using
cuquantum.cutensornet.tensor.decompose()
withcuquantum.cutensornet.tensor.SVDMethod
.Decomposition options can be specified by
cuquantum.cutensornet.tensor.DecompositionOptions
.
As of cuQuantum Python v23.03, the tensor network level decomposition routines are implemented in the experimental subpackage cuquantum.cutensornet.experimental
with the main API cuquantum.cutensornet.experimental.contract_decompose()
.
Given an input tensor network, this function can perform a full contraction followed by a QR or SVD decomposition. This can be specified via cuquantum.cutensornet.experimental.ContractDecomposeAlgorithm
.
If the contract and decompose problem amounts to a ternary-operand gate split problem, commonly seen in quantum circuit simulation (see Gate Split Algorithm for details),
the user can potentially leverage QR decompositions to speed up the execution of contraction and SVD. This can be achieved by setting both cuquantum.cutensornet.experimental.ContractDecomposeAlgorithm.qr_method
and cuquantum.cutensornet.experimental.ContractDecomposeAlgorithm.svd_method
.
Note
The APIs inside cuquantum.cutensornet.experimental
are subject to change and may be integrated into the main package cuquantum.cutensornet
in a future release.
Users are encouraged to leave feedback on NVIDIA/cuQuantum GitHub Discussions.
Usage example¶
import cupy
from cuquantum import contract
from cuquantum.cutensornet.tensor import decompose
from cuquantum.cutensornet.experimental import contract_decompose
# create a random rank-4 tensor
a = cupy.random.random((2,2,2,2)) + cupy.random.random((2,2,2,2)) * 1j
# perform QR decomposition such that A[i,j,k,l] = \sum_{x} Q[i,x,k] R[x,j,l]
q, r = decompose('ijkl->ixk,xjl', a) # QR by default
# check the unitary property of q
identity = contract('ixk,iyk->xy', q, q.conj())
identity_reference = cupy.eye(identity.shape[0])
assert cupy.allclose(identity, identity_reference)
# check if the contraction of the decomposition outputs yields the input
a_reference = contract('ixk,xjl->ijkl', q, r)
assert cupy.allclose(a, a_reference)
More examples on tensor decompositions are available in our sample directory to demonstrate the use of QR and SVD in different settings.
For tensor network decompositions, please refer to this directory for more detailed examples. We have also provided a Jupyter notebook to demonstrate how to easily implement basic MPS algorithms using these new APIs.