tracel-ai/burn · error

Failed to read tensor data synchronously. Try using argwhere

Error message

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

What it means

Tensor::argwhere() synchronously retrieves the coordinates of all true elements; like nonzero(), on async backends the blocking read fails and the expect panics. argwhere_async() is the supported alternative for GPU/async execution.

Source

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

    /// A tensor containing the indices of all non-zero elements of the given tensor. Each row in the
    /// result contains the indices of a non-zero element.
    ///
    /// # 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.argwhere();
    /// println!("{indices}"); // [[0, 0], [0, 2], [1, 1], [2, 1]]
    /// ```
    pub fn argwhere(self) -> Tensor<2, Int> {
        try_read_sync(self.argwhere_async())
            .expect("Failed to read tensor data synchronously. Try using argwhere_async instead.")
    }

    /// Compute the indices of the elements that are true, grouped by element.
    ///
    /// # Returns
    ///
    /// A tensor containing the indices of all non-zero elements of the given tensor. Each row in the
    /// result contains the indices of a non-zero element.
    pub async fn argwhere_async(self) -> Tensor<2, Int> {
        let out_dtype = self.device().settings().int_dtype;
        let inner = Dispatch::bool_argwhere(self.primitive.into(), out_dtype).await;
        Tensor::new(BridgeTensor::int(inner))
    }

    /// Creates a mask for the upper, lower triangle, or diagonal of a matrix, which can be used to
    /// fill the specified area with a value.
    fn tri_mask<S: Into<Shape>>(shape: S, tri_part: TriPart, offset: i64, device: &Device) -> Self {
        let shape: Shape = shape.into();

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Use `tensor.argwhere_async()` and `.await` it in an async context
  2. Use `nonzero_async()` if the extra grouping dimension of argwhere is not needed
  3. Run on a synchronous CPU backend (NdArray) where blocking reads work
  4. Restructure to read tensor data asynchronously via TensorData/into_data async APIs

Example fix

// before
let indices = tensor.argwhere();
// after
let indices = tensor.argwhere_async().await;
Defensive patterns

Strategy: fallback

Validate before calling

if backend_is_async() {
    let indices = tensor.argwhere_async().await;
}

Try / catch

// prefer async read; argwhere() panics when sync read is unsupported
let indices = tensor.argwhere_async().await;

Prevention

When it happens

Trigger: Calling `.argwhere()` on a tensor on an async backend that cannot block (WGPU/WebGPU), especially inside async runtimes; porting CPU tensor code that used argwhere directly to a GPU backend.

Common situations: Mask coordinate extraction in image segmentation pipelines on WGPU; debugging code inside tokio::test with a GPU backend; position-index computation in loss functions on async devices.

Related errors


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