research34 min studyLesson 96 in Engineering

Compiler graphs and kernel fusion

Study graph capture, specialization, memory traffic, and fusion through measurable execution costs and correctness constraints.

On this page

What you’ll understand

  • Identify graph transformations and their correctness obligations.
  • Estimate a memory-traffic bound for a simple fused operation.
  • Explain why fusion can lose through resource pressure or specialization cost.

An eager program launches three kernels and writes two temporary arrays. A compiler might replace them with one kernel that keeps intermediate values in registers. The mathematical expression is unchanged, yet memory traffic and launch overhead can fall sharply. Whether the program becomes faster depends on shapes, memory hierarchy, resource pressure, and compilation costs. Compiler research therefore connects program semantics to the hardware execution schedule, rather than treating fewer graph nodes as a universal performance metric.

Capture a computation with explicit assumptions

A compiler represents operations, data dependencies, shapes, dtypes, and sometimes effects in an intermediate graph. Transformations can reorder independent work, eliminate redundant computation, specialize shapes, or lower high-level operations into device kernels. Correctness includes aliasing and mutation behavior, not merely algebraic equality on isolated values. Random-number generation, host interaction, data-dependent control flow, and unsupported operations can restrict capture or divide execution into separate graph regions.

Specialization makes assumptions that must be checked when the program runs again. A shape or stride change can require another compiled variant; too many variants can consume compilation time and memory. Distinguish first-call latency from steady-state latency and report the workload's shape distribution. A benchmark with one repeated tensor shape may conceal recompilation that dominates a real service with varied requests. Keep a reliable eager reference path for small correctness comparisons.

Ttotal=Tcompile+R TcompiledT_{\mathrm{total}}=T_{\mathrm{compile}}+R\,T_{\mathrm{compiled}}
For R executions of one reusable compiled variant, this simple accounting includes a one-time compile cost. Multiple specializations, cache eviction, and asynchronous compilation need additional terms.↔ Scroll wide equations horizontally.

Use memory traffic to explain fusion

Consider elementwise operations y=a x+b followed by z=max(y,0), where a and b are scalar constants. An unfused path may read x, write y, read y, and write z. A fused path can read x and write z while retaining y locally. Count bytes at the relevant memory boundary and state whether caches, constant loads, and allocation overhead are excluded. Lower traffic matters most when bandwidth or launch latency limits execution.

The roofline model compares arithmetic intensity with available compute and bandwidth to give a simplified performance ceiling. Fusion can increase useful work per transferred byte, but can also increase register use, cause spills, reduce occupancy, or prevent reuse of a highly optimized library operation. Tiling and recomputation can be more valuable than blindly merging everything. FlashAttention is an important example of reorganizing attention around memory movement; its exact-attention claim concerns the mathematical operation, not bitwise identity across floating-point schedules.

Pattainable≤min⁡(Ppeak, BmemI),I=operationsbytes transferredP_{\mathrm{attainable}}\leq\min(P_{\mathrm{peak}},\,B_{\mathrm{mem}}I),\qquad I=\frac{\text{operations}}{\text{bytes transferred}}
This idealized roofline bound uses a consistent operation convention and a specified memory level. It omits latency, occupancy, contention, and many scheduling details, so being below it does not identify a unique bottleneck.↔ Scroll wide equations horizontally.

Evaluate transformations across the complete workload

Validate outputs, gradients, and relevant side effects before timing. A reassociation valid over real numbers may change floating-point rounding or exceptional-value behavior. Decide whether the application permits that relaxation and quantify its consequences. Test representative dtypes, noncontiguous layouts, edge shapes, and boundary conditions. Numerical tolerance should follow the operation and conditioning, rather than being widened until every failing result passes.

Use device-aware timing that waits for the measured asynchronous work to complete, with warm-up and enough independent repetitions. Report kernel counts, transferred bytes when measured, peak memory, compile time, and end-to-end latency or training time. An optimized kernel that saves two milliseconds may have little product impact when input parsing consumes a second. Conversely, reducing allocation can improve peak memory enough to enable a larger useful batch, an effect a fixed-batch microbenchmark would miss.

Count traffic and the compilation crossover

Process 10 million float32 elements with the two-stage elementwise path described above. Assume each array pass reaches external memory, effective bandwidth 400 GB/s, and negligible arithmetic cost. Compilation costs 0.3 s.

  1. One array is 10,000,000 × 4 = 40,000,000 bytes, or 40 decimal MB.

  2. Four unfused array passes transfer 160 MB; two fused passes transfer 80 MB under the stated no-cache assumption.

  3. Bandwidth-only times are 0.0004 s and 0.0002 s, so the estimated saving is 0.0002 s per call.

  4. Recovering a 0.3-second compilation cost requires 0.3/0.0002 = 1,500 calls to break even. Launch overhead, cache reuse, and register effects can change this estimate.

The result

Fusion halves this modeled traffic, but an application needs enough repeated work to amortize compilation and must verify the actual bottleneck.

Explore the model

Interactive lab

Interactive lab · network

Inspect dependencies in a small computation graph

Adjust input x and weight w for the single sigmoid computation σ(wx−0.5). Follow the displayed intermediate dependencies and output. This is an inspectable toy graph, not a compiler, trainable network, kernel profiler, or Transformer implementation.

Inspect dependencies in a small computation graphOne inspectable sigmoid unit, σ(wx − 0.5). Playback traces the computation graph. There is no training, attention mechanism or hidden deep network. Current readings: Product · wx: 1.2; Logit · wx − 0.5: 0.7; Sigmoid output: 0.6682. All parameters are adjustable with the labeled controls below.One input. One weight. One sigmoid.x1.20× w1.20+ b0.70σ0.668output0.668w = 1.00b = −0.50σ(z) = 1 / (1 + exp(−z))
Computation graphSignal trace
Product · wx
1.2
Logit · wx − 0.5
0.7
Sigmoid output
0.6682
t = 0 s

One inspectable sigmoid unit, σ(wx − 0.5). Playback traces the computation graph. There is no training, attention mechanism or hidden deep network. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forA graph exposes dependencies; performance also depends on where and how intermediate values are stored.

Check your understanding

Why can fusing additional operations make a GPU kernel slower?

Try it yourself

A compiled implementation costs 2 s to compile and then takes 8 ms per call; eager execution takes 10 ms. Find the equality point and compare total time for 500 calls.

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Include the one-time cost before comparing repeated-call savings.

Compare with the solution

The saving is 2 ms per call, so equality is at 2/0.002 = 1,000 calls. For 500 calls, eager takes 5 s and compiled execution takes 2 + 500 × 0.008 = 6 s. This assumes one reusable specialization and no additional setup or cache effects.

Take it with you

  • Graph transformations require semantic and numerical correctness checks.
  • Fusion helps by changing memory traffic and scheduling, with resource tradeoffs.
  • Measure compilation amortization and end-to-end effects across real shape variation.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.