Skip to content

Instantly share code, notes, and snippets.

@geohot
Last active October 26, 2026 17:12
Show Gist options
  • Select an option

  • Save geohot/4768597d9dc536446ee2d5de1f29e89d to your computer and use it in GitHub Desktop.

Select an option

Save geohot/4768597d9dc536446ee2d5de1f29e89d to your computer and use it in GitHub Desktop.
Compilers for Machine Learning

Compilers for Machine Learning

A hands-on one semester course where students build their own compiler from scratch, starting from elementwise programs and ending with training SOTA LLMs on GPUs. This course aggressively builds on the previous week, and is an exercise in slop management. If you let any slop in early, it will compound and you will not finish the class.

Course description: This course covers the design and implementation of a modern machine learning compiler, and examines the interaction between IR design, hardware capabilities, and the structure of machine learning programs. Topics covered include term rewriting, code generation, movement operators, kernel fusion, memory hierarchies, GPU architecture, automatic differentiation, and flash attention. It is a project course, providing experience with performance-oriented programming, managing a codebase that grows all semester, and working in 1 or 2 person teams, culminating in a compiler capable of training modern LLMs.

Prerequisites: This course has no formal prerequisites, but it is designed for someone who is deeply familiar with the material in 15-213 or equivalent, highly skilled in the language they choose to implement their compiler in, capable of managing programming projects that are long in timeline, and comfortable with C and some GPU programming. There will be frequent in-person quizzes and lectures will not be posted online, so only sign up if you plan to attend class.

This syllabus will outline the spec, but not the implementation. The implementation and choice of programming language is up to the student. There is no starter code. We will establish a universal, simple, interchange format for UOps.

# gemm_256x256.uir
%0 = buffer 65536 dtype=f32 slot=0
%1 = buffer 65536 dtype=f32 slot=1
%2 = reshape %0 [256 256 1] 
%3 = reshape %1 [256 1 256]
%4 = mul %2 %3
%5 = reduce %4 op=add pop=1

  • 55% -- compiler (weeks 1-10)
    • 5% -- 10 tests -- due every monday (weeks 1-10), judged on correctness by openly accessible binary oracle
    • 20% -- correctness -- due every wednesday, passing all student tests + teacher tests + basic performance gates
    • 15% -- style (did you write slop? can I read your code? can it be simpler?)
    • 15% -- performance (weeks 6-10, graded on a curve)
  • 25% -- final project (weeks 11-14)
  • 20% -- in person quizzes at the start of class (will be at least 20 of them)

No midterm or final. < 70 = F, 70-80 = C, 80-90 = B, 90+ = A.


Week 1: UOps & Rewrites & Renderer?

uops · elementwise ops · symbolic · rewrites · renderer

Students become familiar with the UOp and write a compiler capable of compiling and simplifying elementwise programs. We introduce the graph structure and rewriting. The UOp is hash consed. All shapes are rank 0. We allow rank 1 shapes here, but ALU ops must be rank 0.

UOp(op, src:tuple[UOp, ...], arg)

Recursive properties introduced:

dtype(void,bool,i32,f32)
shape:tuple[int, ...]
bounds:tuple[int, int]

Ops introduced:

CONST -- type determined by the arg 

lambda calculus:
PARAM(ParamArg) -- arg input to the call
CALL(CallArg) -- src[0] is the function body, src[1:] are the params...

lil movement:
STACK(src, ...) -- new leading axis, all src has same shape. until week 4, inputs can only be STACK/CONST.
INDEX -- shape from (n,) -> (), pop axes off the left with srcs
SHRINK(offset, shape) -- offset can be symbolic, shape must be integer

ALU:
CAST/RECIPROCAL/TRUNC
ADD/MUL/MAX/XOR
CMPLT -- returns bool
SHL/FLOORDIV/FLOORMOD -- i32 only
WHERE

The graph rewrite engine should be capable of "running" these programs via const folding also rendering them to C. We support dtype "broadcasting" here.

Lectures:

  • wed - Course intro, turing completeness, the UOp, the format, the first assignment
  • fri - ALU stuff, bottom up greedy rewrite engines, const folding
  • mon - call/param stuff, symbolic simplification, computer algebra systems

Compilers must be handed in by Wednesday every week before 10 AM class.

Week 2: Memory & Shape

Students write a renderer and a runtime capable of compiling and executing C programs.

Recursive properties introduced:

addrspace(GLOBAL,ALU)
versions:dict[UOp, tuple[UOp, ...]] <-- a list of UOps that store to a buffer

Ops introduced:

BUFFER(ParamArg) -- global persistent buffer (never in call)
ALLOC(ParamArg) -- call scope storage, example "float a[10]"
LOAD/STORE -- load has 1 src, store has 2, we load/store from/to GLOBAL buffer
AFTER -- AFTER(buf, <store>)

This can render (loopless) C functions that act on memory and immediates. Loads and stores must be fully ordered for programs to be valid. Loads and stores are bounds checked to never be out of range.

Lectures:

  • wed - toposort and rendering, C refresher
  • fri - memory management and runtime
  • mon - type systems for shape, dtype, and addrspace

Week 3: Loops

loops · gemms · convs

Recursive properties introduced:

ranges:dict[UOp, None]

Ops introduced:

RANGE -- src is the end of the range (3 means 0,1,2) and arg is the range name
END -- srcs are (passthrough, range)

Should be simple, and we can write gemms and convs in this language. Note, basic rangeify is allowed here now.

Week 4: Rangeify + Kernel Fusion/Fission

broadcasting · reduction · rangeify

We still keep the rank < 2 restriction on shapes, but ALU can be rank 1 now.

Ops introduced:

