[−][src]Struct opencv::core::BufferPool
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: #setBufferPoolUsage 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_GRAY2BGR, 0, stream1); cvtColor(d_src2, d_dst2, CV_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 #getBuffer 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_GRAY2BGR, 0, stream1); cvtColor(d_src2, d_dst2, CV_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
impl BufferPool
[src]
pub fn as_raw_BufferPool(&self) -> *const c_void
[src]
pub fn as_raw_mut_BufferPool(&mut self) -> *mut c_void
[src]
impl BufferPool
[src]
pub fn new(stream: &mut Stream) -> Result<BufferPool>
[src]
Gets the BufferPool for the given stream.
Trait Implementations
impl Boxed for BufferPool
[src]
unsafe fn from_raw(ptr: *mut c_void) -> Self
[src]
fn into_raw(self) -> *mut c_void
[src]
fn as_raw(&self) -> *const c_void
[src]
fn as_raw_mut(&mut self) -> *mut c_void
[src]
impl BufferPoolTrait for BufferPool
[src]
fn as_raw_BufferPool(&self) -> *const c_void
[src]
fn as_raw_mut_BufferPool(&mut self) -> *mut c_void
[src]
fn get_buffer(&mut self, rows: i32, cols: i32, typ: i32) -> Result<GpuMat>
[src]
fn get_buffer_1(&mut self, size: Size, typ: i32) -> Result<GpuMat>
[src]
fn get_allocator(&self) -> Result<Ptr<dyn GpuMat_Allocator>>
[src]
impl Drop for BufferPool
[src]
impl Send for BufferPool
[src]
Auto Trait Implementations
impl RefUnwindSafe for BufferPool
impl !Sync for BufferPool
impl Unpin for BufferPool
impl UnwindSafe for BufferPool
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,