Production engineering reference | updated 2026-07-11
NPU and SoC Software Architecture
A contract-first view of the software that turns a model into work on an edge NPU. The focus is the space between a graph compiler and silicon: deployable artifacts, SDK and runtime APIs, memory and command lifecycles, kernel drivers, firmware, C++ hardware models, trace correlation, layer debugging, and release gates.
Coverage boundary
This page adds system contracts instead of repeating existing lessons
The current site already covers accelerator taxonomy, LLVM/MLIR fundamentals, graph optimization, tiling, quantization, C, Git, and Analog CIM. Use the foundation chapters first, then treat the Analog CIM material as an optional specialization. This document begins where those introductions stop.
End-to-end architecture
The stack has two products: an executable artifact and a controlled device
Data-plane work carries tensors and commands. Control-plane work owns discovery, allocation, power, faults, version negotiation, and observability. A robust design makes both planes explicit.
The deployable artifact is the architectural hinge. It should identify the target and ABI, define constants and mutable buffers, carry command or kernel payloads, preserve graph-to-command debug maps, and include enough provenance to reproduce the compile. A binary blob without that contract is difficult to validate, debug, cache, or evolve.
Responsibility catalog
What every component consumes, produces, owns, and must reveal
The compact map shows placement. The catalog below shows engineering ownership. A layer is complete only when its input contract, output contract, decisions, telemetry, and failure behavior are all explicit.
Model plane
Defines application meaning and deployment intent before target-specific lowering begins.
Application
Data + controlConverts a product request, sensor frame, or media stream into model inputs and turns model outputs into product behavior. It owns the user-visible latency and correctness contract, not only tensor I/O.
- Consumes
- Raw requests or sensor data, application configuration, model identity, and service-level policy.
- Produces
- Typed tensor bindings, shape metadata, deadlines, priorities, correlation IDs, and interpreted outputs.
- Owns
- Preprocessing and postprocessing versions, batching and admission policy, fallback, cancellation, and accuracy/latency tradeoffs.
- Must expose
- Request shape, preprocessing time, queue delay, inference time, postprocessing time, fallback reason, and final status.
Failure pattern: training used RGB normalization and NHWC tensors, while deployment silently sends BGR or NCHW; the accelerator is correct but the product result is wrong.
Framework / ONNX
Semantic dataRepresents the portable computation contract. A graph is more than operator names: opset versions, attributes, control flow, broadcasting, aliasing, layouts, quantization metadata, and shape constraints determine the result that every backend must preserve.
- Consumes
- Trained checkpoint or framework module, exporter configuration, example inputs, and external constant files.
- Produces
- A versioned graph with nodes, tensors, constants, symbolic dimensions, dtypes, quantization parameters, and named outputs.
- Owns
- Framework-level semantics and export fidelity; it does not own target scheduling, physical addresses, or device command order.
- Must expose
- Exporter revision, opset imports, source-node mapping, unresolved shape constraints, model digest, and framework golden outputs.
Failure pattern: an exporter decomposes one operation differently after an upgrade, or leaves preprocessing outside the graph, and the importer accepts a graph whose meaning no longer matches the validated model.
Deployment profile
Control policySeparates model semantics from deployment choices. The same graph may need different precision, memory, fallback, and power decisions for a camera, battery device, automotive SoC, or throughput server.
- Consumes
- Model analysis, hardware capability manifest, accuracy tolerance, latency target, memory budget, thermal limits, and fleet policy.
- Produces
- An immutable compile profile naming target revision, shape classes, precision policy, calibration data, fallback rules, and optimization objective.
- Owns
- Allowed approximations, dynamic-shape bounds, SRAM/DRAM limits, power mode, digital fallback, and compatibility floor.
- Must expose
- Profile digest, policy source, rejected constraints, selected objective weights, calibration-set identity, and target capability version.
Failure pattern: important target flags live only in shell scripts or engineer memory, so two builds of the same model produce different artifacts with no reproducible explanation.
Build plane
Proves semantics, makes target decisions, and freezes them into a deployable contract.
Importer and analyzer
Semantic gateTurns an external graph into a canonical internal representation while preserving source identity. It should fail early on ambiguity and provide a support report before expensive target compilation.
- Consumes
- Framework graph, constants, deployment profile, calibration metadata, importer schema, and target support manifest.
- Produces
- Validated typed IR, inferred shape constraints, canonical operators, source maps, support classification, and actionable diagnostics.
- Owns
- Schema and opset checks, shape/type inference, constant integrity, semantic normalization, capability diagnosis, and minimal failing subgraphs.
- Must expose
- Unsupported node path, source location, inferred versus declared shape, fallback reason, warning severity, and normalization history.
Failure pattern: unsupported behavior is discovered after many compiler passes and reported as an internal lowering error, leaving the user unable to identify the original node or repair the model.
NPU compiler
Program constructionConverts validated IR into a legal and efficient command program. Partitioning, layout, quantization, tiling, scheduling, and memory allocation are coupled decisions because each changes traffic, lifetime, engine occupancy, and numerical behavior.
- Consumes
- Canonical IR, deployment profile, target ISA and capabilities, kernel library, calibration data, and measured cost models.
- Produces
- Partitions, lowered kernels or microcode, command DAG, DMA plan, static buffer offsets, constants, relocations, and debug maps.
- Owns
- Legalization, fusion, precision and layout choice, tiling, resource scheduling, memory lifetimes, spill decisions, and fallback boundaries.
- Must expose
- Pass pipeline, IR checkpoints, cost breakdown, rejected alternatives, peak memory, expected cycles/bytes, and every graph-to-command mapping.
Failure pattern: a locally faster fusion increases live memory, forces DRAM spills, and makes the complete graph slower because schedule and allocation were optimized independently.
Artifact packager
Offline/runtime hingeSerializes compiler decisions into a bounded, versioned object that a runtime can validate and load without reconstructing compiler intent. The format is a product ABI, even when only one compiler emits it.
- Consumes
- Code and microcode, constants, command templates, buffer plan, relocations, entry points, ABI schemas, debug map, and build provenance.
- Produces
- A deterministic artifact with aligned sections, manifest, feature requirements, integrity data, signatures when required, and a stable build ID.
- Owns
- Section layout, bounds, compression, relocation records, target/ABI compatibility ranges, hashes, schema evolution, and reproducible serialization.
- Must expose
- Human-readable manifest, section inventory and hashes, compiler/pass revision, model and profile digests, required resources, and debug-symbol availability.
Failure pattern: the runtime accepts an opaque blob for the wrong firmware ABI or hardware stepping, then fails after allocation or submission with no safe compatibility diagnosis.
Host control
Turns an artifact and application request into isolated, asynchronous device work.
SDK
Supported interfaceProvides the supported developer path through compilation, packaging, loading, execution, profiling, and diagnosis. Its job is to make correct lifetime and synchronization behavior easier than unsafe shortcuts.
- Consumes
- Compiler and runtime capabilities, artifact schemas, support matrix, target discovery data, and diagnostic interfaces.
- Produces
- Stable C ABI, C++ RAII wrappers, Python tools, CLI output, examples, headers, packages, compatibility documentation, and reports.
- Owns
- Public handle semantics, ownership rules, error taxonomy, thread-safety contract, binding parity, deprecation policy, and example quality.
- Must expose
- SDK/runtime/driver/firmware versions, target features, artifact inspection, machine-readable errors, trace export, and minimal reproducer tools.
Failure pattern: samples bypass the runtime or rely on hidden global state, so customer applications copy patterns that leak buffers, serialize asynchronous work, or break on upgrades.
User runtime
Execution ownerOwns user-space object lifetime and asynchronous truth. It discovers devices, loads artifacts, manages sessions and buffers, submits work, resolves events, and converts lower-level failures into stable API results.
- Consumes
- Validated artifact, application tensor bindings, dynamic shapes, queue policy, driver capabilities, and device telemetry.
- Produces
- Executable/session handles, buffer and mapping objects, submissions, dependency events, completions, output bindings, and diagnostics.
- Owns
- Artifact cache and load policy, runtime allocation, imports/exports, queue ordering, batching, event lifetime, timeout, fallback, cancellation, and device-loss recovery.
- Must expose
- Session/queue/command IDs, hidden-copy count, allocation and cache statistics, queue delay, submit/complete timestamps, fallback, timeout, and terminal device state.
Failure pattern: a buffer is destroyed while commands still reference it, or a convenience call performs a hidden device-wide synchronization that destroys pipeline overlap.
Kernel driver
Privilege boundaryConverts untrusted user requests into isolated hardware resources. It is the authority for process ownership, DMA-visible memory, queue access, interrupt delivery, firmware lifecycle, power, and reset.
- Consumes
- System calls or ioctls, object handles, buffer import requests, validated submission descriptors, fences, and administrator policy.
- Produces
- Contexts, IOMMU mappings, pinned or imported buffers, queue slots, doorbell access, completion fences, fault reports, and reset results.
- Owns
- Isolation, handle validation, DMA mapping lifetime, cache maintenance, interrupt routing, scheduler admission, firmware loading, power transitions, and reset escalation.
- Must expose
- Process/context identity, mapped bytes, submissions and interrupts, IOMMU faults, firmware health, power state, reset generation, and stable kernel error codes.
Failure pattern: a stale handle or mapping survives context teardown and lets later work DMA into released memory, creating both a correctness fault and a security boundary violation.
Device control
Validates host intent, schedules finite resources, manages the SoC, and reports device truth.
Firmware scheduler
Device authorityReceives queue work after the kernel boundary and turns it into legal engine sequences. It protects the device from malformed descriptors, arbitrates shared resources, watches progress, and owns first-stage recovery.
- Consumes
- Command-ring descriptors, dependency tokens, buffer mappings, queue/context metadata, deadlines, and negotiated feature bits.
- Produces
- Engine dispatches, DMA sequences, resource reservations, completion records, performance snapshots, and structured fault reports.
- Owns
- Descriptor validation, dependency scheduling, fairness, preemption points, SRAM/DMA/engine reservations, watchdogs, queue quarantine, and warm-reset policy.
- Must expose
- Queue and command generation, scheduler state, wait reason, resource occupancy, heartbeat, last completed unit, faulting descriptor, and recovery action.
Failure pattern: reset leaves a stale producer generation or dependency token visible, so new commands wait on work that belonged to the previous firmware epoch.
SoC services
Shared infrastructureSupplies address translation, data movement, communication, time, clocks, resets, and power domains to the NPU. These services determine whether an otherwise correct accelerator can operate predictably inside the SoC.
- Consumes
- Device virtual addresses, transfer descriptors, NoC routes and priorities, clock requests, power votes, reset requests, and timer operations.
- Produces
- IOMMU translations, DMA completions, coherent or explicitly synchronized data, NoC delivery, stable clocks, powered domains, timestamps, and fault interrupts.
- Owns
- Initialization order, translation context, burst and alignment limits, coherency protocol, bandwidth/QoS policy, DVFS sequencing, clock gating, and reset dependencies.
- Must expose
- Bytes and latency per path, page faults, NoC congestion, DMA utilization, clock frequency, voltage/power state, temperature, throttling, and reset cause.
Failure pattern: a compiler schedule assumes bandwidth that the shared NoC cannot provide under camera or ISP traffic, causing deadline misses that never appear in isolated NPU tests.
Trace and counters
Observability planePreserves identity and time across graph nodes, artifacts, queues, firmware commands, engines, memory, and host APIs. Counters without units, scope, correlation, and loss accounting are not actionable telemetry.
- Consumes
- Compiler debug IDs, runtime correlation IDs, firmware events, engine counters, DMA/NoC events, power changes, faults, and clock-sync samples.
- Produces
- A versioned bounded-overhead event stream, counter samples, host/device time conversion, layer timeline, fault bundle, and profiler database.
- Owns
- ID propagation, timestamp width and wrap, clock-domain alignment, event schema, units, sampling and trigger policy, buffer overflow behavior, and privacy controls.
- Must expose
- Lost-event count, sampling interval, counter scope, conversion uncertainty, frequency epoch, schema version, source engine, and trace buffer pressure.
Failure pattern: a layer is slow, but command, DMA, and engine records cannot be joined because each layer generated unrelated IDs and used a different clock without synchronization metadata.
NPU data plane
Fetches the frozen program, performs numerical work, and moves tensors through the memory hierarchy.
Command processors
Dispatch data pathFetches and decodes validated command buffers or microcode, resolves dependencies, programs engines, and emits completion events. It is the hardware realization of the compiler and firmware command model.
- Consumes
- Command buffers, microcode, queue pointers, dependency tokens, tensor descriptors, addresses, engine masks, and execution modes.
- Produces
- Register or descriptor writes to engines, DMA launches, barriers, event updates, completion status, and precise command faults.
- Owns
- Fetch/decode, queue arbitration, branch or loop semantics, barrier ordering, dependency-scoreboard behavior, legal opcode handling, and forward progress.
- Must expose
- Current queue/opcode, commands retired, dependency wait cycles, decode faults, issue stalls, event state, and last known forward-progress point.
Failure pattern: a malformed length or unsupported opcode advances the queue incorrectly, turning one bad command into an unrecoverable device hang rather than a bounded fault.
Compute engines
Numerical data pathPerforms matrix, vector, scalar, activation, reduction, conversion, and optional sparse operations. The contract includes exact numeric behavior for every precision mode, not just nominal throughput.
- Consumes
- Input tensor tiles, weights, accumulator state, tensor views, masks, strides, precision mode, rounding mode, saturation policy, and kernel parameters.
- Produces
- Output tiles, partial sums or reductions, exception/status bits, dependency events, utilization counters, and numerical debug checkpoints.
- Owns
- Operation semantics, accumulator width, rounding and saturation, NaN/Inf policy where relevant, tail handling, sparse metadata, pipeline hazards, and deterministic modes.
- Must expose
- Active and issued cycles, lane utilization, operand starvation, pipeline stalls, overflow/saturation count, sparse skips, and per-mode error status.
Failure pattern: the main matrix shape passes, but tail channels use a different rounding or mask rule, creating small layer errors that accumulate only on production tensor shapes.
Memory system
Storage + movementDelivers constants, activations, commands, and intermediate state through local SRAM, caches, DRAM, and the fabric. Capacity, bank topology, alignment, ordering, and contention shape the achievable schedule.
- Consumes
- Compiler buffer plan, engine load/store traffic, DMA requests, cache operations, physical or device virtual addresses, priorities, and coherency actions.
- Produces
- Data with defined visibility and ordering, allocation capacity, bandwidth and latency service, cache responses, fabric transactions, and memory faults.
- Owns
- Address spaces, SRAM bank mapping, cacheability, replacement and write policy, DRAM channels, arbitration/QoS, coherency, ECC, and memory protection.
- Must expose
- Bytes per level, hit/miss rate, bank conflicts, queue occupancy, DRAM and NoC stalls, peak live memory, ECC events, page faults, and spill traffic.
Failure pattern: tensors fit in total SRAM capacity but collide in the same banks during concurrent compute and DMA, so the realized throughput is far below the compiler estimate.
Deployable artifact anatomy
The runtime should load decisions, not rediscover them
The artifact carries the compiler-to-runtime contract across machines, releases, and trust boundaries. Each section needs explicit bounds, alignment, integrity, compatibility, and ownership rules.
| Artifact section | Required contents | Loader validation question |
|---|---|---|
| Identity and compatibility | Magic, format version, target family/revision, required feature bits, runtime and firmware ABI ranges, endianness, build ID. | Can this runtime, firmware, and hardware revision execute every required feature without reinterpretation? |
| Entry points and tensor ABI | Named entry points, tensor count, shape classes or bounds, dtype, layout, quantization, stride/alignment, mutability, binding index. | Do application bindings match the compiled interface before any device work is submitted? |
| Code and microcode | Engine payloads, kernel IDs, ISA revision, command templates, patch locations, execution permissions, required scratch state. | Are all opcodes, payload sizes, alignments, and executable regions legal for the negotiated target? |
| Constants | Weights, lookup tables, scales, zero points, compression/encryption flags, placement hints, alignment, content hashes. | Are constant bytes intact, trusted when policy requires it, and mapped into legal address classes? |
| Mutable buffers | Static arena size, offsets, lifetimes, alias groups, access permissions, bank/address class, host visibility, dynamic allocation requirements. | Can every buffer be materialized without overlap, overflow, illegal aliasing, or an unsupported memory class? |
| Command and dependency graph | DMA operations, engine commands, barriers, event/token IDs, queue requirements, patchable tensor addresses, timeout classes. | Are dependencies acyclic and bounded, descriptors well formed, and all referenced resources declared? |
| Relocations and resources | Symbols, addends, section references, address widths, SRAM banks, DMA channels, queue count, firmware scratch, counter requirements. | Can relocation arithmetic be checked without truncation, out-of-range access, or resource overcommit? |
| Debug, provenance, and trust | Graph-to-partition/kernel/command map, tensor checkpoints, compiler revision, pass configuration, model/profile digests, section hashes, optional signature. | Can the build be reproduced, faults mapped back to the graph, and every loaded byte authenticated according to policy? |
Failure must be atomic: a rejected artifact must not leave executable memory, DMA mappings, queue state, or partially registered debug identities behind. Loading either produces one valid executable object or rolls back every resource.
Interface explorer
Every boundary needs ownership, invariants, observability, and versioning
Model to compiler
The importer must distinguish what the graph states, what it implies, and what remains dynamic. Operator names alone are not a contract: opset, attributes, layouts, quantization metadata, control flow, aliasing, and preprocessing assumptions all matter.
Compiler to runtime
The compiler freezes decisions that the runtime must execute without reconstructing compiler intent. Treat the artifact format as a versioned product, not an internal serialization accident.
Runtime to kernel driver
User space asks for capabilities, memory, queues, and synchronization. The kernel validates ownership and lifetime, maps memory for DMA, controls reset and power, and prevents one process from corrupting another.
Driver to firmware
A ring, doorbell, and interrupt look simple until wraparound, reset, partial writes, stale generations, and malformed descriptors occur. Define producer and consumer indices, ownership transfer, memory ordering, and recovery together.
Firmware to NPU engines
The scheduler translates a command graph into engine work while preserving dependencies and resource limits. Register writes are only one part; descriptors, local-memory ownership, preemption points, and fault semantics complete the contract.
Trace producer to debugger and profiler
Every layer, partition, command, DMA, interrupt, and counter sample needs a correlation path. Clock-domain conversion must carry source frequency, wrap width, synchronization samples, and uncertainty.
Edge NPU framework and SDK
An SDK is the supported path through the architecture
Headers and bindings are only the surface. A production SDK also defines packaging, target discovery, diagnostics, examples, compatibility policy, telemetry, and the boundary between compile time and run time.
| SDK surface | Required contract | Failure that good design prevents |
|---|---|---|
| C ABI | Opaque handles, explicit ownership, size-versioned structs, stable error codes, no C++ ABI leakage. | Applications breaking when compiler, STL, or internal object layouts change. |
| C++ API | RAII wrappers, typed views, move semantics, futures/events, exception or status policy, thread-safety statement. | Leaked contexts, double frees, hidden synchronization, and ambiguous buffer lifetime. |
| Python tools | Model inspection, compilation orchestration, reports, reproducible config, clear native-error propagation. | Python becoming an undocumented second runtime or hiding target failures. |
| CLI | Machine-readable output, deterministic exit codes, config files, artifact hashes, quiet and verbose modes. | CI scripts scraping human prose and silently accepting partial success. |
| Examples | Minimal sync, async, zero-copy, dynamic-shape, multi-model, profiling, custom-op, and recovery paths. | A sample that works only on a golden model and teaches unsafe lifetime patterns. |
| Compatibility | Documented support matrix across SDK, artifact, driver, firmware, hardware revision, and model opset. | Field failures that appear only after independent component upgrades. |
NPU runtime software
The runtime owns object lifetime and asynchronous truth
Create, load, bind, submit, retire, destroy
Each transition has preconditions. Destroy waits for or cancels in-flight work by policy; a failed device transitions the session to a terminal state instead of pretending later calls can succeed.
Ordering must be named
Define in-order versus out-of-order execution, cross-queue dependencies, host visibility, event reuse, callback context, timeout behavior, and whether cancellation is best effort or guaranteed.
Ownership is separate from visibility
A buffer can be alive but not coherent, mapped but not device-visible, or device-visible but not writable. State transitions should name mapping, cache maintenance, import/export, and fence ownership.
| Concern | C++ production path | Python engineering path |
|---|---|---|
| Hot execution | Queue submission, buffer management, synchronization, callbacks, low-overhead tracing. | Usually wraps native code; avoid per-layer Python dispatch in latency-sensitive paths. |
| Compiler control | Pass implementations, IR ownership, serializers, target backends, runtime ABI. | Experiment orchestration, pass configuration, model analysis, test generation, reports. |
| Hardware models | Bit/cycle models, SystemC/TLM, Verilator harnesses, deterministic simulation. | Stimulus generation, differential comparison, sweep automation, visualization. |
| Tests | Unit, concurrency, sanitizers, ABI, fault injection, performance microbenchmarks. | Model corpus, property tests, tolerance analysis, CI summaries, triage automation. |
Compiler architecture beyond basic rewrites
Scheduling and memory planning solve one coupled resource problem
Graph fusion, tiling, layouts, and quantization are already covered in NPU Practice. Here the focus is pass contracts, constrained scheduling, and offset assignment for a real target.
Prioritize ready work by downstream urgency
Compute an earliest/latest schedule or remaining critical-path length. At each decision, choose a ready operation whose engine and buffers are available. Add transfer and bank-conflict cost to avoid a compute-only optimum.
Overlap repeated tiles and frames
Pick an initiation interval constrained by engine occupancy, DMA throughput, dependencies, and buffer reuse. Prologue, steady state, and epilogue schedules need separate validation.
Use costlier solvers on bounded regions
Dynamic programming, beam search, ILP, or constraint programming can optimize small fused regions. Production compilers usually combine exact local decisions with scalable heuristics and measured cost models.
buffers = sort_by(size_descending, temporary_buffers)
active = interval_index(buffers.live_range)
arena = empty_free_list()
for buffer in buffers:
legal = gaps_not_overlapping(active, buffer.live_range)
legal = enforce_alignment_bank_and_address_class(legal, buffer)
offset = best_fit_with_fragmentation_cost(legal, buffer.size)
if offset is NONE:
offset = grow_arena_or_spill(buffer)
assign(buffer, offset)
reserve_for_lifetime(arena, buffer.live_range, offset, buffer.size)
verify_no_illegal_aliases(arena)
emit_offsets_and_peak_usage(arena)
Allocator proof obligations
- Buffers overlap in address only when lifetimes do not overlap or an in-place alias is explicitly legal.
- Sub-byte and packed formats still satisfy engine and DMA alignment requirements.
- Bank selection respects concurrent access patterns, not only total capacity.
- Dynamic dimensions have bounded arenas, shape classes, or a runtime allocation path.
- Spills include transfer commands, synchronization, and performance cost in the schedule.
- The emitted peak is independently recomputed by a verifier before packaging.
Hardware C++ modeling and integration
One model cannot be fast, bit-exact, cycle-exact, and easy to change at once
Use a model ladder with named fidelity. SystemC/TLM supports architectural exploration and virtual platforms; Verilator compiles SystemVerilog into executable C++ or SystemC models for closer RTL correlation.
| Model contract | Required definition | Correlation evidence |
|---|---|---|
| Functional | Supported op or micro-op semantics, tensor layout, numeric mode, exception behavior. | Golden vectors and randomized differential tests against framework/reference kernels. |
| Temporal | Cycle start/end convention, pipeline occupancy, queue depth, arbitration, backpressure. | Cycle-by-cycle event comparison for directed traces plus aggregate error on model corpus. |
| Memory | Address spaces, transaction size, burst, alignment, banks, cache/coherency assumptions. | Bytes and transactions by engine, bank conflicts, peak occupancy, RTL counter parity. |
| Integration | Register map, descriptors, interrupts, reset, power states, version and feature discovery. | Same driver/firmware tests run against model, FPGA/emulation, and silicon where possible. |
| Known gaps | Deliberately omitted behavior and the expected direction/magnitude of resulting error. | Versioned correlation report; no unexplained tuning constant is accepted as architecture. |
Integration rule: do not let the performance model become a second undocumented ISA. Reuse the same generated register, descriptor, opcode, and trace definitions across compiler, runtime, firmware, model, and debugger whenever the build system permits it.
Hardware metric profiling
Power, cycles, latency, and bandwidth need a shared measurement frame
"Clock latency" is ambiguous. Report device cycles, clock frequency, queue delay, execution duration, and end-to-end wall time separately. Correlate each value to shape, batch, precision, power mode, and temperature.
T = Tqueue + Thost + Tdma + Texec + TsyncExpose overlap; do not add mutually concurrent intervals twice.U = busy cycles / available cyclesDefine available cycles after clock and power gating.BW = transferred bytes / measured timeState payload versus fabric bytes and read/write direction.E = integral(P(t) dt) / completed runsSubtract or report idle baseline and include steady thermal state.| Metric | Collect | Control variables | Common mistake |
|---|---|---|---|
| Latency | Host monotonic timestamps, device start/end cycles, queue events. | Warm/cold, batch, shape, frequency, thermal state, concurrent load. | Mixing compile/setup time with steady execution or reporting only an average. |
| Power | Board rail samples, on-chip monitors, PMIC telemetry, state transitions. | Sample rate, rails included, idle baseline, DVFS, temperature, workload duty cycle. | Dividing a slow power average by a short burst without time alignment. |
| Memory BW | Controller/NoC counters, DMA descriptors, trace bytes, duration. | Read/write, compression, cache hits, payload/overhead, all traffic generators. | Comparing payload bandwidth directly with a raw peak bus figure. |
| Clock and cycles | Cycle counters plus frequency-change events and clock-domain IDs. | DVFS epochs, gating, counter wrap, asynchronous domains, timestamp uncertainty. | Converting all cycles using one nominal frequency. |
Network layer step debugger
"Next layer" is a mapping problem, not a hardware primitive
Compilers fuse, split, reorder, tile, and overlap graph operations. A debugger should expose several step granularities and preserve the many-to-many map between source nodes, compiled regions, commands, and engines.
Framework or ONNX node
Best for model authors. The debugger materializes a semantically meaningful output even when the implementation fused it away, which may require an instrumented recompile.
Partition or fused region
Best for compiler triage. It compares region inputs/outputs, target support, layouts, precision, and reference execution without exposing every tile.
Command, kernel, or micro-op
Best for runtime, firmware, and hardware work. It exposes queue dependencies, addresses, cycles, engine state, counters, and fault snapshots.
| Debugger pane | Data model | Engineering question |
|---|---|---|
| Graph map | Source node, fused region, target/fallback assignment, command IDs. | Where did this operation go, and which boundary added conversion cost? |
| Tensor diff | Shape, dtype, layout, quantization parameters, reference/target values, error histogram. | Where is the first numerical divergence, and does it match the declared tolerance? |
| Memory map | Buffer lifetime, offset, bank, producer/consumer, alias set, residency. | Was data overwritten, misaligned, stale, or transferred unnecessarily? |
| Timeline | Host, driver, firmware, DMA, engine, power, and fault tracks with flows. | Is latency caused by dispatch, dependencies, memory, compute, or recovery? |
| Replay package | Inputs, model/artifact hashes, component versions, device state, trace and logs. | Can another engineer reproduce the same failure without the original machine? |
Git and CI/CD for NPU stacks
Gate contracts at the cheapest level that can disprove them
Git fundamentals already exist in Git Practice. This section focuses on the compiler/runtime/model/hardware release system built on top of version control.
| Pipeline dimension | Fast pull request lane | Scheduled / release lane |
|---|---|---|
| Toolchains | Primary supported compiler and one sanitizer build. | Supported host OS, compiler, architecture, and packaging matrix. |
| Targets | Functional model and one representative hardware revision. | All supported firmware/hardware revisions and compatibility edges. |
| Models | Small operator set plus compact end-to-end smoke models. | Versioned model zoo across shapes, precision modes, dynamic behavior, and fallbacks. |
| Performance | Microbenchmark guardrails with noise budget; fail only on clear regressions. | Dedicated quiet devices, repeated distributions, thermal steady state, baseline approval. |
| Artifacts | Failed traces, diffs, logs, executable manifest, exact command line. | Signed packages, SBOM/provenance, qualification report, dashboards, retained baselines. |
GitHub Actions distinguishes dependency caches from workflow artifacts: caches accelerate reproducible work, while artifacts retain outputs such as binaries, logs, traces, coverage, and reports. A failed NPU test should upload the replay package as an artifact, not hide it inside an ephemeral runner log.
Portfolio build
Six artifacts that demonstrate the architecture
Hardware implementation companion: continue with the Analog CIM board bring-up guide for a concrete PCIe BAR map, UMD/KMD split, Linux probe path, DMA and MSI-X sequence, firmware scheduler, analog program/calibration lifecycle, YOLO dataflow, recovery, and qualification plan.
Primary documentation