Module scope

Module scope 

Source
Expand description

Model teardown — ordered, fallible release of state that owns device memory.

§Why there are no caches here

An earlier version of this module offered generation-checked statics (Scoped, ScopedFlag, ScopedMap) as a safe home for state derived from the loaded model. They are gone, and the reasoning is worth keeping:

A checked static is still a static. It is a dependency the signature does not declare, it cannot be varied in a test without mutating the process, and a site that forgets it fails at runtime — if it is ever read at all. Propagating the value instead makes the same question a compile-time one: add a field, and every construction site that forgot it stops building.

In practice a carrier almost always already exists and the static was bypassing it — ForwardContext reaches every dispatch site in the model, &dyn Model reaches the scheduler, and a backend owns its own device handles. Where no carrier exists, the answer is to add one, not to reach for a guarded global.

§The statics that legitimately remain

What stays is state derived from the process or the device rather than from the checkpoint. Every such site carries a comment arguing its case; these are the categories, so a reader can tell at a glance whether a static they have found is accounted for or is a straggler.

  1. The CUDA host (crate::cuda_host). One primary context per device per process, enforced by the driver; outliving every model is the entire point, since not recreating it is what in-process swapping buys. The full argument is on the declaration.

  2. Log-once latches (std::sync::Once, *_LOGGED, *_WARNED). These hold no value — a Once is a latch, not data — so they cannot produce a wrong answer. Their only cross-model effect is suppressing a duplicate log line for a route the previous model also took. Threading a logging concern through every kernel-dispatch signature to restore one INFO line is not a trade worth making.

  3. One-shot diagnostic latches (*_DUMP_DONE, *_DIAG_DONE). Same shape, and live only when an ATLAS_DUMP_* variable is set: they gate a debug capture whose intent is “one sample per process”, not “one per model”. A stale latch suppresses a duplicate dump; it cannot corrupt one.

  4. Compile-time tables and descriptors. Immutable data with no runtime state — lookup tables are const where the language allows it, and the plugin/benchmark descriptors are static only because they are reached as &'static and need a stable address.

  5. Process lifecycle (the TUI’s terminal guard, shutdown flags, log ring). These describe the process’s relationship to its terminal and its exit, which no model has any bearing on.

Anything not in one of those five is a straggler and should be scoped.

§What this module does provide

ModelResource and Teardown give an ordered, fallible release path, which Drop cannot: it is neither ordered across independent values nor able to report a failure, and on GB10 unified memory frees must happen at a quiescent point in a controlled order.

Structs§

Teardown
Releases a set of resources in reverse registration order — the inverse of how they were built, which is the only order that is safe when later resources borrow earlier ones.

Traits§

ModelResource
State that owns device memory and must be released in a defined order.