tracel-ai/burn · error

scatter_nd is not supported for bool tensors

Error message

scatter_nd is not supported for bool tensors

What it means

The Bool bridge does not implement scatter_nd; the method unconditionally panics. Scatter-style indexed updates are only supported for numeric element types (Float/Int), so attempting one on a bool tensor always aborts.

Source

Thrown at crates/burn-tensor/src/bridge/ops/bool.rs:163

    ) -> BridgeTensor {
        match update {
            IndexingUpdateOp::Add => BridgeTensor::bool(Dispatch::bool_scatter_or(
                dim,
                tensor.into(),
                indices.into(),
                values.into(),
            )),
            _ => unimplemented!(),
        }
    }

    fn scatter_nd(
        _data: BridgeTensor,
        _indices: BridgeTensor,
        _values: BridgeTensor,
        _reduction: IndexingUpdateOp,
    ) -> BridgeTensor {
        panic!("scatter_nd is not supported for bool tensors")
    }

    fn gather_nd(_data: BridgeTensor, _indices: BridgeTensor) -> BridgeTensor {
        panic!("gather_nd is not supported for bool tensors")
    }

    fn device(tensor: &BridgeTensor) -> Device {
        Device::new(tensor.as_dispatch().device())
    }

    fn to_device(tensor: BridgeTensor, device: &Device) -> BridgeTensor {
        BridgeTensor::bool(Dispatch::bool_to_device(
            tensor.into(),
            device.as_dispatch(),
        ))
    }

    async fn into_data_async(tensor: BridgeTensor) -> Result<TensorData, ExecutionError> {

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Scatter on an integer tensor instead, then convert to bool with .bool_cast() / .bool()
  2. Write the mask differently: compute bool results with comparisons (e.g. create Int zeros, scatter 1s, compare == 1)
  3. If the values are boolean flags, scatter uint8/int8 values 0/1 and cast to Bool
  4. Reformulate the op with slicing/assignment or select/gather constructs that Bool does support

Example fix

// before
let mask: Tensor<B, 2, Bool> = zeros.scatter(indices, ones_bool, UpdateOp::Assign);
// after
let ints: Tensor<B, 2, Int> = zeros.scatter(indices, ones, UpdateOp::Assign);
let mask = ints.bool_cast();
Defensive patterns

Strategy: validation

Validate before calling

fn scatter_bool_safe<B: Backend, const D: usize>(
    data: Tensor<B, D, Bool>, _indices: Tensor<B, 1, Int>, _values: Tensor<B, 1, Bool>,
) -> Tensor<B, D, Bool> {
    panic!("scatter is unsupported on Bool; scatter on Int and cast with .bool_cast() instead")
}
// preferred: scatter on Int, then convert
// let ints = zeros_int.scatter(indices, ones_int, UpdateOp::Assign);
// let mask = ints.bool_cast();

Try / catch

std::panic::catch_unwind(|| mask.scatter(indices, values, UpdateOp::Assign))
    .map_err(|_| "scatter_nd unsupported for Bool; scatter on Int and cast")?;

Prevention

When it happens

Trigger: Calling tensor.scatter(indices, values, op) / scatter_nd on a Tensor::<B, D, Bool> — e.g. building boolean masks by writing true/false values at index positions.

Common situations: Porting numeric scatter code to bool masks; constructing boolean lookup masks by scattered assignment; translating models (e.g. from ONNX) that scatter bool values.

Related errors


AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/6fe89bc7f3604b3f. Report an issue: GitHub.