For the complete documentation index, see llms.txt. Markdown versions of all pages are available by appending .md to any URL (e.g. /max/get-started.md).
Mojo struct
SoftmaxRDNA
struct SoftmaxRDNA[dtype: DType, num_m_mmas: Int, num_n_mmas: Int, num_warps_m: Int, num_warps_n: Int, use_exp2: Bool = False]
Online softmax accumulator for RDNA Wave32 attention kernels.
Tracks per-row running maximum and sum across online softmax iterations
so that attention scores can be normalized incrementally as new key/value
tiles arrive. The full() method runs one complete iteration (max β exp β
sum β correction β output update) end-to-end.
Parametersβ
- βdtype (
DType): Element type of the score and output fragments. - βnum_m_mmas (
Int): Number of MMA tiles along the query (row) dimension. - βnum_n_mmas (
Int): Number of MMA tiles along the key (column) dimension. - βnum_warps_m (
Int): Number of warps assigned to the row dimension. - βnum_warps_n (
Int): Number of warps assigned to the column dimension. - βuse_exp2 (
Bool): Selectsexp2instead of naturalexpfor the softmax kernel.
Fieldsβ
- βrowmax_tensor (
SoftmaxRDNA[dtype, num_m_mmas, num_n_mmas, num_warps_m, num_warps_n, use_exp2].RowMaxTensorType): - βrowsum_tensor (
SoftmaxRDNA[dtype, num_m_mmas, num_n_mmas, num_warps_m, num_warps_n, use_exp2].RowSumTensorType): - βscore_frag_rowmax (
SoftmaxRDNA[dtype, num_m_mmas, num_n_mmas, num_warps_m, num_warps_n, use_exp2].ScoreFragTensorType): - βscore_frag_rowsum (
SoftmaxRDNA[dtype, num_m_mmas, num_n_mmas, num_warps_m, num_warps_n, use_exp2].ScoreFragTensorType): - βcorrection (
SoftmaxRDNA[dtype, num_m_mmas, num_n_mmas, num_warps_m, num_warps_n, use_exp2].ScoreFragTensorType):
Implemented traitsβ
comptime membersβ
exp_functionβ
comptime exp_function = _exp2_concrete[_, _] if use_exp2 else _exp_concrete[_, _]
frag_is_row_vectorβ
comptime frag_is_row_vector = True
frag_num_rowsβ
comptime frag_num_rows = ComptimeInt[Int(1)].static_value
frag_sizeβ
comptime frag_size = SoftmaxRDNA[dtype, num_m_mmas, num_n_mmas, num_warps_m, num_warps_n, use_exp2].FragmentLayoutT.static_product
FragmentLayoutTβ
comptime FragmentLayoutT = Layout[*?, *?]
num_colwise_lanesβ
comptime num_colwise_lanes = SIMD(Int(16))
num_colwise_tilesβ
comptime num_colwise_tiles = num_m_mmas
num_colwise_warpsβ
comptime num_colwise_warps = num_warps_m
num_rowwise_lanesβ
comptime num_rowwise_lanes = SIMD(Int(2))
num_rowwise_tilesβ
comptime num_rowwise_tiles = num_n_mmas
num_rowwise_warpsβ
comptime num_rowwise_warps = num_warps_n
row_layoutβ
comptime row_layout = row_major[num_m_mmas, Int(1)]()
RowMaxTensorTypeβ
comptime RowMaxTensorType = TileTensor[dtype, Layout[*?, *?], MutUntrackedOrigin, address_space=AddressSpace.LOCAL]
RowSumTensorTypeβ
comptime RowSumTensorType = SoftmaxRDNA[dtype, num_m_mmas, num_n_mmas, num_warps_m, num_warps_n, use_exp2].RowMaxTensorType
rowwise_lanes_strideβ
comptime rowwise_lanes_stride = SIMD(Int(16))
score_frag_layoutβ
comptime score_frag_layout = row_major[SoftmaxRDNA[dtype, num_m_mmas, num_n_mmas, num_warps_m, num_warps_n, use_exp2].num_colwise_tiles, Int(1)]()
ScoreFragTensorTypeβ
comptime ScoreFragTensorType = TileTensor[dtype, Layout[*?, *?], MutUntrackedOrigin, address_space=AddressSpace.LOCAL]
warp_colsβ
comptime warp_cols = ComptimeInt[Int(2)].static_value
warp_rowsβ
comptime warp_rows = ComptimeInt[Int(16)].static_value
WarpLayoutTβ
comptime WarpLayoutT = Layout[*?, *?]
Methodsβ
__init__β
def __init__(out self)
calculate_qk_maxβ
def calculate_qk_max(self, score: TileTensor[dtype, Storage=score.Storage, address_space=score.address_space, linear_idx_type=score.linear_idx_type], warp_scratch: TileTensor[dtype, Storage=warp_scratch.Storage, address_space=warp_scratch.address_space, linear_idx_type=warp_scratch.linear_idx_type])
calculate_qk_sumβ
def calculate_qk_sum(self, score: TileTensor[dtype, Storage=score.Storage, address_space=score.address_space, linear_idx_type=score.linear_idx_type], warp_scratch: TileTensor[dtype, Storage=warp_scratch.Storage, address_space=warp_scratch.address_space, linear_idx_type=warp_scratch.linear_idx_type])
expβ
def exp(self, score: TileTensor[dtype, Storage=score.Storage, address_space=score.address_space, linear_idx_type=score.linear_idx_type])
calculate_correctionβ
def calculate_correction(self)
update_outputβ
def update_output(self, output: TileTensor[dtype, Storage=output.Storage, address_space=output.address_space, linear_idx_type=output.linear_idx_type])
update_sumβ
def update_sum(self)
update_maxβ
def update_max(self)
fullβ
def full(self, output: TileTensor[dtype, Storage=output.Storage, address_space=output.address_space, linear_idx_type=output.linear_idx_type], score: TileTensor[dtype, Storage=score.Storage, address_space=score.address_space, linear_idx_type=score.linear_idx_type], warp_scratch: TileTensor[dtype, Storage=warp_scratch.Storage, address_space=warp_scratch.address_space, linear_idx_type=warp_scratch.linear_idx_type])
Single-pass online softmax iteration: max -> exp -> sum -> correction -> update output -> update max/sum.
Args:
- βoutput (
TileTensor[dtype, Storage=output.Storage, address_space=output.address_space, linear_idx_type=output.linear_idx_type]): Accumulator tile of partial softmax outputs to correct in place with the per-row renormalization factor. - βscore (
TileTensor[dtype, Storage=score.Storage, address_space=score.address_space, linear_idx_type=score.linear_idx_type]): Attention score tile for this iteration; overwritten in place with exponentiated, max-subtracted values. - βwarp_scratch (
TileTensor[dtype, Storage=warp_scratch.Storage, address_space=warp_scratch.address_space, linear_idx_type=warp_scratch.linear_idx_type]): Shared-memory scratch tile used for cross-warp row reductions of the running maximum and sum.
Was this page helpful?
Thank you! We'll create more content like this.
Thank you for helping us improve!