You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Traces of generative functions aren't generally reliably (de)serializable because they rely on anonymous functions (which have gensym'd names), and in some cases use generated types that make heavy use of gensyms. This means that the environment the code is deserialized into needs to exactly match the environment that it was serialized from in terms of use of gensyms, which is not reliably the case.
Note that the author of a generative function can always write custom (de)serialization code for their traces, and this is the recommended approach at the moment. Also, there is no general guarantee that the data types used as arguments, return values, or random choices inside a trace are themselves reliably serializable in a generic way.
One reason that traces of dynamic modeling language generative functions (https://github.com/probcomp/Gen/blob/master/src/dynamic/trace.jl) are not reliably (de)serializable is that they refer to the generative function that produced them, which in turn refers to an anonymous Julia function, whose name is a gensym. (Traces of static modeling language generative functions are likely less reliably serializable than dynamic traces, because they involve much more generated code.)
Gen could provide a SerializableTrace data type, which would be something like the trace of a dynamic modeling language function, but would be more reliably (de)serializable (using whatever means the user wants e.g. Julia's serialize JLD2 etc.). This new data type would not include a reference to the source generative function, avoiding the particular gensym issue above for dynamic traces. Each generic trace type would implement the Gen.to_serializable_trace(::Trace) function, and a Gen.from_serializable_trace(::SerializableTrace, ::GenerativeFunction). The serializable version of the trace does not need to store any cached values, as long as they can be reconstructed deterministically during from_serializable_trace.
Note that care should be taken with respect to the interaction with untraced randomness. An implementation of from_serializable_trace that ran Gen.generate on a choice trie would not produce the entire trace. That is, storing the arguments and choice trie alone in the serialized trace is not sufficient (e.g. the score could change).
Also, this should be implemented in a compositional way, so that each generative function type (including user-defined types) has its own implementation of to_serializable_trace and from_serializable_trace, and the implementations of these for built-in types should recursively call the same functions on their subtraces.
The text was updated successfully, but these errors were encountered:
Traces of generative functions aren't generally reliably (de)serializable because they rely on anonymous functions (which have gensym'd names), and in some cases use generated types that make heavy use of gensyms. This means that the environment the code is deserialized into needs to exactly match the environment that it was serialized from in terms of use of gensyms, which is not reliably the case.
Note that the author of a generative function can always write custom (de)serialization code for their traces, and this is the recommended approach at the moment. Also, there is no general guarantee that the data types used as arguments, return values, or random choices inside a trace are themselves reliably serializable in a generic way.
One reason that traces of dynamic modeling language generative functions (https://github.com/probcomp/Gen/blob/master/src/dynamic/trace.jl) are not reliably (de)serializable is that they refer to the generative function that produced them, which in turn refers to an anonymous Julia function, whose name is a gensym. (Traces of static modeling language generative functions are likely less reliably serializable than dynamic traces, because they involve much more generated code.)
Gen could provide a
SerializableTrace
data type, which would be something like the trace of a dynamic modeling language function, but would be more reliably (de)serializable (using whatever means the user wants e.g. Julia'sserialize
JLD2 etc.). This new data type would not include a reference to the source generative function, avoiding the particular gensym issue above for dynamic traces. Each generic trace type would implement theGen.to_serializable_trace(::Trace)
function, and aGen.from_serializable_trace(::SerializableTrace, ::GenerativeFunction)
. The serializable version of the trace does not need to store any cached values, as long as they can be reconstructed deterministically duringfrom_serializable_trace
.Note that care should be taken with respect to the interaction with untraced randomness. An implementation of
from_serializable_trace
that ranGen.generate
on a choice trie would not produce the entire trace. That is, storing the arguments and choice trie alone in the serialized trace is not sufficient (e.g. the score could change).Also, this should be implemented in a compositional way, so that each generative function type (including user-defined types) has its own implementation of
to_serializable_trace
andfrom_serializable_trace
, and the implementations of these for built-in types should recursively call the same functions on their subtraces.The text was updated successfully, but these errors were encountered: