JLD.jl
JLD.jl copied to clipboard
Broken function support in julia-0.5 (all functions are generic)
Not sure how we should handle this.
Are there any workarounds in the meantime?
If you stay on the stable release version of Julia, this shouldn't be an issue.
I need threading, unfortunately.
On Sun, Mar 6, 2016 at 10:21 AM Stefan Karpinski [email protected] wrote:
If you stay on the stable release version of Julia, this shouldn't be an issue.
— Reply to this email directly or view it on GitHub https://github.com/JuliaLang/JLD.jl/issues/57#issuecomment-192954412.
IIRC, threading was merged before jb/functions, which caused this breakage, so if you checkout the commit right before jb/functions was merged, that might do the trick for you.
@jeff-regier, if you're willing to do some work, the best workaround would be to implement it. I can't guarantee it's even possible, but if there's only one method defined for the object, then by poking around long enough you might be able to grab the AST.
Here's a head start for you:
f = x->x^2
m = first(methods(f))
fieldnames(m)
Are there any workarounds for this? Will v0.6 change anything about the internals to make this easier/doable?
We shouldn't be grabbing ASTs here, at least in the basic case. Functions are identical to singleton types and should be treated identically. That should make the patch fairly straightforward.
Closures defined in the repl are trickier as the type is obviously transient across sessions. I think it would be ok to not support that case, but we could also take inspiration from Julia serialiser if it does something smarter.
Still getting "ERROR: UndefVarError: isgeneric not defined" in Julia 1.1.1.
Same here. Anyone have any idea?
This is basically the error message.
LoadError: UndefVarError: isgeneric not defined func2expr(::Function) at JLD.jl:845 JLD.AnonymousFunctionSerializer(::Function) at JLD.jl:852 writeas(::Function) at JLD.jl:855 #write#17(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::JLD.JldFile, ::String, ::Function, ::JLD.JldWriteSession) at JLD.jl:514 write(::JLD.JldFile, ::String, ::Function, ::JLD.JldWriteSession) at JLD.jl:514 top-level scope at JLD.jl:1158
It seems like the solution would be to delete the call to isgeneric
with the value true
.
I'm running in to the same bug in Julia 1.5 when trying to save a Makie.Node{MyCustomType}
Hello, just one example where this problem shows up:
julia> using JLD
julia> struct Foo
x::Int64
f::Function
end
julia> foo = Foo(1,maximum)
Foo(1, maximum)
julia> jldopen("test.jld", "w") do file
write(file, "fooj", foo)
end
ERROR: UndefVarError: isgeneric not defined
Stacktrace:
[1] func2expr(fun::Function)
@ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:882
[2] JLD.AnonymousFunctionSerializer(fun::Function)
@ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:889
[...]
Is there any workaround possible if you need to save objects whose type includes a function as field ?
I am still experiencing this issue, is there any workaround?
Example of the problem:
using JLD
f(x) = x
save("test.jld", "f", f)
Output:
Error encountered while save FileIO.File{FileIO.DataFormat{:JLD}, String}("test.jld").
Fatal error:
ERROR: UndefVarError: isgeneric not defined
Stacktrace:
[1] func2expr(fun::Function)
@ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:882
[2] JLD.AnonymousFunctionSerializer(fun::Function)
@ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:889
[3] writeas(fun::Function)
@ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:892
[4] write(parent::JLD.JldFile, name::String, data::Function, wsession::JLD.JldWriteSession; kargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:543
[5] write(parent::JLD.JldFile, name::String, data::Function, wsession::JLD.JldWriteSession)
@ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:543
[6] (::JLD.var"#41#42"{String, typeof(f), Tuple{}})(file::JLD.JldFile)
@ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:1262
[7] jldopen(::JLD.var"#41#42"{String, typeof(f), Tuple{}}, ::String, ::Vararg{String}; kws::Base.Pairs{Symbol, Bool, Tuple{Symbol, Symbol}, NamedTuple{(:compatible, :compress), Tuple{Bool, Bool}}})
@ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:262
[8] #fileio_save#40
@ ~/.julia/packages/JLD/6OyJe/src/JLD.jl:1260 [inlined]
[9] fileio_save(::FileIO.File{FileIO.DataFormat{:JLD}, String}, ::String, ::Function)
@ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:1256
[10] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::FileIO.Formatted, ::String, ::Vararg{Any}; options::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:219
[11] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::FileIO.Formatted, ::String, ::Function)
@ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:196
[12] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::Symbol, ::String, ::String, ::Vararg{Any}; options::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:185
[13] action
@ ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:185 [inlined]
[14] #save#20
@ ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:129 [inlined]
[15] save(::String, ::String, ::Function)
@ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:125
[16] top-level scope
@ ~/Documents/thesis/one_loop_sampling/code/validation.jl:36
Stacktrace:
[1] handle_error(e::UndefVarError, q::Base.PkgId, bt::Vector{Union{Ptr{Nothing}, Base.InterpreterIP}})
@ FileIO ~/.julia/packages/FileIO/DtNtF/src/error_handling.jl:61
[2] handle_exceptions(exceptions::Vector{Tuple{Any, Union{Base.PkgId, Module}, Vector}}, action::String)
@ FileIO ~/.julia/packages/FileIO/DtNtF/src/error_handling.jl:56
[3] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::FileIO.Formatted, ::String, ::Vararg{Any}; options::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:228
[4] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::FileIO.Formatted, ::String, ::Function)
@ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:196
[5] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::Symbol, ::String, ::String, ::Vararg{Any}; options::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:185
[6] action
@ ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:185 [inlined]
[7] #save#20
@ ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:129 [inlined]
[8] save(::String, ::String, ::Function)
@ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:125
[9] top-level scope
@ ~/Documents/thesis/one_loop_sampling/code/validation.jl:36
You could use Serialization: https://docs.julialang.org/en/v1/stdlib/Serialization/#Serialization.serialize
julia> using Serialization
julia> io = IOBuffer()
IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)
julia> serialize(io, x->x^2)
julia> bytes = take!(io)
313-element Vector{UInt8}:
0x37
0x4a
0x4c
0x11
0x04
0x00
0x00
0x00
0x34
0x33
0x13
0x04
0x00
0x00
0x00
0x00
0x00
0x00
0x00
0x01
0x06
0x23
0x31
⋮
0x00
0x09
0xff
0xff
0xff
0xff
0xff
0xff
0xff
0xff
0x4c
0x4c
0x4c
0x4c
0x03
0x00
0x03
0x00
0x4e
0x4e
0xe1
0x29
julia> io2 = IOBuffer(bytes)
IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=313, maxsize=Inf, ptr=1, mark=-1)
julia> g = deserialize(io2)
#11 (generic function with 1 method)
julia> g(5)
25