opencv::core

Struct BufferPool

Source
pub struct BufferPool { /* private fields */ }
Expand description

BufferPool for use with CUDA streams

BufferPool utilizes Stream’s allocator to create new buffers for GpuMat’s. It is only useful when enabled with #setBufferPoolUsage.

   setBufferPoolUsage(true);

Note: set_buffer_pool_usage must be called \em before any Stream declaration.

Users may specify custom allocator for Stream and may implement their own stream based functions utilizing the same underlying GPU memory management.

If custom allocator is not specified, BufferPool utilizes StackAllocator by default. StackAllocator allocates a chunk of GPU device memory beforehand, and when GpuMat is declared later on, it is given the pre-allocated memory. This kind of strategy reduces the number of calls for memory allocating APIs such as cudaMalloc or cudaMallocPitch.

Below is an example that utilizes BufferPool with StackAllocator:

   [include] <opencv2/opencv.hpp>

   using namespace cv;
   using namespace cv::cuda

   int main()
   {
       setBufferPoolUsage(true);                               // Tell OpenCV that we are going to utilize BufferPool
       setBufferPoolConfig(getDevice(), 1024 * 1024 * 64, 2);  // Allocate 64 MB, 2 stacks (default is 10 MB, 5 stacks)

       Stream stream1, stream2;                                // Each stream uses 1 stack
       BufferPool pool1(stream1), pool2(stream2);

       GpuMat d_src1 = pool1.getBuffer(4096, 4096, CV_8UC1);   // 16MB
       GpuMat d_dst1 = pool1.getBuffer(4096, 4096, CV_8UC3);   // 48MB, pool1 is now full

       GpuMat d_src2 = pool2.getBuffer(1024, 1024, CV_8UC1);   // 1MB
       GpuMat d_dst2 = pool2.getBuffer(1024, 1024, CV_8UC3);   // 3MB

       cvtColor(d_src1, d_dst1, cv::COLOR_GRAY2BGR, 0, stream1);
       cvtColor(d_src2, d_dst2, cv::COLOR_GRAY2BGR, 0, stream2);
   }

If we allocate another GpuMat on pool1 in the above example, it will be carried out by the DefaultAllocator since the stack for pool1 is full.

   GpuMat d_add1 = pool1.getBuffer(1024, 1024, CV_8UC1);   // Stack for pool1 is full, memory is allocated with DefaultAllocator

If a third stream is declared in the above example, allocating with [get_buffer] within that stream will also be carried out by the DefaultAllocator because we’ve run out of stacks.

   Stream stream3;                                         // Only 2 stacks were allocated, we've run out of stacks
   BufferPool pool3(stream3);
   GpuMat d_src3 = pool3.getBuffer(1024, 1024, CV_8UC1);   // Memory is allocated with DefaultAllocator

@warning When utilizing StackAllocator, deallocation order is important.

Just like a stack, deallocation must be done in LIFO order. Below is an example of erroneous usage that violates LIFO rule. If OpenCV is compiled in Debug mode, this sample code will emit CV_Assert error.

   int main()
   {
       setBufferPoolUsage(true);                               // Tell OpenCV that we are going to utilize BufferPool
       Stream stream;                                          // A default size (10 MB) stack is allocated to this stream
       BufferPool pool(stream);

       GpuMat mat1 = pool.getBuffer(1024, 1024, CV_8UC1);      // Allocate mat1 (1MB)
       GpuMat mat2 = pool.getBuffer(1024, 1024, CV_8UC1);      // Allocate mat2 (1MB)

       mat1.release();                                         // erroneous usage : mat2 must be deallocated before mat1
   }

Since C++ local variables are destroyed in the reverse order of construction, the code sample below satisfies the LIFO rule. Local GpuMat’s are deallocated and the corresponding memory is automatically returned to the pool for later usage.

   int main()
   {
       setBufferPoolUsage(true);                               // Tell OpenCV that we are going to utilize BufferPool
       setBufferPoolConfig(getDevice(), 1024 * 1024 * 64, 2);  // Allocate 64 MB, 2 stacks (default is 10 MB, 5 stacks)

       Stream stream1, stream2;                                // Each stream uses 1 stack
       BufferPool pool1(stream1), pool2(stream2);

       for (int i = 0; i < 10; i++)
       {
           GpuMat d_src1 = pool1.getBuffer(4096, 4096, CV_8UC1);   // 16MB
           GpuMat d_dst1 = pool1.getBuffer(4096, 4096, CV_8UC3);   // 48MB, pool1 is now full

           GpuMat d_src2 = pool2.getBuffer(1024, 1024, CV_8UC1);   // 1MB
           GpuMat d_dst2 = pool2.getBuffer(1024, 1024, CV_8UC3);   // 3MB

           d_src1.setTo(Scalar(i), stream1);
           d_src2.setTo(Scalar(i), stream2);

           cvtColor(d_src1, d_dst1, cv::COLOR_GRAY2BGR, 0, stream1);
           cvtColor(d_src2, d_dst2, cv::COLOR_GRAY2BGR, 0, stream2);
                                                                    // The order of destruction of the local variables is:
                                                                    //   d_dst2 => d_src2 => d_dst1 => d_src1
                                                                    // LIFO rule is satisfied, this code runs without error
       }
   }

Implementations§

Source§

impl BufferPool

Source

pub fn new(stream: &mut impl StreamTrait) -> Result<BufferPool>

Gets the BufferPool for the given stream.

Trait Implementations§

Source§

impl Boxed for BufferPool

Source§

unsafe fn from_raw(ptr: <BufferPool as OpenCVFromExtern>::ExternReceive) -> Self

Wrap the specified raw pointer Read more
Source§

fn into_raw(self) -> <BufferPool as OpenCVTypeExternContainer>::ExternSendMut

Return the underlying raw pointer while consuming this wrapper. Read more
Source§

fn as_raw(&self) -> <BufferPool as OpenCVTypeExternContainer>::ExternSend

Return the underlying raw pointer. Read more
Source§

fn as_raw_mut( &mut self, ) -> <BufferPool as OpenCVTypeExternContainer>::ExternSendMut

Return the underlying mutable raw pointer Read more
Source§

impl BufferPoolTrait for BufferPool

Source§

fn as_raw_mut_BufferPool(&mut self) -> *mut c_void

Source§

fn get_buffer(&mut self, rows: i32, cols: i32, typ: i32) -> Result<GpuMat>

Allocates a new GpuMat of given size and type.
Source§

fn get_buffer_1(&mut self, size: Size, typ: i32) -> Result<GpuMat>

Allocates a new GpuMat of given size and type.
Source§

impl BufferPoolTraitConst for BufferPool

Source§

fn as_raw_BufferPool(&self) -> *const c_void

Source§

fn get_allocator(&self) -> Result<Ptr<GpuMat_Allocator>>

Returns the allocator associated with the stream.
Source§

impl Debug for BufferPool

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for BufferPool

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Send for BufferPool

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<Mat> ModifyInplace for Mat
where Mat: Boxed,

Source§

unsafe fn modify_inplace<Res>( &mut self, f: impl FnOnce(&Mat, &mut Mat) -> Res, ) -> Res

Helper function to call OpenCV functions that allow in-place modification of a Mat or another similar object. By passing a mutable reference to the Mat to this function your closure will get called with the read reference and a write references to the same Mat. This is unsafe in a general case as it leads to having non-exclusive mutable access to the internal data, but it can be useful for some performance sensitive operations. One example of an OpenCV function that allows such in-place modification is imgproc::threshold. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.