Source-linked AI summary

DLCB: Ahead-of-Time Compilation for Dynamic Deep Learning

Alexander Collins, Bin Fan, Evghenii Gaburov, William Brandon, Sean Lee, Hanfeng Chen, Vinod Grover

arXiv:2610.10547v1cs.PL

TL;DR

Dynamic tensor shapes make static compilation require recompilation, while JIT compilation adds runtime latency. DLCB combines static, parameterized AOT, and JIT compilation using shape constraints and automatic shape generalization in PyTorch. Its dynamic-shape kernels approach fully static compilation performance, while a single dynamic binary avoids repeated compilation as input shapes vary.

  • Problem

    Production workloads vary tensor shapes, while static compilers require fixed shapes and JIT compilers add compilation latency on the inference critical path.

    Source: §1 · p. 1
  • Method

    DLCB uses shape constraints to generate static or parameterized AOT kernels when possible, falls back to cached JIT for unknown ranks, and automatically generalizes shapes in PyTorch.

    Source: §1 · pp. 1–2
  • Results

    DLCB’s dynamic-shape kernels approach fully static compilation performance, and a single dynamic binary eliminates repeated compilation as input shapes vary.

    Source: §7 · p. 12
  • Takeaways & Limitations

    For statically known ranks, DLCB can compile kernels once for a range of shapes, with runtime dimensions supplied at launch.

    Source: §1 · p. 1, §7 · p. 11

    In dynamic mode, unknown dimensions prevent the compiler from determining tensor layout and applying layout optimization.

    Source: §5.1 · p. 9

Abstract

from arXiv · show

Deep learning workloads are increasingly deployed in settings where tensor shapes are not fully known at compile time. Batch sizes vary across requests, sequence lengths differ between inputs, and model architectures admit a range of spatial resolutions. This dynamism creates a fundamental tension: ahead-of-time compiled GPU kernels deliver peak performance but traditionally require fully static tensor shapes, while just-in-time compilation supports dynamic shapes at the cost of runtime compilation overhead. We present DLCB (Deep Learning Compiler Backend), a deep learning compiler that resolves this tension through a unified three-tier compilation strategy. For programs with fully static tensor shapes, DLCB generates static CUDA C++ kernels ahead of time. For programs whose tensor rank is statically known but whose dimension sizes are dynamic, DLCB generates AOT kernels parameterized by those dimensions, compiling once and executing across a range of shapes. For programs with tensors of unknown rank, DLCB falls back to JIT compilation at runtime. For AOT compilation with dynamic shape tensors, our approach builds a system of shape constraints from the input program, and uses a solver to reduce these to either a) fixed constraints that produce hard-coded constants in the generated kernel; b) unresolved constraints which become kernel parameters passed at launch time, along with interpreted host code to check that the constraint holds for a given set of inputs and to compute the values to pass. Our compiler and runtime are embedded in PyTorch, and use an automatic shape generalization pass to enable AOT compilation with dynamic shapes for supported subsets of PyTorch programs

1 Introduction

DLCB addresses the mismatch between dynamic tensor shapes and compilation strategies that require fixed shapes or incur runtime compilation latency. It combines static, parameterized AOT, and JIT paths with shape constraints and automatic shape generalization in a PyTorch integration.

1 Introduction

  • Dynamic production workloads vary tensor shapes, while GPU kernels perform best when compiled with full knowledge of their inputs.Static compilation must recompile when shapes change; JIT compilation tolerates dynamic shapes but adds compilation latency on the inference critical path.Source: §1 · p. 1

Contributions

  • For statically known ranks, DLCB solves operator-derived shape constraints to separate hard-coded dimensions from runtime parameters and checks residual constraints before kernel launches.The generated host code also computes concrete dimension values needed as kernel launch arguments.Source: §1 · p. 2, Contributions · p. 2
  • DLCB selects static kernels for fully known shapes, parameterized AOT kernels for known ranks with dynamic sizes, and cached JIT compilation when ranks are unknown.The paths share a unified interface; AOT kernels use launch-time dimension values and host-side checks.Source: §1 · p. 2

1 Introduction

  • The PyTorch bridge partitions programs into supported subgraphs for AOT compilation and leaves unsupported subgraphs to run in PyTorch eager execution.Compiled binaries are spliced back into the broader execution graph.Source: §1 · p. 2

Contributions

  • An automatic shape-generalization pass identifies dimensions that can become free variables, allowing compiled binaries to be reused across shapes without manual symbolic-dimension annotations.The pass operates on statically traced PyTorch programs.Source: §1 · p. 2, Contributions · p. 2

2 Implementation

