Tullio.jl
Tullio.jl copied to clipboard
Wrong result when the same array appears in both sides of =
When the same array appears in both side of =, the result from Tullio is strange
using Tullio
a = [1,2]
b = [1 2;3 4]
a = b * a
println(a) # [5,11]
a = [1,2]
@tullio a[x] = b[x,y] * a[y]
println(a) # [5,23]
It seems only the first component is right. When calculate the second componet, the first component is already updated to 5, and the second component is calculated by 3*5+4*2=23
.
When there are some complicated operations which have to be seprated into several steps, to avoid extra allocation, I prefer to use the same array repeatedly, and sometimes wrong results may occur like above.
This writes the following function:
# @tullio a[x] = b[x,y] * a[y] verbose=2
function ππΈπ!(::Type, β::AbstractArray{π―}, b, a, πΆπx, πΆπy, β»οΈ = nothing, π = true) where π―
for x in πΆπx
ππΈπΈ = if β»οΈ === nothing
zero(π―)
else
β[x]
end
for y in πΆπy
ππΈπΈ = ππΈπΈ + b[x, y] * a[y]
end
β[x] = ππΈπΈ
end
end
This is called like ππΈπ!(typeof(a), a, b, a, axes(a,1), axes(b,2))
, and so the loop overwrites values of a
that it needs later.
I guess it would be nice to make this an error, by checking for aliasing.
It should still be safe to re-use an array, as long as you are reading and writing at the same point, not different ones. (E.g. things like a .= a .+ 1
are safe, of course.)
Thanks for your response! I think it would be nice to throw an error/warning when reading and writing the same array at different point.