Compiler Engineering Notes: 48 Bilingual Articles and Reading Paths

Numerics, operators, resources, and compiler delivery

Posted by Bruce Lee on 2026-01-02

阅读中文版目录

48 long-form articles on compiler numerics, layouts, scheduling, and delivery. The stories often start with a small question: why does computing a mean require moving data? Why can a program not find a file that exists? Why does a view keep memory alive? Why does Debug work while Release fails?

This is the complete English counterpart of the Chinese collection. Each article retains its original ID and filename so the two editions can be matched directly. The English edition is self-contained.

Where to start

Numerical Correctness — Integers and the Scales That Interpret Them

Article Starting question
Just Take the Mean—Why Is the Compiler Writing Loops? Lower arbitrary reduction axes into executable loops and account for layout and transfer costs.
The Vanishing Dimension: How keep_dims=false Can Break an Inverse Permutation Preserve axis identity when dimensions disappear, then reconstruct the inverse permutation.
Max, Min, and Sum: Similar Operators, Different Mathematical Homework Share reduction structure without copying initialization, accumulation, or rescaling semantics.
This Reduction Does Nothing—Why Can’t We Delete It? A mathematical identity can still require a change of quantized representation.
The Multiplication Is Right; the Scale Is Wrong: An Integer Kernel’s Two Ledgers Track input scales, output scales, and the range of the intermediate product.
Once BatchNorm Becomes Multiply-Add, the Numerical Work Begins Follow fixed statistics through channelwise affine transforms, multipliers, shifts, and biases.
Just a Few Channel Parameters—So Why Is Local Memory Full? Avoid materializing channel parameters across a whole tensor while preserving broadcasting.
Build a Dedicated Operator, Then Remove It: A Design Change Worth Recording Compare the expressiveness and maintenance cost of a dedicated affine operator and its decomposition.
Epsilon Was Nonzero—Until It Nearly Vanished in the Integer Domain Follow epsilon, squares, and reciprocal square roots through normalization range planning.
Floating Point Passes, Quantization Fails: A Rewrite Gives the Output the Input’s Identity Treat the rewritten result type as both a container and a numerical contract.
The Importer Got Clever Too Soon: Algebraic Optimization before Quantization Metadata Understand the interaction between algebraic rewrite order, metadata matching, and constants.

Operators and Layouts — Putting Mathematics into Memory

Article Starting question
Grouped Convolution: Once You Slice the Cake, Slice the Labels Too Split input and weight groups while carrying their quantization metadata with them.
Transposed Convolution Weights: The Shape Is Honest, but Memory Speaks Another Dialect Derive slices from actual weight storage, not just a logical dimension order.
Why Does Reshape Need Code? The Elements Stay the Same; Their Route Changes Prove the linear element mapping and distinguish shape changes from physical rearrangement.
When the Debugger Starts Lying: One Permute, Three Ways to Fix Dump Three alternative branch fixes show why observation paths need layout contracts too.
Broadcasting: Sometimes the Right Address Is the One That Does Not Move Build per-axis address plans for scalars, lower-rank inputs, and more complex broadcasts.
The First Row Works, the Second Disappears: Alignment, Strides, and Padded Constants Make logical widths, physical strides, padded storage, and parameter layouts agree.
Subtracting Zero Can Disappear; Subtracting from Zero Cannot Keep constant folding, commutativity, and operand direction as separate decisions.
Abs and Sign: One Line of Arithmetic Does Not Make Their Parameter Contracts Interchangeable Carry a unary operator’s definition through types, quantization, and parameter encoding.
Who Moved My Scratch Register? Teaching an Emitter to Borrow and Return Replace informal scratch-register conventions with explicit borrowing and lifetime rules.
Putting Activation Inside Convolution: Preserve the Quantization Boundary Before Removing the Node Preserve intermediate quantization and legality when fusing convolution with activation.
A Sigmoid After MatMul: Why the Compiler Still Refuses to Fuse It Understand how consumers, views, and dependencies constrain matrix-activation fusion.
When Weights Move to the Left: A Transpose Identity That Moves the Whole Compiler Chain A transpose identity starts the rewrite; weight identity and quantization axes must follow.

