Hi all,
I am posting some strange issue I am currently encountering with TensorOpertions.jl, here in the development category, because I think it’s pretty advanced. Consider the following code:
using TensorOperations
const rows=10;
const cols=10;
const Sx=ComplexF64[0 1;1 0];
const Sz=ComplexF64[1 0;0 -1];
const Sy=ComplexF64[0 -1im;1im 0];
const Id=one(Sz);
@time begin
@tensor eplaq[-1,-2,-3,-4,-5,-6,-7,-8]:=Id[-1,-2]*Id[-3,-4]*Id[-5,-6]*Id[-7,-8]
end; # 27 seconds
plaq=Array{typeof(eplaq),2}(undef,rows,cols)
for r in 1:rows
for c in 1:cols
plaq[r,c]=zero(eplaq)
end
end;
r = 1;
c = 1;
@time begin
@tensor plaq[r,c][-1,-2,-3,-4,-5,-6,-7,-8]+=Sz[-1,-2]*Sz[-3,-4]*Id[-5,-6]*Id[-7,-8]
end; # 0.005 seconds
precompile(Tuple{typeof(TensorOperations.checked_similar_from_indices), Array{Base.Complex{Float64}, 4}, Type{Base.Complex{Float64}}, Tuple{Int64, Int64}, Tuple{Int64, Int64}, Tuple{Int64, Int64, Int64, Int64}, Tuple{}, Array{Base.Complex{Float64}, 2}, Array{Base.Complex{Float64}, 2}, Symbol, Symbol});
precompile(Tuple{typeof(TensorOperations.checked_similar_from_indices), Array{Base.Complex{Float64}, 4}, Type{Base.Complex{Float64}}, Tuple{Int64, Int64}, Tuple{Int64, Int64}, Tuple{Int64, Int64, Int64, Int64}, Array{Base.Complex{Float64}, 2}, Array{Base.Complex{Float64}, 2}, Symbol, Symbol});
precompile(Tuple{typeof(TensorOperations.checked_similar_from_indices), Array{Base.Complex{Float64}, 6}, Type{Base.Complex{Float64}}, Tuple{Int64, Int64}, Tuple{Int64, Int64, Int64, Int64}, Tuple{Int64, Int64, Int64, Int64, Int64, Int64}, Tuple{}, Array{Base.Complex{Float64}, 2}, Array{Base.Complex{Float64}, 4}, Symbol, Symbol});
precompile(Tuple{typeof(TensorOperations.checked_similar_from_indices), Array{Base.Complex{Float64}, 6}, Type{Base.Complex{Float64}}, Tuple{Int64, Int64}, Tuple{Int64, Int64, Int64, Int64}, Tuple{Int64, Int64, Int64, Int64, Int64, Int64}, Array{Base.Complex{Float64}, 2}, Array{Base.Complex{Float64}, 4}, Symbol, Symbol});
precompile(Tuple{typeof(Base.:(*)), Base.Complex{Float64}, Int64});
t0 = time();
@time for r in 1:rows-1
@tensor plaq[r,c][-1,-2,-3,-4,-5,-6,-7,-8]+=Sz[-1,-2]*Sz[-3,-4]*Id[-5,-6]*Id[-7,-8]
end; # 0.0002 seconds
t = time() - t0 # actually, that was 85 seconds
t0 = time();
@time for r in 1:rows-1
@tensor plaq[r,c][-1,-2,-3,-4,-5,-6,-7,-8]+=Sz[-1,-2]*Sz[-3,-4]*Id[-5,-6]*Id[-7,-8]
end; # 0.0002 seconds
t = time() - t0 # 0.03 seconds, fair enough
I run this, just in the REPL (copy paste) of julia 1.1, with the --trace-compile
option to monitor what is being compiled. If I start by copying the first block of code, up to the first empty line, everything is fine. The first @tensor
call takes some time, but things are getting compiled in the mean time (as I monitor the precompile
statements being generated), and I am probably doing some fishy things over in TensorOperations. The second @time
statement runs almost instantaneously, even though a few more functions are being compiled.
Now copy paste the first block of code after the line break. Note that the body of the loop is exactly the same as the contents of the second @time
statement, which ran instantaneously. No new functions are being compiled, i.e. no new precompile
statements are being generated (up to maybe one or two REPL functions, but nothing from my packages). I specifically added these explicit precompile
statements to ensure that everything was already compiled.
The result that the @time
macro reports is also very small. Nonetheless, the actual run-time is more than 80 seconds. I also tried @profile
, but it says it did not collect any samples. Copy pasting that block again, everything is fast.
So my question: where are these 80 seconds going to. What is Julia doing that it had not already done and does not need to do the second time, and that does not show up in @time
. I used all possible tricks up my sleeve, but did not get any further insight.