---
title: Event Tensor Compiler (ETC)
url: https://www.emergentmind.com/topics/event-tensor-compiler-etc
type: topic
---

# Event Tensor Compiler (ETC)

The Event Tensor Compiler (ETC) is a unified compilation framework designed to address key limitations in megakernel approaches for modern GPU workloads, particularly those involving large language model (LLM) inference. ETC introduces the Event Tensor abstraction to systematically represent fine-grained synchronization, inter-operator dependencies, and dynamic execution patterns in persistent GPU kernels. This enables first-class support for both shape dynamism and data-dependent dynamism, leading to improved GPU utilization, reduced kernel launch overhead, and efficient handling of complex computation graphs [2604.13327].

## 1. Event Tensor Abstraction

An Event Tensor $E$ is a symbolic-shaped, multi-dimensional array of events, each representing a fine-grained synchronization point at the tile level. The principal role of $E$ is to encode producer-to-consumer dependencies among tiled tasks—typically individual CTA-tile invocations of operators—across the computational graph.

Each dimension of $E$ may remain symbolic until runtime, providing support for shape dynamism. Data-dependent dynamism is also natively supported, where index mappings and counters can be initialized or updated based on runtime data (e.g., as in Mixture-of-Experts (MoE) top-k routing).

### Formalism

- Let $T = \{T_1,\ldots,T_M\}$ denote the set of all tasks, with each $T_p$ corresponding to a single tile invocation.
- $E \in \mathbb{N}^{d_1 \times \cdots \times d_r}$ is an $r$-dimensional Event Tensor, with its concrete shape $(d_1,\ldots,d_r)$ potentially symbolic until runtime.
- Two bipartite relation sets define synchronization:
    - $\text{InEdges} \subseteq T \times \text{Index}(E)$
    - $\text{OutEdges} \subseteq T \times \text{Index}(E)$
    - Where $\text{Index}(E) = \{\mathbf{i} \in \mathbb{N}^r \mid 0 \le i_j < d_j\}$.

- For $(T_p, \mathbf{i}) \in \text{OutEdges}$, $T_p$ must call $E[\mathbf{i}].\text{notify()}$ on completion.
- For $(T_q, \mathbf{i}) \in \text{InEdges}$, $T_q$ waits via $E[\mathbf{i}].\text{wait()}$ before starting.

Synchronization semantics rely on global integer counters, with notify implemented as an atomic decrement and wait as spin-wait until zero.

### Example: Split-K Reduction

Given $A \in \mathbb{R}^{N\times K}$, tasks $T_{i,j}$ compute partial sums $B[i,j]=\sum_{k \in [32j,32j+32)}A[i,k]$ and tasks $U_i$ compute $C[i]=\sum_j B[i,j]$. An Event Tensor $E \in \mathbb{N}^N$ is defined such that:

- OutEdges: $(T_{i,j}, i)$ for all $j$
- InEdges: $(U_i, i)$

$T_{i,j}$ calls $E[i].\text{notify()}$ on completion; $U_i$ invokes $E[i].\text{wait()}$ before consuming.

## 2. Compiler Pipeline and Scheduling

The ETC compiler transforms computational graphs annotated with Event Tensors into a single persistent GPU kernel, supporting both static and dynamic scheduling backends. Operators are assumed to be written as CTA-tile-level device functions.

### High-Level Workflow

1. **Frontend IR**: Operators carry per-tile shapes, and InEdges/OutEdges/Types of Event Tensors.
2. **Graph-Level Optimization**: Constant folding and memory planning are performed.
3. **Tile-Level Optimization**: Includes tensor-core usage and pipelining.
4. **Scheduling Transformation**: Selection of static or dynamic scheduling passes.
5. **Prefetch Rewriting**: Optional, for weights.
6. **Code Generation**: Generation of a persistent kernel.
7. **Static Queue Materialization**: For static schedules, per-SM static queues are generated per shape.

### 2.1 Static Scheduling

- For each SM $s$, a fixed ordered task list $Q_s$ is precomputed.
- A fused kernel with $\text{SM\_COUNT}$ CTAs is emitted.
- Each CTA loops over $Q_s$ in order, executing:
    - For each task: wait on InEdges, execute operator, notify on OutEdges.
- At runtime: a single launch, zero scheduling overhead.

### 2.2 Dynamic Scheduling

- On-device scheduler maintains a lock-free global queue.
- At kernel start, initialize all Event counters.
- Push tasks with zero InEdges into the ready queue.
- Each CTA pops tasks, waits on InEdges, executes the operator, and upon completion, decrements respective Event counters. If an Event counter reaches zero, enqueue all dependent consumer tasks.
- No host involvement after kernel launch.

