tracel-ai/burn · error
device index must be non-negative
Error message
device index must be non-negative
What it means
DeviceIndex::from(i32) panics when given a negative i32, because a device index is an unsigned concept that must be >= 0. usize::try_from(i) fails for negative values and the expect message surfaces this. It is a defensive guard against callers encoding invalid device IDs in signed types.
Source
Thrown at crates/burn-tensor/src/device.rs:238
Self::Specified(i)
}
}
impl From<u32> for DeviceIndex {
fn from(i: u32) -> Self {
Self::Specified(i as usize)
}
}
impl From<u64> for DeviceIndex {
fn from(i: u64) -> Self {
Self::Specified(i as usize)
}
}
impl From<i32> for DeviceIndex {
fn from(i: i32) -> Self {
Self::Specified(usize::try_from(i).expect("device index must be non-negative"))
}
}
impl From<i64> for DeviceIndex {
fn from(i: i64) -> Self {
Self::Specified(usize::try_from(i).expect("device index must be non-negative"))
}
}
/// Selector for the more flexible backends whose device handle is a tagged
/// enum (e.g. WGPU, which can target a discrete/integrated/virtual GPU, a CPU
/// adapter, an externally-created wgpu setup, or just "best available").
///
/// The variants mirror `WgpuDevice` from cubecl so the mapping is direct, but
/// it is kept as a burn-owned enum so callers don't have to depend on cubecl.
#[derive(Clone, Debug, Hash, PartialEq, Eq, Default)]
pub enum DeviceKind {
/// Discrete GPU with the given index. The index is the index of the discrete GPU in the listView on GitHub (pinned to d16f7ba2ed)
Solutions
- Validate the index is >= 0 before converting (e.g. with a guard or `if i >= 0`)
- Fix upstream code producing -1 sentinel values (failed device detection) instead of passing it to DeviceIndex
- Use the DeviceError/Result-based constructors or Default device selection when the index is unknown
Example fix
// before
device.index = DeviceIndex::from(raw_id);
// after
let idx = if raw_id >= 0 { DeviceIndex::from(raw_id) } else { DeviceIndex::Default };
device.index = idx; Defensive patterns
Strategy: validation
Validate before calling
fn to_device_index(i: i32) -> Option<DeviceIndex> {
usize::try_from(i).ok().map(DeviceIndex::Specified)
} Type guard
fn valid_device_index(i: i32) -> bool { i >= 0 } Try / catch
// panicking From; cannot catch - pre-validate instead
if i < 0 { return Err(DeviceError::InvalidIndex(i)); }
let idx = DeviceIndex::from(i); Prevention
- Never forward -1 sentinel values from FFI into DeviceIndex
- Wrap signed device ordinals in a validated conversion helper
- Use Default device selection when the ordinal is unknown
When it happens
Trigger: Calling DeviceIndex::from(-1_i32) or any negative i32; propagating an uninitialized/default -1 sentinel device ID from native library bindings (e.g. CUDA/wgpu wrappers that use -1 as 'no device').
Common situations: Interfacing with FFI code that returns -1 on failure and passing the result straight into burn device construction; config files or CLI args parsed as i32 containing negative values.
Related errors
- Distributed operations are not supported for device {other:?
- Autodiff should not wrap an autodiff device.
- Device::gradient_checkpointing requires autodiff; call Devic
- BlackmanWindow size doesn't fit in i64 range.
- HammingWindow size doesn't fit in i64 range.
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/94e633bdad80029c.
Report an issue: GitHub.