How to use `@generated` to eliminate a for loop?

I’d say the most standard way to lift a value to the type domain would be to use Val

Also, there would be ways to write your @generated function so that is manipulates expressions rather than strings (which would remove the need for Meta.parse), but I don’t think it’s really necessary to use a @generated function here.

I’d for example rather use NTuples, for which the compiler can often generate very optimized code in which loops have been unrolled:

julia> x = rand(1000, 1000, 4);

julia> my_matrix_sum(x) = @views @. x[:,:,1] + x[:,:,2] + x[:,:,3] + x[:,:,4]
my_matrix_sum (generic function with 1 method)

julia> using BenchmarkTools
julia> ref = my_matrix_sum(x);
julia> @btime my_matrix_sum($x);
  1.245 ms (2 allocations: 7.63 MiB)
julia> my_matrix_sum2(x) = my_matrix_sum2(x, Val(size(x, 3)));
       function my_matrix_sum2(x, N::Val)
           t = ntuple(N) do i
               @view x[:,:,i]
           end
           (+).(t...)
       end
my_matrix_sum2 (generic function with 2 methods)

julia> @assert ref == my_matrix_sum2(x);
julia> @btime my_matrix_sum2($x);
  1.252 ms (2 allocations: 7.63 MiB)
3 Likes