Documentation ¶
Overview ¶
Package context defines the Context and Variable types: Context organizes variablesMap and variablesMap manages the storage of values typically used as variablesMap.
Index ¶
- Constants
- func EscapeScopeName(scopeName string) string
- func GetGraphParamOr[T any](ctx *Context, g *Graph, key string, defaultValue T) T
- func GetParamOr[T any](ctx *Context, key string, defaultValue T) T
- func VariableParameterNameFromScopeAndName(scope, name string) string
- func VariableScopeAndNameFromParameterName(parameterName string) (scope, name string)
- type Context
- func (ctx *Context) BuildTrainableVariablesGradientsGraph(loss *Node) []*Node
- func (ctx *Context) Checked(checked bool) *Context
- func (ctx *Context) DeleteVariable(scope, name string) bool
- func (ctx *Context) DeleteVariablesInScope()
- func (ctx *Context) EnumerateGraphParams(g *Graph, fn func(scope, key string, value any))
- func (ctx *Context) EnumerateParams(fn func(scope, key string, value any))
- func (ctx *Context) EnumerateVariables(fn func(v *Variable))
- func (ctx *Context) EnumerateVariablesInScope(fn func(v *Variable))
- func (ctx *Context) ExecPopulateGraphParamsMap(g *Graph, params graph.ParamsMap)
- func (ctx *Context) ExecSetVariablesInParams(params graph.ParamsMap, g *Graph)
- func (ctx *Context) GetGraphParam(g *Graph, key string) (value any, found bool)
- func (ctx *Context) GetParam(key string) (value any, found bool)
- func (ctx *Context) In(scope string) *Context
- func (ctx *Context) InAbsPath(scopePath string) *Context
- func (ctx *Context) InitializeVariables()
- func (ctx *Context) InspectVariable(scope, name string) *Variable
- func (ctx *Context) InspectVariableIfLoaded(scope, name string) *Variable
- func (ctx *Context) InspectVariableInScope(name string) *Variable
- func (ctx *Context) IsChecked() bool
- func (ctx *Context) IsReuse() bool
- func (ctx *Context) IsTraining(g *Graph) bool
- func (ctx *Context) Loader() Loader
- func (ctx *Context) Manager() *Manager
- func (ctx *Context) Memory() int64
- func (ctx *Context) NeedsInitialization() bool
- func (ctx *Context) NumParameters() int
- func (ctx *Context) NumVariables() int
- func (ctx *Context) RandomNormal(g *graph.Graph, shape shapes.Shape) (values *Node)
- func (ctx *Context) RandomUniform(g *graph.Graph, shape shapes.Shape) (values *Node)
- func (ctx *Context) Reuse() *Context
- func (ctx *Context) RngStateFromSeed(seed int64)
- func (ctx *Context) RngStateReset()
- func (ctx *Context) Scope() string
- func (ctx *Context) SetGraphParam(g *Graph, key string, value any)
- func (ctx *Context) SetLoader(loader Loader)
- func (ctx *Context) SetParam(key string, value any)
- func (ctx *Context) SetParams(keyValues map[string]any)
- func (ctx *Context) SetTraining(g *Graph, value bool)
- func (ctx *Context) Unique() *Context
- func (ctx *Context) VariableWithShape(name string, shape shapes.Shape) *Variable
- func (ctx *Context) VariableWithValue(name string, value any) *Variable
- func (ctx *Context) WithInitializer(initializer VariableInitializer) *Context
- type Exec
- func (e *Exec) Call(args ...any) []tensor.Tensor
- func (e *Exec) CallWithGraph(args ...any) (outputs []tensor.Tensor, g *Graph)
- func (e *Exec) Context() *Context
- func (e *Exec) Finalize()
- func (e *Exec) GetNodeLogger() graph.LoggerFn
- func (e *Exec) InDevice(deviceNum int) *Exec
- func (e *Exec) Name() string
- func (e *Exec) SetContext(context *Context) *Exec
- func (e *Exec) SetMaxCache(maxCacheSize int) *Exec
- func (e *Exec) SetNodeLogger(loggerFn graph.LoggerFn)
- func (e *Exec) WithName(name string) *Exec
- type ExecGraphFn
- type Graph
- type Loader
- type Manager
- type Node
- type ScopedParams
- type Variable
- func (v *Variable) AssertValid()
- func (v *Variable) ChangedInGraph(g *Graph) bool
- func (v *Variable) InUseByGraph(g *Graph) bool
- func (v *Variable) Name() string
- func (v *Variable) ParamNode(g *Graph) *Node
- func (v *Variable) ParameterName() string
- func (v *Variable) Scope() string
- func (v *Variable) SetTrainable(trainable bool) *Variable
- func (v *Variable) SetValue(value tensor.Tensor)
- func (v *Variable) SetValueGraph(value *Node)
- func (v *Variable) SetValuePreservingOld(value tensor.Tensor)
- func (v *Variable) Shape() shapes.Shape
- func (v *Variable) String() string
- func (v *Variable) Value() tensor.Tensor
- func (v *Variable) ValueGraph(g *Graph) *Node
- type VariableInitializer
Constants ¶
const ( // ScopeSeparator is used between levels of scope. Scope names cannot use this character. ScopeSeparator = "/" // RootScope is the scope at the very root. // Some internal variables (e.g.: default random number generator state) are stored there. RootScope = ScopeSeparator )
const GraphParamIsTraining = "training"
const (
RngStateVariableName = "#rngState"
)
const VariableParameterPrefix = "var:"
VariableParameterPrefix is used to prefix Graph parameter names for variablesMap.
Variables ¶
This section is empty.
Functions ¶
func EscapeScopeName ¶
EscapeScopeName replaces ScopeSeparator in the string and replaces them by "_".
func GetGraphParamOr ¶ added in v0.8.0
GetGraphParamOr either returns the value for the given param key for the given graph, searching successively from the current scope back to the root scope ("/"), or if the key is not found, returns the given default value.
It tries to cast the value to the given type. If it fails, it tries to convert the value to the given type (so an `int` will be converted to a `float64` transparently). If that also fails, an explaining exception is thrown.
It's a convenience method around `ctx.GetGraphParam`.
This is very similar to GetParamOr, but used for parameters that are graph specific. For example Context.IsTraining and Context.SetTraining uses a Graph parameter to set this state, as the same Context is used for evaluation/inference graphs and training graphs, and they will have different values.
func GetParamOr ¶ added in v0.8.0
GetParamOr either returns the value for the given param key in the context `ctx`, searching successively from the current scope back to the root scope ("/"), or if the key is not found, returns the given default value.
It tries to cast the value to the given type. If it fails, it tries to convert the value to the given type (so an `int` will be converted to a `float64` transparently). If that also fails, an explaining exception is thrown.
It's a convenience method around `ctx.GetParam`.
func VariableParameterNameFromScopeAndName ¶ added in v0.9.0
VariableParameterNameFromScopeAndName creates the Variable.ParameterName from its scope and name.
func VariableScopeAndNameFromParameterName ¶ added in v0.9.0
VariableScopeAndNameFromParameterName extracts the scope and name from a variable's [ParameterName]. It will return empty strings for an invalid parameter name.
Types ¶
type Context ¶
type Context struct {
// contains filtered or unexported fields
}
Context organizes information shared in a model (or anything else). A model can spawn multiple computation graphs, e.g: one computation for a training step, one for an evaluation step running on batch, and one for a prediction computation on exactly one example. All these computation graphs should share the same variable (weight) values (and other information). These variables and (hyper-) parameters are organized here.
The Context organizes 3 types of information used by a model, and its graphs:
- Variables: model variables or weights.
- Parameters (normal): hyperparameters and also any arbitrary information that needs sharing among the graph building functions using the Context.
- Per-graph parameters: each graph will have it's own value. E.g: the parameter "training" indicates if the model is being used for training or inference, and this value will be different for a training or evaluation graph.
All 3 types of information are organized in "scopes". The Context object is actually a thin wrapper that contains the current scope (similar to a current directory) and a link to the actual data. One can change scopes by using Context.In("new_scope"): it returns a new Context with the new scope set, but still pointing (sharing) all the data with the previous Context. E.g:
One could create a new context with:
```
func main() { ctx := context.NewContext(manager) ctx.SetParam("dropout_rate") = 0.2 // Set default dropout to 0.2 ... } func ModelGraph(ctx *context.Context, inputs []*Node) (logits *Node) { ... { ctx := ctx.In("output_layer") // Enter "output_layer" scope in temporary new context (same data, different scope) ctx.SetParam("dropout_rate", 0.6) // Let's say we want the "output_layer" only to have dropout=0.6 logits = Dense(ctx, logits, output_dim) } // Exiting "output_later" scope, ctx is back to it's original scope. }
Finally, Context also allows one to checkpoint the variable values (save and load). See checkpoint package.
TODO: Handling of devices with multiple instances (e.g.: multiple GPUs/TPUs).
func NewContext ¶
NewContext constructs a new and empty context.
func (*Context) BuildTrainableVariablesGradientsGraph ¶ added in v0.5.0
BuildTrainableVariablesGradientsGraph returns the gradient of the loss with respect to each trainable variable in the context that was used in the current graph. It returns a tuple Node. Non-trainable variables (Variable.Trainable == false) are not touched.
Typically, this is used by an optimizer.
Note, if during the computation graph the value of the variable is changed with Variable.SetValueGraph, this will calculate the gradient with respect to the new value (*Node) set.
func (*Context) Checked ¶
Checked returns a new context with the checked flag set accordingly. If checked is true checks for reuse/uniqueness are checked according to IsReuse(). If checked is false Variables are dynamically reused or created when needed, without any checks. Usually it is set to true when building models -- to prevent layers to overstepping on each other -- and set to false for supporting variables (like optimizers, metrics and preprocessing).
Notice that re-usability is part of the "reference" component of a Context.
func (*Context) DeleteVariable ¶ added in v0.8.0
DeleteVariable if it exists. Returns whether the variable existed before being deleted.
This should not be called from a graph building function or from within EnumerateVariables: the results are undefined if you do.
func (*Context) DeleteVariablesInScope ¶ added in v0.8.0
func (ctx *Context) DeleteVariablesInScope()
DeleteVariablesInScope deletes all variables under the current scope (ctx.Scope()).
This should not be called from a graph building function or from within EnumerateVariables: the results are undefined if you do.
func (*Context) EnumerateGraphParams ¶
EnumerateGraphParams enumerates all parameters for the graph, for all scopes calls fn with their values.
func (*Context) EnumerateParams ¶
EnumerateParams enumerates all parameters for all scopes calls fn with their values.
func (*Context) EnumerateVariables ¶
EnumerateVariables will call fn for each variable in the context. Notice the order of visitation is deterministic.
Notice that variables' information is stored in the "data" component of Context objects, and is shared among all connected context references.
Example:
fmt.Println("\nVariables:") ctx.EnumerateVariables(func(v *context.Variable) { fmt.Printf("\t%s::%s: shape=%s\n", v.Scope(), v.Name(), v.Shape()) })
func (*Context) EnumerateVariablesInScope ¶ added in v0.8.0
EnumerateVariablesInScope is similar to EnumerateVariables, but enumerate only those under the current context scope.
func (*Context) ExecPopulateGraphParamsMap ¶
ExecPopulateGraphParamsMap will enter the parameter values for every variable used in the given graph.
`Exec*` methods are used by those implementing an executor (context.Exec) or related tests, not normally needed by end users.
func (*Context) ExecSetVariablesInParams ¶
ExecSetVariablesInParams adds all variables (all scopes) used by the graph to the ParamsMap objects.
`Exec*` methods are used by those implementing an executor (context.Exec) or related tests, not normally needed by end users.
func (*Context) GetGraphParam ¶
GetGraphParam returns the value for the given param key for the given graph, searching successively from the current scope back to the root scope ("/"), in case the key is not found.
E.g: if current scope is "/a/b", it will search for the key in "/a/b" scope, then in "/a" and finally in "/", and return the first result found.
This is very similar to GetParam, but used for parameters that are graph specific. For example Context.IsTraining and Context.SetTraining uses a Graph parameter to set this state, as the same Context is used for evaluation/inference graphs and training graphs, and they will have different values.
func (*Context) GetParam ¶
GetParam returns the value for the given param key, searching successively from the current scope back to the root scope ("/"), in case the key is not found.
E.g: if current scope is "/a/b", it will search for the key in "/a/b" scope, then in "/a" and finally in "/", and return the first result found.
See also:
* GetParamOr to get a parameter with a default, if one doesn't exist. * GetGraphParam for parameters that are graph specific.
func (*Context) In ¶
In returns a new reference to the Context with the extra given scope. No ScopeSeparator ("/") is allowed in scope.
Notice that Scope is part of the "reference" component of a Context.
func (*Context) InAbsPath ¶
InAbsPath returns a new reference to the Context with the extra given scope. It should start and have each element separated by ScopeSeparator. Use RootScope for the root scope.
Notice that Scope is part of the "reference" component of a Context.
func (*Context) InitializeVariables ¶
func (ctx *Context) InitializeVariables()
InitializeVariables initializes all variables in the Context that don't yet have a value. Variables create with VariableWithValue or for which values were preloaded are not initialized. Errors are returned in Context.Error().
Notice that variables information is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) InspectVariable ¶
InspectVariable returns the variable with the given name for inspection. It returns nil if a variable with the given name hasn't been created.
It is not affected by Context.Reuse checks.
This will trigger the loading of the variable if a loader (like `checkpoint.Checkpoint`) is attached.
Notice that variables' information is stored in the "data" component of Context objects, and is shared among all connected context references.
The root scope is "/" (RootScope).
func (*Context) InspectVariableIfLoaded ¶ added in v0.9.0
InspectVariableIfLoaded returns the variable if it exists already, but it won't attempt to load it.
It is similar to [InspectVariable] but won't attempt to load the variable.
func (*Context) InspectVariableInScope ¶ added in v0.9.0
InspectVariableInScope works like InspectVariable, but looks for the variable in the current scope.
func (*Context) IsChecked ¶
IsChecked returns whether context is checking reuse rules.
Notice that re-usability is part of the "reference" component of a Context.
func (*Context) IsReuse ¶
IsReuse returns whether Context is marked for reuse. This is irrelevant if IsChecked is false.
Notice that re-usability is part of the "reference" component of a Context.
func (*Context) IsTraining ¶
IsTraining returns whether context is being used for training. This is only a convention adopted by the library components, and it is read with Context.GetGraphParam and GraphParamIsTraining for the current scope. See [SetTraining] to change this value.
Notice that graph parameters is part of the "reference" component of a Context, so this change won't affect other connected context references.
func (*Context) Loader ¶
Loader returns the current configured Loader for this context. See SetLoader for details on how the Loader is used.
Notice that loader configuration is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) Memory ¶ added in v0.4.0
Memory returns the total number of bytes summed across all variables. It does not include associated pointers and structures, just the bytes used by the raw data.
Example:
fmt.Printf("Model memory usage: %s", data.ByteCountIEC(ctx.Memory()))
func (*Context) NeedsInitialization ¶
NeedsInitialization returns whether there are variables that needs initialization.
Notice that variables information is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) NumParameters ¶ added in v0.4.0
NumParameters returns the summed-up number of all variables. It ignores the `DType`, so a `float64` will count as much as a `uint8`.
func (*Context) NumVariables ¶
NumVariables return the number of variables in this Context.
func (*Context) RandomNormal ¶ added in v0.4.0
RandomNormal generates random numbers from a normal distribution, with mean 0.0 and standard deviation 1.0. It generates values with the given shape, each value pseudo-randomly generated.
If you need a different mean and standard deviation, just do something like the example below, where `mean` and `stddev` are the desired mean and standard deviation:
rngState, numbers = RandomNormal(rngState, myShape) numbers = AddScalar(MulScalar(numbers, stddev), mean)
The random number generator (RNG) state is stored in a variable on the root scope of the context, called "#rngState" (RngStateVariableName). The state is initialized with the nanosecond clock, the first time it is used -- so pretty random. But you can initialize it with a fixed seed before using any of the Random* methods.
See details in graph.RandomNormal.
func (*Context) RandomUniform ¶ added in v0.4.0
RandomUniform generates random uniform values from 0.0 to 1.0 (half-open `[0.0, 1.0)`, so 1.0 is never returned) for float numbers in the given shape.
The random number generator (RNG) state is stored in a variable on the root scope of the context, called "#rngState" (RngStateVariableName). The state is initialized with the nanosecond clock, the first time it is used -- so pretty random. But you can initialize it with a fixed seed before using any of the Random* methods.
See details in graph.RandomNormal.
func (*Context) Reuse ¶
Reuse returns a new reference to the Context set to reuse of variables, if it is not already in reuse mode. Otherwise, returns itself. If checked is false, this setting is irrelevant.
Notice that re-usability is part of the "reference" component of a Context.
func (*Context) RngStateFromSeed ¶ added in v0.4.0
RngStateFromSeed initializes the default context random number generator (RNG) state with a static seed. If the state has already been created, it is reset to a value based on the seed.
The random number generator (RNG) state is stored in a variable on the root scope of the context, called "#rngState" (RngStateVariableName).
func (*Context) RngStateReset ¶ added in v0.4.0
func (ctx *Context) RngStateReset()
RngStateReset resets the default context random number generator (RNG) to a random seed based on the nanosecond clock.
This is done automatically for new contexts, but if the context was loaded from a checkpoint, and one wants to reset it (as opposed to continue the previous state), one can call this.
The random number generator (RNG) state is stored in a variable on the root scope of the context, called "#rngState" (RngStateVariableName).
func (*Context) Scope ¶
Scope returns the full scope path.
Notice that Scope is part of the "reference" component of a Context.
func (*Context) SetGraphParam ¶
SetGraphParam sets the given Graph param in the current scope. It will be visible (by GetGraphParam) for this Graph within this scope and descendant scopes (but not by other scopes).
Notice each time a new graph is created, the associated "graph parameters" in the context will be empty.
This is very similar to SetParam, but used for parameters that are graph specific. For example Context.IsTraining and Context.SetTraining uses a Graph parameter to set this state, as the same Context is used for evaluation/inference graphs and training graphs, and they should have different values.
func (*Context) SetLoader ¶
SetLoader configures given loader to be used as the default Loader for this Context.
Loader is used just after any new variable is created, either with VariableWithValue or VariableWithShape. If the Loader has a value of the variable created, it will override the value given in VariableWithValue, or skip the initializer for VariableWithShape.
An example of a loader in gomlx/context/checkpoints.
Notice that loader configuration is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) SetParam ¶
SetParam sets the given param in the current scope. It will be visible (by GetParam) within this scope and descendant scopes (but not by other scopes).
Note: the scoped parameters of the context are saved in `checkpoints` package using Json encoding. This works well for `string`, `float64` and `int` and slices of those values, but other types may not be recovered correctly later. See `checkpoints` package to add support for some other specific type, if you get a different type when loading the json.
See also SetGraphParam for parameters that are graph-specific.
func (*Context) SetParams ¶ added in v0.9.0
SetParams sets a collection of parameters in the current scope. It will be visible (by GetParam) within this scope and descendant scopes (but not by other scopes).
This is a shortcut to multiple calls to `Context.SetParam` and the same observations apply.
func (*Context) SetTraining ¶
SetTraining marks the context for the given graph as training. This is a convention adopted by the library components, and it simply sets it with Context.SetGraphParam and GraphParamIsTraining to the given value. See IsTraining to check for this value.
Notice that the graph parameters is part of the "reference" component of a Context, so this change won't affect other connected context references.
func (*Context) Unique ¶
Unique returns a new reference to the Context, set to only allow new variables, if it is not already in unique mode. If checked is false, this setting is irrelevant.
Notice that re-usability is part of the "reference" component of a Context.
func (*Context) VariableWithShape ¶
VariableWithShape creates or returns an existing variable with the given shape in the current scope. It is initialized with the current variable initializer set for the context. By default, variables are marked as trainable.
If a Loader is configured (see SetLoader), and the value is available to load, it will override the value given here -- e.g.: the value could be actually loaded from the last checkpoint.
Notice that variables information is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) VariableWithValue ¶
VariableWithValue creates a variable that is initialized with the given value in the current scope. By default, variables are marked as trainable. The value given must be concrete, that is a tensor or a normal Go value, that can be converted to a tensor -- a graph *Node does not work here, this is assumed to be a constant.
If a Loader is configured (see SetLoader), and the value is available to load, it will override the value given here -- e.g.: the value could be actually loaded from the last checkpoint.
Notice that variables' information is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) WithInitializer ¶
func (ctx *Context) WithInitializer(initializer VariableInitializer) *Context
WithInitializer returns a new reference to the Context, with the initializer set.
Notice that default variable initialization is part of the "reference" component of a Context, so this change won't affect other context references.
type Exec ¶
type Exec struct {
// contains filtered or unexported fields
}
Exec creates and executes computation graphs that take as input a Context as needed based on the inputs shapes, to allow the function to access (both read and set) variables and everything in the Context. Otherwise very similar to graph.Exec.
It simplifies the process of executing a graph building function with real values.
For example, assume you wrote:
def LogitsGraph(ctx *context.Context, inputs *Node) *Node { logits := layers.Dense(ctx.In("dense0", inputs, 5)) logits = layers.Dense(ctx.In("dense1", logits, 5)) logits = Sigmoid(logits) return logits }
And then with Exec one can do:
ctx := context.NewContext(manager) var logitsFn = context.NewExec(manager, ctx, LogitsGraph) batch := [][]float32{ {1, 2, 3}, {4, 5, 6} } // 2 examples with 3 features (shape=[2,3]) fmt.Printf("Logits(%v) = %v\n", batch, logitsFn.Call(batch)[0].Value())
Call method always outputs a slice with all the outputs, even when there are no outputs (in which case it returns nil). Call takes as input the materialized values (tensors) you want to execute the graph with -- you don't need to path the *Context of *Graph to Call, those are filled automatically by Exec.
Notice ctxGraphFn, the function that builds the computation graph, is only called the first time Call is used -- so it's slower the first time, since it has to compile the graph. After that the execution is much faster. But that means that changes to Context.SetParams() or Context.SetGraphParams() after the first execution will not have any effect.
Exec also manages updates to variables automatically. Example: we implement a counter, which takes no input values (just the *Graph object), it just creates a variable if not there yet, increments it and returns its value.
```
ctx := context.NewContext(manager) counter := context.NewExec(manager, ctx, func(ctx *context.Context, g *Graph) *Node { dtype := types.Int64 counterVar := ctx.WithInitializer(initializers.Zeros).VariableWithShape("counter", types.MakeShape(dtype)) counterNode := counterVar.ValueGraph(graph) counterNode = Add(counterNode, OnesLike(counterNode)) counterVar.SetValueGraph(counterNode) return counterNode }) fmt.Printf("%s\n", counter.Call()[0]) // == 1 fmt.Printf("%s\n", counter.Call()[0]) // == 2 fmt.Printf("%s\n", ctx.InspectVariable(ctx.Scope(), "counter").Value()) // == 2
```
Behind the scenes it automatically adds the used variables (Variable.ValueGraph) as side inputs, and the updated variables (Variable.SetValueGraph) as extra outputs of the graph, and during the graph execution it automatically use these values to update the materialized variable values in Context variables. It will also automatically initialize Context variables when needed.
Notice, like with graph.Exec, the need to build different graphs for different shapes can be expensive when sizes of the inputs varies a lot. The usual solution is to use shapes with size in a power scale (for instance powers of 2) and masking of tensors for unused slices. For safety concerns there are a maximum number of different instantiations of the graph. It can be set or disabled with SetMaxCache.
Errors in Call are returned inside the returned tensors.
There is concurrency safety with the cache of Graphs, but XLA concurrency is not documented. TODO: figure it out.
func NewExec ¶
func NewExec[F ExecGraphFn](manager *Manager, ctx *Context, ctxGraphFn F) *Exec
NewExec constructs an Exec object that uses the given ctxGraphFn to build computation graphs with a Context. ctxGraphFn must take a *Context input parameter followed by one or more *Node parameters as input and return one or more *Node.
The Context ctx passed will be passed to all computation graph construction calls (ctxGraphFn), as well as during the graph execution later. If set to nil, it automatically creates a new one.
Before the execution of a graph, if needed, it initializes the variables in the context.
This is a generic wrapper around NewExecAny that check that types are correct (but doesn't support all possible types of ctxGraphFn).
func NewExecAny ¶
NewExecAny constructs an Exec object that uses the given ctxGraphFn to build computation graphs with a Context. ctxGraphFn must take a *Context input parameter followed by one or more *Node parameters as input and return one or more *Node. Alternatively it can, instead of *Node inputs, take a *Graph object -- if effectively no tensors will be used as input.
The Context ctx passed will be passed to all computation graph construction calls (ctxGraphFn), as well as during the graph execution later. If set to nil, it automatically creates a new one.
Before the execution of a graph, if needed, it initializes the variables in the context. And updated variables in the graph are updated also during execution. More details see Exec.
If any input or output parameter of ctxGraphFn is not a *Node (except the *Context and optionally a *Graph), or if there are no inputs or outputs, it returns an error.
func (*Exec) Call ¶
Call parses the arguments into tensors (if they are not yet) and executes the graph corresponding to the shapes of the arguments.
Notice Context shouldn't be passed by Call, it will use automatically the context stored in context.Exec -- you can change it with SetContext.
If a graph does not yet exist one is created, compiled and cached for the shapes of the inputs. It passes the context to the registered ctxGraphFn. After the very first invocation of Call the context is marked as Context.Reuse().
It returns the outputs in a slice, even if there is only one output.
It panics with an informative error if something goes wrong.
func (*Exec) CallWithGraph ¶
CallWithGraph is similar to Call, but it also returns the computation graph used in the call. Since Exec creates different computation graphs for different set of parameters, this can help disambiguate in case the user needs to use the Graph for something else.
It returns the outputs in a slice, even if there is only one output, and the graph used to execute the computation.
It panics with an informative error if something goes wrong.
func (*Exec) Context ¶
Context returns the associated Context object, usually created during the creation of the Exec object. It can be set to something different with SetContext().
func (*Exec) Finalize ¶
func (e *Exec) Finalize()
Finalize clears the cache, finalizing the graphs. The Exec object shouldn't be used after that.
func (*Exec) GetNodeLogger ¶
GetNodeLogger returns the currently registered LoggerFn.
func (*Exec) InDevice ¶
InDevice sets the device num to be used by graphs constructed by Exec. This should be called before any invocations of Call(). It returns a reference to itself so calls can be cascaded.
func (*Exec) SetContext ¶
SetContext associates the given Context to the Exec object. Should be called before the first Call is made. Notice that only after the first time context is used to build a graph, it is set to Reuse. If the Context variables were already created, it should be marked with Context.Reuse. It returns a reference to itself so calls can be cascaded.
func (*Exec) SetMaxCache ¶
SetMaxCache sets the maximum size of the cache. Set it to -1 to have unlimited cache size. It returns a reference to itself so calls can be cascaded.
func (*Exec) SetNodeLogger ¶
SetNodeLogger with the function to be called for the nodes marked for logging during execution. If set to nil nothing will be logged.
type ExecGraphFn ¶ added in v0.5.0
type ExecGraphFn interface { func(*Context, *Graph) | func(*Context, []*Node) | func(*Context, *Node) | func(*Context, *Node, *Node) | func(*Context, *Node, *Node, *Node) | func(*Context, *Node, *Node, *Node, *Node) | func(*Context, *Node, *Node, *Node, *Node, *Node) | func(*Context, *Node, *Node, *Node, *Node, *Node, *Node) | func(*Context, *Graph) *Node | func(*Context, []*Node) *Node | func(*Context, *Node) *Node | func(*Context, *Node, *Node) *Node | func(*Context, *Node, *Node, *Node) *Node | func(*Context, *Node, *Node, *Node, *Node) *Node | func(*Context, *Node, *Node, *Node, *Node, *Node) *Node | func(*Context, *Node, *Node, *Node, *Node, *Node, *Node) *Node | func(*Context, *Graph) (*Node, *Node) | func(*Context, []*Node) (*Node, *Node) | func(*Context, *Node) (*Node, *Node) | func(*Context, *Node, *Node) (*Node, *Node) | func(*Context, *Node, *Node, *Node) (*Node, *Node) | func(*Context, *Node, *Node, *Node, *Node) (*Node, *Node) | func(*Context, *Node, *Node, *Node, *Node, *Node) (*Node, *Node) | func(*Context, *Node, *Node, *Node, *Node, *Node, *Node) (*Node, *Node) | func(*Context, *Graph) (*Node, *Node, *Node) | func(*Context, []*Node) (*Node, *Node, *Node) | func(*Context, *Node) (*Node, *Node, *Node) | func(*Context, *Node, *Node) (*Node, *Node, *Node) | func(*Context, *Node, *Node, *Node) (*Node, *Node, *Node) | func(*Context, *Node, *Node, *Node, *Node) (*Node, *Node, *Node) | func(*Context, *Node, *Node, *Node, *Node, *Node) (*Node, *Node, *Node) | func(*Context, *Node, *Node, *Node, *Node, *Node, *Node) (*Node, *Node, *Node) | func(*Context, *Graph) []*Node | func(*Context, []*Node) []*Node | func(*Context, *Node) []*Node | func(*Context, *Node, *Node) []*Node | func(*Context, *Node, *Node, *Node) []*Node | func(*Context, *Node, *Node, *Node, *Node) []*Node | func(*Context, *Node, *Node, *Node, *Node, *Node) []*Node | func(*Context, *Node, *Node, *Node, *Node, *Node, *Node) []*Node }
ExecGraphFn is a type parameter for accepted function types for NewExec constructor.
type Loader ¶
type Loader interface { // LoadVariable tries to load the variable v pointed by its scope and name. // If it's not found, returns false, and initialization continues as usual. // Errors can be reported with Context.Panic. // // It is called at most once for each variable: if a values is loaded owner is transferred and the Loader // can "forget" about that variable, it's assumed to be transferred to the context. LoadVariable(ctx *Context, scope, name string) (value tensor.Tensor, found bool) }
Loader can be implemented by any library providing loading of variables for Context. Loader implementations need to provide values on demand -- as a variables are used, even if they load everything up-front.
An example of a loader in gomlx/context/checkpoints. An example for testing can be found in context_test.go:ConstantLoader.
type ScopedParams ¶
type ScopedParams struct {
// contains filtered or unexported fields
}
ScopedParams provides a mapping from string to any data type that is "scoped":
- For every scope there is a map of string to data.
- Accessing a key triggers a search from the current scope up to the root scope, the first result found is returned.
Example: let's say the current ScopedParams hold:
Scope: "/": { "x":10, "y": 20, "z": 40 } Scope: "/a": { "y": 30 } Scope: "/a/b": { "x": 100 } ScopedParams.Get("/a/b", "x") -> 100 ScopedParams.Get("/a/b", "y") -> 30 ScopedParams.Get("/a/b", "z") -> 40 ScopedParams.Get("/a/b", "w") -> Not found.
Notice that "/" (== ScopeSeparator constant) separates parts of the scope path, and the root scope is referred to as "/". There is no "empty" scope, and every scope name must start with a ScopeSeparator.
The Context object uses ScopedParams to store the normal hyperparameters (see `Context.GetParam` and `Context.SetParam`) and to store the graph hyperparameters (see `Context.GetGraphParam` and `Context.SetGraphParam`).
Usually there will be no need for the end user to use this.
func NewScopedParams ¶
func NewScopedParams() *ScopedParams
NewScopedParams create an empy ScopedParams.
func (*ScopedParams) Enumerate ¶
func (p *ScopedParams) Enumerate(fn func(scope, key string, value any))
Enumerate enumerates all parameters stored in the ScopedParams structure and calls the given closure with them.
func (*ScopedParams) Get ¶
func (p *ScopedParams) Get(scope, key string) (value any, found bool)
Get retrieves the value for the given key in the given scope or any parent scope. E.g: Get("/a/b", "myKey") will search for "myKey" in scopes "/a/b", "/a" and "/" consecutively until "myKey" is found.
It returns the first value found if any, and whether some value was found.
func (*ScopedParams) Set ¶
func (p *ScopedParams) Set(scope, key string, value any)
Set sets the value for the given key, in the given scope.
type Variable ¶
type Variable struct { // Trainable indicates whether variable is trainable. If set to false it won't be // touched by trainers of the model. Trainable bool // contains filtered or unexported fields }
Variable is a value shared among computation graphs, or across multiple executions of the same graph. It's commonly used to store the weights (aka. parameters) of an ML model. It's defined in a scope in a Context.
The materialized value can be accessed in between graph executions by Value and SetValue methods.
During the computation graph building, for a particular graph, one can access the graph value (Node) of a variable with the methods
They are only initialized when Context.InitializeVariables. That is, they are created and used in graph building possibly before they are actually initialized -- when building a graph they are passed as parameters (the corresponding graph node is called ParameterNode), and have their values passed only during execution.
func (*Variable) AssertValid ¶ added in v0.5.0
func (v *Variable) AssertValid()
AssertValid panics if the variable is in an invalid state: if it's nil or it's shape is not yet set.
func (*Variable) ChangedInGraph ¶
ChangedInGraph returns whether the variable is in use and was changed in the computation graph g.
func (*Variable) InUseByGraph ¶
InUseByGraph returns whether the variable is currently in use by the given graph.
func (*Variable) ParamNode ¶
ParamNode returns the given Graph g's Node that corresponds to the parameter that will be fed with the current variable value when the graph is executed. It's the initial value of the variable in the computation Graph.
If parameter Node hasn't been created for the Graph g yet, one is created.
Since the value of a variable can change in the middle of the graph (e.g: something that uses the variable after a gradient descent is applied) consider using ValueGraph to read the current associated value of a variable in a graph.
func (*Variable) ParameterName ¶
ParameterName used when creating a parameter node in a Graph to access the variable, or as a key when saving. It is a unique name for the variable that includes the scope and the variable name, and is reversible.
func (*Variable) SetTrainable ¶
SetTrainable sets the variable trainable status. Returns itself, so calls can be cascated.
func (*Variable) SetValue ¶
SetValue updates the tensor holding the variable value. NOTE: Because often variables are large in size, the previous value is immediately freed (as opposed to wait for garbage collection). If the previous value is used somewhere else, use SetValuePreservingOld.
func (*Variable) SetValueGraph ¶
SetValueGraph sets the Node associated with the current value of the variable for the computation graph where value is defined.
This is used to "communicate" among different parts of the graph building that this value Node should be used as the variable value.
train.Trainer will use the last value set here during graph building and use it as output of the graph execution and then update the variables (with SetValue) accordingly after each graph execution, for example, after each Trainer.TrainStep call.
func (*Variable) SetValuePreservingOld ¶
SetValuePreservingOld updates the tensor holding the variable value, and dont' free old value. If previous value is not used, use SetValue instead that will free it immediately.
func (*Variable) Value ¶
Value returns the tensor holding the variable value. Use this to manipulate the value in Go. If building a computation Graph use Node().
WARNING: memory management here is tricky: a call to SetValue will trigger the current value to be deallocated, and what is returned by a previous call to Value to become invalid. The recommendation is not to use this is a concurrent set up -- or to create proper locking mechanisms.
func (*Variable) ValueGraph ¶
ValueGraph returns the Node of the Graph that holds the current value of the variable. It can be changed for the graph (for instance when applying a gradient descent) by SetGraph.
type VariableInitializer ¶
type VariableInitializer = initializers.VariableInitializer
VariableInitializer builds a valueNode that returns a value to initialize a variable of the given shape. It is defined in the Context.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package checkpoints implements checkpoint management: saving and loading of checkpoints.
|
Package checkpoints implements checkpoint management: saving and loading of checkpoints. |
Package ctxtest holds test utilities for packages that depend on context package.
|
Package ctxtest holds test utilities for packages that depend on context package. |
Package initializers include several weight initializers, to be used with context.
|
Package initializers include several weight initializers, to be used with context. |