cswork / libraryOpen practice workspace

Articles

ML Compiler Engineer Interview Guide 2026: MLIR, CUDA, Kernel Optimization, and Systems

Prepare for an ML compiler engineer interview with MLIR, IR transformations, CUDA kernels, performance analysis, correctness, and systems design practice.

ML compiler interviews reward precise reasoning across representations. Prepare to move from a model or tensor operation to an intermediate representation, a transformation or lowering, generated code, and measured runtime behavior. MLIR's public documentation describes a multi-level IR, dialects, passes, conversion, and GPU support; those are durable concepts, but the exact interview depth depends on the team. Pair compiler theory with small implementation and debugging exercises.

Use the linked drills as evidence-building exercises: solve first, then compare the explanation and record the failure mode you missed.

Quick answer

Prepare across four connected layers: IR semantics, transformations and lowering, GPU execution, and systems debugging. A strong answer names the invariant before the optimization, explains where legality is checked, and validates the result with both correctness tests and measurements. The exact balance depends on whether the role owns graph compilers, kernels, runtimes, or framework integration.

What the interview is likely to test

AreaConcrete preparation targetStrong evidence
MLIR and IR designOperations, types, regions, SSA, dialect boundariesYou can explain what information an operation carries and when a rewrite is legal.
Passes and loweringRewrite patterns, conversion targets, pass orderingYou preserve semantics, diagnose unsupported cases, and test intermediate states.
GPU executionMemory access, launch overhead, occupancy, synchronizationYou profile first and avoid treating occupancy as a performance score.
Systems codingC++, ownership, concurrency, parsing, data structuresYou write a correct baseline and reason about lifetime, failure, and complexity.
DebuggingWrong code, crashes, regressions, nondeterminismYou bisect the pipeline and produce a minimal reproducible case.

Build one small portfolio exercise that lowers or rewrites an operation and prints the IR before and after. Add a negative test, a correctness oracle, and one benchmark. The artifact gives every theory topic a concrete anchor.

When presenting the exercise, separate legality from profitability. A rewrite can preserve types and semantics yet make runtime slower because of extra memory traffic, synchronization, or launch overhead. Conversely, a faster benchmark is not enough if dynamic shapes or uncommon layouts break. State the supported domain, test outside it, and show the profile that justified the optimization.

Include one explicit fallback path and explain whether unsupported inputs fail during compilation or continue through a slower reference implementation.

The compiler stack you should be able to draw

Be ready to place a problem on a stack: frontend or model import, dialect representation, canonicalization, shape or type reasoning, fusion or tiling, lowering, target-specific code generation, runtime launch, and profiling. Explain what information is preserved or lost at each boundary. This prevents answers from jumping directly from a high-level model to a claimed speedup.

A good diagram includes both the happy path and a failure path. What happens when a shape is dynamic, an operation has no lowering, a layout is incompatible, or a target feature is unavailable? The answer should distinguish a compile-time diagnostic, a fallback path, and a runtime error.

MLIR fundamentals and dialect design

MLIR questions often test whether you understand operations, types, regions, blocks, SSA values, attributes, and dialect boundaries. Explain why a dialect gives a domain a vocabulary and invariants, and why a lowering pipeline should make legality and conversion explicit. Use small examples rather than reciting every API name.

When discussing a pass, state its precondition, transformation, postcondition, and verification. Say whether it is local or global, how it affects analyses, and how you would test it. A pass that is fast but changes semantics is not an optimization; correctness belongs in the design, not only in the final benchmark.

CUDA and kernel reasoning

You do not need to pretend that every compiler role is a kernel-authoring role. You should understand enough CUDA to reason about thread and block mapping, memory coalescing, shared memory, synchronization, occupancy, launch overhead, and device-host transfers. Tie each concept to a workload and a profile signal.

A kernel optimization answer should have a baseline, a representative shape, a correctness check, and a reason the bottleneck is where you think it is. Consider numerical tolerance, alignment, layout, and tail behavior. If the operation is memory-bound, more arithmetic may not help; if it is launch-bound, changing the kernel body may miss the issue.

Lowering and code generation trade-offs

When lowering an operation, decide what the target needs to know: layout, shape, memory space, vector width, synchronization, or aliasing. Explain how you would handle dynamic dimensions and unsupported operations. A fallback can improve coverage, but it can also create expensive transfers or obscure performance regressions.

