Mila
Deep Neural Network Library
Loading...
Searching...
No Matches
Mila::Dnn::MLP< TDeviceType, TPrecision > Class Template Referenceexport

Dense feed-forward (MLP) composite component. More...

Inheritance diagram for Mila::Dnn::MLP< TDeviceType, TPrecision >:
Mila::Dnn::CompositeComponent< TDeviceType, TPrecision > Mila::Dnn::Component< TDeviceType, TPrecision >

Public Types

using ComponentPtr = typename CompositeComponentBase::ComponentPtr
using CompositeComponentBase = CompositeComponent<TDeviceType, TPrecision>
using GeluType = Gelu<TDeviceType, TPrecision>
using LinearType = Linear<TDeviceType, TPrecision>
using MR = typename DeviceTypeTraits<TDeviceType>::memory_resource
using TensorType = Tensor<TPrecision, MR>
Public Types inherited from Mila::Dnn::CompositeComponent< TDeviceType, TPrecision >
using ComponentBase = Component<TDeviceType, TPrecision>
using ComponentPtr = std::shared_ptr<Component<TDeviceType, TPrecision>>

Public Member Functions

 MLP (const std::string &name, const MLPConfig &config, std::optional< DeviceId > device_id=std::nullopt)
 Construct an MLP component.
 ~MLP () override=default
 Default destructor.
TensorType & backward (const TensorType &input, const TensorType &output_grad)
 Backward pass using captured forward intermediates.
TensorType & decode (const TensorType &input) const
 Single-token inference convenience: fc1 -> gelu -> fc2 with no gradient capture.
TensorType & forward (const TensorType &input)
 Forward pass.
MemoryStats getMemoryStats () const override
 Return the current memory allocation breakdown for this component.
const ComponentType getType () const override
 Get the component type identifier.
std::string toString () const override
 Human-readable status and configuration summary.
void zeroGradients () override
 Zero gradients for all child components.
Public Member Functions inherited from Mila::Dnn::CompositeComponent< TDeviceType, TPrecision >
 CompositeComponent (CompositeComponent &&) noexcept=default
 CompositeComponent (const CompositeComponent &)=delete
 CompositeComponent (const std::string &name)
 Construct composite component with name.
CompositeComponentaddComponent (ComponentPtr component)
 Add a pre-constructed child component (chainable).
size_t childCount () const noexcept
 Get the number of direct children.
void clearComponents ()
 Clear all child components.
ComponentPtr findComponent (const std::string &path) const
 Resolve a dot-separated component path within this composite.
ComponentPtr getComponent (const std::string &name) const
 Retrieve a direct child component by name.
const std::vector< ComponentPtr > & getComponents () const
 Get all child components in insertion order.
DeviceId getDeviceId () const override
 Get the compute device for this composite.
std::vector< ITensor * > getGradients () const override
 Get all parameter gradients from all children.
std::vector< ITensor * > getParameters () const override
 Get all parameters from all children.
bool hasChildren () const noexcept
 Check if this composite has any children.
bool hasComponent (const std::string &name) const
 Check if a named child component exists.
CompositeComponentoperator= (CompositeComponent &&) noexcept=default
CompositeComponentoperator= (const CompositeComponent &)=delete
dim_t parameterCount () const override
 Count parameters across all children.
bool removeComponent (const std::string &name)
void saveFlatTensors (Serialization::SafeTensorsWriter &writer, const std::string &prefix, Serialization::TensorSavePass pass) const override
 Recurse into children, extending the flat dotted prefix.
void synchronize () override
 Synchronize all child components.
ComponentPtr tryFindComponent (const std::string &path) const
 Try to resolve a dot-separated component path within this composite.
Public Member Functions inherited from Mila::Dnn::Component< TDeviceType, TPrecision >
 Component (const std::string &name)
 Construct component with required name identifier.
virtual void build (const BuildContext &context) final
 Build the component with the provided BuildContext (canonical overload).
const std::string getName () const
 Get the component's name identifier.
virtual std::vector< std::string > getParameterNames () const
 List all available parameter names for this component.
virtual MemoryStats getRequiredMemory (const BuildContext &context) const
 Report what build( context ) would allocate, without allocating it.
TrainingMode getTrainingMode () const noexcept
 The current runtime behavioral mode of this Component.
virtual bool isBuilt () const final
 Returns true if build() has completed successfully.
virtual void loadParameter (const std::string &, const Serialization::ITensorBlob &)
 Load a parameter from serialized tensor data.
void setTrainingMode (TrainingMode mode)
 Set the runtime behavioral mode for this Component.

Protected Member Functions

void onBuilding (const BuildContext &context) override
 Build-time callback invoked by the CompositeComponent framework.
void onTrainingModeChanging (TrainingMode training_mode) override
 Propagate training-mode changes to child components.
Protected Member Functions inherited from Mila::Dnn::CompositeComponent< TDeviceType, TPrecision >
template<typename TComponent>
std::shared_ptr< TComponent > getComponentAs (const std::string &name) const
 Retrieve a typed child component by name.
void load_ (ModelArchive &archive, SerializationMode mode) override
 Restore children from their nested scopes, mirroring save_().
