tracel-ai/burn · error
ndarray scatter_nd requires contiguous indices
Error message
ndarray scatter_nd requires contiguous indices
What it means
In the same scatter_nd kernel, the indices tensor is flattened via as_slice, which returns None for non-contiguous storage; the expect panics with 'ndarray scatter_nd requires contiguous indices'. Like the data check, this reflects the backend kernel's contiguous-memory-only implementation.
Source
Thrown at crates/burn-ndarray/src/ops/base.rs:325
let data_shape: Vec<usize> = data.shape().to_vec();
let idx_shape: Vec<usize> = indices.shape().to_vec();
let m = idx_shape.len();
let k = idx_shape[m - 1];
// Number of index tuples = product of batch dims (first M-1 dims of indices)
let num_indices: usize = idx_shape[..m - 1].iter().product();
// Size of each slice to scatter = product of data.shape[K..]
let slice_size: usize = data_shape[k..].iter().product();
let mut output = data.into_owned();
let output_flat = output
.as_slice_mut()
.expect("ndarray scatter_nd requires contiguous data");
// Flatten indices to [num_indices, K]
let idx_flat = indices
.as_slice()
.expect("ndarray scatter_nd requires contiguous indices");
// Flatten values to [num_indices, slice_size]
let val_flat = values
.as_slice()
.expect("ndarray scatter_nd requires contiguous values");
let strides: Vec<usize> = {
let mut s = vec![0usize; k];
if k > 0 {
s[k - 1] = slice_size;
for i in (0..k - 1).rev() {
s[i] = s[i + 1] * data_shape[i + 1];
}
}
s
};
for n in 0..num_indices {View on GitHub (pinned to d16f7ba2ed)
Solutions
- Copy the indices into a new owned contiguous tensor before calling scatter_nd.
- Construct index tensors directly (from vec/IntNdArrayElement) instead of slicing existing ones.
- Report as a bug if produced through burn's public high-level API, which should maintain contiguity.
Example fix
// before let idx = big_index_tensor.slice(s![.., 0]); let out = data.scatter(idx, values); // after let idx_owned = idx.to_data().convert::<IntNdArrayElement>(); let idx = NdArrayTensor::new(idx_owned.into_ndarray()); // contiguous copy let out = data.scatter(idx, values);
Defensive patterns
Strategy: validation
Validate before calling
// Copy indices into a fresh contiguous tensor before scatter let idx_owned = indices.to_data().convert::<IntNdArrayElement>(); let indices = NdArrayTensor::new(idx_owned.into_ndarray());
Prevention
- Construct index tensors directly from vectors instead of slicing
- Make indices contiguous after any permute/slice
- Cover scatter_nd with integration tests on the ndarray backend
When it happens
Trigger: Calling scatter_nd where the indices tensor is a non-contiguous view (e.g. produced by slicing/indexing another tensor) on the ndarray backend.
Common situations: Building index tensors by slicing a larger index buffer; graph-captured models passing strided index intermediates; reusing views after permute operations.
Related errors
- ndarray scatter_nd requires contiguous data
- ndarray gather_nd requires contiguous indices
- Requires autodiff tensor.
- an enabled float tensor must use an autodiff primitive
- Should be float, got int
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/30df85c207c4c785.
Report an issue: GitHub.