Skip to content

Commit f0be3f9

Browse files
committed
Fix inference problems by using a generated function
1 parent 63f1b79 commit f0be3f9

File tree

1 file changed

+57
-25
lines changed

1 file changed

+57
-25
lines changed

src/Interpolations.jl

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -214,37 +214,69 @@ Base.length(x::WeightedIndex) = 1
214214
Base.to_indices(A, I::Tuple{Vararg{Union{Int,WeightedIndex}}}) = I
215215
@propagate_inbounds Base._getindex(::IndexLinear, A::AbstractVector, i::Int) = getindex(A, i) # ambiguity resolution
216216
@inline function Base._getindex(::IndexStyle, A::AbstractArray{T,N}, I::Vararg{Union{Int,WeightedIndex},N}) where {T,N}
217-
interp_getindex(A, I)
217+
interp_getindex(A, I, ntuple(d->0, Val(N))...)
218218
end
219219

220-
# This follows a "move processed indexes to the back" strategy, so J contains the yet-to-be-processed
221-
# indexes and I all the processed indexes.
222-
interp_getindex(A::AbstractArray{T,N}, J::Tuple{Int,Vararg{Any,L}}, I::Vararg{Int,M}) where {T,N,L,M} =
223-
interp_getindex(A, Base.tail(J), I..., J[1])
224-
function interp_getindex(A::AbstractArray{T,N}, J::Tuple{WeightedIndex,Vararg{Any,L}}, I::Vararg{Int,M}) where {T,N,L,M}
225-
wi = J[1]
226-
_interp_getindex(A, indexes(wi), weights(wi), Base.tail(J), I...)
220+
# The non-generated version is currently disabled due to https://github.com/JuliaLang/julia/issues/29117
221+
# # This follows a "move processed indexes to the back" strategy, so J contains the yet-to-be-processed
222+
# # indexes and I all the processed indexes.
223+
# interp_getindex(A::AbstractArray{T,N}, J::Tuple{Int,Vararg{Any,L}}, I::Vararg{Int,M}) where {T,N,L,M} =
224+
# interp_getindex(A, Base.tail(J), I..., J[1])
225+
# function interp_getindex(A::AbstractArray{T,N}, J::Tuple{WeightedIndex,Vararg{Any,L}}, I::Vararg{Int,M}) where {T,N,L,M}
226+
# wi = J[1]
227+
# interp_getindex1(A, indexes(wi), weights(wi), Base.tail(J), I...)
228+
# end
229+
# interp_getindex(A::AbstractArray{T,N}, ::Tuple{}, I::Vararg{Int,N}) where {T,N} = # termination
230+
# @inbounds A[I...] # all bounds-checks have already happened
231+
#
232+
# ## Handle expansion of a single dimension
233+
# # version for WeightedAdjIndex
234+
# @inline interp_getindex1(A, i::Int, weights::NTuple{K,Any}, rest, I::Vararg{Int,M}) where {M,K} =
235+
# weights[1] * interp_getindex(A, rest, I..., i) + interp_getindex1(A, i+1, Base.tail(weights), rest, I...)
236+
# @inline interp_getindex1(A, i::Int, weights::Tuple{Any}, rest, I::Vararg{Int,M}) where M =
237+
# weights[1] * interp_getindex(A, rest, I..., i)
238+
# interp_getindex1(A, i::Int, weights::Tuple{}, rest, I::Vararg{Int,M}) where M =
239+
# error("exhausted the weights, this should never happen")
240+
#
241+
# # version for WeightedArbIndex
242+
# @inline interp_getindex1(A, indexes::NTuple{K,Int}, weights::NTuple{K,Any}, rest, I::Vararg{Int,M}) where {M,K} =
243+
# weights[1] * interp_getindex(A, rest, I..., indexes[1]) + interp_getindex1(A, Base.tail(indexes), Base.tail(weights), rest, I...)
244+
# @inline interp_getindex1(A, indexes::Tuple{Int}, weights::Tuple{Any}, rest, I::Vararg{Int,M}) where M =
245+
# weights[1] * interp_getindex(A, rest, I..., indexes[1])
246+
# interp_getindex1(A, indexes::Tuple{}, weights::Tuple{}, rest, I::Vararg{Int,M}) where M =
247+
# error("exhausted the weights and indexes, this should never happen")
248+
249+
interp_getindex(A::AbstractArray{T,N}, J::Tuple{Int,Vararg{Any,K}}, I::Vararg{Int,N}) where {T,N,K} =
250+
interp_getindex(A, Base.tail(J), Base.tail(I)..., J[1])
251+
@generated function interp_getindex(A::AbstractArray{T,N}, J::Tuple{WeightedAdjIndex{L,W},Vararg{Any,K}}, I::Vararg{Int,N}) where {T,N,K,L,W}
252+
ex = :(w[1]*interp_getindex(A, Jtail, Itail..., j))
253+
for l = 2:L
254+
ex = :(w[$l]*interp_getindex(A, Jtail, Itail..., j+$(l-1)) + $ex)
255+
end
256+
quote
257+
$(Expr(:meta, :inline))
258+
Jtail = Base.tail(J)
259+
Itail = Base.tail(I)
260+
j, w = J[1].istart, J[1].weights
261+
$ex
262+
end
263+
end
264+
@generated function interp_getindex(A::AbstractArray{T,N}, J::Tuple{WeightedArbIndex{L,W},Vararg{Any,K}}, I::Vararg{Int,N}) where {T,N,K,L,W}
265+
ex = :(w[1]*interp_getindex(A, Jtail, Itail..., ij[1]))
266+
for l = 2:L
267+
ex = :(w[$l]*interp_getindex(A, Jtail, Itail..., ij[$l]) + $ex)
268+
end
269+
quote
270+
$(Expr(:meta, :inline))
271+
Jtail = Base.tail(J)
272+
Itail = Base.tail(I)
273+
ij, w = J[1].indexes, J[1].weights
274+
$ex
275+
end
227276
end
228277
interp_getindex(A::AbstractArray{T,N}, ::Tuple{}, I::Vararg{Int,N}) where {T,N} = # termination
229278
@inbounds A[I...] # all bounds-checks have already happened
230279

