Per-call context shared between a custom op's forward and backward passes.
FunctionCtx is the C++-side counterpart of lucid.autograd.Function's
Python ctx object. A fresh instance is created on each Function.apply
invocation and is passed unchanged as the first argument to both
forward(ctx, ...) and backward(ctx, grad_output), providing the only
legal channel for state to cross the forward/backward boundary.
See Also
lucid.autograd.FunctionCtx — Python-facing wrapper class.
PythonBackwardNode — owns one FunctionCtx per custom op call.
Attributes
saved_tensors_std::vector<std::shared_ptr<TensorImpl>>save_for_backward as strong references so they survive until the backward pass executes.extras_std::unordered_map<std::string, py::object>ctx.<name> = value / ctx.<name> access from Python. Used for scalars, shape tuples, hyperparameters, and other non-tensor state.Notes
The object is heap-allocated and jointly owned by the Python wrapper and
the associated PythonBackwardNode, so it outlives the forward
call and remains valid for the entire backward traversal. Capturing
tensors through Python closures instead of saving them through ctx
bypasses this ownership tracking and leaks memory.
Constructors
1FunctionCtx
void FunctionCtx()Construct a FunctionCtx for a custom Function::forward call.
The newly created context starts with empty saved_tensors_ and
extras_ containers; the user's forward body populates them
via save_for_backward and store before returning.
Defaulted — no resources need acquisition at construction.
Methods
1Save tensors needed for the backward pass.
Stores strong shared_ptr references so that the underlying
TensorImpl buffers remain alive until backward completes,
even if the Python-side handle goes out of scope. Mirrors the
semantics of lucid.autograd.FunctionCtx.save_for_backward.
Parameters
tensorsstd::vector<std::shared_ptr<TensorImpl>>saved_tensors() should return them. Moved into the context.Notes
Each call overwrites the previously saved list; saving twice does not
accumulate. To stash non-tensor data (shapes, axes, scalars) use the
store / load extras bag instead.