Home · ASPLOS 2026 · Compilers & Programming Languages

Linear Layouts: Robust Code Generation of Efficient Tensor Computation Using F_2

Keren Zhou, Mario Lezcano Casado, Adam P. Goucher, Akhmed Rakhmati, Jeff Niu, Justin Lebar and 5 others

Conference
ASPLOS 2026
Published
2026
Pages
132-146
Citations
3

To run a matrix multiply fast on a GPU, you have to keep shuffling the numbers between the arrangement memory likes and the arrangement the tensor-core hardware demands — and today's compilers handle these arrangements one hard-coded case at a time, needing a separate hand-written conversion for every pair, which is buggy and explodes as new chips arrive; this work from the Triton team shows that every such arrangement is really just a matrix of ones and zeros, so all the conversions become plain linear algebra that composes automatically, wiping out the case explosion, fixing whole classes of bugs, and speeding real kernels.

The argument in one glance

  1. Problem

    GPU tensor layouts are handled one hard-coded case at a time

    Fast tensor computation depends on tensor layouts — how a logical tensor maps to hardware registers, threads, warps, and memory. A GPU wants data one way for memory access and another for its matrix-multiply units, so data is constantly converted between layouts. But compilers hard-code a fixed set of layouts and a separate hand-written conversion for each pair.

  2. What people did

    Add each layout and conversion by hand

    Support layouts as special compiler attributes, and for each new layout write the code for it and the routines to convert it to and from every other layout.

  3. Why it fell short

    The conversions explode quadratically and are buggy

    The number of layout-to-layout conversions grows with the square of the number of layouts, so adding a layout means heavy compiler surgery. The manual work is error-prone — 12 percent of the bugs filed against Triton are layout-related — and, without first-class layouts, compilers leave data movement suboptimal, forcing experts to hand-optimize what the compiler cannot.

  4. This paper's idea

    Model every layout as a binary matrix (Linear Layouts)

    Linear Layouts treats each tensor layout as a linear map over the two-element field — a matrix of ones and zeros acting on the bits of the hardware and tensor indices. Swizzling and broadcasting become XOR and AND on bit-vectors, and any layout conversion is just composing matrices (multiply, invert), eliminating the quadratic explosion. Integrated into Triton, it automatically derives optimal data movement, fixes many bugs, and delivers up to a 1.40 times speedup (1.07 times on average) across 265 real benchmarks.

Why this problem is worth solving

The speed of a GPU tensor kernel turns on a detail most people never see: exactly where each number physically lives.

A tensor is a logical array of numbers, but to compute with it on a GPU, every number must physically reside somewhere concrete — in a particular register of a particular thread within a particular warp, or in a spot in shared memory. The mapping from the logical tensor to these hardware resources is called the tensor layout, and it is decisive for performance. The reason is that different parts of the GPU want data arranged differently. When loading from memory, you want a coalesced layout, where adjacent threads read adjacent addresses, so the hardware can fetch a wide chunk in one go and maximize bandwidth. But the tensor-core units that do fast matrix multiplication — driven by special instructions on NVIDIA, AMD, and Intel GPUs — require their inputs distributed across threads and warps in a specific, different layout to compute correctly. So a kernel is constantly rearranging data between the layout that is good for memory and the layout that is good for compute, an operation called a layout conversion. To make matters harder, the required layouts differ across GPU generations (NVIDIA’s Ampere, Hopper, and Blackwell each differ), across vendors, and across data types, so the space of layouts and conversions a compiler must handle is large and growing.

The trouble is that today’s tools handle this explosion of layouts the worst possible way — by hand, one case at a time.

Deep-learning practitioners who need peak performance rely on vendor libraries like cuDNN and cuBLAS, but those cover only a limited set of standard operators; a custom operator from a new model falls outside them, forcing developers to write GPU kernels from scratch and wrestle with layouts directly. Deep-learning compilers such as Triton, TVM, and XLA do better by building layouts into their backends, but they support only a limited, fixed set of layouts and of conversions between them. Defining a new custom layout requires substantial changes to the compiler, and — this is the crux — a conversion routine must exist for each pair of layouts, so the number of conversions grows with the square of the number of layouts: a quadratic explosion. Every one of those routines is hand-written and error-prone; the paper notes that fully 12 percent of the bugs filed against Triton’s repository are layout-related. And because these compilers do not treat layouts as a first-class object to optimize, they often leave data movement suboptimal, so expert authors resort to hand-tuning conversions the compiler cannot express — as the authors of FlashAttention 3 did, manually using byte-permute and warp-shuffle instructions to bypass shared memory. What is missing is a general, systematic, robust way to represent layouts and their conversions.

