-
-
Notifications
You must be signed in to change notification settings - Fork 210
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
Using Zygote failed on Julia v1.0.0, MacOS #7
Comments
Do you still get this reliably? Seems like it's probably not related to Zygote itself. |
Forget it, this seems to be the problem of my dirty General Registry. |
Keno
added a commit
that referenced
this issue
Feb 24, 2019
Right now Zygote inserts stacks whenever it needs to use an ssa value not defined in the first basic block. This is of course unnecessary. The condition for needing stacks is that the basic block that defines it is self-reachable (i.e. in a loop). Otherwise, we can simply insert phi nodes to thread the desired SSA value through to the exit block (we don't need to do anything in the adjoint, since the reversal of the CFG ensures dominance). Removing stacks allows for both more efficient code generation and enables higher order auto-diff (since we use control flow in Zygote, but can't handle differentiating code that contains stacks). The headline example is something like the following: ``` function foo(b, x) if b sin(x) else cos(x) end end ``` Then looking at `@code_typed derivative(x->foo(true, x), 1.0)`, we get: Before: ``` CodeInfo( 1 ── %1 = $(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Int8,1}, svec(Any, Int64), :(:ccall), 2, Array{Int8,1}, 0, 0))::Array{Int8,1} │ %2 = $(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Any,1}, svec(Any, Int64), :(:ccall), 2, Array{Any,1}, 0, 0))::Array{Any,1} │ %3 = $(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Any,1}, svec(Any, Int64), :(:ccall), 2, Array{Any,1}, 0, 0))::Array{Any,1} │ %4 = Base.sin::typeof(sin) │ invoke %4(_3::Float64)::Float64 │ %6 = %new(##334#335{Float64}, x)::##334#335{Float64} │ %7 = %new(##758#back#336{##334#335{Float64}}, %6)::##758#back#336{##334#335{Float64}} [snip] 23 ─ %52 = invoke %47(1::Int8)::Tuple{Nothing,Nothing,Any} │ %53 = Base.getfield(%52, 3, true)::Any └─── goto #24 24 ─ return %53 ) => Any ``` After: ``` CodeInfo( 1 ─ %1 = Base.sin::typeof(sin) │ invoke %1(_3::Float64)::Float64 │ %3 = Core.Intrinsics.not_int(true)::Bool └── goto #3 if not %3 2 ─ invoke Zygote.notnothing(nothing::Nothing)::Union{} └── $(Expr(:unreachable))::Union{} 3 ┄ %7 = invoke Zygote.cos(_3::Float64)::Float64 │ %8 = Base.mul_float(1.0, %7)::Float64 └── goto #4 4 ─ goto #5 5 ─ goto #6 6 ─ goto #7 7 ─ return %8 ) => Float64 ``` Which is essentially perfect (there's a bit of junk left over, but LLVM can take care of that. The only thing that doesn't get removed is the useless invocation of `sin`, but that's a separate and known issue).
Keno
added a commit
that referenced
this issue
Mar 6, 2019
Right now Zygote inserts stacks whenever it needs to use an ssa value not defined in the first basic block. This is of course unnecessary. The condition for needing stacks is that the basic block that defines it is self-reachable (i.e. in a loop). Otherwise, we can simply insert phi nodes to thread the desired SSA value through to the exit block (we don't need to do anything in the adjoint, since the reversal of the CFG ensures dominance). Removing stacks allows for both more efficient code generation and enables higher order auto-diff (since we use control flow in Zygote, but can't handle differentiating code that contains stacks). The headline example is something like the following: ``` function foo(b, x) if b sin(x) else cos(x) end end ``` Then looking at `@code_typed derivative(x->foo(true, x), 1.0)`, we get: Before: ``` CodeInfo( 1 ── %1 = $(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Int8,1}, svec(Any, Int64), :(:ccall), 2, Array{Int8,1}, 0, 0))::Array{Int8,1} │ %2 = $(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Any,1}, svec(Any, Int64), :(:ccall), 2, Array{Any,1}, 0, 0))::Array{Any,1} │ %3 = $(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Any,1}, svec(Any, Int64), :(:ccall), 2, Array{Any,1}, 0, 0))::Array{Any,1} │ %4 = Base.sin::typeof(sin) │ invoke %4(_3::Float64)::Float64 │ %6 = %new(##334#335{Float64}, x)::##334#335{Float64} │ %7 = %new(##758#back#336{##334#335{Float64}}, %6)::##758#back#336{##334#335{Float64}} [snip] 23 ─ %52 = invoke %47(1::Int8)::Tuple{Nothing,Nothing,Any} │ %53 = Base.getfield(%52, 3, true)::Any └─── goto #24 24 ─ return %53 ) => Any ``` After: ``` CodeInfo( 1 ─ %1 = Base.sin::typeof(sin) │ invoke %1(_3::Float64)::Float64 │ %3 = Core.Intrinsics.not_int(true)::Bool └── goto #3 if not %3 2 ─ invoke Zygote.notnothing(nothing::Nothing)::Union{} └── $(Expr(:unreachable))::Union{} 3 ┄ %7 = invoke Zygote.cos(_3::Float64)::Float64 │ %8 = Base.mul_float(1.0, %7)::Float64 └── goto #4 4 ─ goto #5 5 ─ goto #6 6 ─ goto #7 7 ─ return %8 ) => Float64 ``` Which is essentially perfect (there's a bit of junk left over, but LLVM can take care of that. The only thing that doesn't get removed is the useless invocation of `sin`, but that's a separate and known issue).
bors bot
added a commit
that referenced
this issue
Aug 3, 2020
751: Fix FFT type promotions r=CarloLucibello a=wkearn I ran into an issue with type promotions while using `Conv` layers in Flux when I tried to run model output through FFTs. I tracked it down to the definitions of the adjoints for the various `fft` variants. The 1/N factors needed in the `irfft` adjoints automatically promoted `Float32` arrays to `Float64` arrays, which then caused the error when propagated back through the chain. A minimal example is included below. This pull request just changes all those multiplications by 1/N into divisions by N, which prevents the promotion. I also added a few tests that assert that the gradients are the right types. The tests with `irfft(x,dims)` throw an error that is not related to the type promotion, so I commented those out. ```julia x = randn(Float32,16,1,1) m = Conv((5,),1=>1,relu,pad=SamePad()) loss(x) = sum(abs2,irfft(rfft(m(x)),16)) gradient(()->loss(x),Flux.params(m)) ┌ Warning: Slow fallback implementation invoked for ∇conv_data! You probably don't want this; check your datatypes. │ yT = AbstractFloat │ T1 = AbstractFloat │ T2 = Float32 └ @ NNlib C:\Users\wkearney\.julia\packages\NNlib\sSn9M\src\conv.jl:206 ERROR: UndefRefError: access to undefined reference Stacktrace: [1] getindex at .\array.jl:745 [inlined] [2] #conv_direct!#149(::Float64, ::Bool, ::typeof(NNlib.conv_direct!), ::Array{AbstractFloat,5}, ::Array{AbstractFloat,5}, ::Array{Float32,5}, ::DenseConvDims{3,(5, 1, 1),1,1,(1, 1, 1),(2, 2, 0, 0, 0, 0),(1, 1, 1),false}) at C:\Users\wkearney\.julia\packages\NNlib\sSn9M\src\impl\conv_direct.jl:98 [3] (::NNlib.var"#kw##conv_direct!")(::NamedTuple{(:alpha, :beta),Tuple{Float64,Bool}}, ::typeof(NNlib.conv_direct!), ::Array{AbstractFloat,5}, ::Array{AbstractFloat,5}, ::Array{Float32,5}, ::DenseConvDims{3,(5, 1, 1),1,1,(1, 1, 1),(2, 2, 0, 0, 0, 0),(1, 1, 1),false}) at .\none:0 [4] #∇conv_data_direct!#152(::Float64, ::Bool, ::typeof(NNlib.∇conv_data_direct!), ::Array{AbstractFloat,5}, ::Array{AbstractFloat,5}, ::Array{Float32,5}, ::DenseConvDims{3,(5, 1, 1),1,1,(1, 1, 1),(2, 2, 0, 0, 0, 0),(1, 1, 1),false}) at C:\Users\wkearney\.julia\packages\NNlib\sSn9M\src\impl\conv_direct.jl:163 [5] ∇conv_data_direct! at C:\Users\wkearney\.julia\packages\NNlib\sSn9M\src\impl\conv_direct.jl:158 [inlined] [6] #∇conv_data!#106(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(∇conv_data!), ::Array{AbstractFloat,5}, ::Array{AbstractFloat,5}, ::Array{Float32,5}, ::DenseConvDims{3,(5, 1, 1),1,1,(1, 1, 1),(2, 2, 0, 0, 0, 0),(1, 1, 1),false}) at C:\Users\wkearney\.julia\packages\NNlib\sSn9M\src\conv.jl:208 [7] ∇conv_data!(::Array{AbstractFloat,5}, ::Array{AbstractFloat,5}, ::Array{Float32,5}, ::DenseConvDims{3,(5, 1, 1),1,1,(1, 1, 1),(2, 2, 0, 0, 0, 0),(1, 1, 1),false}) at C:\Users\wkearney\.julia\packages\NNlib\sSn9M\src\conv.jl:206 [8] #∇conv_data!#67(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(∇conv_data!), ::Array{AbstractFloat,3}, ::Array{AbstractFloat,3}, ::Array{Float32,3}, ::DenseConvDims{1,(5,),1,1,(1,),(2, 2),(1,),false}) at C:\Users\wkearney\.julia\packages\NNlib\sSn9M\src\conv.jl:148 [9] ∇conv_data! at C:\Users\wkearney\.julia\packages\NNlib\sSn9M\src\conv.jl:148 [inlined] [10] #∇conv_data#39 at C:\Users\wkearney\.julia\packages\NNlib\sSn9M\src\conv.jl:103 [inlined] [11] ∇conv_data at C:\Users\wkearney\.julia\packages\NNlib\sSn9M\src\conv.jl:101 [inlined] [12] #1241 at C:\Users\wkearney\.julia\dev\Zygote\src\lib\nnlib.jl:42 [inlined] [13] (::Zygote.var"#4101#back#1243"{Zygote.var"#1241#1242"{Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},Array{Float32,3},Array{Float32,3},DenseConvDims{1,(5,),1,1,(1,),(2, 2),(1,),false}}})(::Array{AbstractFloat,3}) at C:\Users\wkearney\.julia\packages\ZygoteRules\6nssF\src\adjoint.jl:49 [14] Conv at C:\Users\wkearney\.julia\packages\Flux\IjMZL\src\layers\conv.jl:147 [inlined] [15] (::typeof(∂(λ)))(::Array{Float64,3}) at C:\Users\wkearney\.julia\dev\Zygote\src\compiler\interface2.jl:0 [16] loss at .\REPL[6]:1 [inlined] [17] (::typeof(∂(loss)))(::Float32) at C:\Users\wkearney\.julia\dev\Zygote\src\compiler\interface2.jl:0 [18] #7 at .\REPL[8]:1 [inlined] [19] (::typeof(∂(#7)))(::Float32) at C:\Users\wkearney\.julia\dev\Zygote\src\compiler\interface2.jl:0 [20] (::Zygote.var"#56#57"{Params,Zygote.Context,typeof(∂(#7))})(::Float32) at C:\Users\wkearney\.julia\dev\Zygote\src\compiler\interface.jl:177 [21] gradient(::Function, ::Params) at C:\Users\wkearney\.julia\dev\Zygote\src\compiler\interface.jl:54 ``` Co-authored-by: William Kearney <William.Kearney.ctr@nrlssc.navy.mil>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The following procedure works on Ubuntu 16.04, Julia v1.0.0.
But fails on MacOS 10.13.6, Julia v1.0.0
The text was updated successfully, but these errors were encountered: