JuliaIO / BSON.jl

Other
158 stars 39 forks source link

world age issue in loading closure #69

Open CarloLucibello opened 4 years ago

CarloLucibello commented 4 years ago

While working at https://github.com/FluxML/model-zoo/pull/209, I encountered the following problem when loading a saved closure within the function train:

julia> import BSON

julia> function train()
           model = x -> x
           BSON.@save "model.bson" model    
           model = BSON.load("model.bson")[:model]
           ŷ = model(1)
       end
train (generic function with 1 method)

julia> train()
ERROR: MethodError: no method matching (::BSON.__deserialized_types__.var"#94#95")(::Int64)
The applicable method may be too new: running in world age 27203, while current world is 27204.
Closest candidates are:
  #94(::Any) at REPL[73]:2 (method too new to be called from this world context.)
Stacktrace:
 [1] train() at ./REPL[73]:5
 [2] top-level scope at REPL[74]:1

Notice that if I just execute the body of the function in REPL, everything works fine:

julia> import BSON

julia> model = x -> x
#96 (generic function with 1 method)

julia> BSON.@save "model.bson" model

julia> model = BSON.load("model.bson")[:model]
#96 (generic function with 1 method)

julia> ŷ = model(1)
1
MikeInnes commented 4 years ago

This is part of how Julia works:

julia> function test()
         f = eval(:(x -> x))
         f(1)
       end
test (generic function with 1 method)

julia> test()
ERROR: MethodError: no method matching (::var"#3#4")(::Int64)
The applicable method may be too new: running in world age 26764, while current world is 26765.

So I'm not sure there's much we can do about it. I'd suggest that this is a bad code pattern and one should just stick to loading bson files at the toplevel.

If you really need it, you can use invokelatest.

racinmat commented 3 years ago

I had similar problem too, I solved it by modifying the function I want to serialize in a way that all used variables are used as the input, so the function does not depend on the outer context. Then it works. Although it's a bit annoying, it's definitely less fragile.