Phase 09 — Hardware Abstraction & Portability (The Keystone Phase)

Difficulty: ⭐⭐⭐⭐⭐ | Estimated Time: 2 weeks Roles supported: Head of Engineering [GPU], Runtime/Platform Architect, Compiler/Backend Engineer Hardware needed: none — the HAL and its backends are real C, runnable on any machine


Why This Phase Exists

This is the JD's central mandate, verbatim: "a platform that operates independently of the underlying hardware" and "decouple software from hardware environments." Every other phase has been building the knowledge to do this credibly — you can't abstract hardware you don't understand (Phases 01–08), and you can't sell the abstraction without the security/licensing that makes it a product (Phase 11).

A hardware-abstraction layer (HAL) is the single most important architectural artifact a hardware-agnostic AI platform owns. Get it right and you can support NVIDIA, AMD, Intel, and a startup's accelerator behind one API, route each workload to the best backend, and capture the market gap that NVIDIA's lock-in creates. Get it wrong and you've built either a leaky abstraction that performs terribly or a lowest-common-denominator wrapper that delivers a fraction of each chip's capability.

You will build a real HAL in C — a stable API, a backend ABI, and dlopen-loaded vendor plugins (CPU-reference, a "fast" backend, a "limited" backend) — the literal architecture of decoupling software from hardware. Then you'll grapple with the hard parts: capability negotiation, the abstraction-vs-performance tradeoff, and versioning the ABI.


Concepts

  • API vs ABI: the difference, why it's the crux of plugin systems, ABI stability rules (struct layout, versioning, symbol visibility)
  • The HAL pattern: a stable front-end API + a backend interface (vtable of function pointers) + dynamic backend loading (dlopen/dlsym)
  • Capability negotiation: backends declare what they support (dtypes, ops, features); the platform queries and routes — no lowest-common-denominator
  • The portability landscape revisited (from Phase 03 Ch. 9): CUDA, ROCm/HIP, oneAPI/Level Zero, Metal, Vulkan/SPIR-V, and the compiler layer (Triton/MLIR) as a backend strategy
  • The abstraction-vs-performance tension: leaky abstractions, escape hatches, per-backend fast paths; why "write once, run anywhere, fast" is the hard part
  • Backend selection/routing: choosing a backend per workload by capability + benchmark (ties to Phase 01 Ch. 10, Phase 07 Ch. 8)
  • Versioning a plugin ABI: how to evolve the interface without breaking shipped backends (reserved fields, version structs, capability flags)
  • Conformance testing: one test suite, all backends must pass — the contract that makes the abstraction trustworthy
  • Build/packaging: shipping a platform that loads the right backend for the customer's hardware (incl. air-gapped, Phase 07/11)
  • The business case: why this layer is the platform's moat and how it's monetized (OEM integrations, the JD's commercialization mandate)

Labs

Lab 01 — A GPU HAL with dlopen Backends (C)

FieldValue
GoalBuild a hardware-abstraction layer: a stable C API, a backend ABI (function-pointer vtable + capability struct), and three dlopen-loaded backends (cpu_ref, "fast", "limited"). Run the same program on any backend; route by capability.
ConceptsAPI/ABI separation, function-pointer vtables, dlopen/dlsym, capability negotiation, backend selection, ABI versioning.
Steps1) make && ./hal_demo — loads all backends, queries capabilities, runs a tensor op on each, routes a request to a capable backend. 2) Read hal.h (the contract), hal.c (loader/router), and the three backend_*.c. 3) Reproduce: a request needing FP16 routes away from the "limited" backend; the ABI version check rejects a stale backend. 4) Extensions: a new backend without recompiling the core, a fast-path escape hatch, ABI evolution.
StackC (C11), dlopen (POSIX)
OutputA HAL core + 3 loadable .so/.dylib backends + a demo that routes by capability and version-checks the ABI.
How to TestBuilt-in: every backend passes the same conformance test (correct results); capability routing sends FP16 work only to capable backends; an ABI-version mismatch is detected and the backend rejected.
Talking PointsWhy API≠ABI is the crux; how capability negotiation avoids lowest-common-denominator; the abstraction-vs-performance escape hatch; how you'd version this ABI to not break shipped vendor backends; how this maps to real stacks (CUDA/ROCm/Level Zero).
Resume Bullet"Designed and built a GPU hardware-abstraction layer in C with a versioned backend ABI and dlopen-loaded vendor plugins; implemented capability negotiation and routing, with a single conformance suite all backends pass."
ExtensionsAdd a 4th backend (a .so) with no core recompile — prove the ABI is real; a per-backend fast-path escape hatch; bump the ABI version and show old + new backends coexisting via the version field.

Lab 02 — Portability Strategy Decision Doc + Conformance Harness (Markdown + Python)

FieldValue
GoalProduce the architectural decision record (ADR) a real platform needs — which portability posture (HAL-over-vendor-libs vs Triton/MLIR vs full compiler), with costs — backed by a conformance harness that runs one test matrix against multiple "backends."
ConceptsThe three portability postures (Phase 03 Ch. 9–10), conformance testing, capability matrices, the build-vs-adopt analysis.
Steps1) Read STRATEGY-ADR.md (a worked decision record) and fill the decision matrix for a scenario. 2) python conformance.py — runs a capability/correctness matrix against mock backends; prints a support matrix + conformance pass/fail. 3) Write your own ADR for "support NVIDIA + AMD + a startup accelerator within 12 months."
StackMarkdown (ADR) + Python (conformance harness)
OutputA completed ADR + a conformance report (which backend supports/passes what).
How to Testpython conformance.py asserts the matrix is computed correctly and flags non-conformant backends; the ADR follows the provided rubric.
Talking PointsThe three postures and their costs; why conformance testing is what makes an abstraction trustworthy; how you'd phase a multi-vendor rollout; the build-vs-adopt argument for the compiler layer (Phase 03 Ch. 10).
Resume Bullet"Authored the hardware-portability architecture decision record (HAL vs Triton/MLIR vs full compiler) and built a conformance harness enforcing a single test matrix across heterogeneous backends."
ExtensionsAdd a performance-conformance tier (backends must hit X% of roofline, not just pass correctness); model the 12-month multi-vendor rollout as a dependency plan.

Deliverables Checklist

  • HAL: builds, all backends load, conformance passes, capability routing works, ABI version checked
  • You added a 4th backend without recompiling the core (proof the ABI is real)
  • You can explain API vs ABI and the rules for evolving a plugin ABI
  • ADR completed for a multi-vendor scenario with costed options
  • Conformance harness runs and flags non-conformant backends
  • One page: "our platform's hardware-abstraction architecture" (the Phase 12 capstone's backbone)

Interview Relevance

This phase is the JD's thesis. Expect the hardest, most senior questions here.

  • "Design a hardware-abstraction layer for an AI platform. Walk me through the API/ABI boundary."
  • "How do you avoid a lowest-common-denominator abstraction?"
  • "How do you version a plugin ABI so a year-old vendor backend still loads?"
  • "Build vs adopt: would you write your own compiler layer or use Triton/MLIR? Defend it."
  • "How is decoupling software from hardware actually a defensible business?" (→ system-design/, Phase 11)