DLCB’s PyTorch bridge partitions and lowers supported regions, while graph compilation builds constraints, optimizes and partitions the graph, and generates kernels and host programs. At runtime, the system dispatches static, dynamic AOT, or JIT thunks according to what is known about tensor shapes.

2.1 PyTorch-DLCB bridge

  • The bridge partitions supported operators into compilable regions, lowers them to DLCB IR, and leaves unsupported operators in the PyTorch graph.For traced programs, shape generalization identifies dimensions safe to abstract; traced size-one broadcast dimensions can receive specialized paths guarded by runtime checks.Source: §2.1.1 · p. 3, §2.1.2 · p. 3, §2.1.3 · p. 3

2.2 Graph compilation

  • Graph compilation incrementally adds operator-derived shape constraints, enabling contradictions such as incompatible operand shapes to be detected during graph construction.Optimization includes stride assignment, fusion, and pattern rewrites; the graph is then partitioned into vendor-library or custom-kernel thunks.Source: §2.2 · p. 4, §2.2.1 · p. 4, §2.2.2 · p. 4
  • Coordinate-based inference maps each output coordinate to the required inputs, and kgen emits CUDA kernels that compute outputs by iterating over output coordinates.Dynamic dimensions left free by constraint solving become integer kernel parameters.Source: §2.2.3 · p. 4
  • The host code generator turns residual expressions into an interpreted CPU program that resolves dimensions, verifies constraints, and supplies launch arguments before each kernel launch.At runtime, the interpreter fills output slots with resolved shapes, strides, and constants for the kernel launcher.Source: §2.2.4 · pp. 4–5

2.3 Runtime kernel launch

  • Static thunks specialize on concrete shapes, dynamic AOT thunks reuse a binary for inputs with matching rank and element type, and JIT thunks compile on demand when rank is unknown.Dynamic AOT invocation runs the host program to resolve dimensions before memory allocation and kernel dispatch; JIT kernels are cached for subsequent matching shapes.Source: §2.3 · p. 6

3 Constraint Solving

DLCB represents shape constraints as equalities over dimension expressions and repeatedly applies rewrite rules to simplify them. At a fixed point, dimensions become constants, runtime inputs, or residual expressions handled by host code.

3 Constraint Solving

  • The fixed-point solver operates on equality constraints between dimension expressions represented as nodes in a DAG, and is also instantiated for coordinate-set constraints during kernel generation.Expression nodes track free variables and use content-addressed hashes for structural equality.Source: §3 · p. 6
  • The solver repeatedly applies prioritized rewrites—including substitution, list unpacking, arithmetic inversion, and common-subexpression cancellation—until no rule applies.Contradictory equalities between integer literals cause failure.Source: §3 · pp. 6–7
  • The rule set does not solve arbitrary equation systems, but the authors report it suffices for constraints generated by the supported operators’ regular patterns.They argue that a general-purpose solver would add unnecessary overhead and complexity for this bounded constraint vocabulary.Source: §3 · p. 7
  • At a fixed point, dimensions are either compile-time integer literals, runtime named literals, or residual expressions evaluated by the host program at launch.Named literals become kernel parameters; residual constraints are compiled into interpreted host code.Source: §3 · p. 7

4 Dynamic Kernel Generation

kgen generates CUDA kernels for pointwise thunks by inferring how output coordinates map to the inputs needed across operator compositions. It represents coordinates symbolically, propagates them backward through the graph, and uses the resulting maps for code generation and dynamic vectorization.

4 Dynamic Kernel Generation

  • kgen derives input coordinates for arbitrary operator compositions through backward coordinate inference, then generates CUDA kernels that load required inputs and write outputs.This avoids implementing index arithmetic separately for each operator combination.Source: §4 · p. 7

4.1 Coordinate Representation

  • Coordinates represent logical tensor positions through coordinate sets and arithmetic expressions, with bounded coordinate spaces supporting scalar or vector positions.Expression nodes are shared when structurally identical, so sub-expressions are computed only once in the generated kernel.Source: §4.1 · pp. 7–8

4.2 Output Annotation and the Inference Problem

  • kgen assigns each output tensor a free-variable coordinate set, then determines the input coordinates needed for each output in topological order.The resulting coordinate map can be evaluated independently by each thread.Source: §4.2 · p. 8

4.3 Coordinate Inference

  • Coordinate inference propagates output-to-input coordinate transformations backward until rewrite rules resolve every graph node’s coordinate expression..Source: §4.3 · p. 8
  • Operator-specific reverse transforms handle identity and broadcast indexing, reshape arithmetic, reduction loops, and gather’s index-dependent data access.For broadcast dimensions of size 1, the input coordinate maps to 0; reductions iterate across the reduced axis.Source: §4.3 · p. 8

