Hi
To pass CPU pointer from c++ to python numpy I am using this code
np_arg = reinterpret_cast<PyArrayObject*>(PyArray_SimpleNewFromData(ND, dims, NPY_LONGDOUBLE, reinterpret_cast<void*>(c_arr)));
My question is how to pass c++ GPU pointer to python numba ?
Thanks
You need to wrap the pointer value in an object that implements the CUDA Array Interface. The interface needs more than just the pointer - it also needs to know the shape and type of the data so you will have to provide that in your implementation as well.
Here’s an example of a simple object implementing the interface. MyArray wraps a pointer obtained from cudaMalloc (though it could have come from anywhere, a C++ function, etc.):
from numba import cuda
from ctypes import CDLL, POINTER, byref, c_void_p, c_size_t
import cupy as cp
class MyArray:
def __init__(self, shape, typestr, data):
if isinstance(shape, int):
shape = (shape,)
self._shape = shape
self._data = data
self._typestr = typestr
@property
def __cuda_array_interface__(self):
return {
'shape': self._shape,
'typestr': self._typestr,
'data': (self._data, False),
'version': 2
}
# Use ctypes to get the cudaMalloc function from Python
cudart = CDLL('libcudart.so')
cudaMalloc = cudart.cudaMalloc
cudaMalloc.argtypes = [POINTER(c_void_p), c_size_t]
# Allocate some Numba-external memory with cudaMalloc
ptr = c_void_p()
float32_size = 4
nelems = 32
alloc_size = float32_size * nelems
cudaMalloc(byref(ptr), alloc_size)
# Wrap our memory in a CUDA Array Interface object
arr = MyArray(nelems, 'f4', ptr.value)
# Call a kernel on our object wrapping the pointer
@cuda.jit
def initialize(x):
i = cuda.grid(1)
if i < len(x):
x[i] = 3.14
initialize[1, nelems](arr)
# Use CuPy for a convenient way to print our data to show that the kernel
# initialized it
print(cp.asarray(arr))
I think I’m still not sure what you’re attempting to do. What do you mean by “numpy.ndarray GPU pointer”? Do you want a CUDA device array? Further down that page there are also ways to allocate Pinned Memory and Unified Memory, and for mapping an existing ndarray into GPU memory. Do any of these look like what you need?
Hi Graham
I want to send GPU vector from c++ to python numba.
to send CPU array is very easy
example
first declare and init
double c_arr[SIZE] = { 1, 2, 3, 4, 5,6,7,8,9};
second
np_arg = reinterpret_cast<PyArrayObject*>(PyArray_SimpleNewFromData(1, &dims, getType(), reinterpret_cast<void*>(data)));
This line create numpy.ndarray
and then I can send it to python
presult = PyObject_CallObject(pFunc, pArgs);
Now is the problem
Instead of CPU double array c_arr[SIZE] = { 1, 2, 3, 4, 5,6,7,8,9};
I am creating GPU array
double * in_d;
cudaMalloc((void**)&in_d, SIZEsizeof(double));
cudaMemcpy(in_d, data, SIZEsizeof(double), cudaMemcpyHostToDevice);
I want to send in_d to python
How can I do it?
Thanks
Razi
Perhaps you can create a Python int from the pointer with PyLong_FromVoidPtr() to send over to the Python side, then pass that to the constructor of a MyArray-like object (from the example above).