Resources and Scheduling — Who Still Needs This Data?

Article Starting question
Why Does Someone Keep Borrowing My “Temporary” Register? Express register ownership through scope and define the limits of automatic release.
A Few More Branches in the Graph—and Synchronization Registers Run Out First? Explain how graph fan-out and dependency joins create synchronization-resource pressure.
The View Moved No Data. Why Can’t We Return the Memory? Follow asynchronous consumers through view chains before reclaiming underlying storage.
The Address Fits. Why Does the Compiler Say Memory Is Full? Separate encodable addresses, allocation intervals, and actual memory budgets.
Why Write the Same Final State Twice? Distinguish persistent state, final state, and direct-output buffers.
I Waited for the Event. Why Isn’t the Data Ready? Make synchronization events cover the actual production of data across execution engines.
You Caught the Exception. What Happens to the Half-Written Machine Code? After catching an error, account for the state and output already produced.
One More Loop, and the Binary Snapshot Looks Like a Different Program Examine how loops, labels, and independent emitter instances affect binary determinism.
“I Parsed a Number” Does Not Mean the Input Is Valid Check full input consumption, signs, and field ranges after parsing succeeds.
Fewer Operations—So Why Disable the Optimization? Treat disabling an optimization as a design decision about slicing and quantization contracts.

Compiler Engineering — From a Development Tree to a Deliverable

Article Starting question
Debug Works, but Release “Optimizes Away” a Write A required write hidden in an assertion disappears when checks are disabled.
“I Only Rebuilt It.” Why Did the Installation Directory Disappear? Define the responsibilities and failure states of environment setup, builds, and installation.
One Version of the Headers, Another Version of the Generator Headers, libraries, generators, and caches jointly determine toolchain identity.
The Library Is in the Package. Why Can’t the Program Find It? Connect real library files, SONAMEs, linker names, and runtime search paths.
The Compiler Moved. Its Lookup-Table Module Didn’t Get the Address Use real functionality and missing-resource tests to validate relocation.
Why Is Packing Compiler Outputs into One File Hard? Treat a model file as a protocol with offsets, lengths, and ownership.
Compilation Failed. Why Is There Still a “Successful Model” in the Directory? Make output directories, temporary artifacts, and stale files part of a clear success contract.
Why Does the Same Release Package Get a Different Hash Every Time? Separate archive-event time, package timestamps, and byte reproducibility.
The Assembly Looks Right. Does That Mean the Machine Code Is Right? Understand what pseudoassembly, assembly, machine code, and mathematical references each prove.
The Most Useful Words in an Operator Specification May Be “Not Yet Confirmed” Keep unknowns explicit rather than turning example tables into capability promises.
You Found the Operator’s Name. Does That Make It Supported? Require evidence for a complete compilation path before calling an operator supported.
An Instruction’s Four Identities: Why Code Generation Needs More Than Strings Assign responsibilities and diagnostics across operation, kernel, emission, and encoding layers.
It Only Moves Data. How Can It Still Be Wrong? Preserve coordinates, strides, aliasing, and quantization when moving data.
Same Output Shape, Different Answers: Pooling, Resizing, and Index Reductions Let window denominators, sampling coordinates, and index rules determine actual results.
A Function Name Cannot Hold Its Numerical Contract Specify domains, approximations, precision, and axes beyond a function’s name.

Follow a question across the series

Each article is an independent Markdown file, ready to read, edit, or import into a blog platform. Tables and code blocks require no online resources.

Connections to earlier blog posts

Editorial calendar