4.4 CUDA C++ Code Generation

  • The completed coordinate map is emitted as CUDA C++, compiled to a cubin at graph-compile time, and launched without recompilation at inference.The host program supplies unresolved dynamic dimensions; generated code evaluates coordinates, loads inputs, and writes each thread’s output.Source: §4.4 · p. 8

4.5 Dynamic Vectorization

  • Dynamic vectorization selects a type-compatible width at compile time, then uses a runtime guard to choose vectorized execution or scalar fallback.The vectorized branch requires every input and output’s last dimension to be divisible by the width and contiguous; grouped coordinates become vector loads and stores.Source: §4.5 · p. 9

5 Evaluation

On TorchVision classification models, DLCB-static exceeds PyTorch eager on average, while DLCB-dynamic is slower on average. DLCB compilation is much faster than torch.compile, and dynamic compilation avoids recompiling when new shapes appear.

5.1 End-to-end inference throughput

  • Dynamic shapes prevent constant-folding and common-subexpression elimination of shape- and stride-dependent expressions, leaving expensive integer division or modulo in address computations.For the same subgraph, dynamic kernels are slower than static counterparts.Source: §5.1 · p. 9
  • A single runtime vector-length guard often misses TorchVision’s differing optimal widths; checking widths 1, 2, 4, and 8 adds overhead.Vectorization typically improves single-kernel performance by 20–25%.Source: §5.1 · p. 9
  • Unknown compile-time dimensions prevent dynamic mode from identifying NCHW versus NHWC tensors and applying layout optimization.NHWC is generally faster for convolution kernels because it better leverages tensor cores.Source: §5.1 · p. 9
  • If only a few dimensions are dynamic, future work could constant-fold more expressions and derive NCHW versus NHWC layout from shape variables.Source: §5.1 · p. 9
  • 1.10x static and 0.92x dynamic speedup relative to eager; dynamic mode is slower than eager on average.Dynamic mode still beats eager on some models.Source: §5.1 · p. 9, Figure 2 · p. 10

5.2 Compilation cost

  • 0.84 s median compile time versus 9.4 s for torch.compile—roughly a 10× reduction—and DLCB-dynamic compiles once without recompiling for new shapes.The dynamic compilation cost is incurred ahead of time at model load.Source: Figure 3 · p. 10, §5.2 · p. 11

6 Related Work

Related systems address shape specialization through static compilation, graph-level dynamic-shape handling, JIT dispatch, symbolic shape inference, or parameterized kernels. DLCB’s distinction is its AOT kernel-parameter approach for known-rank dynamic shapes.

Static-shape compilers

  • Production-oriented static compilers such as XLA, TVM, Halide, Triton, Glow [16], and Relay [15] require concrete dimensions or shape-specific tuning.MLIR supports symbolic dimensions, while DLCB describes its constraint language as a lightweight CUDA-targeted analogue.Source: §6 · p. 11

Dynamic-shape systems

  • DISC [24] handles dynamic shapes with a CPU shape-inference subgraph, whereas DLCB classifies dimensions at compile time and passes free dimensions as kernel parameters.Nimble dispatches to per-shape kernels with JIT fallback; DLCB’s AOT path avoids runtime recompilation for known rank.Source: §6 · p. 11

JIT compilation and PyTorch

  • PyTorch 2 is DLCB’s state-of-the-art reference, while nvFuser generates fused CUDA kernels at runtime and recompiles for each distinct shape.Ansor and AutoTVM also require schedule re-search per shape; Proteus respecializes kernels via runtime JIT.Source: §6 · p. 11

Parameterized kernels

  • PLUTO fixes tile sizes at compile time, while PPCG passes problem size N at runtime; DLCB generalizes runtime parameters to dynamic tensor dimensions.Tiramisu also parameterizes schedules by runtime problem sizes.Source: §6 · p. 11

7 Conclusion

DLCB uses shape constraints to compile AOT kernels for known-rank dynamic tensors, while automatic shape generalization makes them reusable across varying production inputs. Evaluation reports near-static performance and avoids repeated compilation across shapes.

  • DLCB partitions dimensions into compile-time constants and runtime parameters, verifies residual shape constraints before launch, and falls back to JIT when rank is unknown.Source: §7 · p. 11
  • Automatic shape generalization identifies safe dimensions to abstract in traced PyTorch programs, enabling parameterized AOT kernels for production inputs with varying shapes.Source: §7 · pp. 11–12
  • DLCB’s dynamic-shape kernels approach fully-static compilation performance, while one dynamic binary avoids repeated compilation as deployment shapes vary.Source: §7 · p. 12
Loading 2610.10547v1…