### 2.3 Dynamism Support

- **Shape Dynamism**: Event Tensor shapes and edge mappings are symbolic and instantiated concretely at runtime.
- **Data-Dependent Dynamism**: Index expressions can access runtime tensors (e.g., MoE’s $\mathit{topk}$ or $\mathit{exp\_indptr}$), enabling compilation ahead-of-time while supporting dynamic event graphs.

## 3. Persistent-Kernel Design

### 3.1 Kernel Launch Strategy

ETC eliminates repeated kernel launches by fusing subgraphs—often entire LLM decoding workloads—into a single persistent kernel. CTAs either loop over a static work list or pull new work adaptively from the ready queue.

### 3.2 Synchronization Semantics

All synchronization is implemented through global integer arrays, with atomic decrements for notifications (possibly spin-free) and spin-wait for waits. This design avoids the need for specialized runtimes.

### 3.3 Cross-Operator Task Parallelism

ETC exposes tile-level dependencies across traditional operator boundaries, enabling parallel execution patterns such as:

- Overlapping attention Q-Norm+RoPE with K/V Norm+RoPE.
- Fusing MLP GEMM+activation+post-norm in pipeline stages.
- Grouping and GroupGEMM fusion for MoE layers via dynamic events.

### 3.4 Scheduling Constraints

A task is eligible for dispatch when its InEdge event counters are zero. In static scheduling, the task order is precomputed on the host to respect these constraints; in dynamic scheduling, on-device queueing maintains correctness.

## 4. Performance Evaluation

Benchmarks on NVIDIA B200 GPUs using CUDA 13 and PyTorch 2.8 provide insights into ETC’s efficiency and latency benefits.

### 4.1 Cross-Operator Fusion

- **GEMM+ReduceScatter** (dynamic scheduling): up to 1.40× speedup over cuBLAS+NCCL baseline.
- **AllGather+GEMM** (static scheduling): up to 1.40× speedup.

### 4.2 Mixture-of-Experts (MoE) Layer

- Qwen3-30B-A3B, TP=1, tokens=64–1024 (dynamic): up to 1.23× speedup versus Triton for 512–1024 tokens.
- ETC shows consistent gains over Triton and FlashInfer across token counts.

### 4.3 LLM Low-Batch Inference

| Batch | vLLM Normalized Latency | SGLang | ETC |
|-------|-----------------------|--------|-----|
| 1     | 1.00                  | 0.83   | 0.68|
| 4     | 1.00                  | 0.89   | 0.75|
| 16    | 1.00                  | 0.95   | 0.79|
| 64    | 1.00                  | 0.98   | 0.82|

Qwen3-32B, TP=4: ETC matches or slightly exceeds vLLM and SGLang across batch sizes, reporting ≈1.05× on small batches.

### 4.4 Warm-up Overhead

| Engine  | Warm-up Time (s) | # CUDA-Graph Captures |
|---------|------------------|----------------------|
| vLLM    | 123              | 67                   |
| SGLang  | 583              | 203                  |
| ETC     | 35               | 1                    |

ETC achieves significant reductions in system warm-up times and CUDA-Graph capture overhead.

## 5. Design Trade-Offs and Practical Considerations

### Static vs Dynamic Scheduling

- **Static scheduling**: Minimizes runtime overhead and is optimal for regular DAGs (e.g., standard transformer layers, AllGather+GEMM).
- **Dynamic scheduling**: Accommodates data-dependent, unpredictable workloads (MoE, communication jitter), but introduces scheduler push/pop costs and potential contention, especially in multi-GPU tensor-parallel (TP) deployments.

### Scalability

Event Tensors support scaling to millions of events with minimal compilation-time overhead. However, the memory footprint for counters grows with the number of tiles, and spin-waiting for events can consume cycles. In practice, such overhead is often amortized through overlapping workloads.

### Programming Model and Automation

Device functions require explicit tiling and event annotation. Automatic derivation of event graphs from high-level programs represents an open direction. Coverage of hot input shapes for sampled static schedules may require manual tuning.

## 6. Implications and Future Directions

The Event Tensor abstraction and ETC compiler unify static and dynamic megakernel fusion in a single consistent framework, supporting both runtime shape and data-dependent dynamism without requiring recompilation or CUDA-Graph recapture. This suggests substantial potential for deploying high-performance LLM inference systems with reduced operational overhead and flexible support for next-generation dynamic workloads. A plausible implication is that continued development in automatic event graph generation and shape management may further lower the barrier for adoption in complex deep learning pipelines [2604.13327].

Source: https://www.emergentmind.com/topics/event-tensor-compiler-etc