{"record":{"id":"94985b9da748d903","repo":"huggingface/candle","slug":"mm-prefix-ranges-last-dimension-must-be-contiguous","errorCode":null,"errorMessage":"mm_prefix_ranges last dimension must be contiguous","messagePattern":"mm_prefix_ranges last dimension must be contiguous","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-flash-attn/src/lib.rs","lineNumber":638,"sourceCode":"            if mm_prefix_ranges.dtype() != DType::I32 {\n                candle::bail!(\n                    \"mm_prefix_ranges must be i32, got {:?}\",\n                    mm_prefix_ranges.dtype()\n                )\n            }\n            match &*storage {\n                candle::Storage::Cuda(_) => {}\n                _ => candle::bail!(\"mm_prefix_ranges must be a cuda tensor\"),\n            }\n            let (mm_batch, max_ranges, two) = layout.shape().dims3()?;\n            if mm_batch != batch_size || two != 2 {\n                candle::bail!(\n                    \"mm_prefix_ranges shape must be ({batch_size}, max_ranges, 2), got {:?}\",\n                    layout.shape()\n                )\n            }\n            if layout.stride().last().copied() != Some(1) {\n                candle::bail!(\"mm_prefix_ranges last dimension must be contiguous\")\n            }\n            Some((\n                storage,\n                layout.start_offset(),\n                layout.stride()[0],\n                max_ranges,\n            ))\n        } else {\n            None\n        };\n\n        let stream = dev.cuda_stream();\n        let alibi_slopes_ptr = if let Some(alibi_slopes) = &self.alibi_slopes {\n            if alibi_slopes.dtype() != DType::F32 {\n                candle::bail!(\n                    \"DType mismatch alibi_slopes {:?}, expected {:?}\",\n                    alibi_slopes.dtype(),\n                    DType::F32","sourceCodeStart":620,"sourceCodeEnd":656,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-flash-attn/src/lib.rs#L620-L656","documentation":"After the shape check, the kernel requires mm_prefix_ranges to have its last dimension contiguous (stride 1), because it reads range pairs as flat (start,end) int pairs via raw pointers. Non-contiguous last dims (from slicing, transposing, or strided views) would make the kernel read wrong memory.","triggerScenarios":"Passing an mm_prefix_ranges tensor produced by strided slicing/transposing/permute without calling .contiguous(), so layout.stride().last() != Some(1).","commonSituations":"Building ranges from a larger buffer via narrow/slice, or transposing a (batch, 2, max_ranges) tensor into (batch, max_ranges, 2) without materializing it.","solutions":["Call .contiguous() on mm_prefix_ranges before passing it to flash-attn","Construct the tensor in (batch, max_ranges, 2) layout directly instead of transposing","Avoid narrow/slice views on the last dimension; copy into a fresh contiguous tensor"],"exampleFix":"// before\nlet ranges = ranges.t()?.contiguous()?; // still strided last dim in some views\n// after\nlet ranges = ranges.t()?.contiguous()?.contiguous(); // ensure C-contiguous\n// or simply:\nlet ranges = ranges.to_contiguous()?;","handlingStrategy":"validation","validationCode":"let ranges = ranges.contiguous()?; // ensure last-dim stride == 1 before the call","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"last dimension must be contiguous\") => {\n        let r = ranges.contiguous()?;\n        // retry with contiguous tensor\n    }\n    other => other?,\n}","preventionTips":["Call .contiguous() on any tensor derived from slice/transpose/permute","Prefer constructing tensors in final layout rather than transposing","Check layout.stride().last() == Some(1) in debug builds"],"tags":["cuda","flash-attn","contiguity","stride"],"backgroundTag":"non-contiguous-tensor","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}