#1972·warp

Improve the error when NumPy attempts to convert a CUDA wp.array

Author: christophercrouzetCreated Sep 17, 2026Updated Sep 17, 2026
Labelsdocs

Bug description

Calling np.asarray() on a CUDA wp.array is unsupported, but the resulting error does not identify the unsupported NumPy conversion or explain how to perform the conversion correctly.

Warp exposes __array_interface__ for CPU arrays only, which allows NumPy to consume CPU wp.array objects directly. For a CUDA array, __array_interface__ raises AttributeError, as expected. However, because wp.array does not implement __array__, NumPy falls back to treating the object as a Python sequence and repeatedly invokes wp.array.__getitem__().

When NumPy probes the first out-of-bounds index, Warp raises an unrelated indexing error such as:

RuntimeError: Invalid indexing in slice: 2

For a larger array, the reported number is simply the size of its first dimension. This can make a valid CUDA array appear corrupt or incorrectly shaped and gives no indication that .numpy() is the supported conversion API.

Minimal reproduction

python
import numpy as np
import warp as wp


a = wp.zeros((2, 3), dtype=wp.float32, device="cuda")

# The supported explicit CUDA-to-CPU conversion succeeds.
print(a.numpy().shape)

# This unsupported implicit conversion produces a misleading indexing error.
np.asarray(a, dtype=np.float64)

Current result:

(2, 3)
RuntimeError: Invalid indexing in slice: 2

Expected behavior

Warp should reject the implicit conversion immediately with an actionable error. For example:

TypeError: Cannot implicitly convert a Warp array on device 'cuda:0' to a
NumPy array. NumPy requires CPU-accessible memory. Call array.numpy() to
perform an explicit device-to-host copy.

The error should occur for both of these forms:

python
np.asarray(a)
np.asarray(a, dtype=np.float64)

This issue is only requesting a better diagnostic. np.asarray(cuda_array) should not silently synchronize and copy the data to CPU. The existing explicit conversion remains:

python
host_array = cuda_array.numpy()

Acceptance criteria

  • np.asarray(cuda_array) fails immediately with an actionable error mentioning array.numpy().
  • np.asarray(cuda_array, dtype=...) produces the same actionable error.
  • np.asarray(cpu_array) retains its current zero-copy behavior through __array_interface__.
  • cuda_array.numpy() continues to perform the supported device-to-host conversion.
  • Regression tests cover both the CPU and CUDA paths.