Trying to understand what LoopVectorization does/doesn’t like.
If I broadcast-add elements of tuples
function bcast_add(x::NTuple{N,T},y::NTuple{N,T}) where {N,T}
@avx for i = 1:length(first(x))
x_i = getindex.(x,i) .+ getindex.(y,i)
setindex!.(x,x_i,i)
end
end
using @avx gives an Expression not recognized error which disappears if I remove getindex.(...) or setindex.(...). Are these operations not supported?
Note that the original poster on Slack cannot see your response here on Discourse. Consider transcribing the appropriate answer back to Slack, or pinging the poster here on Discourse so they can follow this thread. (Original message )(More Info)
That’s correct, @avx doesn’t know how to deal with broadcasting, though this would be a conceivable feature to add. Perhaps open an issue in LoopVectorization.jl?
using LoopVectorization, Base.Cartesian
@generated function foo!(x::Tuple{Vararg{Array,N}}) where {N}
quote
@nextract $N x x
@avx for i = 1:length(first(x))
@nexprs $N n -> x_n[i] = exp(x_n[i])
end
end
end
using Random
x = (rand(100), randn(100), randexp(100))
foo!(x)
x
I could be wrong but don’t think any kind of two-deep indexing is going to work […] I think things like x[n][i] also won’t work, it needs to know what arrays it’s dealing with. You could generate code though, for each N build the unrolled expression with all N loops visible. Either just a loop for N in 1:10 @eval fun!(x::NTuple{$N,T}, y::...) or a generated function.