0

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?

4
  • 1
    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. Commented Dec 28, 2024 at 23:45
  • 1
    You should really avoid creating arrays that way since it is not efficient with cupy (moving data from/to the host/device through the PCIe/NvLink interconnect is inherently slow, especially when it is scalar). You can fill the array on the host and send it entirely on the device, or build it directly on the device (fastest solution but clearly cumbersome for small arrays). Commented Dec 28, 2024 at 23:50
  • 1
    If you do not care about performance of this, then you can write a function calling arr.get() based on the type of arr (e.g. it can even take the list -- to convert to an array -- in parameter). Commented Dec 28, 2024 at 23:56
  • @JérômeRichard these are super helpful insight, thank you! I totally forgot that a numpy array or a scalar created in python would be on CPU device. Using cupy to create scalars turned out to eliminate a lot of the problems Commented Dec 30, 2024 at 4:13

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.