REDUCE (axis count / op)
STAGE -- temp buffer
EXPAND

Rangeify removes shapes from all ops. We have to confront questions about materialization here.

Week 5: Movement Ops

movement ops

Now we introduce movement ops and loops, allowing rank >= 2 shapes for the first time. Note how you can derive gemms and convs from the basic movement ops.

Ops introduced:

RESHAPE/PERMUTE

STACK supports arbitrary inputs, SHRINK supports STACKs in the params.

PAD and FLIP are composite ops here. This compiler is now capable of compiling any model, splitting it into kernels to avoid repeated compute, and compiling it to C.

Autodiff only works on pure shape graphs, not STORE, CALL, AFTER, RANGE, END.

Here you will run Qwen, you'll also learn about Taylor expansion for SIN/LOG2/EXP2/SQRT.

Week 6: Autodiff + Multithreading

autodiff · threads · FLOPS counting · fast GEMMs

axistype(LOOP,GLOBAL)

Ops introduced:

GRADIENT/DETACH

You'll add GRADIENT/DETACH ops and train MNIST. You'll extend your C program to support threads and begin considering GPUs.

Weeks 7: GPUs & Hardware Accelerators

parallel · GPUs · hardware accelerators · tensor cores

axistype(LOOP,GLOBAL,LOCAL)
addrspace(GLOBAL,LOCAL,ALU)

Here we add kernels, GPUs, axis mappings, and tensor cores. This can produce decent torch-competitive CUDA/HIP code now.

Week 8: Memory Hierarchies & Multithreading & Fast Kernels

upcasting · flash attention

Now things get fast. Still only on CPU, but we can now produce SOTA-competitive C code for GEMMs, reduces, and convs.

Ranges can have axis type LOOP, UPCAST, or THREAD.

Weeks 9–10: Real Models

real models · symbolic

Here we implement a real LLM and train models.

Weeks 11–End: Student Projects

Use your compiler to implement a paper, port it to strange hardware, mostly anything


At a Glance

Weeks Topics Milestone
1–2 UOps, elementwise ops, symbolic, rewrites Compile & simplify elementwise programs to C
3–4 Loops, movement ops, reduction, rangeify Compile any model to C (slow, but correct)
5–6 Memory hierarchies, upcasting, GEMMs, convs SOTA-competitive CPU code
7–8 Call, GPUs, accelerators, tensor cores Torch-competitive CUDA/HIP code
9–10 Real models, autodiff Train a real LLM
11+ Student projects Choose a project and extend your compiler
@paulopacitti

Copy link
Copy Markdown

please make it open source, I want to learn thru this material

@JaydeepChauhan14

Copy link
Copy Markdown

If possible please open source this I am also want to learn thru this material.

@danialhasan

Copy link
Copy Markdown

this wil be very cool when it drops

@rayhanadev

rayhanadev commented Oct 1, 2026 •

Copy link
Copy Markdown

would love to have you at purdue george! tons of extremely talented students who care a lot about this stuff. we at purdue hackers ran a for dummies gpu programming workshop a while ago! would be great to have someone with experience come in to teach a course on it :)

https://events.purduehackers.com/events/workshop/gpu-programming

image image image

@rhuangx

rhuangx commented Oct 1, 2026 •

Copy link
Copy Markdown

Would love to bring this to UT Austin, George! I co-founded Longhorn Silicon, UT Austin’s first student silicon design organization. We’re building Lambda, an ASIC targeting LLMs up to 1.5 billion parameters, with a planned tapeout by 2028. We’d love to build an ML compiler end to end through your course and apply it to Reef. You can reach us at info@longhornsilicon.com

IMG_0146

@shreyjoshi2004

Copy link
Copy Markdown

Would absolutely love to bring this to UT Dallas!

@georgxzh

georgxzh commented Oct 2, 2026 •

Copy link
Copy Markdown

Let's make it happen at UWaterloo

@shaheermir

Copy link
Copy Markdown

Big +1 to open sourcing this. Lots of people interested in self studying this outside of school. Would really appreciate it!

@dakolli

dakolli commented Oct 3, 2026

Copy link
Copy Markdown

Is recruitment that bad, you need to go teach kids to source employees 🤣 Cool of you to do though.

@LeoLiang-zihao

Copy link
Copy Markdown

Yo can you opensource it?

@arygupt

arygupt commented Oct 6, 2026

Copy link
Copy Markdown

Would love to have this at UMD

@jeffreywolberg

Copy link
Copy Markdown

Please release lectures 🙏

@JustinMeimar

Copy link
Copy Markdown

One incredibly fun aspect of the grading scheme for our compiler class is Competitive Testing: making student compilers fight one another. The tournament would run in a cross product, with each team submitting tests to attack other compilers, and their own submission earning defensive points for successfully handling a program.

Back when we had to chisel code by hand, implementing the entirety of the language specification in one semester was virtually impossible (even with groups of four). Implementing a tricky construct correctly enabled you to submit difficult tests, which others would likely fail, then harvest a bunch of points for your team.

I'd highly recommend having compilers fight each other, rather than a private set of tests. After TA-ing this course twice, once in 2024, then again in 2025 (when everyone began using agents), it's really useful when assigning grades to have an infinite skill ceiling/leader-board by which an objective "winner" can be declared. We would use a reference solution to filter valid tests, then it was off to the races!

@boom567

boom567 commented Oct 8, 2026

Copy link
Copy Markdown

A really interesting course (covering exactly the kind of project I’ve wanted to do myself). I just hope we’re left with some materials so we can follow the instructions and learn at our own pace

@ozzyozbourne

Copy link
Copy Markdown

please release lectures, it would be a massive help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment