# Use pre-allocated cuda memory pointer to initialize an opencv GpuMat in python

**URL:** <https://forum.opencv.org/t/use-pre-allocated-cuda-memory-pointer-to-initialize-an-opencv-gpumat-in-python/203>\
**Category:** Python\
**Tags:** cuda\
**Created:** [December 8, 2020, 4:38am UTC](https://forum.opencv.org/t/use-pre-allocated-cuda-memory-pointer-to-initialize-an-opencv-gpumat-in-python/203 "2020-12-08T04:38:48Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![bebop\_blues](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@bebop\_blues](https://forum.opencv.org/u/bebop_blues)\
**Post date:** [December 8, 2020, 4:38am UTC](https://forum.opencv.org/t/use-pre-allocated-cuda-memory-pointer-to-initialize-an-opencv-gpumat-in-python/203/1 "2020-12-08T04:38:48Z")

</div>

Is there a way to use a memory pointer that has already been allocated to create a GpuMat in OpenCV python?

There is the C++ definition for `GpuMat()` which takes `void* data` as input.

Looking at the functions exported to Python:

```auto
    //! copy constructor
    CV_WRAP GpuMat(const GpuMat& m);

    //! constructor for GpuMat headers pointing to user-allocated data
    GpuMat(int rows, int cols, int type, void* data, size_t step = Mat::AUTO_STEP);
    GpuMat(Size size, int type, void* data, size_t step = Mat::AUTO_STEP);

    //! creates a GpuMat header for a part of the bigger matrix
    CV_WRAP GpuMat(const GpuMat& m, Range rowRange, Range colRange);
    CV_WRAP GpuMat(const GpuMat& m, Rect roi);

```

The functions with `void* data` do not have the `CV_WRAP` and are not ported to python?

Is there some other way to use pre-allocated cuda pointers in Python opencv?

---

<div class="post-metadata">

**Author:** ![bleulake](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/bleulake/32/77_2.png) [@bleulake](https://forum.opencv.org/u/bleulake)\
**Post date:** [December 8, 2020, 8:02am UTC](https://forum.opencv.org/t/use-pre-allocated-cuda-memory-pointer-to-initialize-an-opencv-gpumat-in-python/203/2 "2020-12-08T08:02:12Z")

</div>

I attach pictures.  
The first picture I attached was an apriltag picture  
The second picture attached is the command window.  
I’m not sure what’s the problem.

apriltag picture & program command execution result

 ![pictures](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/1X/247caca9cf88c4985a7d46a9dcec067abd25e3b8.jpeg)

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [December 8, 2020, 9:48am UTC](https://forum.opencv.org/t/use-pre-allocated-cuda-memory-pointer-to-initialize-an-opencv-gpumat-in-python/203/3 "2020-12-08T09:48:19Z")

</div>

> [@bebop\_blues](#):
>
> Is there a way to use a memory pointer that has already been allocated to create a GpuMat in OpenCV python?

Hi, I’m sure this has been asked a lot before on the previous forum but I cannot find a link to give you. As far as I am aware this is not possible and I think someone was looking at writing the code to enable this but I am not sure if they got anywhere with it.

> [@bebop\_blues](#):
>
> The functions with `void* data` do not have the `CV_WRAP` and are not ported to python?

As above they are not wrapped because this won’t work.

> [@bleulake](#):
>
> The second picture attached is the command window.  
> I’m not sure what’s the problem.

I had a quick glance at the code. Isn’t this an apriltag library error?

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [December 8, 2020, 4:03pm UTC](https://forum.opencv.org/t/use-pre-allocated-cuda-memory-pointer-to-initialize-an-opencv-gpumat-in-python/203/4 "2020-12-08T16:03:55Z")

</div>

wrap your data into a `cv::Mat` first.

`GpuMat` from `Mat` should be available.

edit: or rather, build a numpy array, and then OpenCV should have ways to turn that into a GpuMat.

---

<div class="post-metadata">

**Author:** ![bebop\_blues](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@bebop\_blues](https://forum.opencv.org/u/bebop_blues)\
**Post date:** [December 8, 2020, 6:45pm UTC](https://forum.opencv.org/t/use-pre-allocated-cuda-memory-pointer-to-initialize-an-opencv-gpumat-in-python/203/5 "2020-12-08T18:45:28Z")

</div>

Yes, this way would definitely work, but my input is already an array pointer from cuda, so it would involve one dtoh and one htod transfer, which seems wasteful.

---

<div class="post-metadata">

**Author:** ![bebop\_blues](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@bebop\_blues](https://forum.opencv.org/u/bebop_blues)\
**Post date:** [December 8, 2020, 6:47pm UTC](https://forum.opencv.org/t/use-pre-allocated-cuda-memory-pointer-to-initialize-an-opencv-gpumat-in-python/203/6 "2020-12-08T18:47:07Z")

</div>

I tried looking at the old forums and I only found a couple of similar unanswered questions. If it is not too much trouble, could you please provide the intuition behind why this approach wouldn’t work in Python.  
I am not able to grasp why this would work in cpp, but passing a similar pointer in python would fail.

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [December 8, 2020, 6:57pm UTC](https://forum.opencv.org/t/use-pre-allocated-cuda-memory-pointer-to-initialize-an-opencv-gpumat-in-python/203/7 "2020-12-08T18:57:42Z")

</div>

Without looking into it I would assume you can’t get the pointer. If you can I would think that it wouldn’t be in the same address space (CUDA context) in the OpenCV library as it was in the library you created it in. I may be wrong, a quick way to find out would be to give it a go, add CV\_WRAP re-build and observe the addresses etc. in the debugger (if your using windows VS will allow you to debug python c++ modules).

---

<div class="post-metadata">

**Author:** ![bebop\_blues](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@bebop\_blues](https://forum.opencv.org/u/bebop_blues)\
**Post date:** [December 8, 2020, 7:03pm UTC](https://forum.opencv.org/t/use-pre-allocated-cuda-memory-pointer-to-initialize-an-opencv-gpumat-in-python/203/8 "2020-12-08T19:03:14Z")

</div>

I tried that, it was taking the int value of the pointer as a scalar, so I removed the CV\_WRAP of the constructors which take in a scalar value as input, but still I get the same result as passing a scalar value.

I missed the fact that opencv might create a new cuda context, I assumed it would use the default context.

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [December 9, 2020, 4:17pm UTC](https://forum.opencv.org/t/use-pre-allocated-cuda-memory-pointer-to-initialize-an-opencv-gpumat-in-python/203/9 "2020-12-09T16:17:47Z")

</div>

If you just wrapped the signature with the data pointer then I would expect you to get a compilation error as the python bindings can’t deal with a `void *`. Did you do something like the below?

```
CV_WRAP inline GpuMat(int rows, int cols, int type, uint64 dataAddr, size_t step = Mat::AUTO_STEP) :
    GpuMat(rows, cols, type, (void*)dataAddr, step){}

```

Assuming 64 bit did the memory address which you passed in as an 8 byte integer access access the same location inside OpenCV? Which library are you creating the memory with and how do you get the memory address?

---

<div class="post-metadata">

**Author:** ![Yuval\_Grossman](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/yuval_grossman/32/9122_2.png) [@Yuval\_Grossman](https://forum.opencv.org/u/Yuval_Grossman)\
**Post date:** [November 19, 2023, 7:15pm UTC](https://forum.opencv.org/t/use-pre-allocated-cuda-memory-pointer-to-initialize-an-opencv-gpumat-in-python/203/10 "2023-11-19T19:15:31Z")

</div>

Hi guys, any new findings in this discussion?  
I’m trying to convert torch.Tensor on cuda to cv2.cuda\_GpuMat.  
I managed to do it the other way by defining the **cuda\_array\_interface** property of the tensor, specifically torch know how to handle the cudaPtr() of GpuMat, so I wonder why shouldn’t it be the other way?

---

<div class="post-metadata">

**Author:** ![Yuval\_Grossman](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/yuval_grossman/32/9122_2.png) [@Yuval\_Grossman](https://forum.opencv.org/u/Yuval_Grossman)\
**Post date:** [November 20, 2023, 8:35am UTC](https://forum.opencv.org/t/use-pre-allocated-cuda-memory-pointer-to-initialize-an-opencv-gpumat-in-python/203/11 "2023-11-20T08:35:50Z")

</div>

I found the solution!  
from version 4.8.0 there is a function cv2.cuda.createGpuMatFromCudaMemory(), which accepts a pointer and build a GpuMat.

for example: if x is my torch.Tensor, we can do:  
h, w = x.shape  
cv2.cuda.createGpuMatFromCudaMemory(h, w, cv2.CV\_32F, x.data\_ptr())

hope it helps someone, I bearly managed to find it just by checking what other functions are in the cv2.cuda module