Testing should cover semantic equivalence, verifier behavior, generated IR, and end-to-end runtime. Keep a small lit test for the transformation, a negative test for invalid input, and a performance test that is isolated from correctness. Report optimization results with workload and hardware context rather than a universal percentage.

Systems and debugging

Compiler bugs can be hard to localize because the symptom appears far from the cause. Build a reduction: shrink the model or IR, print the relevant intermediate form, compare before and after the pass, and find the first representation that violates an invariant. Check whether the issue is parsing, transformation, code generation, runtime, or measurement.

Systems questions may include caches, memory ownership, concurrency, distributed compilation, or build infrastructure. Apply the same discipline: define ownership, synchronization, failure, and observability. A compiler engineer is still operating software used by other engineers, so reproducibility and a clear diagnostic are part of performance.

How to prepare for a deep technical loop

Use one small IR transformation, one CUDA or performance exercise, and one end-to-end design per study session. Write the precondition and postcondition before coding. Then explain how you would prove or test correctness and how you would know the optimization mattered.

Interview questions and strong answer signals

These prompts are practice questions, not predictions of an exact interview. A strong answer defines the problem, states assumptions, makes trade-offs visible, and explains how correctness or impact would be measured.

What makes an MLIR pass correct?

State legal input, transformed output, semantic equivalence, and verifier requirements. Test representative and invalid IR, include shape or type edge cases, and check downstream compatibility. If the pass changes a property used by later passes, update or invalidate the relevant analysis explicitly.

How would you debug a wrong-code compiler bug?

Reduce the input, capture the relevant IR at each stage, find the first divergence from expected semantics, and isolate the smallest transformation. Add a regression test at the earliest layer that reproduces the bug, then validate end-to-end behavior.

How do you decide whether to fuse operations?

Estimate memory traffic, launch overhead, register and shared-memory pressure, shape variability, and reuse. Validate against representative shapes and numerical tests. Fusion is a trade-off, not a universal win.

What does a CUDA performance investigation look like?

Define workload and baseline, profile kernel and transfer timelines, inspect occupancy or memory behavior, change one variable, and rerun correctness and performance checks. Include tail behavior and compilation or warm-up effects.

How would you handle an unsupported operation?

Choose among a clear diagnostic, a legal fallback, or a decomposition based on coverage, correctness, performance, and maintenance. Make the choice visible and test the path rather than silently producing a slow or incorrect result.

Tell me about a time you found a bug across layers.

Describe the symptom, the reduction, the first false hypothesis, the signal that localized the issue, the fix, and the regression test. Emphasize how you made the next occurrence easier to diagnose.

Seven-day preparation plan

Use the plan as a compact loop. Spend more time reviewing mistakes than collecting new topics, and adjust the emphasis to the current job posting.

DayFocusWhat to do
Day 1Focused practiceSSA, data structures, and compiler debugging reduction.
Day 2Focused practiceMLIR operations, dialects, and pass invariants.
Day 3Focused practiceCUDA memory, mapping, synchronization, and profiling.
Day 4Focused practiceLowering, fallback, verification, and tests.
Day 5Focused practiceSystems ownership, concurrency, and build failures.
Day 6Focused practiceRun a deep technical mock with a design sketch.
Day 7Focused practiceReview transformations, measurements, and role requirements.

Frequently asked questions

Do I need to know all of MLIR?

No. Know the IR model, dialect and pass concepts, verification, lowering, and how to learn the relevant dialect for the role.

How much CUDA should I study?

Enough to discuss memory, execution, synchronization, profiling, and correctness. The posting determines whether hands-on kernel work is central.

Are compiler questions only theoretical?

Expect a mix of coding, debugging, representation reasoning, and systems trade-offs.

How should I present a speedup?

Include workload, baseline, hardware, variance, correctness, and what changed. Avoid context-free claims.

Final takeaway

Do not prepare MLIR, CUDA, and compilers as three disconnected trivia lists. Practice one end-to-end story: represent an operation, transform or lower it, inspect generated behavior, measure a bottleneck, and prove that the optimization preserves semantics. That is the thread an interviewer can follow from whiteboard reasoning to production debugging.

Sources and Further Reading

Research note: Public facts and documentation were checked on September 3, 2026. Hiring stages, pricing, platform behavior, and product details can change; the reader's current invitation and official pages are the source of truth.