-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Closed
Description
Follow-up of this discourse thread.
Thanks to @mbauman's investigation, it seems that we loose constant propagation in the definition of _setindex:
Line 57 in c708ca2
| return (ifelse(i == 1, v, first), _setindex(v, i - 1, tail...)...) |
To illustrate, the following MWE (tested on v1.5.3 and v1.6) shows that the compiler cannot predict the dimension of selectdim(A, 1, 1) if A is an AbstractArray of dimension strictly greater than 2:
julia> f(A) = selectdim(A, 1, 1);
julia> A = rand(2,2);
julia> @code_warntype f(A)
Variables
#self#::Core.Compiler.Const(f, false)
A::Array{Float64,2}
Body::SubArray{Float64,1,Array{Float64,2},Tuple{Int64,Base.Slice{Base.OneTo{Int64}}},true}
1 ─ %1 = Main.selectdim(A, 1, 1)::SubArray{Float64,1,Array{Float64,2},Tuple{Int64,Base.Slice{Base.OneTo{Int64}}},true}
└── return %1
julia> A = rand(2,2,2);
julia> @code_warntype f(A)
Variables
#self#::Core.Compiler.Const(f, false)
A::Array{Float64,3}
Body::Union{SubArray{Float64,2,Array{Float64,3},Tuple{Int64,Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}}},true}, SubArray{Float64,1,Array{Float64,3},Tuple{Int64,Base.Slice{Base.OneTo{Int64}},Int64},true}}
1 ─ %1 = Main.selectdim(A, 1, 1)::Union{SubArray{Float64,2,Array{Float64,3},Tuple{Int64,Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}}},true}, SubArray{Float64,1,Array{Float64,3},Tuple{Int64,Base.Slice{Base.OneTo{Int64}},Int64},true}}
└── return %1In the linked discourse discussion, @mbauman proposed the following solution:
julia> @inline function Base._setindex(v, i::Int, args...)
ntuple(dim->ifelse(i==dim, v, args[dim]), length(args))
end
julia> f(A)
2×2 view(::Array{Float64, 3}, 1, :, :) with eltype Float64:
0.901717 0.427261
0.130018 0.669248
julia> @code_warntype f(A)
Variables
#self#::Core.Const(f)
A::Array{Float64, 3}
Body::SubArray{Float64, 2, Array{Float64, 3}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}, Base.Slice{Base.OneTo{Int64}}}, true}Metadata
Metadata
Assignees
Labels
No labels