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

Updating zygote errors? MethodError: no method matching getindex(::Nothing, ::String) #3

Closed
chriselrod opened this issue Aug 15, 2018 · 1 comment

Comments

@chriselrod
Copy link

(v1.0) pkg> up
  Updating registry at `~/.julia/registries/General`
  Updating git-repo `https://github.com/JuliaRegistries/General.git`
  Updating git-repo `https://github.com/FluxML/Zygote.jl`
 Resolving package versions...
  Updating `~/.julia/environments/v1.0/Project.toml`
 [no changes]
  Updating `~/.julia/environments/v1.0/Manifest.toml`
 [no changes]
ERROR: MethodError: no method matching getindex(::Nothing, ::String)
Stacktrace:
 [1] #build_versions#45(::Bool, ::Function, ::Pkg.Types.Context, ::Array{Base.UUID,1}) at /home/chris/Documents/prog/julia-dev/usr/share/julia/stdlib/v1.0/Pkg/src/Operations.jl:1016
 [2] build_versions at /home/chris/Documents/prog/julia-dev/usr/share/julia/stdlib/v1.0/Pkg/src/Operations.jl:1005 [inlined]
 [3] up(::Pkg.Types.Context, ::Array{Pkg.Types.PackageSpec,1}) at /home/chris/Documents/prog/julia-dev/usr/share/julia/stdlib/v1.0/Pkg/src/Operations.jl:1209
 [4] #up#31(::Pkg.Types.UpgradeLevel, ::Pkg.Types.PackageMode, ::Bool, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::Pkg.Types.Context, ::Array{Pkg.Types.PackageSpec,1}) at /home/chris/Documents/prog/julia-dev/usr/share/julia/stdlib/v1.0/Pkg/src/API.jl:184
 [5] up at /home/chris/Documents/prog/julia-dev/usr/share/julia/stdlib/v1.0/Pkg/src/API.jl:158 [inlined]
 [6] do_up!(::Dict{Symbol,Any}, ::Array{Pkg.Types.PackageSpec,1}, ::Dict{Symbol,Any}) at /home/chris/Documents/prog/julia-dev/usr/share/julia/stdlib/v1.0/Pkg/src/REPLMode.jl:610
 [7] #invokelatest#1(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::Any, ::Any, ::Vararg{Any,N} where N) at ./essentials.jl:686
 [8] invokelatest(::Any, ::Any, ::Vararg{Any,N} where N) at ./essentials.jl:685
 [9] do_cmd!(::Pkg.REPLMode.PkgCommand, ::REPL.LineEditREPL) at /home/chris/Documents/prog/julia-dev/usr/share/julia/stdlib/v1.0/Pkg/src/REPLMode.jl:542
 [10] #do_cmd#30(::Bool, ::Function, ::REPL.LineEditREPL, ::String) at /home/chris/Documents/prog/julia-dev/usr/share/julia/stdlib/v1.0/Pkg/src/REPLMode.jl:507
 [11] do_cmd at /home/chris/Documents/prog/julia-dev/usr/share/julia/stdlib/v1.0/Pkg/src/REPLMode.jl:503 [inlined]
 [12] (::getfield(Pkg.REPLMode, Symbol("##41#44")){REPL.LineEditREPL,REPL.LineEdit.Prompt})(::REPL.LineEdit.MIState, ::Base.GenericIOBuffer{Array{UInt8,1}}, ::Bool) at /home/chris/Documents/prog/julia-dev/usr/share/julia/stdlib/v1.0/Pkg/src/REPLMode.jl:842
 [13] #invokelatest#1 at ./essentials.jl:686 [inlined]
 [14] invokelatest at ./essentials.jl:685 [inlined]
 [15] run_interface(::REPL.Terminals.TextTerminal, ::REPL.LineEdit.ModalInterface, ::REPL.LineEdit.MIState) at /home/chris/Documents/prog/julia-dev/usr/share/julia/stdlib/v1.0/REPL/src/LineEdit.jl:2261
 [16] run_frontend(::REPL.LineEditREPL, ::REPL.REPLBackendRef) at /home/chris/Documents/prog/julia-dev/usr/share/julia/stdlib/v1.0/REPL/src/REPL.jl:1029
 [17] run_repl(::REPL.AbstractREPL, ::Any) at /home/chris/Documents/prog/julia-dev/usr/share/julia/stdlib/v1.0/REPL/src/REPL.jl:191
 [18] (::getfield(Base, Symbol("##720#722")){Bool,Bool,Bool,Bool})(::Module) at ./logging.jl:311
 [19] #invokelatest#1 at ./essentials.jl:686 [inlined]
 [20] invokelatest at ./essentials.jl:685 [inlined]
 [21] macro expansion at ./logging.jl:308 [inlined]
 [22] run_main_repl(::Bool, ::Bool, ::Bool, ::Bool, ::Bool) at ./client.jl:330
 [23] exec_options(::Base.JLOptions) at ./client.jl:242
 [24] _start() at ./client.jl:421
@MikeInnes
Copy link
Member

Thanks for the report, but although Zygote does break a lot of things I don't expect this to be my fault :) Please can you report this to Pkg.jl.

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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants