huggingface/candle · error
Metal where_cond {left:?} {right:?} not implemented
Error message
Metal where_cond {left:?} {right:?} not implemented What it means
Beyond matching branch dtypes, where_cond on Metal needs a kernel for the (condition-dtype, value-dtype) pair. Pairs outside the dispatch table (e.g. an I64 condition or unsupported combination) hit this bail, since no Metal kernel implements that selection.
Source
Thrown at candle-core/src/metal_backend/mod.rs:880
.with_label("where")
.build()?;
let encoder = self.device.command_encoder()?;
if t.dtype() != f.dtype() {
crate::bail!(
"Invalid where: different dtypes for values {:?} != {:?}",
t.dtype(),
f.dtype()
);
}
let name = match (self.dtype, t.dtype()) {
(DType::U8, DType::F32) => "where_u8_f32",
(DType::U32, DType::F32) => "where_u32_f32",
(DType::U8, DType::BF16) => "where_u8_bf16",
(DType::U8, DType::F16) => "where_u8_f16",
(DType::U8, DType::I64) => "where_u8_i64",
(DType::U8, DType::U32) => "where_u8_u32",
(DType::U8, DType::U8) => "where_u8_u8",
(left, right) => crate::bail!("Metal where_cond {left:?} {right:?} not implemented"),
};
let src = buffer_o(&self.buffer, layout, self.dtype);
let t = buffer_o(&t.buffer, t_l, t.dtype);
let f = buffer_o(&f.buffer, f_l, f.dtype);
candle_metal_kernels::call_where_cond(
&device.device,
&encoder,
&device.kernels,
name,
dtype.size_in_bytes(),
dims,
src,
layout.stride(),
layout.is_contiguous(),
t,
t_l.stride(),
t_l.is_contiguous(),
f,View on GitHub (pinned to d5fee525bf)
Solutions
- Ensure the condition tensor is a supported dtype (U8/U32/F32 etc. per table) via to_dtype on the mask
- Align value-tensor dtype to a supported pair (F32 is broadly supported)
- Compute where_cond on CPU and move the result to Metal
- Upgrade candle for new Metal where_cond kernels
Example fix
// before let out = mask_i64.where_cond(&a, &b)?; // i64 mask unsupported // after let out = mask_i64.to_dtype(DType::U8)?.where_cond(&a, &b)?;
Defensive patterns
Strategy: validation
Validate before calling
let mask = if matches!(mask.dtype(), DType::I64 | DType::F32) {
mask.to_dtype(DType::U8)?
} else { mask };
if !matches!(a.dtype(), DType::F32 | DType::F16 | DType::BF16 | DType::U32 | DType::U8 | DType::I64) {
anyhow::bail!("where_cond value dtype unsupported on Metal");
} Try / catch
match mask.where_cond(&a, &b) {
Ok(y) => y,
Err(e) if e.to_string().contains("where_cond") && e.to_string().contains("not implemented") => {
mask.to_dtype(DType::U8)?.where_cond(&a.to_dtype(DType::F32)?, &b.to_dtype(DType::F32)?)
}
Err(e) => return Err(e.into()),
} Prevention
- Use U8/U32 masks for where_cond on Metal
- Keep selected values in broadly supported dtypes (F32)
- Prefer comparison ops that emit U8 masks
When it happens
Trigger: Calling where_cond on Metal with a condition/value dtype combination missing from the table, such as an I64 mask with F16 values, or U32 condition with BF16 values.
Common situations: Using comparison results (which may be U8/U32) with float tensors of unusual dtype; masks produced in one dtype and applied to tensors of another; porting CUDA-working code to Metal.
Related errors
- Metal contiguous unary {name} {dtype:?} not implemented
- Metal strided unary {name} {dtype:?} not implemented
- Invalid where: different dtypes for values {:?} != {:?}
- Metal conv1d {dtype:?} not implemented
- metal col2im1d {dtype:?} not implemented
AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02).
Data as JSON: /api/errors/138beb2fcb7029b6.
Report an issue: GitHub.