JLD.jl icon indicating copy to clipboard operation
JLD.jl copied to clipboard

Broken function support in julia-0.5 (all functions are generic)

Open timholy opened this issue 8 years ago • 15 comments

Not sure how we should handle this.

timholy avatar Feb 28 '16 13:02 timholy

Are there any workarounds in the meantime?

jeff-regier avatar Mar 05 '16 19:03 jeff-regier

If you stay on the stable release version of Julia, this shouldn't be an issue.

StefanKarpinski avatar Mar 06 '16 18:03 StefanKarpinski

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.

jeff-regier avatar Mar 06 '16 23:03 jeff-regier

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.

StefanKarpinski avatar Mar 07 '16 02:03 StefanKarpinski

@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)

timholy avatar Mar 07 '16 16:03 timholy

Are there any workarounds for this? Will v0.6 change anything about the internals to make this easier/doable?

ChrisRackauckas avatar Dec 28 '16 05:12 ChrisRackauckas

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.

MikeInnes avatar Feb 17 '17 16:02 MikeInnes

Still getting "ERROR: UndefVarError: isgeneric not defined" in Julia 1.1.1.

denizyuret avatar Aug 17 '19 14:08 denizyuret

Same here. Anyone have any idea?

hjkim1304 avatar Aug 19 '19 21:08 hjkim1304

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

hjkim1304 avatar Aug 19 '19 21:08 hjkim1304

It seems like the solution would be to delete the call to isgeneric with the value true.

StefanKarpinski avatar Aug 20 '19 16:08 StefanKarpinski

I'm running in to the same bug in Julia 1.5 when trying to save a Makie.Node{MyCustomType}

xtalax avatar Mar 04 '21 17:03 xtalax

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 ?

sylvaticus avatar Aug 28 '22 13:08 sylvaticus

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

benoitseron avatar Dec 09 '22 09:12 benoitseron

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

mkitti avatar Dec 09 '22 23:12 mkitti