What people did before, and where it broke

  • Use vendor libraries for standard operations. Call cuDNN or cuBLAS to get peak performance on common operators. Where it broke. They cover only a limited set of operators; a custom operator forces writing kernels from scratch and dealing with layouts by hand.
  • Bake a fixed set of layouts into the compiler. Have compilers like Triton, TVM, and XLA support layouts as special attributes. Where it broke. Only a limited set of layouts and conversions is supported, and adding a new one requires heavy compiler changes.
  • Hand-write a conversion for each pair of layouts. Implement each layout-to-layout conversion routine individually. Where it broke. The number of conversions grows quadratically with the number of layouts, the manual work is error-prone (a large share of Triton’s bugs), and data movement is left suboptimal.
  • The gap. No framework represented all layouts and all their conversions in one general, composable, provably-correct formalism that a compiler could optimize automatically. Providing that, using linear algebra over a binary field, is what Linear Layouts does.

How Linear Layouts works

From hand-coded per-pair conversions to composable matrix algebra

  1. new

  2. new

  3. new

  4. new

  5. new

The idea

Turn a sprawl of special cases into one piece of mathematics. The heart of Linear Layouts is to stop treating each tensor layout as a bespoke special case and instead model every layout as a single kind of mathematical object: a linear map over the two-element field, a matrix of ones and zeros that acts on the bits of a hardware-resource index to produce the bits of a logical-tensor index — so swizzling and broadcasting become nothing more than XOR and AND operations on bit-vectors. Replacing ad-hoc, case-by-case reasoning about how the hardware behaves with one precise mathematical formalism is the same move the GPU memory-model work covered elsewhere on this site makes, capturing what the hardware does in an exact algebraic model so that a whole domain can be reasoned about uniformly instead of one situation at a time.

Compose conversions instead of enumerating them. Because every layout is a matrix, a conversion between any two layouts is simply the composition of their matrices — a matrix multiply and inverse — so the compiler computes arbitrary conversions on demand rather than storing a hand-written routine for each pair, which is exactly what dissolves the quadratic explosion that plagues layout systems. Generating a combinatorial space of cases from a small, general representation, rather than hand-writing every case, is the same strategy the relational-graph-network compiler work covered elsewhere on this site takes, producing what would be an unmanageable explosion of specialized kernels from a compact set of general templates instead.

Let the algebra reveal the fastest data movement, automatically. Having layouts as algebra lets the compiler search that structure for the best way to move data: a layout engine in Triton automatically derives swizzles that provably maximize read and write vectorization and minimize shared-memory bank conflicts, optimal warp shuffles, and generic lowerings of hardware instructions, so data movement is optimized generically rather than hand-tuned per kernel. Making the compiler automatically generate efficient GPU code and optimize data movement that experts otherwise tune by hand, cutting engineering effort, is the same aim the deep-learning-training compiler work covered elsewhere on this site pursues, turning laborious hand-optimization of GPU kernels into automatic, systematic code generation.

Following a layout conversion through Linear Layouts

Converting a memory layout into a tensor-core layout

A trace of Linear Layouts computing and optimizing one conversion, following the paper's design.

Step 1 of 5

Load in a memory-friendly layout

A kernel loads a tensor from global memory in a coalesced, bandwidth-friendly layout, but the tensor-core matrix-multiply instruction needs the data in a different, specific layout.

Two layouts, good for two different purposes, must be reconciled.

Why it works

  • Layouts are the key to tensor performance. Because a GPU forces data into different arrangements for memory access and for compute → tensors must be constantly converted between layouts → so how layouts and their conversions are handled determines performance.
  • One algebra replaces a sprawl of special cases. Because every layout can be written as a binary matrix acting on index bits → the messy, case-by-case handling collapses into linear algebra → so any layout in the family plugs in and is treated uniformly.
  • Composition kills the quadratic explosion. Because a conversion between two layouts is just the composition of their matrices → arbitrary conversions are computed by matrix multiply and inverse rather than hand-written per pair → so the number-of-layouts-squared explosion of code disappears.
  • Algebraic structure exposes the best data movement. Because swizzling and broadcasting are XOR and AND on bit-vectors within the algebra → the compiler can search that structure for the conversion that maximizes vectorization and avoids bank conflicts → so optimal hardware primitives are derived generically rather than hand-tuned.
  • First-class layouts are more correct and less work. Because layouts and conversions are computed from a formalism instead of coded case-by-case → whole classes of layout bugs vanish and backend effort drops → so the compiler is both more robust and easier to extend.

