flashinfer.attention.prims_ts.prims_ts_batch_decode_with_kv_cache¶
- flashinfer.attention.prims_ts.prims_ts_batch_decode_with_kv_cache(query: Tensor, kv_cache: Tensor | tuple[Tensor, Tensor], workspace_buffer: Tensor, paged_kv_indptr: Tensor, paged_kv_indices: Tensor, seq_lens: Tensor, max_seq_len: int, *, seq_len_q: int = 1, qo_indptr: Tensor | None = None, max_seq_len_q: int | None = None, bmm1_scale: float | None = None, bmm2_scale: float = 1.0, out: Tensor | None = None, out_dtype: dtype | None = None, mask_type: Literal['dense', 'causal'] = 'dense', window_left: int = -1, kv_layout: Literal['HND'] = 'HND') Tensor¶
Launch fixed or packed-Q native-CSR FMHA decode with caller scratch.
For
seq_len_q=1,queryand the returned output both have shape[B, Hq, D]. Forseq_len_q>1, both use compact token-major[B, SQ, Hq, D]storage. The kernel writes that layout directly; no layout transpose is performed. Whenqo_indptris supplied, Q and O use packed[total_q, Hq, D]storage. Requestbowns rowsqo_indptr[b]:qo_indptr[b+1];max_seq_len_qis only the static workspace/JIT bound and is required for this standalone packed interface. To keep this launch path free of device-to-host synchronization, callers must ensure that packed offsets start at zero, are strictly increasing, end atquery.shape[0], and have every delta at mostmax_seq_len_q. For causal masking, every fixed or packed per-request Q length must also be no greater than the corresponding liveseq_lensvalue.kv_cacheis either a combined[pages, 2, Hkv, page_size, D]tensor or a(K, V)tuple of[pages, Hkv, page_size, D]tensors. The metadata uses FlashInfer’s native CSR page-ID ABI;seq_lensis explicit andmax_seq_lenis the exact static maximum used for automatic policy selection and JIT caching. It must be no larger than2,147,483,520so the padded 128-token K/V tile endpoint remains representable as signed Int32. Each request must own enough CSR entries for its live length:(seq_lens[b] + page_size - 1) // page_size <= ( paged_kv_indptr[b + 1] - paged_kv_indptr[b] )
The indptr must start at zero, increase strictly, and end at
paged_kv_indices.numel(); every live page ID must indexkv_cache.workspace_buffermust be zero-initialized before its first use and re-zeroed whenever an argument contributing to the semantic JIT key changes, because the internal section offsets can change with that key. It is exclusive to one in-flight launch or captured graph and must not overlap query, K/V cache, metadata, or output storage. Runtime sequence lengths must remain positive and no larger thanmax_seq_len; this hot path deliberately does not read device metadata back to the host. Live CSR, length, page-ID, and packed-Q values may change between completed launches or graph replays only while all of their contracts remain valid. They must not be mutated concurrently with a launch or replay that reads them. Warm the semantic key before CUDA graph capture and provideoutto avoid an output allocation. Captured graphs must retain stable metadata storage;qo_indptrvalues may change only while the packed-offset contract remains valid, every delta stays within the compiled bound, and the final offset continues to match the captured query/output extent.window_left=-1disables the left window; a non-negative value requires causal masking and includes the current token. No backend fallback or scheduling knob is exposed.