-
Notifications
You must be signed in to change notification settings - Fork 29
Open
Description
Hi, thanks for this great package! I probably have more of a question than an issue with this package. I'm trying to generalize the following function from 3 to N, i.e. I want to contract a vararg number of matrices.
function contractouter(dst::AbstractArray{T,3}, xs::Vararg{AbstractMatrix{T}, 3}) where {T}
a,b,c = xs
@tullio dst[i,j,k] = a[i,z] * b[j,z] * c[k,z]
end
I tried using @generate
and build up the expression myself.
@generated function contractouter(dst::AbstractArray{T,N}, xs::Vararg{AbstractMatrix{T}, N}) where {T, N}
xnames = Expr(:tuple)
for i in 1:N
push!(xnames.args, Symbol(:x, i))
end
inds = Expr(:tuple)
for i in 1:N
push!(inds.args, Symbol(:i, i))
end
prod_expr = nothing
for i in 1:N
xi = xnames.args[i]
ii = inds.args[i]
term = :($(Expr(:ref, xi, ii, :z)))
if prod_expr === nothing
prod_expr = term
else
prod_expr = :($prod_expr * $term)
end
end
index_expr = nothing
for i in 1:N
ii = inds.args[i]
term = :($(Expr(:ref, :dst, ii)))
if index_expr === nothing
index_expr = term
else
push!(index_expr.args, ii)
end
end
# @show index_expr, prod_expr
quote
$(Expr(:(=), xnames, :xs))
@tullio $index_expr = $prod_expr
return dst
end
end
But I always end up with this:
julia> M=rand(4,5,6); a=rand(4,10); b=rand(5,10); c=rand(6,10); contractouter(M, a, b, c)
ERROR: The function body AST defined by this @generated function is not pure. This likely means it contains a closure, a comprehension or a generator.
Is @tullio
not designed to be called from @generated
functions or am I making a mistake somewhere ..
Metadata
Metadata
Assignees
Labels
No labels