{"record":{"id":"151a90233dccadb9","repo":"huggingface/candle","slug":"block-table-last-dimension-must-be-contiguous","errorCode":null,"errorMessage":"block_table last dimension must be contiguous","messagePattern":"block_table last dimension must be contiguous","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-flash-attn/src/lib.rs","lineNumber":509,"sourceCode":"        let (seqlens_k, seqlens_k_layout) = self.seqlens_k.storage_and_layout();\n        let seqlens_k = match &*seqlens_k {\n            candle::Storage::Cuda(c) => c.as_cuda_slice::<u32>()?, // Should be i32!\n            _ => candle::bail!(\"seqlens_k must be a cuda tensor\"),\n        };\n        let seqlens_k = match seqlens_k_layout.contiguous_offsets() {\n            Some((o1, o2)) => seqlens_k.slice(o1..o2),\n            None => candle::bail!(\"seqlens_k has to be contiguous\"),\n        };\n\n        let block_table = if let Some(block_table) = self.block_table.as_ref() {\n            let (block_table_storage, block_table_layout) = block_table.storage_and_layout();\n            match &*block_table_storage {\n                candle::Storage::Cuda(_) => {}\n                _ => candle::bail!(\"block_table must be a cuda tensor\"),\n            }\n            let block_table_stride = block_table_layout.shape().dims2()?.1;\n            if block_table_layout.stride().last().copied() != Some(1) {\n                candle::bail!(\"block_table last dimension must be contiguous\")\n            }\n            Some((\n                block_table_storage,\n                block_table_layout.start_offset(),\n                block_table_stride,\n            ))\n        } else {\n            None\n        };\n\n        let q = q.as_cuda_slice::<T>()?;\n        let k = k.as_cuda_slice::<T>()?;\n        let v = v.as_cuda_slice::<T>()?;\n        let q = q.slice(q_l.start_offset()..);\n        let k = k.slice(k_l.start_offset()..);\n        let v = v.slice(v_l.start_offset()..);\n\n        let q_stride = q_l.stride();","sourceCodeStart":491,"sourceCodeEnd":527,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-flash-attn/src/lib.rs#L491-L527","documentation":"Raised in candle-flash-attn/src/lib.rs when the `block_table` tensor's last (innermost) dimension stride is not 1, i.e. its rows are not contiguous. The kernel indexes the block table assuming a row-major contiguous layout, so call `.contiguous()` (or reshape/transpose appropriately) before passing it.","triggerScenarios":"Passing a block_table view whose last axis is strided — e.g. a transposed table, a column slice of a wider buffer, or any tensor from narrow/permute without contiguity in dim 1.","commonSituations":"Reusing a (max_blocks, batch) table transposed to (batch, max_blocks) without .contiguous(); slicing page tables out of a fused metadata tensor.","solutions":["Call .contiguous() on block_table before passing it","Ensure it is created as a contiguous [batch, max_num_blocks_per_seq] tensor","Avoid permute/transpose on the table; build it in the required layout"],"exampleFix":"// before\nlet block_table = pages_buf.t()?.contiguous()?; // wrong layout then fix\nlet block_table = pages_buf.t()?; // last dim strided\n// after\nlet block_table = pages_buf.t()?.contiguous()?; // stride 1 on last dim\n","handlingStrategy":"validation","validationCode":"fn ensure_block_table_layout(bt: &Tensor) -> candle::Result<Tensor> {\n    let (_, last_stride) = (bt.dim(0)?, bt.stride()[1]);\n    if last_stride != 1 { return bt.contiguous(); }\n    Ok(bt.clone())\n}\nlet block_table = ensure_block_table_layout(&block_table)?;","typeGuard":"fn block_table_contiguous(t: &Tensor) -> bool {\n    t.dims().len() == 2 && *t.stride().last().unwrap_or(&0) == 1\n}","tryCatchPattern":"let block_table = block_table.map(|bt| bt.contiguous()).transpose()?;\nmatch flash_attn_varlen(&q, &k, &v, &sq, &sk, scale, max_q, max_k, None, None, block_table.as_ref()) {\n    Err(e) if e.to_string().contains(\"block_table last dimension must be contiguous\") => { /* rebuild table contiguously */ }\n    r => r?,\n}","preventionTips":["Never transpose/permute the block table; build it in [batch, max_blocks] order","Call .contiguous() on tables derived from views or slices","Assert last stride == 1 in debug builds before paged attention calls"],"tags":["cuda","flash-attention","contiguity","paged-attention"],"backgroundTag":"tensor-not-contiguous","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}