8000 cuda: add python bindings to allow GpuMat and Stream objects to be in… · opencv/opencv@076edfb · GitHub
[go: up one dir, main page]

Skip to content

Commit 076edfb

Browse files
committed
cuda: add python bindings to allow GpuMat and Stream objects to be initialized from raw pointers
1 parent 0052d46 commit 076edfb

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

modules/core/include/opencv2/core/cuda.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,29 @@ The function does not reallocate memory if the matrix has proper attributes alre
567567
*/
568568
CV_EXPORTS_W void ensureSizeIsEnough(int rows, int cols, int type, OutputArray arr);
569569

570+
/** @brief Python overload to create a GpuMat from existing GPU memory
571+
572+
@param rows Row count.
573+
@param cols Column count.
574+
@param type Type of the matrix.
575+
@param cudaMemoryAddress Address of the allocated GPU memory on the device. This does not allocate matrix data. Instead, it just initializes the matrix header that points to the specified cudaMemoryAddress, which means that no data is copied. This operation is very efficient and can be used to process external data using OpenCV functions. The external data is not automatically deallocated, so you should take care of it.
576+
@param step Number of bytes each matrix row occupies. The value should include the padding bytes at the end of each row, if any. If the parameter is missing (set to AUTO_STEP ), no padding is assumed and the actual step is calculated as cols*elemSize(). See GpuMat::elemSize.
577+
*/
578+
CV_EXPORTS_W GpuMat inline createGpuMat(int rows, int cols, int type, uint64 cudaMemoryAddress, size_t step = Mat::AUTO_STEP) {
579+
return GpuMat(rows, cols, type, reinterpret_cast<void*>(cudaMemoryAddress), step);
580+
};
581+
582+
/** @overload
583+
584+
@param size 2D array size: Size(cols, rows). In the Size() constructor, the number of rows and the number of columns go in the reverse order.
585+
@param type Type of the matrix.
586+
@param cudaMemoryAddress Address of the allocated GPU memory on the device. This does not allocate matrix data. Instead, it just initializes the matrix header that points to the specified cudaMemoryAddress, which means that no data is copied. This operation is very efficient and can be used to process external data using OpenCV functions. The external data is not automatically deallocated, so you should take care of it.
587+
@param step Number of bytes each matrix row occupies. The value should include the padding bytes at the end of each row, if any. If the parameter is missing (set to AUTO_STEP ), no padding is assumed and the actual step is calculated as cols*elemSize(). See GpuMat::elemSize.
588+
*/
589+
CV_EXPORTS_W inline GpuMat createGpuMat(Size size, int type, uint64 cudaMemoryAddress, size_t step = Mat::AUTO_STEP) {
590+
return GpuMat(size, type, reinterpret_cast<void*>(cudaMemoryAddress), step);
591+
};
592+
570593
/** @brief BufferPool for use with CUDA streams
571594
572595
BufferPool utilizes Stream's allocator to create new buffers for GpuMat's. It is
@@ -921,6 +944,13 @@ class CV_EXPORTS_W Stream
921944
friend class DefaultDeviceInitializer;
922945
};
923946

947+
948+
/** @brief Python overload to create a Stream object from the address stored in an existing CUDA Runtime API stream pointer (cudaStream_t)
949+
950+
@param cudaStreamMemoryAddress Memory address stored in a CUDA Runtime API stream pointer (cudaStream_t). The created Stream object does not perform and allocation or deallocation and simply wraps existing raw CUDA Runtime API stream pointer.
951+
*/
952+
CV_EXPORTS_W Stream wrapStream(uint64 cudaStreamMemoryAddress);
953+
924954
class CV_EXPORTS_W Event
925955
{
926956
public:

modules/core/src/cuda_stream.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,14 @@ Stream cv::cuda::StreamAccessor::wrapStream(cudaStream_t stream)
586586

587587
#endif
588588

589+
Stream cv::cuda::wrapStream(uint64 cudaStreamMemoryAddress) {
590+
#ifndef HAVE_CUDA
591+
throw_no_cuda();
592+
#else
593+
return cv::cuda::StreamAccessor::wrapStream(reinterpret_cast<cudaStream_t>(cudaStreamMemoryAddress));
594+
#endif
595+
}
596+
589597
/////////////////////////////////////////////////////////////
590598
/// StackAllocator
591599

modules/python/test/test_cuda.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,12 @@ def test_cuda_interop(self):
4040
cuMat = cv.cuda_GpuMat()
4141
cuMat.upload(npMat)
4242
self.assertTrue(cuMat.cudaPtr() != 0)
43+
cuMatFromPtr = cv.cuda.createGpuMat(cuMat.size(),cuMat.type(),cuMat.cudaPtr(), cuMat.step)
44+
self.assertTrue(cuMat.cudaPtr() == cuMatFromPtr.cudaPtr())
4345
stream = cv.cuda_Stream()
4446
self.assertTrue(stream.cudaPtr() != 0)
47+
streamFromPtr = cv.cuda.wrapStream(stream.cudaPtr())
48+
self.assertTrue(stream.cudaPtr() == streamFromPtr.cudaPtr())
4549
asyncstream = cv.cuda_Stream(1) # cudaStreamNonBlocking
4650
self.assertTrue(asyncstream.cudaPtr() != 0)
4751

0 commit comments

Comments
 (0)
0