tracel-ai/burn · error

Failed to read tensor data synchronously. Try using nonzero_

Error message

Failed to read tensor data synchronously. Try using nonzero_async instead.

What it means

Tensor::nonzero() synchronously reads the indices of true elements; on async backends (WGPU/CUDA) the result may not be ready or the backend may not support a blocking read, so try_read_sync returns None and the expect panics. The library offers nonzero_async() as the always-valid alternative.

Source

Thrown at crates/burn-tensor/src/tensor/api/bool.rs:226

    /// the non-zero elements in that dimension.
    ///
    /// # Example
    ///
    /// ```rust
    /// use burn_tensor::{Tensor, Bool};
    ///
    /// let device = Default::default();
    /// let tensor = Tensor::<2, Bool>::from_bool(
    ///     [[true, false, true], [false, true, false], [false, true, false]],
    ///     &device,
    /// );
    /// let indices = tensor.nonzero();
    /// println!("{}", indices[0]); // [0, 0, 1, 2]
    /// println!("{}", indices[1]); // [0, 2, 1, 1]
    /// ```
    pub fn nonzero(self) -> Vec<Tensor<1, Int>> {
        try_read_sync(self.nonzero_async())
            .expect("Failed to read tensor data synchronously. Try using nonzero_async instead.")
    }

    /// Compute the indices of `true` elements in the tensor (i.e., non-zero for boolean tensors).
    ///
    /// # Returns
    ///
    /// A vector of tensors, one for each dimension of the given tensor, containing the indices of
    /// the non-zero elements in that dimension.
    pub async fn nonzero_async(self) -> Vec<Tensor<1, Int>> {
        let indices = self.argwhere_async().await;

        if indices.shape().num_elements() == 0 {
            // Return empty vec when all elements are zero
            return vec![];
        }

        let dims = indices.shape();
        indices

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Switch to `tensor.nonzero_async()` and await it in an async context
  2. Run the read on a CPU-capable step (e.g. `tensor.into_data()` / bring results back with an async read API)
  3. Execute the call on a synchronous backend (NdArray/CPU) where sync reads are supported
  4. Restructure code so the nonzero result is consumed asynchronously rather than blocking

Example fix

// before
let indices = tensor.nonzero();
// after
let indices = tensor.nonzero_async().await;
Defensive patterns

Strategy: fallback

Validate before calling

// prefer the async variant on GPU/async backends
if backend_is_async() {
    let indices = tensor.nonzero_async().await;
}

Try / catch

// expect() panics; avoid by using the async API
let indices = tokio::task::block_in_place(|| tensor.nonzero_async())
    .map_err(|e| e)?;

Prevention

When it happens

Trigger: Calling `.nonzero()` on a tensor whose backend executes asynchronously and cannot synchronously resolve the future (e.g. WGPU in async runtime contexts, or inside an async function where block_on would deadlock).

Common situations: WGPU users calling nonzero() inside tokio tasks; batch verification code ported from CPU backends to GPU backends; sparse-mask extraction during inference on WebGPU.

Related errors


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