{"record":{"id":"0989ce9fdf0630ea","repo":"huggingface/candle","slug":"input3-has-to-be-contiguous","errorCode":null,"errorMessage":"input3 has to be contiguous","messagePattern":"input3 has to be contiguous","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-transformers/src/models/segment_anything/image_encoder.rs","lineNumber":74,"sourceCode":"        s3: &candle::CpuStorage,\n        l3: &candle::Layout,\n    ) -> Result<(candle::CpuStorage, candle::Shape)> {\n        use rayon::prelude::*;\n\n        let Add3(b, q_h, q_w, k_h, k_w) = *self;\n        let s1 = s1.as_slice::<f32>()?;\n        let s1 = match l1.contiguous_offsets() {\n            None => candle::bail!(\"input1 has to be contiguous\"),\n            Some((o1, o2)) => &s1[o1..o2],\n        };\n        let s2 = s2.as_slice::<f32>()?;\n        let s2 = match l2.contiguous_offsets() {\n            None => candle::bail!(\"input2 has to be contiguous\"),\n            Some((o1, o2)) => &s2[o1..o2],\n        };\n        let s3 = s3.as_slice::<f32>()?;\n        let s3 = match l3.contiguous_offsets() {\n            None => candle::bail!(\"input3 has to be contiguous\"),\n            Some((o1, o2)) => &s3[o1..o2],\n        };\n        let mut dst = vec![0f32; b * q_h * q_w * k_h * k_w];\n        dst.par_chunks_exact_mut(k_h * k_w)\n            .enumerate()\n            .for_each(|(b_idx, dst)| {\n                let s1_idx = b_idx * k_h * k_w;\n                let s2_idx = b_idx * k_h;\n                let s3_idx = b_idx * k_w;\n                for h_idx in 0..k_h {\n                    let s1_idx = s1_idx + h_idx * k_w;\n                    let s2_idx = s2_idx + h_idx;\n                    let dst_idx = h_idx * k_w;\n                    for w_idx in 0..k_w {\n                        let s1_idx = s1_idx + w_idx;\n                        let s3_idx = s3_idx + w_idx;\n                        let dst_idx = dst_idx + w_idx;\n                        dst[dst_idx] = s1[s1_idx] + s2[s2_idx] + s3[s3_idx]","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-transformers/src/models/segment_anything/image_encoder.rs#L56-L92","documentation":"Same Add3 contiguity check, applied to the third input (V-side tensor). The CPU parallel kernel slices raw storage using `contiguous_offsets()`; a strided layout on input3 cannot be safely read, so the op bails.","triggerScenarios":"The third argument of the add-by-broadcast op is non-contiguous — typically a transposed or narrowed value tensor fed into SAM's image-encoder attention add on CPU without `.contiguous()`.","commonSituations":"Seen when adapting value branches of attention (e.g. squeezing/transposing v) and skipping materialization, or when chaining views across ops that PyTorch would handle lazily but this raw-pointer kernel cannot.","solutions":["Call `.contiguous()?` on the third input before the op.","Use the same idiom as neighboring code: `v.squeeze(0)?.transpose(0, 1)?.contiguous()?`.","Audit any local modifications to image_encoder.rs that removed contiguous() calls.","Run on the supported CPU path or let candle's standard ops (which handle strides) do the add instead of the fused op."],"exampleFix":"// before\nlet v = values.squeeze(0)?.transpose(0, 1);\nlet out = add3(q, k, v)?;\n// after\nlet out = add3(q, k, values.squeeze(0)?.transpose(0, 1)?.contiguous()?)?;","handlingStrategy":"validation","validationCode":"fn ensure_contiguous(t: &Tensor) -> candle::Result<Tensor> {\n    if t.layout().contiguous_offsets().is_none() { t.contiguous() } else { Ok(t.clone()) }\n}\nlet v = ensure_contiguous(&input3)?;","typeGuard":"fn is_contiguous(t: &Tensor) -> bool {\n    t.layout().contiguous_offsets().is_some()\n}","tryCatchPattern":"match add3_forward(q, k, v) {\n    Ok(t) => t,\n    Err(e) if e.to_string().contains(\"input3 has to be contiguous\") => {\n        add3_forward(q, k, v.contiguous()?)\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Always .contiguous() the value tensor after squeeze/transpose chains.","Don't remove contiguous() calls from image_encoder.rs as a micro-optimization.","Check layout contiguity with contiguous_offsets() before custom CPU kernels.","Keep GPU/CPU dispatch paths separate and tested."],"tags":["cpu","contiguity","custom-op","candle"],"backgroundTag":"tensor-not-contiguous","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}