-
-
Notifications
You must be signed in to change notification settings - Fork 213
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
Specifying type for list comprehension sometimes crashes Julia #1344
Comments
I've never seen this kind of non-fatal type inference error before, interesting. Passing |
Note that the crash is avoided if you say And that a similar-looking error can be produced as follows, after which the above example no longer crashes Julia: julia> gradient(only, fill(1))
Internal error: encountered unexpected error in runtime:
BoundsError(a=Array{Core.Compiler.VarState, (2,)}[Core.Compiler.VarState(typ=Zygote.Pullback{Tuple{typeof(Base.Iterators.only), Array{Int64, 0}}, Any}, undef=false), Core.Compiler.VarState(typ=Int64, undef=false)], i=(3,))
...
(nothing,)
julia> gradient(1) do x
v = eltype(x)[i for i in x]
only(v)
end
ERROR: Mutating arrays is not supported -- called setindex!(Array{Int64, 0}, ...) |
reducing a bit: julia> _, back = pullback(only, fill(1))
(1, Zygote.var"#60#61"{typeof(∂(only))}(∂(only)))
julia> @code_lowered back.back(1.)
CodeInfo(
1 ─ $(Expr(:meta, :inline))
│ %2 = Base.getfield(#self#, :t)
│ %3 = Base.getindex(%2, 2)
│ %4 = Base.getindex(%2, 1)
│ %5 = %3 !== 0x01
└── goto #4 if not %5
2 ─ goto #3
3 ─ phi_1_1 = nothing
└── goto #1
@ iterators.jl:1425 within `Pullback`
4 ─ %10 = (%4)(nothing)
│ %11 = Zygote.gradindex(%10, 2)
│ %12 = Zygote.tuple(nothing, %11)
└── return %12
)
julia> @code_warntype back.back(1.)
ERROR: BoundsError: attempt to access 2-element Vector{Core.Compiler.VarState} at index [3]
Stacktrace:
[1] setindex!
@ ./array.jl:966 [inlined]
[2] stupdate!(state::Nothing, changes::Core.Compiler.StateUpdate)
@ Core.Compiler ./compiler/typelattice.jl:380
[3] typeinf_local(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)
@ Core.Compiler ./compiler/abstractinterpretation.jl:2424
[4] typeinf_nocycle(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)
@ Core.Compiler ./compiler/abstractinterpretation.jl:2482
[5] _typeinf(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)
@ Core.Compiler ./compiler/typeinfer.jl:230
[6] typeinf(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)
@ Core.Compiler ./compiler/typeinfer.jl:213
[7] typeinf_frame(interp::Core.Compiler.NativeInterpreter, method::Method, atype::Any, sparams::Core.SimpleVector, run_optimizer::Bool)
@ Core.Compiler ./compiler/typeinfer.jl:909
[8] typeinf_code(interp::Core.Compiler.NativeInterpreter, method::Method, atype::Any, sparams::Core.SimpleVector, run_optimizer::Bool)
@ Core.Compiler ./compiler/typeinfer.jl:894
[9] code_typed_by_type(tt::Type; optimize::Bool, debuginfo::Symbol, world::UInt64, interp::Core.Compiler.NativeInterpreter)
@ Base ./reflection.jl:1280
[10] code_typed(f::Any, types::Any; optimize::Bool, debuginfo::Symbol, world::UInt64, interp::Core.Compiler.NativeInterpreter)
@ Base ./reflection.jl:1239
[11] code_warntype(io::Base.TTY, f::Any, t::Any; debuginfo::Symbol, optimize::Bool, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ InteractiveUtils ~/.julia/juliaup/julia-1.8.4+0.x64.linux.gnu/share/julia/stdlib/v1.8/InteractiveUtils/src/codeview.jl:64
[12] code_warntype(io::Base.TTY, f::Any, t::Any)
@ InteractiveUtils ~/.julia/juliaup/julia-1.8.4+0.x64.linux.gnu/share/julia/stdlib/v1.8/InteractiveUtils/src/codeview.jl:60
[13] code_warntype(f::Any, t::Any; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ InteractiveUtils ~/.julia/juliaup/julia-1.8.4+0.x64.linux.gnu/share/julia/stdlib/v1.8/InteractiveUtils/src/codeview.jl:142
[14] code_warntype(f::Any, t::Any)
@ InteractiveUtils ~/.julia/juliaup/julia-1.8.4+0.x64.linux.gnu/share/julia/stdlib/v1.8/InteractiveUtils/src/codeview.jl:142
[15] top-level scope
@ REPL[4]:1 |
As a workaround, and maybe a further hint, using using LinearAlgebra, Zygote
struct NoZeroArray
a::Vector{Float64}
b::Vector{Float64}
end
struct HasZeroArray
a::Vector{Float64}
b::Array{Float64, 0}
end
loss(h) = dot(h.a, h.a) + only(h.b) # crashes for 0-dim Array, works for 1-element-Vector
loss2(h) = dot(h.a, h.a) + h.b[] # works always
hz = HasZeroArray([1., 2., 3., 4., 5.], fill(3.8))
nz = NoZeroArray([1., 2., 3., 4., 5.], [3.8])
(grad,) = Zygote.gradient(loss, nz) # works
(grad,) = Zygote.gradient(loss, hz) # crashes
(grad,) = Zygote.gradient(loss2, nz) # works
(grad,) = Zygote.gradient(loss2, hz) # works also: julia> _, back = pullback(v -> v[], fill(1.0))
(1.0, Zygote.var"#75#76"{Zygote.Pullback{Tuple{var"#7#8", Array{Float64, 0}}, Tuple{Zygote.var"#2610#back#529"{Zygote.var"#539#541"{0, Float64, Array{Float64, 0}, Tuple{}}}}}}(∂(#7)))
julia> @code_lowered back.back(1.)
CodeInfo(
1 ─ $(Expr(:meta, :inline))
│ %2 = Base.getfield(#self#, :t)
│ %3 = Base.getindex(%2, 1)
│ @ REPL[5]:1 within `Pullback`
│ %4 = (%3)(Δ)
│ %5 = Zygote.gradindex(%4, 2)
│ %6 = Zygote.tuple(nothing, %5)
└── return %6
)
julia> @code_warntype back.back(1.)
MethodInstance for (::Zygote.Pullback{Tuple{var"#7#8", Array{Float64, 0}}, Tuple{Zygote.var"#2610#back#529"{Zygote.var"#539#541"{0, Float64, Array{Float64, 0}, Tuple{}}}}})(::Float64)
from (j::Zygote.Pullback)(Δ) @ Zygote ~/.julia/packages/Zygote/JeHtr/src/compiler/interface2.jl:105
Arguments
#self#::Zygote.Pullback{Tuple{var"#7#8", Array{Float64, 0}}, Tuple{Zygote.var"#2610#back#529"{Zygote.var"#539#541"{0, Float64, Array{Float64, 0}, Tuple{}}}}}
Δ::Float64
Body::Tuple{Nothing, Zygote.OneElement{Float64, 0, Tuple{}, Tuple{}}}
1 ─ $(Expr(:meta, :inline))
│ %2 = Base.getfield(#self#, :t)::Tuple{Zygote.var"#2610#back#529"{Zygote.var"#539#541"{0, Float64, Array{Float64, 0}, Tuple{}}}}
│ %3 = Base.getindex(%2, 1)::Zygote.var"#2610#back#529"{Zygote.var"#539#541"{0, Float64, Array{Float64, 0}, Tuple{}}}
│ %4 = (%3)(Δ)::Tuple{Nothing, Zygote.OneElement{Float64, 0, Tuple{}, Tuple{}}}
│ %5 = Zygote.gradindex(%4, 2)::Zygote.OneElement{Float64, 0, Tuple{}, Tuple{}}
│ %6 = Zygote.tuple(nothing, %5)::Tuple{Nothing, Zygote.OneElement{Float64, 0, Tuple{}, Tuple{}}}
└── return %6 |
Specifying type for list comprehension sometimes causes an unexpected runtime error that sometimes crashes Julia. This is a heightened version of #1343 because it breaks Julia rather than throwing an error. Reproduction is a bit finicky (probably because the Julia runtime is broken) but I consistently get a dire error of some sort when I run this as the first thing in a REPL session after loading Zygote. The error is present on both 1.8.4 and 1.9.0-alpha1.
Full MWE:
The text was updated successfully, but these errors were encountered: