Plugin system
While GraphPPL
is backend agnostic, specific inference backends might require additional functionality or data saved in nodes. To accommodate these needs, GraphPPL
exposes a plugin system that allows users to extend the functionality of the package. Plugins allow the core package to remain lightweight, as well as allowing backend-specific functionality. For example, a node does not need to know by which line of code it was originally created. As an example, for debugging purposes, it might be useful to save this information in the node. GraphPPL
implements a plugin that, when enabled on a model, saves this information in every node. This allows for useful debugging, while switching this functionality off when not needed saves the memory footprint of the model.
Creating a plugin
A plugin is a structure that contains a set of functions that are called at specific points in the model creation process. The plugin is implemented with the GraphPPL.preprocess_plugin
and GraphPPL.postprocess_plugin
functions:
GraphPPL.preprocess_plugin
— Functionpreprocess_plugin(plugin, model, context, label, nodedata, options)
Call a plugin specific logic for a node with label and nodedata upon their creation.
GraphPPL.postprocess_plugin
— Functionpostprocess_plugin(plugin, model)
Calls a plugin specific logic after the model has been created. By default does nothing.
Within these functions, the plugin can modify the model, add new nodes, or modify existing nodes. Also, additional data can be passed to nodes in the preprocess_plugin
function.
Available plugins
The following plugins are available by default in GraphPPL
:
GraphPPL.VariationalConstraintsPlugin
: adds constraints to the model that are used in variational inference.GraphPPL.MetaPlugin
: adds arbitrary metadata to nodes in the model.GraphPPL.NodeCreatedByPlugin
: adds information about the line of code that created the node.GraphPPL.NodeTagPlugin
: allows attaching atag
to factor nodes for later inspection.GraphPPL.NodeIdPlugin
: allows attaching a uniqueid
to factor nodes for later inspection.
Using a plugin
To use a plugin, call the with_plugins
function when constructing a model:
GraphPPL.with_plugins
— Functionwith_plugins(generator::ModelGenerator, plugins::PluginsCollection)
Attaches the plugins
to the generator
. For example:
plugins = GraphPPL.PluginsCollection(GraphPPL.NodeCreatedByPlugin())
new_generator = GraphPPL.with_plugins(generator, plugins)
The PluginsCollection
is a collection of plugins that will be applied to the model. The order of plugins in the collection is important, as the preprocess_plugin
and postprocess_plugin
functions are called in the order of the plugins in the collection.
Reference
GraphPPL.UnknownPluginType
— TypeA trait object for unknown plugins. Such plugins cannot be added to the collection, unless they implement the plugin_type
method.
GraphPPL.plugin_type
— FunctionChecks the type of the plugin and returns the corresponding trait object.
GraphPPL.PluginsCollection
— TypeA collection of plugins.
GraphPPL.add_plugin
— Functionadd_plugin(collection::PluginsCollection, plugin)
Adds a plugin to the collection. The plugin must be of a type that is supported by the collection.
GraphPPL.VariableNodePlugin
— TypeA trait object for plugins that add extra functionality for variable nodes.
GraphPPL.FactorNodePlugin
— TypeA trait object for plugins that add extra functionality for factor nodes.
GraphPPL.FactorAndVariableNodesPlugin
— TypeA trait object for plugins that add extra functionality both for factor and variable nodes.