void onExecutionContextSet () override
 Hook invoked after ExecutionContext is set.
virtual void optimize ()
 Virtual hook for graph optimization after construction.
void requireSerializableParameters () const override
 No-op override: a composite names no parameters of its own.
void save_ (ModelArchive &archive, SerializationMode mode) const override
Protected Member Functions inherited from Mila::Dnn::Component< TDeviceType, TPrecision >
IExecutionContextgetExecutionContext () const
 Get the shared execution context.
bool hasExecutionContext () const noexcept
 Check if execution context has been set.
template<TensorDataType TParameterPrecision, typename TMemoryResource>
void loadParameterFromBlob (const std::string &param_name, const Serialization::ITensorBlob &blob, Tensor< TParameterPrecision, TMemoryResource > &target, const shape_t &expected_shape)
 Load a tensor blob into a parameter tensor with validation.
template<TensorDataType TParameterPrecision, typename TMemoryResource>
void saveParameterToArchive (ModelArchive &archive, const std::string &parameter_name, const Tensor< TParameterPrecision, TMemoryResource > &parameter) const
 Write one parameter tensor into the archive under "tensors/<name>".
template<TensorDataType TParameterPrecision, typename TMemoryResource>
void saveParameterToWriter (Serialization::SafeTensorsWriter &writer, const std::string &flat_name, const Tensor< TParameterPrecision, TMemoryResource > &parameter, Serialization::TensorSavePass pass) const
 Drive one parameter through one pass of a flat safetensors save.
void setExecutionContext (IExecutionContext *context)
 Set the execution context for this component.

Additional Inherited Members

Static Public Member Functions inherited from Mila::Dnn::Component< TDeviceType, TPrecision >
static constexpr DeviceType getDeviceType ()
 Compile-time device type for this component instance.
static constexpr TensorDataType getPrecision () noexcept
 Compile-time tensor precision for this component instance.
Protected Types inherited from Mila::Dnn::Component< TDeviceType, TPrecision >
using HostStagingMemoryResource
 Host memory a device-resident parameter stages through.
Protected Attributes inherited from Mila::Dnn::Component< TDeviceType, TPrecision >
BuildContext build_context_ { shape_t{ 1 }, RuntimeMode::Training }
 The BuildContext stored at build time.

Detailed Description

template<DeviceType TDeviceType, TensorDataType TPrecision>
requires PrecisionSupportedOnDevice<TPrecision, TDeviceType>
class Mila::Dnn::MLP< TDeviceType, TPrecision >

Dense feed-forward (MLP) composite component.

Device-templated composite implementing the GPT-2 dense FFN: Input -> Linear(in_features, hidden_size) -> GELU -> Linear(hidden_size, in_features) -> Output

The component is honest about the single activation it supports: GELU. The gated FFN family (SwiGLU and friends) is a separate component (GatedMLP) with a different 2H -> H shape contract; it is not expressible here and is not a runtime option. A future generalized elementwise Activation component will replace the fixed Gelu child, at which point the activation function becomes a compile-time parameter (see Specifications/FfnAndMoE.md). Until then MLP is the dense GELU FFN, full stop.

The component composes child components (two Linear projections and a GELU) and delegates forward/backward calls to them. Child components own their intermediate tensors; MLP stores non-owning pointers to those tensors after forward() to chain backward().

Threading: call sites must ensure that forward/backward/zeroGradients are invoked in a thread-safe manner relative to one another; this class does not provide internal synchronization.

Template Parameters
TDeviceTypeDevice type for execution (CPU, CUDA, ...).
TPrecisionTensor data precision. Must be supported on the device.

Constructor & Destructor Documentation

◆ MLP()

template<DeviceType TDeviceType, TensorDataType TPrecision>
Mila::Dnn::MLP< TDeviceType, TPrecision >::MLP ( const std::string & name,
const MLPConfig & config,
std::optional< DeviceId > device_id = std::nullopt )
inlineexplicit

Construct an MLP component.

The constructor validates the provided config, constructs the internal child component graph (fc1 -> gelu -> fc2), and optionally creates and assigns an execution context when device_id is provided.

Parameters
nameComponent name used to name child subcomponents.
configMLP configuration (input features, hidden size, bias).
device_idOptional device identifier; when present the MLP creates an owned execution context bound to that device and sets it on the component. If the provided device_id type does not match the template TDeviceType, an exception is thrown.
Exceptions
std::invalid_argumentif config is invalid (via config.validate()).
std::invalid_argumentif device_id is present but has a mismatched device type.

◆ ~MLP()

template<DeviceType TDeviceType, TensorDataType TPrecision>
Mila::Dnn::MLP< TDeviceType, TPrecision >::~MLP ( )
overridedefault

Default destructor.

Child components are stored as shared_ptr and will be destroyed automatically.

Member Function Documentation

◆ backward()

template<DeviceType TDeviceType, TensorDataType TPrecision>
TensorType & Mila::Dnn::MLP< TDeviceType, TPrecision >::backward ( const TensorType & input,
const TensorType & output_grad )
inline

Backward pass using captured forward intermediates.

