Below is a very memory and performance intensive part of my code which aims to a system of non-linear equations via tensor contractions.
Performance and memory intensive code
function calculate_residual_memeff(T2)
# g_vvoo,g_voov,g_vovo,g_oovv,g_oooo,g_vvvv= deserialize("g_vvoo.jlbin"),deserialize("g_voov.jlbin"),deserialize("g_vovo.jlbin"),deserialize("g_oovv.jlbin"),deserialize("g_oooo.jlbin"),deserialize("g_vvvv.jlbin")
g_vvoo::Array{Float64,4} = deserialize("g_vvoo.jlbin")
g_voov::Array{Float64,4} = deserialize("g_voov.jlbin")
g_vovo::Array{Float64,4} = deserialize("g_vovo.jlbin")
g_oovv::Array{Float64,4} = deserialize("g_oovv.jlbin")
g_oooo::Array{Float64,4} = deserialize("g_oooo.jlbin")
g_vvvv::Array{Float64,4} = deserialize("g_vvvv.jlbin")
fvv::Array{Float64,2} , foo::Array{Float64,2} = deserialize("fvv.jlbin"),deserialize("foo.jlbin")
nv::Int64 = deserialize("nv.jlbin")
nocc::Int64 = deserialize("nocc.jlbin")
R2u::Array{Float64,4} = zeros(Float64,nv,nv,nocc,nocc)
R2::Array{Float64,4} = zeros(Float64,nv,nv,nocc,nocc)
@tensor begin
Trm1[a_1,a_2,i_1,i_2] := 0.5* g_vvoo[a_1,a_2,i_1,i_2]
R2u[a_1,a_2,i_1,i_2] += Trm1[a_1,a_2,i_1,i_2]
# @notensor Trm1 = nothing
# @notensor g_vvoo = nothing
Trm2[a_1,a_2,i_1,i_2] := - g_voov[a_1,i_3,i_1,a_3] * T2[a_2,a_3,i_3,i_2]
R2u[a_1,a_2,i_1,i_2] += Trm2[a_1,a_2,i_1,i_2]
# @notensor Trm2 = nothing
Trm3[a_1,a_2,i_1,i_2] := - g_vovo[a_2,i_3,a_3,i_2] * T2[a_1,a_3,i_1,i_3]
R2u[a_1,a_2,i_1,i_2] += Trm3[a_1,a_2,i_1,i_2]
# @notensor Trm3 = nothing
Trm4[a_1,a_2,i_1,i_2] := - g_vovo[a_2,i_3,a_3,i_1] * T2[a_1,a_3,i_3,i_2]
R2u[a_1,a_2,i_1,i_2] += Trm4[a_1,a_2,i_1,i_2]
# @notensor Trm4 = nothing
# @notensor g_vovo = nothing
Trm5[a_1,a_2,i_1,i_2] := 2*g_voov[a_1,i_3,i_1,a_3] * T2[a_2,a_3,i_2,i_3]
R2u[a_1,a_2,i_1,i_2] += Trm5[a_1,a_2,i_1,i_2]
# @notensor Trm5 = nothing
# @notensor g_voov = nothing
Trm6[a_1,a_2,i_1,i_2] := 0.5*g_oooo[i_3,i_4,i_1,i_2] * T2[a_1,a_2,i_3,i_4]
R2u[a_1,a_2,i_1,i_2] += Trm6[a_1,a_2,i_1,i_2]
# @notensor Trm6 = nothing
# @notensor g_oooo = nothing
Trm7[a_1,a_2,i_1,i_2] := fvv[a_2,a_3] * T2[a_1,a_3,i_1,i_2]
R2u[a_1,a_2,i_1,i_2] += Trm7[a_1,a_2,i_1,i_2]
# @notensor Trm7 = nothing
# @notensor fvv = nothing
Trm8[a_1,a_2,i_1,i_2] := + 0.5*g_vvvv[a_1,a_2,a_3,a_4] * T2[a_3,a_4,i_1,i_2]
R2u[a_1,a_2,i_1,i_2] += Trm8[a_1,a_2,i_1,i_2]
# @notensor Trm8 = nothing
# @notensor g_vvvv = nothing
Trm9[a_1,a_2,i_1,i_2] := - foo[i_3,i_2] * T2[a_1,a_2,i_1,i_3]
R2u[a_1,a_2,i_1,i_2] += Trm9[a_1,a_2,i_1,i_2]
# @notensor Trm9 = nothing
# @notensor foo = nothing
B1[i_4,a_4,a_1,i_1] := 2*(g_oovv[i_3,i_4,a_3,a_4] * T2[a_1,a_3,i_1,i_3])
R2u[a_1,a_2,i_1,i_2] += B1[i_4,a_4,a_1,i_1] * T2[a_2,a_4,i_2,i_4]- B1[i_4,a_4,a_1,i_1] * T2[a_2,a_4,i_4,i_2]
# @notensor B1 = nothing
B2[i_4,a_4,a_1,i_1] := 0.5*(g_oovv[i_3,i_4,a_3,a_4] * T2[a_1,a_3,i_3,i_1])
R2u[a_1,a_2,i_1,i_2] += B2[i_4,a_4,a_1,i_1] * T2[a_2,a_4,i_4,i_2]
# @notensor B2 = nothing
B3[i_4,i_2] := 2*(g_oovv[i_3,i_4,a_3,a_4] * T2[a_3,a_4,i_3,i_2])
R2u[a_1,a_2,i_1,i_2] += -B3[i_4,i_2] * T2[a_1,a_2,i_1,i_4]
# @notensor B3 = nothing
B4[i_4,a_3,a_1,i_1] := (g_oovv[i_3,i_4,a_3,a_4] * T2[a_1,a_4,i_1,i_3])
R2u[a_1,a_2,i_1,i_2] += -B4[i_4,a_3,a_1,i_1] * T2[a_2,a_3,i_2,i_4] + B4[i_4,a_3,a_1,i_1] * T2[a_2,a_3,i_4,i_2]
# @notensor B4 = nothing
B5[a_3,a_2] := (g_oovv[i_3,i_4,a_3,a_4] * T2[a_2,a_4,i_4,i_3])
R2u[a_1,a_2,i_1,i_2] += B5[a_3,a_2] * T2[a_1,a_3,i_1,i_2]
# @notensor B5 = nothing
B6[i_4,i_2] := (g_oovv[i_3,i_4,a_3,a_4] * T2[a_3,a_4,i_2,i_3])
R2u[a_1,a_2,i_1,i_2] += B6[i_4,i_2] * T2[a_1,a_2,i_1,i_4]
# @notensor B6 = nothing
B7[a_4,a_2] := 2*(g_oovv[i_3,i_4,a_3,a_4] * T2[a_2,a_3,i_4,i_3])
R2u[a_1,a_2,i_1,i_2] += - B7[a_4,a_2] * T2[a_1,a_4,i_1,i_2]
# @notensor B7 = nothing
B8[i_4,a_3,a_1,i_2] := 0.5*(g_oovv[i_3,i_4,a_3,a_4] * T2[a_1,a_4,i_3,i_2])
R2u[a_1,a_2,i_1,i_2] += +B8[i_4,a_3,a_1,i_2] * T2[a_2,a_3,i_4,i_1]
# @notensor B8 = nothing
B9[i_3,i_4,i_1,i_2] := 0.5* (g_oovv[i_3,i_4,a_3,a_4] * T2[a_3,a_4,i_1,i_2])
R2u[a_1,a_2,i_1,i_2] += + B9[i_3,i_4,i_1,i_2] * T2[a_1,a_2,i_3,i_4]
# @notensor B9 = nothing
# @notensor g_oovv = nothing
R2[a,b,i,j] := R2u[a,b,i,j] + R2u[b,a,j,i]
# @notensor R2u = nothing
end
return R2
end
I want to write a type stable code that is also memory efficient. For example, after the variable Trm1
has been used once, it is no longer needed. So I want to delete the variable from memory and free the memory. One of the ways I read was to assign the variable as nothing
and then manually run GC.gc()
. However, this is causing type conversion problems as Trm1
has type Array{Float64,4}
and thus it cannot be assigned to nothing
. Is there any way to overcome this issue and free up the memory associated with Trm1
just after itâs work has ended?