Mapslices() warntype?

I’m wondered seeing that mapslices() gives warntype as below:

julia> const mat = randn(3,2)
3×2 Array{Float64,2}:
  1.49498   -1.98461  
 -0.935659  -0.0317199
  0.783414  -0.284129 

julia> mapslices(prod, mat, dims = 1)
1×2 Array{Float64,2}:
 -1.09583  -0.0178864

julia> @code_warntype mapslices(prod, mat, dims = 1)
Body::Any
...
5 ┄ %16 = Base.:(var"#mapslices#109")(dims, @_3, f, A)::Any
└──       return %16

is there any way to avoid the warntype? thanks.

Mapslices can’t be inferred, because Julia has no way of telling what prod applied to a slice mat looks like without trying. Therefore mapslices first figures that out by calling prod on the first slice and then it calls an inner function which then is “typestable”. [source]

See keyword “function barrier” in the [performance tips]. Therefore you do not need to worry much about that warning, are you calling mapslices in highly performance relevant code or inner loops?

mapslices just doesn’t behave very well, IMO, and you are much better off building the same thing from other pieces. These are fine:

@code_warntype map(prod, eachcol(mat))
@code_warntype map(prod, eachslice(mat, dims=2)) # same, with keyword

although of course you can write prod(mat, dims=1), but I guess it’s an example. If your function returns arrays, you want something like this:

f(x) = vcat(x, x .^ 2)
mapslices(f, mat, dims=1) == reduce(hcat, map(f, eachcol(mat))) # true
@code_warntype mapslices(f, mat, dims=1)          # Any
@code_warntype reduce(hcat, map(f, eachcol(mat))) # Array{Float64,2}

yes, using in performance sensitive inner loop… so, even with the function barrier inner_mapslices!(), seems like mapslices() is still very slow compared to map( , eachcol() ) as suggested by @mcabbott:

julia> @btime prod($mat, dims = $1);
  57.745 ns (1 allocation: 96 bytes)

julia> @btime map($prod, eachcol($mat));
  76.787 ns (6 allocations: 256 bytes)

julia> @btime map($prod, eachslice($mat, dims = $2));
  585.473 ns (7 allocations: 272 bytes)

julia> @btime mapslices($prod, $mat, dims = $1);
  4.639 μs (54 allocations: 2.56 KiB)

it’s interesting to see that map( , eachslice()) is that much slower than map(, eachcol() ) !

another thing to note is the confusion of dims: 1 is used in prod() and mapslices() but 2 should be used in eachslice() !!!

Yes, see e.g. mapslices, map interpret dims differently · Issue #34840 · JuliaLang/julia · GitHub, Equivalent of mapslices with views? · Issue #29146 · JuliaLang/julia · GitHub, and maybe https://discourse.julialang.org/t/ann-lazystack-slicemap-starslice .