Uses the child-owned tensors captured by the most recent forward() invocation to chain backward calls without recomputing forward:

  • fc2_->backward(captured_activation_output, output_grad)
  • gelu_->backward(...)
  • fc1_->backward(input, ...)

The method clears the cached forward pointers before returning to avoid accidental reuse.

Preconditions:

  • Component must be built.
  • forward() must have been called previously to populate internal forward caches.
Parameters
inputThe original input tensor passed to forward(); required by fc1_->backward.
output_gradGradient tensor w.r.t. the MLP output.
Returns
Reference to the input-gradient tensor (owned by the fc1 child).
Exceptions
std::runtime_errorif the component is not built or if forward() was not called.

◆ decode()

template<DeviceType TDeviceType, TensorDataType TPrecision>
TensorType & Mila::Dnn::MLP< TDeviceType, TPrecision >::decode ( const TensorType & input) const
inline

Single-token inference convenience: fc1 -> gelu -> fc2 with no gradient capture.

Relies on single-stream ordering for inter-op dependencies; the caller synchronizes before reading results on the host.

◆ forward()

template<DeviceType TDeviceType, TensorDataType TPrecision>
TensorType & Mila::Dnn::MLP< TDeviceType, TPrecision >::forward ( const TensorType & input)
inline

Forward pass.

Chains child component forward calls:

  • fc1_->forward(input)
  • gelu_->forward(...)
  • fc2_->forward(...)

The function stores non-owning pointers to child-owned intermediate tensors produced during the forward call; these pointers are used by backward() to chain gradients.

Preconditions:

  • Component must be built (onBuilding called).
  • Input tensor must be bound to the same device/context as the component.
Parameters
inputInput tensor bound to this component's device/context.
Returns
Reference to the output tensor produced by the final Linear child (owned by that child).
Exceptions
std::runtime_errorif the component is not built prior to calling forward.

◆ getMemoryStats()

template<DeviceType TDeviceType, TensorDataType TPrecision>
MemoryStats Mila::Dnn::MLP< TDeviceType, TPrecision >::getMemoryStats ( ) const
inlineoverridevirtual

Return the current memory allocation breakdown for this component.

Reflects allocations at the moment of the call. The returned stats naturally track the component lifecycle:

After construction – nothing; construction allocates none After build( Inference ) – parameters + T=1 state buffers After build( Training ) – parameters + T=full state buffers After setTrainingMode( Train ) – parameters + state + gradients

For CompositeComponent and Network, the returned stats are the recursive aggregate of all child components.

May be called at any time – no lifecycle preconditions.

Returns
MemoryStats reflecting current allocations.

Implements Mila::Dnn::Component< TDeviceType, TPrecision >.

◆ getType()

template<DeviceType TDeviceType, TensorDataType TPrecision>
const ComponentType Mila::Dnn::MLP< TDeviceType, TPrecision >::getType ( ) const
inlineoverridevirtual

Get the component type identifier.

Used for serialization and runtime type identification.

Returns
Component type enum value.

Implements Mila::Dnn::Component< TDeviceType, TPrecision >.

◆ onBuilding()

template<DeviceType TDeviceType, TensorDataType TPrecision>
void Mila::Dnn::MLP< TDeviceType, TPrecision >::onBuilding ( const BuildContext & context)
inlineoverrideprotectedvirtual

Build-time callback invoked by the CompositeComponent framework.

Validates the input shape, computes the hidden shape, and builds each child with the appropriate shape: fc1 receives the input shape, the GELU and fc2 receive the hidden shape. After building, cached forward pointers are cleared.

Parameters
contextBuild context; inputShape().back() must equal config_.getInputFeatures().
Exceptions
std::invalid_argumentif the input shape rank < 1 or last dimension mismatches config.

Reimplemented from Mila::Dnn::Component< TDeviceType, TPrecision >.

◆ onTrainingModeChanging()

template<DeviceType TDeviceType, TensorDataType TPrecision>
void Mila::Dnn::MLP< TDeviceType, TPrecision >::onTrainingModeChanging ( TrainingMode training_mode)
inlineoverrideprotectedvirtual

Propagate training-mode changes to child components.

Parameters
training_modeNew training mode.

Reimplemented from Mila::Dnn::CompositeComponent< TDeviceType, TPrecision >.

◆ toString()

template<DeviceType TDeviceType, TensorDataType TPrecision>
std::string Mila::Dnn::MLP< TDeviceType, TPrecision >::toString ( ) const
inlineoverridevirtual

Human-readable status and configuration summary.

Returns
String containing component introspection information suitable for logging.

Reimplemented from Mila::Dnn::CompositeComponent< TDeviceType, TPrecision >.

◆ zeroGradients()

template<DeviceType TDeviceType, TensorDataType TPrecision>
void Mila::Dnn::MLP< TDeviceType, TPrecision >::zeroGradients ( )
inlineoverridevirtual

Zero gradients for all child components.

Reimplemented from Mila::Dnn::Component< TDeviceType, TPrecision >.


The documentation for this class was generated from the following file:
  • Mila/Src/Dnn/Components/FFN/MLP/MLP.ixx