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

Make traces more reliably (de)serializable #129

Open
marcoct opened this issue Sep 30, 2019 · 1 comment
Open

Make traces more reliably (de)serializable #129

marcoct opened this issue Sep 30, 2019 · 1 comment
Assignees
Labels
enhancement New feature or request

Comments

@marcoct
Copy link
Collaborator

marcoct commented Sep 30, 2019

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.

@marcoct marcoct added the enhancement New feature or request label Sep 30, 2019
@marcoct
Copy link
Collaborator Author

marcoct commented Feb 5, 2021

Here is a version that works when there is no non-addressable (aka 'untraced') randomness (see https://www.gen.dev/dev/ref/gfi/#Mathematical-concepts-1):

import Serialization
import Gen
function save_trace(trace, filename)
	choices = Gen.DynamicChoiceMap(get_choices(trace))
        args = Gen.get_args(trace)
        serializable_trace = (args, choices)
        Serialization.serialize(filename, serializable_trace)
	nothing
end
function load_trace(my_model, filename)
        (args, choices) = Serialization.deserialize(filename)
        trace, = Gen.generate(my_model, args, choices)
	return trace
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants