{"record":{"id":"cf389bc86b18c83e","repo":"huggingface/candle","slug":"metal-conv1d-dtype-not-implemented","errorCode":null,"errorMessage":"Metal conv1d {dtype:?} not implemented","messagePattern":"Metal conv1d (.+?) not implemented","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-core/src/metal_backend/mod.rs","lineNumber":938,"sourceCode":"        let dilation = params.dilation;\n        let padding = params.padding;\n        let k_size = params.k_size;\n        let l_out = (dims[2] + 2 * padding - dilation * (k_size - 1) - 1) / stride + 1;\n        let dst_el = dims[0] * l_out * dims[1] * k_size;\n        let dst = self\n            .device\n            .new_buffer_builder()\n            .with_size_for(dst_el, self.dtype)\n            .with_label(\"conv1d_im2col\")\n            .build()?;\n        let encoder = self.device.command_encoder()?;\n        let name = match self.dtype {\n            DType::F32 => \"im2col1d_f32\",\n            DType::F16 => \"im2col1d_f16\",\n            DType::BF16 => \"im2col1d_bf16\",\n            DType::U8 => \"im2col1d_u8\",\n            DType::U32 => \"im2col1d_u32\",\n            dtype => crate::bail!(\"Metal conv1d {dtype:?} not implemented\"),\n        };\n        let src = buffer_o(&self.buffer, layout, self.dtype);\n        candle_metal_kernels::call_im2col1d_strided(\n            &self.device.device,\n            &encoder,\n            &self.device.kernels,\n            name,\n            layout.shape().dims(),\n            strides,\n            (k_size, stride, padding, dilation),\n            src,\n            &dst,\n        )\n        .map_err(MetalError::from)?;\n        drop(encoder);\n        let col = Self {\n            buffer: dst,\n            device,","sourceCodeStart":920,"sourceCodeEnd":956,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-core/src/metal_backend/mod.rs#L920-L956","documentation":"conv1d on Metal is implemented via im2col1d kernels available only for F32, F16, BF16, U8 and U32. A conv1d on a tensor of any other dtype (e.g. I64) hits this bail before calling call_im2col1d_strided.","triggerScenarios":"Calling Tensor::conv1d (or modules using it) on a Metal tensor whose dtype is not one of F32/F16/BF16/U8/U32 — practically only I64/F64-style inputs trigger it.","commonSituations":"Running integer embeddings directly through a 1D conv; dtype accidentally left as i64 after tokenization; model weights loaded with an unsupported dtype on Metal.","solutions":["Cast the input (and weights) to F32/F16/BF16 before conv1d","Fix upstream dtype handling so activations are float for conv layers","Run conv1d on CPU and move results back to Metal"],"exampleFix":"// before\nlet y = x_i64.conv1d(&kernel, padding, stride, dilation, groups)?;\n// after\nlet y = x_i64.to_dtype(DType::F32)?.conv1d(&kernel, padding, stride, dilation, groups)?;","handlingStrategy":"validation","validationCode":"if !matches!(x.dtype(), DType::F32 | DType::F16 | DType::BF16 | DType::U8 | DType::U32) {\n    x = x.to_dtype(DType::F32)?;\n}\nlet y = x.conv1d(&kernel, p, s, d, g)?;","typeGuard":null,"tryCatchPattern":"match x.conv1d(&k, p, s, d, g) {\n    Ok(y) => y,\n    Err(e) if e.to_string().contains(\"conv1d\") && e.to_string().contains(\"not implemented\") => {\n        x.to_dtype(DType::F32)?.conv1d(&k.to_dtype(DType::F32)?, p, s, d, g)\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Keep conv layer inputs/weights float (F32/F16/BF16)","Cast token id tensors to float before conv-based embedding mixing","Validate model dtypes after checkpoint loading"],"tags":["metal","gpu","conv1d","dtype","candle"],"backgroundTag":"unsupported-dtype-for-op","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}