What it costs (trade-offs and scope)

  • The layout family is those expressible as linear maps. Linear Layouts covers any layout that can be represented as a permutation of indices or via swizzling — a broad and practically important family — but a layout that cannot be expressed as a linear map over the two-element field falls outside the framework.
  • The speedups are modest on average. The improvement is up to 1.40 times but averages 1.07 times across 265 benchmarks; much of the value is in correctness, robustness, and engineering effort rather than a uniformly large speedup, and common access patterns were already well served by the legacy heuristics.
  • It is a compiler-backend change tied to Triton. The work is implemented in and integrated with Triton’s GPU backend. Its benefits are realized through Triton (though the mathematical framework is general); other compilers would need their own integration.
  • The abstraction has a learning curve. Reasoning about layouts as binary matrices and bit-level linear algebra is powerful but unfamiliar, so adopting or extending the framework requires thinking in these terms rather than in concrete layout diagrams.
  • Optimality is within the modeled objectives. The automatic swizzling provably maximizes vectorization and minimizes bank conflicts, which are the right proxies for data-movement efficiency, but they are specific objectives; the true best kernel could depend on factors outside them.
  • Hardware coverage depends on modeling each target. Supporting a GPU’s special units means expressing their required layouts in the formalism and lowering to their intrinsics; the approach makes this systematic, but each new hardware family still must be brought into the model.

The evaluation

Three ways to handle tensor layouts for GPU kernels

PropertyVendor librariesLegacy compiler layoutsLinear Layouts
Supports custom and new layouts
Layout-to-layout conversionsNot applicable
Correctness and robustnessHigh for supported ops
Automatic data-movement optimizationInternal to the library
OutcomePeak but inflexibleSuboptimal and buggyUp to 1.40x, average 1.07x, fewer bugs
Three ways to handle tensor layouts for GPU kernels, as framed by the paper. Vendor libraries (cuDNN, cuBLAS) are fast but cover only standard operators. Legacy compiler layout systems (as in Triton before this work) bake in a limited set of layouts and hand-write a conversion routine for each pair, so conversions grow with the square of the number of layouts, adding a layout requires heavy changes, and the manual code is error-prone (12 percent of Triton's bugs are layout-related) with suboptimal data movement. Linear Layouts models every layout as a matrix of ones and zeros over the two-element field acting on index bits, so swizzling and broadcasting are XOR and AND operations, and any conversion is computed by composing matrices (multiply and inverse) — eliminating the quadratic explosion. Integrated into Triton as a layout engine that automatically chooses and propagates layouts, it derives provably optimal swizzles (maximizing vectorization, minimizing shared-memory bank conflicts) and warp shuffles. It improves correctness, fixes many pre-existing Triton bugs, reduces backend engineering effort, and yields up to a 1.40 times speedup, averaging 1.07 times across 265 real-world benchmark cases.Underlined values explain themselves when clicked.

Check yourself

Check your understanding

  1. 1. What is a tensor layout, and why does it matter for GPU performance?

  2. 2. Why does the traditional way of handling layouts scale so badly?

  3. 3. What is the key idea of Linear Layouts?

  4. 4. Beyond raw speed, what does integrating Linear Layouts into Triton achieve, and what are its results?

Sources

The paper is “Linear Layouts: Robust Code Generation of Efficient Tensor Computation Using F_2” by Keren Zhou, Mario Lezcano Casado, Adam P. Goucher, Akhmed Rakhmati, Jeff Niu, Justin Lebar, Pawel Szczerbuk, Peter Bell, Phil Tillet, Thomas Raoux, and Zahi Moudallal, published at ASPLOS 2026, DOI 10.1145/3760250.3762221. The authors are affiliated with OpenAI and George Mason University.

This explainer is based on the full text of the paper, obtained from the authors’ arXiv version (arXiv:2505.23819), which corresponds to the CC-BY version of record. The problem framing (tensor layouts as mappings between logical tensors and GPU hardware resources; the need to convert between coalesced memory-friendly layouts and tensor-core compute layouts; the proliferation of layouts across GPU generations, vendors, and data types; the limitations of vendor libraries and of deep-learning compilers that support a fixed set of layouts with hand-written per-pair conversions leading to a quadratic explosion; the report that 12 percent of Triton’s bugs are layout-related; and the example of FlashAttention 3 hand-optimizing conversions), the Linear Layouts approach (modeling every layout as a linear map over the two-element field, a binary matrix acting on the bits of the indices; expressing swizzling and broadcasting as XOR and AND on bit-vectors; composing arbitrary conversions via matrix multiplication and inverse to eliminate the quadratic explosion; and integration into Triton’s GPU backend as a layout engine that automatically chooses and propagates layouts), the novel algorithms (automatic optimal swizzling discovery that provably maximizes read/write vectorization and minimizes bank conflicts, automatic optimal warp-shuffle generation, and generic lowering of hardware intrinsics), and the results (up to a 1.40 times speedup with an average of 1.07 times across 265 real-world benchmark cases, alongside improved correctness through fixing many pre-existing Triton bugs and reduced backend engineering effort) are all drawn directly from the paper. Background explanations of GPUs, threads and warps, tensor cores, shared memory and bank conflicts, coalesced access, and linear algebra over a binary field are standard and provided to make the paper’s contribution understandable.

Related papers on Compilers & Programming Languages

See all 162 →