Date Article
2026-01-06 Just Take the Mean—Why Is the Compiler Writing Loops?
2026-01-11 The Vanishing Dimension: How keep_dims=false Can Break an Inverse Permutation
2026-01-18 Max, Min, and Sum: Similar Operators, Different Mathematical Homework
2026-01-22 This Reduction Does Nothing—Why Can’t We Delete It?
2026-01-28 The Multiplication Is Right; the Scale Is Wrong: An Integer Kernel’s Two Ledgers
2026-02-02 Once BatchNorm Becomes Multiply-Add, the Numerical Work Begins
2026-02-09 Just a Few Channel Parameters—So Why Is Local Memory Full?
2026-02-13 Build a Dedicated Operator, Then Remove It: A Design Change Worth Recording
2026-02-19 Epsilon Was Nonzero—Until It Nearly Vanished in the Integer Domain
2026-02-24 Floating Point Passes, Quantization Fails: A Rewrite Gives the Output the Input’s Identity
2026-03-03 The Importer Got Clever Too Soon: Algebraic Optimization before Quantization Metadata
2026-03-07 Grouped Convolution: Once You Slice the Cake, Slice the Labels Too
2026-03-13 Transposed Convolution Weights: The Shape Is Honest, but Memory Speaks Another Dialect
2026-03-18 Why Does Reshape Need Code? The Elements Stay the Same; Their Route Changes
2026-03-25 When the Debugger Starts Lying: One Permute, Three Ways to Fix Dump
2026-03-29 Broadcasting: Sometimes the Right Address Is the One That Does Not Move
2026-04-03 The First Row Works, the Second Disappears: Alignment, Strides, and Padded Constants
2026-04-09 Subtracting Zero Can Disappear; Subtracting from Zero Cannot
2026-04-15 Abs and Sign: One Line of Arithmetic Does Not Make Their Parameter Contracts Interchangeable
2026-04-20 Who Moved My Scratch Register? Teaching an Emitter to Borrow and Return
2026-04-25 Putting Activation Inside Convolution: Preserve the Quantization Boundary Before Removing the Node
2026-05-01 A Sigmoid After MatMul: Why the Compiler Still Refuses to Fuse It
2026-05-07 When Weights Move to the Left: A Transpose Identity That Moves the Whole Compiler Chain
2026-05-12 Why Does Someone Keep Borrowing My “Temporary” Register?
2026-05-17 A Few More Branches in the Graph—and Synchronization Registers Run Out First?
2026-05-23 The View Moved No Data. Why Can’t We Return the Memory?
2026-05-29 The Address Fits. Why Does the Compiler Say Memory Is Full?
2026-06-03 Why Write the Same Final State Twice?
2026-06-08 I Waited for the Event. Why Isn’t the Data Ready?
2026-06-14 You Caught the Exception. What Happens to the Half-Written Machine Code?
2026-06-20 One More Loop, and the Binary Snapshot Looks Like a Different Program
2026-06-25 “I Parsed a Number” Does Not Mean the Input Is Valid
2026-06-30 Fewer Operations—So Why Disable the Optimization?
2026-07-05 Debug Works, but Release “Optimizes Away” a Write
2026-07-12 “I Only Rebuilt It.” Why Did the Installation Directory Disappear?
2026-07-16 One Version of the Headers, Another Version of the Generator
2026-07-22 The Library Is in the Package. Why Can’t the Program Find It?
2026-07-27 The Compiler Moved. Its Lookup-Table Module Didn’t Get the Address
2026-08-03 Why Is Packing Compiler Outputs into One File Hard?
2026-08-07 Compilation Failed. Why Is There Still a “Successful Model” in the Directory?
2026-08-13 Why Does the Same Release Package Get a Different Hash Every Time?
2026-08-18 The Assembly Looks Right. Does That Mean the Machine Code Is Right?
2026-08-25 The Most Useful Words in an Operator Specification May Be “Not Yet Confirmed”
2026-08-29 You Found the Operator’s Name. Does That Make It Supported?
2026-09-04 An Instruction’s Four Identities: Why Code Generation Needs More Than Strings
2026-09-09 It Only Moves Data. How Can It Still Be Wrong?
2026-09-16 Same Output Shape, Different Answers: Pooling, Resizing, and Index Reductions
2026-09-20 A Function Name Cannot Hold Its Numerical Contract

If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. All the images used in the blog are my original works or AI works, if you want to take it,don't hesitate. Thank you !