New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow access to CUDA pointers for interoperability with other libraries #16513
Conversation
Hi @pwuertz, thanks for joining the discussion on Numba. I don't have comment for your effort here (yet), but I'd like to kindly ask that when this PR (and any subsequent ones) is merged, it'd be nice if you could follow numba/numba#5104 and add opencv to the list 🙂 Thank you. |
I believe it should own upstream |
@alalek Please note that For out-of-the-box interoperability with other libraries like Numba and Cupy I was planning on implementing the CUDA array interface (CAI) in a follow-up PR. As described earlier, I'm having trouble figuring out some OpenCV python binding generator details though. Also note that within the current CAI specification (version 2), the responsibility for lifetime and synchronization resides with the user (similar to using cv::Mat constructors with data pointers). If this changes in some future version I'd be willing to update the CAI version on the OpenCV side of course. |
@@ -681,6 +684,9 @@ class CV_EXPORTS_W Stream | |||
//! returns true if stream object is not default (!= 0) | |||
operator bool_type() const; | |||
|
|||
//! return Pointer to CUDA stream | |||
CV_WRAP void* cudaPtr() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is StreamAccessor
to do it: https://docs.opencv.org/master/d6/df1/structcv_1_1cuda_1_1StreamAccessor.html. I think it's better to wrap accessor rather expose private fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StreamAccessor
Not sure that this can help to reach the final goal:
to implement
__cuda_array_interface__
within theGpuMat
python binding
inline | ||
void* GpuMat::cudaPtr() const | ||
{ | ||
return data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is CV_PROP_RW
macro that allows to expose object properties to Python and other languages. You do not need own method for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe current approach is fine.
We should not allow changing of this pointer through CV_PROP_RW
.
|
@alalek It's true that # allocated dataX_cpu, dataX_gpu_cv, stream_cv
# (proof of principle numba views dataX_gpu_nb, stream_nb)
t1 = time.time()
data1_gpu_cv.upload(arr=data1_cpu, stream=stream_cv) # OpenCV upload
kernel_nb(data1_gpu_nb, out=data2_gpu_nb, stream=stream_nb) # Numba operation
data2_gpu_cv.download(dst=data2_cpu, stream=stream_cv) # OpenCV download
t2 = time.time() # CPU time: 0.001 s
stream_nb.synchronize()
t3 = time.time() # GPU time: 0.042 s
# verified data2_cpu So you can freely mix OpenCV and Numba operations on a single, fully async stream. @asmorkalov Oh sorry, haven't noticed the |
@asmorkalov Even with How to proceed? Using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me 👍
This is a proposal for adding
CV_WRAP
compatiblecudaPtr()
getter methods toGpuMat
andStream
, required for enabling interoperability between OpenCV and other CUDA supporting python libraries like Numba, CuPy, PyTorch, etc.Here is an example for sharing a
GpuMat
with CuPy:In this example
CudaArrayInterface
is a (incomplete) adapter class that implements the cuda array interface used by other frameworks:If possible, I'd like to implement
__cuda_array_interface__
within theGpuMat
python binding in a future PR (not sure how to define a python property using the wrapper generator though).