ATOM model operations guide#
ATOM (AiTer Optimized Model) wraps AITER kernels with model-level abstractions for LLM inference on AMD ROCm/HIP GPUs. This guide documents every operator class in atom/model_ops/, their AITER kernel mappings, quantization paths, and fused kernel chains.
Quick reference#
ATOM Class |
File |
AITER Kernel / Import |
Purpose |
|---|---|---|---|
|
|
|
Quantized linear dispatch |
|
|
(inherits |
Column-sharded TP linear |
|
|
(inherits |
Row-sharded TP linear |
|
|
(inherits |
Fused Q/K/V projection |
|
|
(inherits |
Merged gate+up projection |
|
|
|
Unified attention entry |
MHA |
|
|
Multi-head attention |
|
|
|
Multi-head latent attention |
Shared DSA indexer scorer |
|
|
Scoring and top-k for every DSA indexer (DeepSeek-V3.2 / GLM-5.x, GLM-5.3 kpool, DeepSeek-V4, V4.1): the attention builder publishes a step’s rows once ( |
DSA FP4 index cache |
|
|
FP4 (E2M1 + e8m0) index-cache geometry and the DSA FP4 predicate |
|
|
|
FP4 MQA scoring’s ragged rows (DeepSeek-V4, V4.1, V3.2 decode and its DCP shard): rows grouped into sequences ( |
|
|
|
Mixture of experts |
|
|
|
RMS normalization |
|
|
|
Layer normalization |
|
|
|
SiLU gated activation |
|
|
|
Vocab embedding |
|
|
|
LM output head |
|
|
|
Rotary position embedding |
|
|
|
Token sampling |
|
|
Triton |
Speculative decoding |
|
|
Triton |
|
AITER integration overview#
ATOM is a thin model-level inference engine. Every compute-heavy operation delegates to an AITER kernel. The general pattern is:
An ATOM
nn.Moduleowns model weights and configuration.Its
forward()method selects the appropriate AITER function based on quantization type, parallelism settings, and phase (prefill vs. decode).Results are optionally reduced across tensor-parallel (TP) or data-parallel (DP) groups.
AITER kernel mapping table#
ATOM Wrapper |
AITER Function / Import Path |
Backend Type |
|---|---|---|
|
|
hipBLASLt |
|
|
hipBLASLt |
|
|
CK |
|
|
CK |
|
|
CK |
|
|
CK |
MHA prefill |
|
ASM / CK |
MHA decode (ASM) |
|
ASM |
MHA decode (persistent ASM) |
|
ASM |
MHA decode (Triton) |
|
Triton |
MHA prefill (Triton unified) |
|
Triton |
MLA decode |
|
ASM |
MLA prefill |
|
ASM |
MLA KV cache |
|
CK |
RoPE |
|
Triton |
RMSNorm |
|
CK |
SiLU+Mul |
|
CK |
TopK routing |
|
CK |
Sampling |
|
CK |
FusedMoE |
|
CK |
ASM MoE |
|
ASM |
Quantization |
|
CK / Triton |
Linear operations#
All linear layers inherit from LinearBase in atom/model_ops/linear.py.
Class hierarchy#
LinearBase (nn.Module)
+-- ReplicatedLinear # No TP sharding
| +-- MergedReplicatedLinear
+-- ColumnParallelLinear # tp_dim=0, shard output
| +-- QKVParallelLinear # Fused Q/K/V with per-head sharding
+-- MergedColumnParallelLinear # tp_dim=0, merged gate+up
+-- RowParallelLinear # tp_dim=1, shard input, optional all-reduce
Quantization dispatch#
LinearBase.forward() dispatches to different GEMM kernels based on QuantType:
|
Weight dtype |
GEMM Kernel |
Scale Shape |
|---|---|---|---|
|
BF16/FP16 |
|
None |
|
FP8 |
|
|
|
INT8 |
|
|
|
FP8 |
|
|
|
FP8 |
|
|
|
MXFP4 ( |
|
|
When x_scale is not provided, the input is dynamically quantized via get_hip_quant(quant_type).
Tensor parallel sharding#
ColumnParallelLinear (
tp_dim=0): Shards weight rows (output dimension) across GPUs. Each GPU ownsoutput_size / tp_sizerows.RowParallelLinear (
tp_dim=1): Shards weight columns (input dimension). Ifreduce_results=True, output is all-reduced across TP group.QKVParallelLinear: Extends
ColumnParallelLinearwith per-head sharding. Q heads are evenly divided; KV heads are either divided or replicated whennum_kv_heads < tp_size.MergedColumnParallelLinear: Handles gate and up projections merged into a single weight with
output_sizesas a list (e.g.,[intermediate_size, intermediate_size]).
Weight processing#
After loading, process_weights_after_loading() handles:
e4m3fn to e4m3fnuz normalization (AMD FP8 format conversion).
Weight reshuffling via
shuffle_weights()for pre-shuffled GEMM kernels.Scale reshuffling via
fp4_utils.e8m0_shuffle()for MXFP4 block scales.MXFP4 K alignment: a preshuffled MXFP4 weight must have K a multiple of 256 (
MXFP4_PRESHUFFLE_K_ALIGN); the preshuffled GEMMs walk K in 256-wide steps and do not mask a tail. Agate_up -> act -> downMLP whose per-rank intermediate is unaligned pads it as a pair, like MoE’sintermediate_pad: passmxfp4_k_pad_align(quant_config, down_prefix)asoutput_pad_aligntoMergedColumnParallelLinearandinput_pad_aligntoRowParallelLinear. Only a pair that is MXFP4 or bf16 in the checkpoint is padded (a bf16 pair may be quantized online; its zeroed rows quantize to zero): the padded parameters are zeroed when allocated, and every load path writes the real shard at the front of its padded slot (requiresact(0, 0) == 0). A padded layer requantized online from a quantized source (NVFP4, FP8), or a static pair whose halves aren’t both MXFP4 or bf16, is refused at construction. Any preshuffled MXFP4 weight still unaligned is refused here at load. Exempt: the gfx1250 32x4 scale layout, whose kernels take K % 128 (mxfp4_k_pad_alignpads to 128 there), andATOM_USE_FP4_NON_SHUFFLE_TRITON_GEMM=1, whose GEMM reads the raw layout. A refused layer can be kept out of MXFP4 (online quant:exclude_layer).Per-tensor requantization via
requantize_with_max_scale()when multiple output partitions have separate scales.
Attention operations#
Base: Attention (base_attention.py)#
The top-level Attention class in base_attention.py is a dispatcher. It:
Selects the backend via
get_attn_backend()fromatom/utils/selector.py.Instantiates the backend’s implementation class (
impl_cls).Registers itself in
compilation_config.static_forward_contextunderlayer_name.On
forward(), callstorch.ops.aiter.unified_attention_with_output_base, which is a custom op decorated with@mark_spliting_op— this preventstorch.compilefrom tracing into attention internals, enabling full-graph capture.
Backend selection logic (in selector.py):
Condition |
Backend Class |
Implementation |
|---|---|---|
|
|
|
|
|
|
Multi-head attention (attention_mha.py)#
The MHA Attention class handles standard models (Llama, Qwen3, Mixtral, etc.).
Forward flow:
Reshape Q, K, V to
[num_tokens, num_heads, head_dim].Apply RoPE + KV cache write via
rope_cache().Dispatch to the appropriate backend via
dispatch_backend().
RoPE + KV cache paths:
Condition |
Kernel Chain |
|---|---|
|
|
Triton path ( |
|
ASM path + |
|
Attention dispatch:
Phase |
Condition |
Method |
AITER Kernel |
|---|---|---|---|
Prefill |
Always |
|
|
Decode |
|
|
|
Decode |
past a paged kernel’s envelope, or |
|
|
Decode |
|
|
|
Decode |
Default |
|
|
The use_triton_attn flag is set when sliding_window != -1 or head_dim != 128.
Both paged kernels stop short of unified, at different points, and drafting
multiplies the query group into both limits (base_attention.py):
Kernel |
Envelope |
Past it |
|---|---|---|
gluon |
|
no layout arm; Triton fails to compile |
|
|
|
_dispatch_decode is the single place that answers this; the runners do not
re-decide. Unified carries one descale for the whole tensor, so a per-token
quantized layer routed there raises rather than returning wrong numbers.
Multi-head latent attention (attention_mla.py)#
MLAAttention implements DeepSeek’s MLA with a compressed KV representation. Key data structures:
@dataclass
class MLAModules:
q_lora_rank: Optional[int]
kv_lora_rank: int
qk_nope_head_dim: int
qk_rope_head_dim: int
qk_head_dim: int
v_head_dim: int
rotary_emb: torch.nn.Module
q_proj: Optional[torch.nn.Module]
kv_b_proj: torch.nn.Module
o_proj: torch.nn.Module
indexer: Optional[torch.nn.Module]
Forward flow:
If prefill and not sparse: Standard MHA-style prefill with
flash_attn_varlen_func, preceded bykv_b_projGEMM to produce K_nope and V from compressedkv_c_normed.Otherwise: Fused Q projection + K up-projection via batched FP8/FP4 BMM (
_q_proj_and_k_up_proj), then:fused_qk_rope_concat_and_cache_mlawrites to KV cache.Decode:
mla_decode_fwd(ASM persistent MLA kernel).Prefill (sparse):
mla_prefill_fwd.
V up-projection + O projection via batched BMM (
_v_up_proj_and_o_proj).
Batched GEMM backends for MLA projections:
Condition |
Kernel |
|---|---|
|
|
Default |
|
Prefill GEMM optimizations (for kv_b_proj):
Condition |
Kernel |
|---|---|
|
|
|
|
Default |
|
Backend abstraction (attentions/backends.py)#
The AttentionBackend abstract class defines three required methods:
get_name()— Returns backend identifier string.get_builder_cls()— Returns theAttentionMetadataBuildersubclass.get_impl_cls()— Returns the attention implementation class.
CommonAttentionBuilder provides shared metadata preparation (slot mapping, block tables, cumulative sequence lengths) used by both AiterBackend and AiterMLABackend. It marshals block_tables on every prefill step, whether or not that step also uploads the buffer, because the slot arithmetic in token_layout/prefill.py reads the packed table back rather than the batch’s ragged rows.
KV cache operations#
Operation |
AITER Kernel |
Used By |
|---|---|---|
Standard KV cache write |
|
MHA (BF16 KV) |
FP8 KV cache write |
|
MHA (FP8 KV) |
MLA KV cache write |
|
MLA prefill |
Fused QK RoPE + MLA cache |
|
MLA decode |
Mixture of experts (MoE)#
FusedMoE class (moe.py)#
FusedMoE is the top-level MoE module. It handles:
Expert routing via
select_experts().Weight creation and quantization dispatch via
quant_method.Tensor/Expert/Data parallelism via
FusedMoEParallelConfig.Optional shared expert fusion and MORI communication.
Constructor parameters:
FusedMoE(
num_experts: int, # Global number of experts
top_k: int, # Experts per token
hidden_size: int, # Input hidden dimension
intermediate_size: int, # Expert intermediate dimension
reduce_results: bool, # Whether to all-reduce output
renormalize: bool, # Renormalize routing weights
use_grouped_topk: bool, # Use grouped top-k (DeepSeek)
activation: ActivationType, # Silu, Gelu, Swiglu, etc.
...
)
Quantization methods#
FusedMoE selects a quant_method at construction time:
Quant Config |
Method Class |
GEMM Kernel |
|---|---|---|
|
|
|
FP8 ( |
|
|
FP8 compressed-tensors |
|
|
MXFP4 ( |
|
|
The ASM MoE path (asm_moe from aiter.fused_moe_bf16_asm) is used by FP8 methods and supports a16 mode where activations remain in BF16/FP16 while weights are FP8/INT8.
TopK routing (topK.py)#
Routing Function |
AITER Kernel |
Used For |
|---|---|---|
|
|
Standard top-k (Mixtral) |
|
|
Grouped top-k (DeepSeek) |
|
|
Biased grouped top-k (DeepSeek V3) |
Shared expert fusion: When is_rocm_aiter_fusion_shared_expert_enabled() returns True, the top-k buffers are extended with shared expert IDs appended after routed expert IDs. This allows shared expert computation to be fused into the same MoE kernel call. The metadata is initialized via init_aiter_topK_meta_data(). Under DP attention with MoRI EP, fusion is wired up only for MXFP4 / NVFP4 routed experts; FP8 MoE models such as DeepSeek-V3 must run with ATOM_FUSE_SHARED_EXPERT=0, or FusedMoE raises NotImplementedError.
FusedMoEParallelConfig#
@dataclass
class FusedMoEParallelConfig:
tp_size: int # Tensor parallel size
dp_size: int # Data parallel size
ep_size: int # Expert parallel size
tp_rank: int
dp_rank: int
ep_rank: int
use_ep: bool # Whether expert parallelism is active
local_ep_size: int # Local EP size (GPUs per node * TP)
Key properties:
use_all2all_kernels:Truewhendp_size > 1, EP is enabled, and MORI is available.use_mori_kernels: AlwaysTrue(currently).
MORI integration (fused_moe/mori_prepare_finalize.py)#
MORI (MoE Router Infrastructure) provides all-to-all communication kernels for expert parallelism. MoriPrepareAndFinalize implements:
prepare(): Dispatches tokens to remote experts viamori_op.dispatch(), in the layer’s routed-rows wire (MXFP8 with e8m0 scales where the experts take MXFP8,ATOM_MORI_FP4_DISPATCHfor MXFP4, bf16 otherwise).finalize(): Combines expert outputs viamori_op.combine()and copies results back.
The FusedMoEModularKernel orchestrates the prepare-compute-finalize pipeline.
Routing before the rows move (fused_moe/routed_rows.py)#
A MoE method splits into select_experts(layer, x, router_logits) (logical
routes), place_experts(layer, topk_weights, topk_ids, gathered) (the EPLB
remap and load record, the shared column in the layer’s expert layout) and
apply(layer, x, topk_weights, topk_ids, ..., x_scale=None). FusedMoE routes
on the rank that owns the rows, before any of them move: the MORI dispatch, the
DP gather (DP attention without the all2all kernels), the PCP gather
(ATOM_PCP_MOE_MERGE, inside FusedMoE._run_experts) and the comm-fused DPA
gather all carry top-k weights and ids rather than router logits. Rows are
placed after every gather, so a gathered row – held alike by every rank –
picks the same EPLB replica on each (gathered); and where the legacy layout
widens in the prefilled shared column (LEGACY_AITER), whose ids say by row
position which rank runs a row’s shared expert, a gather is followed by
reassign_gathered_shared_ids, which gives the rows this rank’s ids for their
gathered positions. Every routing kernel takes the pass’s real row count,
Context.scheduled_tokens_gpu (an entry of the step’s
forward_vars["batch_info"], read on device so a replayed graph follows its
own step), and routes the rows past it to -1, so they are neither sent nor
computed. Only a consumer of the pass’s whole rows (running_tokens) gets the
count (pass_scheduled_tokens_gpu): the MoE sort reads it as its row count, so
a subset of the rows – a PCP shard, gathered rows – gets None and runs every
row, unless it declares a pass of its own with its own count
(ForwardContext.use_pass_rows, as V4.1’s decoder does over a prefill’s tails
with ReplayPlan.filled_gpu / finishing_gpu). The rows travel in
RoutedRowsWire, the method’s routed_rows_wire – the one format both the
gathers and the MoRI v1 dispatch use: MXFP4 under ATOM_MORI_FP4_DISPATCH,
MXFP8 where the experts take MXFP8 activations (FlyDSL fused_moe, the Triton
a8w4 EP experts), bf16 otherwise (the TP Triton path, MegaMoE, the MoRI v2
transport). Rows already in the wire carry their e8m0 rows as x_scale through
apply, the modular kernel and prepare, so nothing is quantized twice.
MoE quantization config (fused_moe/config.py)#
FusedMoEQuantConfig describes activation and weight quantization for MoE layers:
@dataclass
class FusedMoEQuantConfig:
_a1: FusedMoEQuantDesc # First activation (input to gate_up)
_a2: FusedMoEQuantDesc # Second activation (input to down_proj)
_w1: FusedMoEQuantDesc # gate_up_proj weights
_w2: FusedMoEQuantDesc # down_proj weights
Factory functions:
fp8_w8a8_moe_quant_config()— FP8 weights and activations.mxfp4_w4a16_moe_quant_config()— MXFP4 weights, unquantized activations.FUSED_MOE_UNQUANTIZED_CONFIG— No quantization.
Triton MoE fallback (fused_moe_triton.py)#
triton_kernel_fused_experts() provides a Triton-based MoE path. It takes rows routed already (FusedMoE.select_experts, before any gather or dispatch): routing_from_dispatched() sorts their top-k ids into the Triton routing data, with a gate_valid mask for rows another rank owns or rows past the real row count, and the expert GEMMs run on that. This path is used for MXFP4 MoE under ATOM_USE_TRITON_MOE.
Normalization#
RMSNorm (layernorm.py)#
RMSNorm supports multiple forward paths depending on configuration flags:
Condition |
Kernel / Path |
Returns |
|---|---|---|
|
|
Padded output |
|
|
(output, residual) |
|
|
(output, residual) |
|
|
(FP8 output, scale) |
|
|
(MXFP4 output, scale) |
Default, no residual |
|
Output |
Default, with residual |
|
(output, residual) |
Constructor parameters:
RMSNorm(
dim: int,
eps: float = 1e-6,
x_pad_to_multiple: int = 0,
fused_allreduce: bool = False,
fused_quant: bool = False,
quant_config: Optional[QuantizationConfig] = None,
)
LayerNorm (layernorm.py)#
LayerNorm wraps layernorm2d_fwd and layernorm2d_fwd_with_add (with bias support):
LayerNorm(dim: int, eps: float = 1e-6)
Without residual:
layernorm2d_fwd(x, weight, bias, eps)With residual:
layernorm2d_fwd_with_add(out, x, residual, residual_out, weight, bias, eps)
Activation functions#
SiluAndMul (activation.py)#
SiluAndMul computes SiLU(x_first_half) * x_second_half. It splits the last dimension in half.
Condition |
Kernel |
Output |
|---|---|---|
|
|
|
|
|
|
Default |
|
BF16 output |
Constructor:
SiluAndMul(
fused_quant: bool = False,
quant_config: Optional[QuantizationConfig] = None,
)
Embedding and output head#
VocabParallelEmbedding (embed_head.py)#
Partitions the vocabulary across TP ranks. Each rank holds num_embeddings / tp_size rows.
Forward:
Mask input token IDs to this rank’s partition range
[vocab_start_idx, vocab_end_idx).F.embedding()on local partition.Zero out out-of-range positions.
all_reduce()across TP group.
ParallelLMHead (embed_head.py)#
Extends VocabParallelEmbedding for the output projection. Key differences:
Forward extracts only the last token per sequence during prefill (via
cu_seqlens_q[1:] - 1).Uses
tgemm.mm(x, self.weight, self.bias)for the logit computation (notF.linear).Calls
tensor_model_parallel_all_gather()to gather logits across TP ranks.
Rotary position embedding (RoPE)#
RotaryEmbedding (rotary_embedding.py)#
Precomputes cos/sin caches at initialization and applies RoPE in-place.
Constructor:
RotaryEmbedding(
head_size: int,
rotary_dim: int,
max_position_embeddings: int,
base: float,
is_neox_style: bool = True,
dtype: Optional[torch.dtype] = None,
)
Forward: Calls aiter.rope_cached_positions_2c_fwd_inplace(query_, key_, cos, sin, positions, rotate_style, ...) which applies RoPE to Q and K tensors in-place using precomputed caches indexed by position IDs.
get_rope() factory#
get_rope(head_size, rotary_dim, max_position, base, rope_scaling=None)
Returns a cached RotaryEmbedding instance. Currently rope_scaling must be None.
Integration in attention#
MHA (
attention_mha.py): RoPE is applied during therope_cache()phase, either via the fusedfused_qk_norm_rope_cache_quant_shufflekernel, viafused_qk_rope_reshape_and_cache, or via standalonerotary_emb(position, q, k).MLA (
attention_mla.py): RoPE is applied toq_peandk_ropetensors. During decode, this is fused intofused_qk_rope_concat_and_cache_mla. During prefill, it is applied viaself.rotary_emb(positions, prefill_q_pe, k_rope).
Sampling#
Sampler (sampler.py)#
Unified sampling supporting both greedy (temperature=0) and random (temperature>0) sampling in a single kernel call.
Forward:
def forward(self, logits, temperatures) -> sampled_tokens:
mixed_sample_outer_exponential(sampled_tokens, logits, exponential, temperatures, eps)
aiter.mixed_sample_outer_exponential performs temperature-scaled exponential sampling: it divides logits by temperature, then uses the Gumbel-max trick with pre-generated exponential random variates.
Fallback methods (currently unreachable due to early return):
greedy_sample():aiter.ops.triton.topk.topk(logits, 1)random_sample():aiter.ops.triton.softmax.softmax(logits)followed by exponential sampling andtopk.
Required channel (required_channel.py)#
Holds a request with a RequiredChannel (atom/sampling_params.py; today only
Kimi-K3 under tool_choice="required") to its tools channel by masking the
target logits before any sampler reads them. Until the channel opens, the end
ids (the format’s own plus the engine’s EOS and stop_token_ids) are -inf;
once the output ends with after (K3: <|close|>response<|sep|>), each next
row keeps only the forced id of opening. The channel is open once opening
is written, or once the model writes opening[:opens_at] itself (K3:
<|open|>tools<|sep|>); the state is then UNCONSTRAINED and the request
costs nothing more.
constrain_logitsmasks a step’s rows in place: plain decode and prefill rows by the request’s state, verification rows as if the drafts before them were accepted, and the bonus row after every draft. A mismatching draft is therefore rejected by the ordinary rejection sampler.advance_statesfolds the step’s emitted ids into each state on the GPU, so a deferred-output step reads its predecessor’s states throughdecode_srcbefore the host has seen those ids.
constrain_logits runs VOCAB_PROGRAMS (16) programs per request, each
writing every 16th 1,024-column block of a forced row without reading it;
advance_states runs one per request. On MI355X over K3’s vocabulary a step
with no forced row costs what one program per request did (5-7 us for a
DSpark7 verify step at bs 1-64), and one with all seven draft rows forced
15-52 us. A batch with no unopened channel launches neither kernel. constrain_logits_reference / advance_states_reference are
the pure-torch twins the tests hold the kernels to.
RejectionSampler (rejection_sampler.py)#
Implements rejection sampling for speculative decoding (MTP). Given draft token IDs and target model logits:
Computes
target_argmax = target_logits.argmax(dim=-1).Runs a Triton kernel
rejection_greedy_sample_kernelthat sequentially compares draft tokens against target argmax, accepting until first mismatch.On full acceptance, appends the bonus token.
Returns
(output_token_ids, num_bonus_tokens).
Fused kernel chains#
ATOM uses fused kernels to reduce memory traffic by combining multiple operations into a single kernel launch.
Fused Operation |
Components |
Controlled By |
AITER Kernel |
|---|---|---|---|
RMSNorm + FP8 quant |
RMSNorm, per-tensor FP8 static quant |
|
|
RMSNorm + MXFP4 quant |
RMSNorm, per-1x32 MXFP4 quant |
|
|
RMSNorm + add + pad |
Residual add, RMSNorm, output padding |
|
|
AllReduce + RMSNorm |
TP all-reduce, RMSNorm |
|
|
SiLU + mul + FP8 quant |
SiLU activation, multiply, FP8 quant |
|
|
SiLU + mul + MXFP4 quant |
SiLU activation, multiply, MXFP4 quant |
|
|
QK norm + RoPE + cache + quant |
Q/K norm, RoPE, KV cache write, optional FP8 quant, weight shuffle |
|
|
RoPE + reshape + cache |
RoPE, K reshape, KV cache write |
Triton attention path |
|
QK RoPE + MLA cache |
Q RoPE, KV concat, MLA cache write, FP8 quant |
MLA decode path |
|
GEMM + split + cat (FP4) |
KV_b_proj GEMM, split K_nope/V, cat K_rope |
|
|
GEMM + split + cat (FP8) |
KV_b_proj GEMM, split K_nope/V, cat K_rope |
|
|
FP8 BMM + RoPE + cache (MLA) |
Batched FP8 BMM, RoPE, MLA KV cache write |
MLA decode with FP8 |
|
FP4 BMM + RoPE + cache (MLA) |
Batched FP4 BMM, RoPE, MLA KV cache write |
MLA decode with MXFP4 |
|
Source files#
atom/model_ops/#
File |
Description |
|---|---|
|
|
|
|
|
|
|
Top-level |
|
MHA implementation: prefill (flash), decode (ASM/Triton paged attention) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Helper utilities: |
atom/model_ops/attentions/#
File |
Description |
|---|---|
|
|
|
|
|
|
atom/model_ops/attentions/pool_layout/ and .../token_layout/#
Two packages, two axes. pool_layout answers where a byte lives in the
cache pools and is a function of the config; token_layout answers where
this step’s tokens go and is a function of the batch, so it is rebuilt every
step. A backend consumes both and belongs to neither.
Membership has three parts, and only the third is machine-checkable. By
topic — the axis decides, not the dependencies. Arithmetic, not staging —
a member computes an answer and does not write or upload a forward_vars
mirror; page_unit_geometry is a mixin over self.model_runner and still
qualifies because it only reads, so taking self is not the line, having a
side effect on the step’s buffers is. Reachable without aiter or the rest
of atom, so a member is importable on a runner with no AITER build and no
GPU — CI is such a runner, and one import failure during collection aborts the
whole run rather than one test, so tests/test_layout_packages.py enforces
that part over both packages. Do not mistake the checkable part for the rule.
Two absences are deliberate. v4_kernels/pool_index.py is
v4_pool_geometry’s device-side half — the same row formulas as @triton.jit
device functions for the eight kernels that address the pool — and stays with
the kernels; tests/test_pool_index.py pins the two sides together. And a
per-token shape that only one caller has stays with that caller: V4’s decode
positions are ragged, and the one-token decode slot mapping comes from
last_block_num_tokens rather than from a position.
File |
Description |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
atom/model_ops/fused_moe/#
File |
Description |
|---|---|
|
|
|
|
|
|
|
|
|
MoE utility functions |
atom/utils/#
File |
Description |
|---|---|
|
|