{"record":{"id":"6a87c67eb7f7ec44","repo":"huggingface/candle","slug":"seqlens-q-has-to-be-contiguous-6a87c6","errorCode":null,"errorMessage":"seqlens_q has to be contiguous","messagePattern":"seqlens_q has to be contiguous","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-flash-attn/src/lib.rs","lineNumber":488,"sourceCode":"        k: &candle::CudaStorage,\n        k_l: &Layout,\n        v: &candle::CudaStorage,\n        v_l: &Layout,\n        is_bf16: bool,\n    ) -> Result<(candle::CudaStorage, Shape)> {\n        // https://github.com/Dao-AILab/flash-attention/blob/184b992dcb2a0890adaa19eb9b541c3e4f9d2a08/csrc/flash_attn/flash_api.cpp#L327\n        let dev = q.device();\n        let out_shape = q_l.shape().clone();\n        let out_l = Layout::contiguous(&out_shape);\n\n        let (seqlens_q, seqlens_q_layout) = self.seqlens_q.storage_and_layout();\n        let seqlens_q = match &*seqlens_q {\n            candle::Storage::Cuda(c) => c.as_cuda_slice::<u32>()?, // Should be i32!\n            _ => candle::bail!(\"seqlens_q must be a cuda tensor\"),\n        };\n        let seqlens_q = match seqlens_q_layout.contiguous_offsets() {\n            Some((o1, o2)) => seqlens_q.slice(o1..o2),\n            None => candle::bail!(\"seqlens_q has to be contiguous\"),\n        };\n\n        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            }","sourceCodeStart":470,"sourceCodeEnd":506,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-flash-attn/src/lib.rs#L470-L506","documentation":"The varlen path requires seqlens_q to be a contiguous tensor so it can take a single flat slice via contiguous_offsets(). Non-contiguous layouts (strided/sliced views) cannot be handed to the kernel directly.","triggerScenarios":"Passing seqlens_q produced by narrow/slice/pad operations that leave a non-contiguous layout, or .transpose/.index_select views without .contiguous().","commonSituations":"Deriving cu_seqlens from a padded batch tensor by slicing rows/columns, reusing cached seqlens tensors that were reshaped with non-unit strides.","solutions":["Call .contiguous() on seqlens_q before passing it","Build seqlens fresh as a flat 1D contiguous tensor (Tensor::new/from_vec gives contiguous layout)","Avoid narrow/slice views for seqlens; copy the needed values into a new tensor"],"exampleFix":"// before\nlet seqlens_q = padded_seqlens.narrow(1, 0, batch + 1)?; // non-contiguous view\n// after\nlet seqlens_q = padded_seqlens.narrow(1, 0, batch + 1)?.contiguous()?;","handlingStrategy":"validation","validationCode":"fn ensure_contiguous(t: &Tensor) -> candle::Result<Tensor> {\n    if t.is_contiguous() { Ok(t.clone()) } else { t.contiguous() }\n}\nlet seqlens_q = ensure_contiguous(&seqlens_q)?;","typeGuard":"fn contiguous_cuda_u32(t: &Tensor) -> bool {\n    t.is_contiguous() && t.device().is_cuda() && t.dtype() == candle::DType::U32\n}","tryCatchPattern":"match flash_attn_varlen(&q, &k, &v, &seqlens_q.contiguous()?, &seqlens_k.contiguous()?, scale, max_q, max_k, None, None, None) {\n    Err(e) if e.to_string().contains(\"has to be contiguous\") => { /* log tensor layout, rebuild */ }\n    r => r?,\n}","preventionTips":["Call .contiguous() on any tensor built from narrow/slice before kernel calls","Prefer constructing seqlens fresh via Tensor::from_vec (always contiguous)","Avoid storing seqlens as views of larger buffers"],"tags":["cuda","flash-attention","contiguity","varlen"],"backgroundTag":"tensor-not-contiguous","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}