metrale_model_layers/layer/transformer_layer/
graph_hooks.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! 2026-09-26: `LayerGraphHooks`, the host-side work a layer does around a CUDA-graph decode
4//! step: the per-step prestage and its re-arm, and the room check and bookkeeping of a
5//! replayed step.
6//!
7//! Owner: model-layers.
8//! Invariants: none beyond the types.
9
10use anyhow::Result;
11use metrale_gpu_runtime::gpu::GpuBackend;
12
13use crate::layer::LayerState;
14
15/// 2026-09-26: A supertrait of `TransformerLayer`; see the module header.
16pub trait LayerGraphHooks {
17    /// 2026-09-25: Per-step host work of a layer that computes on the host at decode (the
18    /// PLE hash and slot upload). The model's single-token decode calls it before any
19    /// CUDA graph replay or capture, when the token id is on the host (`decode_a.rs`), so
20    /// a graph reads only device buffers refreshed here. Default: nothing.
21    fn decode_prestage(
22        &self,
23        _token: u32,
24        _state: &mut dyn LayerState,
25        _gpu: &dyn GpuBackend,
26        _stream: u64,
27    ) -> Result<()> {
28        Ok(())
29    }
30
31    /// 2026-09-25: Re-arm prestaged state that a failed CUDA-graph capture consumed, so the
32    /// same step can re-run eagerly (`decode_a.rs`). It must not recompute the prestage
33    /// work: PLE's history already advanced in `decode_prestage`.
34    fn decode_prestage_rearm(&self, _state: &mut dyn LayerState) {}
35
36    /// 2026-09-25: Update host-side per-sequence bookkeeping for a step served by a
37    /// replayed CUDA graph, in which the layer's `decode` did not run. `seq_len` is the
38    /// length before the step's `k` rows. GLM-5.3's DSA layer rewinds its indexer-cache
39    /// length to `seq_len` when it is ahead, errors when it is behind, and then advances it
40    /// by `k` (`Glm5NextDsaState::sync_to`). The model calls it after a replay in
41    /// `decode_a.rs`, `verify_b.rs`, `verify_c.rs` and `verify_c2.rs`. Default: nothing.
42    fn sync_replayed_step(
43        &self,
44        _state: &mut dyn LayerState,
45        _seq_len: usize,
46        _k: usize,
47    ) -> Result<()> {
48        Ok(())
49    }
50
51    /// 2026-09-25: Return an error for a replayed step whose writes would land past the end
52    /// of a host-tracked cache. The model calls it before launching the graph;
53    /// `sync_replayed_step` runs only after the launch. The step ends at `seq_len + k`.
54    /// Default: nothing.
55    fn check_replay_room(&self, _state: &dyn LayerState, _seq_len: usize, _k: usize) -> Result<()> {
56        Ok(())
57    }
58}