# cuTENSOR 2.0：应用程序和性能

## PyTorch 和 TensorFlow

from cutensor.torch import EinsumGeneral
output =  EinsumGeneral('kc,nchw->nkhw', input_a, input_b) // similar to torch.einsum(...)

## CuPy

CuPy 最近增加了对 cuTENSOR 2.0 的支持，这使得 Python 开发者能够轻松利用 cuTENSOR 提升性能。要将 cuTENSOR 作为 CuPy 的后端，请导出 CUPY_ACCELERATORS=cub, cutensor 环境变量并安装正确的 CuPy 版本。

pip install cupy-cuda12x cutensor-cu12

conda install -c conda-forge cupy "cutensor>=2" cuda-version=X.Y

import cupy as cp

# tensor contraction can be accelerated by cuTENSOR
a = cp.random.random((3, 4, 5))
b = cp.random.random((4, 5, 6))
c = cp.random.random((6, 7))
out = cp.einsum(“abc,bcd,de->ae”, a, b, c)

import cupy as cp
import cupyx.cutensor as cutensor

alpha = 1.0
beta = 0.0
mode_a = ('a', 'b', 'c')
mode_b = ('b', 'c', 'd')
mode_c = ('d', 'e')
mode_ab = ('a', 'd')
mode_abc = ('a', 'e')
a = cp.random.random((3, 4, 5))
b = cp.random.random((4, 5, 6))
c = cp.random.random((6, 7))
ab = cp.empty((3, 6))
abc = cp.empty((3, 7))
cutensor.contraction(alpha, a, mode_a, b, mode_b, beta, ab, mode_ab)
cutensor.contraction(alpha, ab, mode_ab, c, mode_c, beta, abc, mode_abc)

## Julia Lang

CUDA.jl (v5.2.0) 新增了对 cuTENSOR 2.0 的支持，使得 Julia 开发者能够轻松利用 cuTENSOR 的性能提升。要在 Julia 中使用 cuTENSOR，请安装 CUDA.jl 包

using CUDA
using cuTENSOR

dimsA = (3, 4, 5)
dimsB = (4, 5, 6)
indsA = ['a', 'b', 'c']
indsB = ['b', 'c', 'd']
A = rand(Float32, (dimsA...,))
B = rand(Float32, (dimsB...,))
dA = CuArray(A)
dB = CuArray(B)
ctA = CuTensor(dA, indsA)
ctB = CuTensor(dB, indsB)

ctC = ctA * ctB      # cuTENSOR is used to perform the contraction

C, indsC = collect(ctC)

CUDA.jl 还提供了直接访问 cuTENSOR 的更低级别 API，因此上述收缩也可以表示为：

using CUDA
using cuTENSOR

dimsA = (3, 4, 5)
dimsB = (4, 5, 6)
dimsC = (3, 6)
indsA = ['a', 'b', 'c']
indsB = ['b', 'c', 'd']
indsC = ['a', 'd']
A = rand(Float32, (dimsA...,))
B = rand(Float32, (dimsB...,))
C = zeros(Float32, (dimsC...,))
dA = CuArray(A)
dB = CuArray(B)
dC = CuArray(C)

alpha = rand(Float32)
beta = rand(Float32)
opA = cuTENSOR.OP_IDENTITY
opB = cuTENSOR.OP_IDENTITY
opC = cuTENSOR.OP_IDENTITY
opOut = cuTENSOR.OP_IDENTITY
comp_type = cuTENSOR.COMPUTE_DESC_TF32
plan  = cuTENSOR.plan_contraction(dA, indsA, opA,
dB, indsB, opB,
dC, indsC, opC, opOut;
compute_type=comp_type)
dC = cuTENSOR.contract!(plan, alpha, dA, dB, beta, dC)
C = collect(dC)

## 性能

### cuTENSOR 2.0.0 与 1.7.0 的对比

cuTENSOR 2.0.0 的性能比其 1.x 前身有显著提升，其中关键的改进包括以下内容：

• 核函数的改进
• 改进性能模型以选择最佳内核
• 引入即时编译支持

• 类似于 QC是一个基准测试，可以捕捉常见的量子电路模拟中的张量收缩结构，张量平均维度为 19.。
• rand1000 是一个 公共收缩基准测试，它包含随机收缩，平均张量维度为 4。

### 量子电路模拟

• cuTENSOR 2.0 的性能始终优于 PyTorch。
• cuTENSOR 2.0 的性能优于上一代产品 (类似于图 3)
• 即时编译可进一步提升性能 (类似于图 4)
• 与 FP32 相比，TF32 显著提升了性能。
• 与 PyTorch 相比，速度提升尤为明显，这是因为 PyTorch 消耗了过多的内存，因此无法使用更具计算效率的收缩路径。我们比较了 PyTorch 仍然能够计算的最佳路径：与 16 GB 中间张量相对应的路径。

### 量子化学多体理论

CCSD (T) 方法通过一系列激发级别整合相关电子运动，从而增强了 Hartree-Fock 方法。在此方法中，单电子和双电子激发通过迭代方式计算，而三电子激发则通过非迭代方式应用偏差修正。

## 开始使用 cuTENSOR 2.0

[1] Huang, Cupjin, et al. “Classical simulation of quantum supremacy circuits.” arXiv preprint arXiv:2005.06787 (2020).
[2] Springer, Charara, Hoehnerbach. SIAM CSE’23, “The Importance of Middle Tensor Mode Order.”
[3] Pan, Feng, et al. “Efficient Quantum Circuit Simulation by Tensor Network Methods on Modern GPU.” arXiv preprint arXiv:2310.03978 (2023).