Improve the error when NumPy attempts to convert a CUDA wp.array
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: 2For 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
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: 2Expected 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:
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:
host_array = cuda_array.numpy()Acceptance criteria
np.asarray(cuda_array)fails immediately with an actionable error mentioningarray.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.
Source: NVIDIA/warp