Research

Research

We study a single question: how can one high-level program stay correct and fast while the data it works on and the machine it runs on keep changing?

The problem

Computation is written once. It has to run everywhere.

A matrix multiply, a graph traversal, a physical simulation — each is easy to state at a high level. But making it fast forces a cascade of decisions: how is the data stored, dense or sparse and in which format? How is the work tiled and ordered? Does it run on a CPU, a GPU, an accelerator, or a cluster?

Today those decisions are usually baked into the program. Change the data format or the hardware, and much of the code has to be rewritten. That is expensive, and it is why so much high-performance software is narrow and brittle.

Our work is about breaking that coupling — separating what a program computes from how its data is represented and where it runs, and building compilers that fill in the rest.

The approach

One computation, lowered through a stack of decisions

Each layer fixes one more decision. Because the layers are separate, a change at the bottom — a new format, a new machine — does not require rewriting the top.

  1. 01

    Languages

    What you write

    High-level languages and libraries over tensors, relations, graphs, and objects in space.

  2. 02

    Compiler abstractions

    What the compiler reasons about

    Iteration models and intermediate representations that capture the computation on its own, apart from any data structure or machine.

  3. 03

    Representations & formats

    How the data is stored

    Dense and sparse data structures, layouts, and formats — chosen without changing what is computed.

  4. 04

    Schedules & execution

    How the work is organized

    Loop orders, tiling, fusion, and distribution — the strategy for running the computation well.

  5. 05

    Machine targets

    Where it runs

    CPUs, GPUs, accelerators, and distributed clusters, reached from the same source.

From one program to many machines

The same computation should reach CPUs, GPUs, accelerators, and distributed clusters. We express the mapping to hardware as explicit, separate schedules — data distribution apart from computation distribution — so targeting new hardware means writing a schedule, not a new program. This runs from distributed tensor algebra through to co-designed dataflow accelerators.

Distributed & accelerator work

Compilers that generate compilers

If writing a compiler by hand is expensive, generate it. We build meta-compilers, fast baseline JITs, and virtual-machine generators — technology like Copy-and-Patch and Deegen that derives high-performance compilers and interpreters from a description instead of hand-written code.

Meta-compilation work

How we work

We build the systems, then find the abstraction

The group's results tend to come as working systems — compilers, languages, and simulators that run real workloads — alongside the abstractions that make them general. Papers are accompanied by artifacts and open-source releases, and the work spans the full stack, from formal intermediate representations down to co-designed hardware.

Much of it is done with collaborators across programming languages, systems, computer architecture, and graphics, both at Stanford and elsewhere.