Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inference hang when inlining is off #20714

Closed
timholy opened this issue Feb 21, 2017 · 3 comments · Fixed by #21933
Closed

Inference hang when inlining is off #20714

timholy opened this issue Feb 21, 2017 · 3 comments · Fixed by #21933
Labels
compiler:inference Type inference

Comments

@timholy
Copy link
Member

timholy commented Feb 21, 2017

If you check out the master branch of AxisArrays.jl (currently, this is commit 4d2f8ccc08d582adcf0a029d28f5ccd12b72f406), then the following script succeeds with normal inlining but hangs during inference with --inline=no:

using AxisArrays

Base.reduced_indices(A::AxisArray, region)  = reduced_indices(axes(A), region)

@inline reduced_indices{Ax<:Axis}(axs::Tuple{Vararg{Axis}}, region::Type{Ax}) =
    _reduced_indices(reduced_axis, (), region, axs...)

@inline _reduced_indices{name}(f, out, chosen::Type{Axis{name}}, ax::Axis{name}, axs...) =
    _reduced_indices(f, (out..., f(ax)), chosen, axs...)
@inline _reduced_indices{name}(f, out, chosen::Axis{name}, ax::Axis{name}, axs...) =
    _reduced_indices(f, (out..., f(ax)), chosen, axs...)
@inline _reduced_indices(f, out, chosen, ax::Axis, axs...) =
    _reduced_indices(f, (out..., ax), chosen, axs...)
_reduced_indices(f, out, chosen) = out

reduced_axis(ax) = ax(oftype(ax.val, Base.OneTo(1)))

C = AxisArray(collect(reshape(1:15,3,5)), :y, :x)
sum(C, Axis{:x})

Observed in JuliaArrays/AxisArrays.jl#56.

@timholy
Copy link
Member Author

timholy commented Feb 21, 2017

Note that this is not a regression, because it also affects julia-0.5.

@timholy
Copy link
Member Author

timholy commented Mar 23, 2017

Here's a completely self-contained reproducer; it also doesn't require setting --inline=no, but note the comment about changing a @noinline to an @inline.

This reproduces the hang for both 0.5 and 0.6.

immutable Axis{name,T}
    val::T
end
(::Type{Axis{name}}){name,T}(val::T) = Axis{name,T}(val)

(A::Axis{name}){name}(i) = Axis{name}(i)

immutable AxisArray{T,N,D,Ax} <: AbstractArray{T,N}
    data::D
    axes::Ax
    (::Type{AxisArray{T,N,D,Ax}}){T,N,D,Ax}(data::AbstractArray{T,N}, axs::Tuple{Vararg{Axis,N}}) = new{T,N,D,Ax}(data, axs)
end
function AxisArray{T,N}(A::AbstractArray{T,N}, axs::NTuple{N,Axis})
    AxisArray{T,N,typeof(A),typeof(axs)}(A, axs)
end

Base.reduced_indices(A::AxisArray, region)  = reduced_indices(A.axes, region)

@inline reduced_indices{Ax<:Axis}(axs::Tuple{Vararg{Axis}}, region::Type{Ax}) =
    _reduced_indices(reduced_axis, (), region, axs...)

@noinline _reduced_indices{name}(f, out, chosen::Type{Axis{name}}, ax::Axis{name}, axs...) =
    _reduced_indices(f, (out..., f(ax)), chosen, axs...)
@noinline _reduced_indices{name}(f, out, chosen::Axis{name}, ax::Axis{name}, axs...) =
    _reduced_indices(f, (out..., f(ax)), chosen, axs...)
# If you change this next line to @inline, then it works fine
@noinline _reduced_indices(f, out, chosen, ax::Axis, axs...) =
    _reduced_indices(f, (out..., ax), chosen, axs...)
_reduced_indices(f, out, chosen) = out

reduced_axis(ax) = ax(oftype(ax.val, Base.OneTo(1)))

Base.similar{T,S,N}(A::AxisArray{T,N}, ::Type{S}, axs::Tuple{Axis,Vararg{Axis}}) =
    AxisArray(similar(A.data, S, map(ax->length(ax.val), axs)), axs)
Base.size(A::AxisArray) = size(A.data)
Base.getindex(A::AxisArray, i::Int, j::Int) = A.data[i, j]
Base.setindex!(A::AxisArray, val, i::Int, j::Int) = A.data[i, j] = val

C = AxisArray(collect(reshape(1:15,3,5)), (Axis{:y}(1:3), Axis{:x}(1:5)))
D = sum(C, Axis{:x})

For 0.6 I'm on

julia> versioninfo()
Julia Version 0.6.0-pre.alpha.229
Commit cc917b5 (2017-03-22 21:53 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.9.1 (ORCJIT, broadwell)

@timholy
Copy link
Member Author

timholy commented Mar 23, 2017

Even simpler:

julia> include("hang2.jl")
reduced_axis (generic function with 1 method)

julia> reduced_indices((Axis{:y}(1:3), Axis{:x}(1:5)), Axis{:y})
(Axis{:y,UnitRange{Int64}}(1:1), Axis{:x,UnitRange{Int64}}(1:5))

julia> reduced_indices((Axis{:y}(1:3), Axis{:x}(1:5)), Axis{:x})
^C^C^C^C^CWARNING: Force throwing a SIGINT
WARNING: An error occurred during inference. Type inference is now partially disabled.
InterruptException()
unknown function (ip: 0x7fdf07cdd19f)
(Axis{:y,UnitRange{Int64}}(1:3), Axis{:x,UnitRange{Int64}}(1:1))

julia> ^C

with hang2.jl:

immutable Axis{name,T}
    val::T
end
(::Type{Axis{name}}){name,T}(val::T) = Axis{name,T}(val)

(A::Axis{name}){name}(i) = Axis{name}(i)

@inline reduced_indices{Ax<:Axis}(axs::Tuple{Vararg{Axis}}, region::Type{Ax}) =
    _reduced_indices(reduced_axis, (), region, axs...)

@noinline _reduced_indices{name}(f, out, chosen::Type{Axis{name}}, ax::Axis{name}, axs...) =
    _reduced_indices(f, (out..., f(ax)), chosen, axs...)
@noinline _reduced_indices{name}(f, out, chosen::Axis{name}, ax::Axis{name}, axs...) =
    _reduced_indices(f, (out..., f(ax)), chosen, axs...)
# If you change this next line to @inline, then it works fine
@noinline _reduced_indices(f, out, chosen, ax::Axis, axs...) =
    _reduced_indices(f, (out..., ax), chosen, axs...)
_reduced_indices(f, out, chosen) = out

reduced_axis(ax) = ax(oftype(ax.val, Base.OneTo(1)))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:inference Type inference
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants