# Passing pointer from c++ to python

**URL:** <https://numba.discourse.group/t/passing-pointer-from-c-to-python/1523>\
**Category:** Numba\
**Created:** [August 21, 2022, 12:29pm UTC](https://numba.discourse.group/t/passing-pointer-from-c-to-python/1523 "2022-08-21T12:29:33Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Razi](https://avatars.discourse-cdn.com/v4/letter/r/fbc32d/32.png) [@Razi](https://numba.discourse.group/u/Razi)\
**Post date:** [August 21, 2022, 12:29pm UTC](https://numba.discourse.group/t/passing-pointer-from-c-to-python/1523/1 "2022-08-21T12:29:33Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![gmarkall](https://yyz2.discourse-cdn.com/free1/user_avatar/numba.discourse.group/gmarkall/32/42_2.png) [@gmarkall](https://numba.discourse.group/u/gmarkall)\
**Post date:** [August 23, 2022, 9:33am UTC](https://numba.discourse.group/t/passing-pointer-from-c-to-python/1523/2 "2022-08-23T09:33:10Z")

</div>

You need to wrap the pointer value in an object that implements the [CUDA Array Interface](https://numba.readthedocs.io/en/latest/cuda/cuda_array_interface.html). 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.):

```python
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))

```

This produces:

```auto
[3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14
 3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14 3.14
 3.14 3.14 3.14 3.14]

```

---

<div class="post-metadata">

**Author:** ![gmarkall](https://yyz2.discourse-cdn.com/free1/user_avatar/numba.discourse.group/gmarkall/32/42_2.png) [@gmarkall](https://numba.discourse.group/u/gmarkall)\
**Post date:** [August 23, 2022, 9:37am UTC](https://numba.discourse.group/t/passing-pointer-from-c-to-python/1523/3 "2022-08-23T09:37:51Z")

</div>

There is some more background on this in [https://raw.githubusercontent.com/numba/nvidia-cuda-tutorial/main/session-3/session-3-with-notes.pdf](https://raw.githubusercontent.com/numba/nvidia-cuda-tutorial/main/session-3/session-3-with-notes.pdf) (session 3 from the [NVIDIA Numba CUDA tutorial](https://github.com/numba/nvidia-cuda-tutorial)) - see slides 33-35.

I’ve now added the above code as an example in that repo: [nvidia-cuda-tutorial/cai\_implementation.py at main · numba/nvidia-cuda-tutorial · GitHub](https://github.com/numba/nvidia-cuda-tutorial/blob/main/session-3/examples/cai_implementation.py)

---

<div class="post-metadata">

**Author:** ![Razi](https://avatars.discourse-cdn.com/v4/letter/r/fbc32d/32.png) [@Razi](https://numba.discourse.group/u/Razi)\
**Post date:** [August 23, 2022, 4:21pm UTC](https://numba.discourse.group/t/passing-pointer-from-c-to-python/1523/4 "2022-08-23T16:21:40Z")

</div>

Hi Graham  
Thanks for quick response.  
I have code in c++ that create numpy.ndarray CPU pointer and send it to python .

np\_arg = reinterpret\_cast\<PyArrayObject\*\>(PyArray\_SimpleNewFromData(ND, dims, NPY\_LONGDOUBLE, reinterpret\_cast\<void\*\>(c\_arr)));  
presult = PyObject\_CallObject(pFunc, pArgs);

The pointer np\_arg is numpy.ndarray type  
I want to create in the c++ code numpy.ndarray GPU pointer and pass it to python ,what is the correct way?

---

<div class="post-metadata">

**Author:** ![gmarkall](https://yyz2.discourse-cdn.com/free1/user_avatar/numba.discourse.group/gmarkall/32/42_2.png) [@gmarkall](https://numba.discourse.group/u/gmarkall)\
**Post date:** [August 23, 2022, 9:43pm UTC](https://numba.discourse.group/t/passing-pointer-from-c-to-python/1523/5 "2022-08-23T21:43:20Z")

</div>

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](https://numba.readthedocs.io/en/stable/cuda/memory.html#data-transfer)? 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?

---

<div class="post-metadata">

**Author:** ![Razi](https://avatars.discourse-cdn.com/v4/letter/r/fbc32d/32.png) [@Razi](https://numba.discourse.group/u/Razi)\
**Post date:** [August 24, 2022, 2:58pm UTC](https://numba.discourse.group/t/passing-pointer-from-c-to-python/1523/6 "2022-08-24T14:58:56Z")

</div>

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, SIZE_sizeof(double));  
cudaMemcpy(in\_d, data, SIZE_sizeof(double), cudaMemcpyHostToDevice);  
I want to send in\_d to python  
How can I do it?  
Thanks  
Razi

---

<div class="post-metadata">

**Author:** ![gmarkall](https://yyz2.discourse-cdn.com/free1/user_avatar/numba.discourse.group/gmarkall/32/42_2.png) [@gmarkall](https://numba.discourse.group/u/gmarkall)\
**Post date:** [August 24, 2022, 3:49pm UTC](https://numba.discourse.group/t/passing-pointer-from-c-to-python/1523/7 "2022-08-24T15:49:14Z")

</div>

Perhaps you can create a Python `int` from the pointer with [`PyLong_FromVoidPtr()`](https://docs.python.org/3/c-api/long.html#c.PyLong_FromVoidPtr) to send over to the Python side, then pass that to the constructor of a `MyArray`-like object (from the example above).

---

<div class="post-metadata">

**Author:** ![Razi](https://avatars.discourse-cdn.com/v4/letter/r/fbc32d/32.png) [@Razi](https://numba.discourse.group/u/Razi)\
**Post date:** [August 25, 2022, 10:49am UTC](https://numba.discourse.group/t/passing-pointer-from-c-to-python/1523/8 "2022-08-25T10:49:19Z")

</div>

Thanks  
it’s working fine
