I am trying to make a numpy/cupy interchange script, similar to this backend implementation. Such that by using something like from Util.Backend import backend as bd, I can create bd.array() that can switch between numpy and cupy. But I had a lot of trouble doing so, especially about creating array.
After some experiments, it seems that an assignment in the form of:
import cupy as cp
A = cp.array([1, 2, 3])
B = cp.array([A[0], A[1], 3])
Will result in error:
TypeError: Implicit conversion to a NumPy array is not allowed. Please use `.get()` to construct a NumPy array explicitly.
However, if the same array creation is written as:
B = cp.array([A[0], A[1], A[2]])
Then it becomes totally fine (which is also weird, since I did not import numpy at all in the example above, it's almost like [] is being created as a numpy array first).
Similarly,
s = 2
c = 3
one = 1.0
B = cp.array([s, c, one])
Is fine. But if some of the entries are not created in the same way, such as:
s = cp.sin(2)
c = cp.cos(1)
one = 1.0
B = cp.array([s, c, one])
Then the TypeError would come in again. Note that if numpy is used instead of cupy, none of the above array creation would have raised an error.
This post seem to indicate that cupy does not support a mix type data. But by the suggested method I would have to write CParray.get() to make the conversion, it is a cupy method and not a numpy one, thus will create new errors if that backend module is running numpy.
Would it be possible to find a way to write array creations so that cp and np are interchangeable?
A[0]is stored on the GPU device. Mixing CPU data with GPU ones is clearly a bad idea and is likely to be a bug (most people don't want this since it is inefficient) so this is certainly why it is forbidden. If all variable are on the device, the operation could be on the GPU in an implicit kernel (not very efficiently though since the indices are on the host and expensive operation are also done per item) though I agree this is a bit weird to accept that here. I guess it make more sense for list of large 1D arrays stored on the GPU device for example.arr.get()based on the type ofarr(e.g. it can even take the list -- to convert to an array -- in parameter).