topk: Output selection width, including invalid tail slots.
segments: Local Q start/end, global compressed K start/end, and raw
prefix length modulo ratio. Packed segments require batch size one.
"""
indexer = _load_indexer_op()
batch, length, heads, dim = query.shape
result = torch.full((batch, length, topk), -1, device=query.device, dtype=torch.int32)
for start, end, key_start, key_end, residual in split_compressed_segments(segments, ratio):
if key_end <= key_start or start == end:
continue
residue = torch.full((batch,), residual, device=query.device, dtype=torch.int32)
metadata = None
if _requires_metadata(query.device):
metadata = _load_indexer_metadata_op()(
heads, 1, dim, topk, cmp_residual_k=residue,
batch_size=batch, max_seqlen_q=end-start, max_seqlen_k=key_end-key_start,
layout_q="BSND", layout_k="BSND", mask_mode=3, cmp_ratio=ratio,
)
with torch.autocast(device_type=query.device.type, enabled=False):
indices, _ = indexer(
query[:, start:end].contiguous(), key[:, key_start:key_end].unsqueeze(2).contiguous(),
weights[:, start:end].float().contiguous(), topk,
cmp_residual_k=residue, metadata=metadata,
layout_q="BSND", layout_k="BSND", mask_mode=3, cmp_ratio=ratio,