231-
## Handle expansion of a single dimension
232-
# version for WeightedAdjIndex
233-
@inline _interp_getindex(A, i::Int, weights::NTuple{K,Number}, rest, I::Vararg{Int,M}) where {M,K} =
234-
weights[1] * interp_getindex(A, rest, I..., i) + _interp_getindex(A, i+1, Base.tail(weights), rest, I...)
235-
@inline _interp_getindex(A, i::Int, weights::Tuple{Number}, rest, I::Vararg{Int,M}) where M =
236-
weights[1] * interp_getindex(A, rest, I..., i)
237-
_interp_getindex(A, i::Int, weights::Tuple{}, rest, I::Vararg{Int,M}) where M =
238-
error("exhausted weights, this should never happen") # helps inference
239-
240-
# version for WeightedArbIndex
241-
@inline _interp_getindex(A, indexes::NTuple{K,Int}, weights::NTuple{K,Number}, rest, I::Vararg{Int,M}) where {M,K} =
242-
weights[1] * interp_getindex(A, rest, I..., indexes[1]) + _interp_getindex(A, Base.tail(indexes), Base.tail(weights), rest, I...)
243-
@inline _interp_getindex(A, indexes::Tuple{Int}, weights::Tuple{Number}, rest, I::Vararg{Int,M}) where M =
244-
weights[1] * interp_getindex(A, rest, I..., indexes[1])
245-
_interp_getindex(A, indexes::Tuple{}, weights::Tuple{}, rest, I::Vararg{Int,M}) where M =
246-
error("exhausted weights and indexes, this should never happen")
247-
248280
"""
249281
w = value_weights(degree, δx)
250282

0 commit comments

Comments
 (0)