Skip to main content
Custom epilogues allow you to fuse element-wise operations directly into the GEMM kernel, eliminating separate kernel launches and improving memory bandwidth efficiency.

Overview

Instead of:
You can fuse everything into a single kernel:
This approach:
  • Reduces memory traffic
  • Eliminates kernel launch overhead
  • Improves overall throughput

Epilogue Fusion Configuration (EFC)

For Blackwell (SM100) and later architectures, CUTLASS provides the Epilogue Fusion Configuration (EFC) framework for defining custom epilogues.

Basic Example: Alpha-Beta Scaling

This example demonstrates a GEMM with custom epilogue that computes:
1

Define the kernel class

Start by extending the base EFC kernel:
2

Define tensor arguments

Specify the input and output tensors:
3

Define the epilogue operation

Implement the custom fusion logic:
4

Configure the epilogue

Set up the epilogue fusion configuration:

Running the Example

Command Line Usage

With NCU Profiling

Advanced Examples

Activation Functions

Fuse common activation functions:

Multiple Outputs

Generate multiple output tensors:

Complex Expressions

Implement sophisticated fusion patterns:

Legacy Epilogue Interface (Pre-SM90)

For older architectures, use the high-level Python interface:
See examples/python/deprecated/01_epilogue.ipynb for more details.

Supported Operations

The epilogue can include:

Mathematical Operations

  • Addition, subtraction, multiplication, division
  • Power, exponential, logarithm
  • Trigonometric functions (sin, cos, tan)

Activation Functions

  • ReLU, Leaky ReLU, PReLU
  • Sigmoid, tanh
  • GELU, SiLU
  • Softmax (with limitations)

Memory Operations

  • Load from multiple input tensors
  • Store to multiple output tensors
  • Conditional stores

Type Conversions

  • Mixed precision computations
  • Type casting between FP32, FP16, BF16, INT8

Performance Considerations

Follow these guidelines for optimal performance:
  • Minimize memory traffic: Read each input tensor only once
  • Limit register pressure: Avoid storing too many intermediate values
  • Use vectorized operations: Leverage SIMD instructions where possible
  • Consider data types: Match precision requirements to avoid unnecessary conversions

Memory Bandwidth

Epilogue fusion is most beneficial when:
Profile your kernel to ensure the epilogue doesn’t become memory-bound.

Register Usage

Monitor register usage with NCU:
High register pressure can reduce occupancy.

Data Type Support

Supported Input Types (A, B)

  • FP16, BF16
  • TF32
  • INT8, UINT8
  • FP8 (E4M3FN, E5M2)

Supported Accumulator Types

  • FP32 (for all floating-point inputs)
  • FP16 (for FP16 and FP8 inputs)
  • INT32 (for INT8/UINT8 inputs)

Supported Output Types (C, D)

  • FP32, FP16, BF16
  • INT32, INT8, UINT8
  • FP8 (E4M3FN, E5M2) with FP32 accumulator

Constraints

Be aware of these limitations:
  • MMA tiler M must be 64/128 (single CTA) or 128/256 (2-CTA mode)
  • MMA tiler N must be 32-256 in steps of 32
  • Cluster shape must be power of 2, total size ≤ 16
  • Contiguous dimensions must be 16-byte aligned
  • All epilogue tensors must have the same major order (row or column)

Debugging Tips

Enable Verification

Check Memory Alignment

Examples in the Repository

Find complete working examples:
  • Custom epilogue: examples/python/CuTeDSL/blackwell/epilogue/custom_epilogue_dense_gemm.py
  • Activation fusion: examples/python/CuTeDSL/blackwell/epilogue/activation_custom_epilogue_dense_gemm.py
  • Synthetic examples: examples/python/CuTeDSL/blackwell/epilogue/synthetic_custom_epilogue_dense_gemm.py
  • Legacy interface: examples/python/deprecated/01_epilogue.ipynb

Next Steps

Basic GEMM

Master basic GEMM operations first

Grouped GEMM

Combine custom epilogues with grouped operations