内存占用随循环次数增长

这里的for center循环我希望每次更新psi
psi,U = itinnerexceptcenter(psi,psio,center);
但好像系统把所有的循环过来的psi都记住了导致了内存随循环次数近线性增长。
该如何降低内存占用,感谢~

using Random
N = 10;#物理格点个数
maxdim=16;
sites=siteinds("S=1/2",N); # siteinds给出后是不会变的 但是linkinds会变化
s=siteinds("S=1/2",N);
#file = h5open("Final MPS.h5", "r")
#psiT=read(file,list_first_level(file)[1],MPS);
Random.seed!(1234)
psiT=randomMPS(ComplexF64, sites; linkdims=64);
psio=randomMPS(ComplexF64, sites; linkdims=64);









"""
innerexcept(psi::MPS, psio::MPS, center::Int)

return the optimised ITensor for center & psi of orthogonal center = center

Inputs:
-------
- psi   :MPS as iterative start point 
- psio   :MPS without truncate 

"""

function innerexceptcenter(psi::MPS, psio::MPS, center::Int, N::Int=length(psio)) 
    psi=orthogonalize(psi,center) # 移动正交中心 注意会改变linkinds
    psi=dag(psi) # dag 不会改变linkinds
    res=ITensor[];
    for i in 1:N
        if i==center
            push!(res,psio[i])
        else
            push!(res,psio[i]*psi[i])
        end
    end

    L=res[1]; 
    R=res[end];

    if center==1 # 仅有R
        # 对R计算
        for j in (N-1): -1 : (center+1)
            R*=res[j]
        end
        return  L*R #再dag回来
    elseif center==N # 仅有L
        # 对L计算
        for j in 2:(center-1)
            L*=res[j]
        end
        return  L*R#再dag回来
    else
        # 对R计算
        for j in 2:(center-1)
            L*=res[j]
        end
        # 对R计算
        for j in (N-1): -1 : (center+1)
            R*=res[j]
        end
        return  L*res[center]*R #再dag回来
    end
    
end

# 迭代方法innerexceptcenter
function itinnerexceptcenter(psi::MPS, psio::MPS, center::Int, N::Int=length(psio)) 
    psi=orthogonalize(psi,center) # 移动正交中心 注意会改变linkinds
    psi=dag(psi) # dag 不会改变linkinds 需要dagger才能

    function fl(n::Int)
        if n==0
            return ITensor(1)
        else
            return psi[n]*psio[n]*fl(n-1)
        end
    end

    function fr(n::Int)
        if n==N+1
            return ITensor(1)
        else
            return psi[n]*psio[n]*fr(n+1)
        end
    end
    
    return dag(psi), fl(center-1)*psio[center]*fr(center+1)

end

"""
iterative_truncate(psio::MPS)

return a MPS global truncated from psio

Inputs:
-------
- psio  :MPS that is subjected to truncation

"""
function iterative_truncate(psio::MPS,N::Int=length(psio))
    psi=copy(psio);
    truncate!(psi;maxdim=maxdim) # psi作为迭代truncate的原始输入 truncate后并不归一!!!
    ustart=norm(psi-psio)
    

    observable = ustart
    @show ustart
    for center in vcat(collect(range(1,N)),reverse(collect(range(1,N))))
        psi,U = itinnerexceptcenter(psi,psio,center); #返回正交中心应取的值U以及移动过后的psi
    
        psi[center] .= U;
        a=norm(psi-psio)
        
        if a<= observable 
            observable = a 
        end

    end

    uover=observable;
    @show uover
    return psi;
end



psi=truncate(psiT;maxdim=maxdim)
a=8;
#@time innerexceptcenter(psiT,psiT,a);
#@time itinnerexceptcenter(psiT,psiT,a)
@time iterative_truncate(psiT)


读别人代码确实是个很费神的事儿。
你函数名有很多单词可以加下划线隔开的……

另外你这个例子我没跑通。比如siteindx()函数。
可以的话再精简一下:

  1. 专业函数用julia内置函数重写一下——不需要复现,你首先保持输入变量类型不变,再拿输入函数简单算一下,最后保证输出类型不变。如果你不算一下,输入输出没关系,可能会被编译器优化掉。
  2. 你可以一个函数一个函数排除,代码一行一行删,把剩下的最精简的部分提取出来测试。

好多人代码太长不看的,特别是带专业词汇的代码,更是晦涩难懂。别人看不懂懒得看,只能你自己解决了

我在用ITensors做DMRG计算时遇到了类似的问题,根据ITensors社区的说法是julia 1.9在内存管理方面有一些问题,如果你在使用1.9版本请尽快升级到1.10,如果没能解决问题的话,还可以尝试手动collect garbage,比如在每次使用完psi时加一句GC.gc(),希望我的经验对你有些帮助。

感谢感谢我会去查看的~