Tullio with pre-computed index broadcasting

It’s my first time with Tullio, so my problem may look very basic. Here is a minimal example that provides the error "expected integers!" :

using Tullio

m,r = 5,5
rr = div(r*(r-1),2)
A = rand(m,rr)
B = rand(m,r)
C = similar(B)

jbar = Vector{Vector{Int}}(undef,r)
jtild = Vector{Vector{Int}}(undef,r)
for j in 1:r
    jbar[j] = vcat(1:j-1,j+1:r)
    jtild[j] = vcat([(k-1)*r-div(k*(k+1),2)+j for k in 1:j-1],[(j-1)*r-div(j*(j-1),2)+k for k = 1:(r-j)])
end

@tullio C[i,j] =  dot(A[i,jtild[j]],B[i,jbar[j]])

I then replaced the @tullio line with @tullio C[i,j] = A[i,jtild[j][k]]*B[i,jbar[j][k]] but I have the error UndefVarError: j not defined.

edit:
The following code works, but I don’t understand why the previous one wouldn’t.

using Tullio

m,r = 5,5
rr = div(r*(r-1),2)
A = rand(m,rr)
B = rand(m,r)
C = similar(B)

jbar = Matrix{Int}(undef,r-1,r)
jtild = Matrix{Int}(undef,r-1,r)
for j in 1:r
    jbar[:,j] = vcat(1:j-1,j+1:r)
    jtild[:,j] = vcat([(k-1)*r-div(k*(k+1),2)+j for k in 1:j-1],[(j-1)*r-div(j*(j-1),2)+k for k = 1:(r-j)])
end

@tullio C[i,j] =  A[i,jtild[k,j]]*B[i,jbar[k,j]]
1 Like

The first one indexes A using not a number but an array of numbers, to make an array. Such things sometimes work by accident but aren’t the goal, and will sometimes be very inefficient. In particular, the code trying to check that all indices within jtild are in-bounds for A fails; it understands arrays if integers but not arrays of arrays.

The second one, with A[i,jtild[j][k]], also fails in the bounds-checking code. But this time because the macro writes a literal tild[j] outside of a loop over j. It notices the [k] but is insufficiently recursive. That’s more clearly a bug, but not sure how easy it’ll be to fix.

The third one with A[i,jtild[k,j]] is much easier for Tullio to understand, as it only has arrays of numbers, and only one level of indexing.

3 Likes

Thank you !