Struct rustacuda::prelude::DeviceBuffer
source · pub struct DeviceBuffer<T> { /* private fields */ }
Expand description
Fixed-size device-side buffer. Provides basic access to device memory.
Implementations§
source§impl<T> DeviceBuffer<T>
impl<T> DeviceBuffer<T>
sourcepub unsafe fn uninitialized(size: usize) -> CudaResult<Self>
pub unsafe fn uninitialized(size: usize) -> CudaResult<Self>
Allocate a new device buffer large enough to hold size
T
’s, but without
initializing the contents.
Errors:
If the allocation fails, returns the error from CUDA. If size
is large enough that
size * mem::sizeof::<T>()
overflows usize, then returns InvalidMemoryAllocation.
Safety:
The caller must ensure that the contents of the buffer are initialized before reading from the buffer.
Examples:
use rustacuda::memory::*;
let mut buffer = unsafe { DeviceBuffer::uninitialized(5).unwrap() };
buffer.copy_from(&[0u64, 1, 2, 3, 4]).unwrap();
sourcepub unsafe fn zeroed(size: usize) -> CudaResult<Self>
pub unsafe fn zeroed(size: usize) -> CudaResult<Self>
Allocate a new device buffer large enough to hold size
T
’s and fill the contents with
zeroes (0u8
).
Errors:
If the allocation fails, returns the error from CUDA. If size
is large enough that
size * mem::sizeof::<T>()
overflows usize, then returns InvalidMemoryAllocation.
Safety:
The backing memory is zeroed, which may not be a valid bit-pattern for type T
. The caller
must ensure either that all-zeroes is a valid bit-pattern for type T
or that the backing
memory is set to a valid value before it is read.
Examples:
use rustacuda::memory::*;
let buffer = unsafe { DeviceBuffer::zeroed(5).unwrap() };
let mut host_values = [1u64, 2, 3, 4, 5];
buffer.copy_to(&mut host_values).unwrap();
assert_eq!([0u64, 0, 0, 0, 0], host_values);
sourcepub unsafe fn from_raw_parts(
ptr: DevicePointer<T>,
capacity: usize
) -> DeviceBuffer<T>
pub unsafe fn from_raw_parts(
ptr: DevicePointer<T>,
capacity: usize
) -> DeviceBuffer<T>
Creates a DeviceBuffer<T>
directly from the raw components of another device buffer.
Safety
This is highly unsafe, due to the number of invariants that aren’t checked:
ptr
needs to have been previously allocated viaDeviceBuffer
orcuda_malloc
.ptr
’sT
needs to have the same size and alignment as it was allocated with.capacity
needs to be the capacity that the pointer was allocated with.
Violating these may cause problems like corrupting the CUDA driver’s internal data structures.
The ownership of ptr
is effectively transferred to the
DeviceBuffer<T>
which may then deallocate, reallocate or change the
contents of memory pointed to by the pointer at will. Ensure
that nothing else uses the pointer after calling this
function.
Examples:
use std::mem;
use rustacuda::memory::*;
let mut buffer = DeviceBuffer::from_slice(&[0u64; 5]).unwrap();
let ptr = buffer.as_device_ptr();
let size = buffer.len();
mem::forget(buffer);
let buffer = unsafe { DeviceBuffer::from_raw_parts(ptr, size) };
sourcepub fn drop(dev_buf: DeviceBuffer<T>) -> DropResult<DeviceBuffer<T>>
pub fn drop(dev_buf: DeviceBuffer<T>) -> DropResult<DeviceBuffer<T>>
Destroy a DeviceBuffer
, returning an error.
Deallocating device memory can return errors from previous asynchronous work. This function destroys the given buffer and returns the error and the un-destroyed buffer on failure.
Example:
use rustacuda::memory::*;
let x = DeviceBuffer::from_slice(&[10, 20, 30]).unwrap();
match DeviceBuffer::drop(x) {
Ok(()) => println!("Successfully destroyed"),
Err((e, buf)) => {
println!("Failed to destroy buffer: {:?}", e);
// Do something with buf
},
}
source§impl<T: DeviceCopy> DeviceBuffer<T>
impl<T: DeviceCopy> DeviceBuffer<T>
sourcepub fn from_slice(slice: &[T]) -> CudaResult<Self>
pub fn from_slice(slice: &[T]) -> CudaResult<Self>
Methods from Deref<Target = DeviceSlice<T>>§
sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of elements in the slice.
Examples
use rustacuda::memory::*;
let a = DeviceBuffer::from_slice(&[1, 2, 3]).unwrap();
assert_eq!(a.len(), 3);
sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true
if the slice has a length of 0.
Examples
use rustacuda::memory::*;
let a : DeviceBuffer<u64> = unsafe { DeviceBuffer::uninitialized(0).unwrap() };
assert!(a.is_empty());
sourcepub fn as_ptr(&self) -> *const T
pub fn as_ptr(&self) -> *const T
Return a raw device-pointer to the slice’s buffer.
The caller must ensure that the slice outlives the pointer this function returns, or else it will end up pointing to garbage. The caller must also ensure that the pointer is not dereferenced by the CPU.
Examples:
use rustacuda::memory::*;
let a = DeviceBuffer::from_slice(&[1, 2, 3]).unwrap();
println!("{:p}", a.as_ptr());
sourcepub fn as_mut_ptr(&mut self) -> *mut T
pub fn as_mut_ptr(&mut self) -> *mut T
Returns an unsafe mutable device-pointer to the slice’s buffer.
The caller must ensure that the slice outlives the pointer this function returns, or else it will end up pointing to garbage. The caller must also ensure that the pointer is not dereferenced by the CPU.
Examples:
use rustacuda::memory::*;
let mut a = DeviceBuffer::from_slice(&[1, 2, 3]).unwrap();
println!("{:p}", a.as_mut_ptr());
sourcepub fn split_at(&self, mid: usize) -> (&DeviceSlice<T>, &DeviceSlice<T>)
pub fn split_at(&self, mid: usize) -> (&DeviceSlice<T>, &DeviceSlice<T>)
Divides one DeviceSlice into two at a given index.
The first will contain all indices from [0, mid)
(excluding the index mid
itself) and
the second will contain all indices from [mid, len)
(excluding the index len
itself).
Panics
Panics if min > len
.
Examples:
use rustacuda::memory::*;
let buf = DeviceBuffer::from_slice(&[0u64, 1, 2, 3, 4, 5]).unwrap();
let (left, right) = buf.split_at(3);
let mut left_host = [0u64, 0, 0];
let mut right_host = [0u64, 0, 0];
left.copy_to(&mut left_host).unwrap();
right.copy_to(&mut right_host).unwrap();
assert_eq!([0u64, 1, 2], left_host);
assert_eq!([3u64, 4, 5], right_host);
sourcepub fn split_at_mut(
&mut self,
mid: usize
) -> (&mut DeviceSlice<T>, &mut DeviceSlice<T>)
pub fn split_at_mut(
&mut self,
mid: usize
) -> (&mut DeviceSlice<T>, &mut DeviceSlice<T>)
Divides one mutable DeviceSlice into two at a given index.
The first will contain all indices from [0, mid)
(excluding the index mid
itself) and
the second will contain all indices from [mid, len)
(excluding the index len
itself).
Panics
Panics if min > len
.
Examples:
use rustacuda::memory::*;
let mut buf = DeviceBuffer::from_slice(&[0u64, 0, 0, 0, 0, 0]).unwrap();
{
let (left, right) = buf.split_at_mut(3);
let left_host = [0u64, 1, 2];
let right_host = [3u64, 4, 5];
left.copy_from(&left_host).unwrap();
right.copy_from(&right_host).unwrap();
}
let mut host_full = [0u64; 6];
buf.copy_to(&mut host_full).unwrap();
assert_eq!([0u64, 1, 2, 3, 4, 5], host_full);
sourcepub fn chunks(&self, chunk_size: usize) -> DeviceChunks<'_, T> ⓘ
pub fn chunks(&self, chunk_size: usize) -> DeviceChunks<'_, T> ⓘ
Returns an iterator over chunk_size
elements of the slice at a time. The chunks are device
slices and do not overlap. If chunk_size
does not divide the length of the slice, then the
last chunk will not have length chunk_size
.
See exact_chunks
for a variant of this iterator that returns chunks of always exactly
chunk_size
elements.
Panics
Panics if chunk_size
is 0.
Examples:
use rustacuda::memory::*;
let slice = DeviceBuffer::from_slice(&[1u64, 2, 3, 4, 5]).unwrap();
let mut iter = slice.chunks(2);
assert_eq!(iter.next().unwrap().len(), 2);
let mut host_buf = [0u64, 0];
iter.next().unwrap().copy_to(&mut host_buf).unwrap();
assert_eq!([3, 4], host_buf);
assert_eq!(iter.next().unwrap().len(), 1);
sourcepub fn chunks_mut(&mut self, chunk_size: usize) -> DeviceChunksMut<'_, T> ⓘ
pub fn chunks_mut(&mut self, chunk_size: usize) -> DeviceChunksMut<'_, T> ⓘ
Returns an iterator over chunk_size
elements of the slice at a time. The chunks are
mutable device slices and do not overlap. If chunk_size
does not divide the length of the
slice, then the last chunk will not have length chunk_size
.
See exact_chunks
for a variant of this iterator that returns chunks of always exactly
chunk_size
elements.
Panics
Panics if chunk_size
is 0.
Examples:
use rustacuda::memory::*;
let mut slice = DeviceBuffer::from_slice(&[0u64, 0, 0, 0, 0]).unwrap();
{
let mut iter = slice.chunks_mut(2);
assert_eq!(iter.next().unwrap().len(), 2);
let host_buf = [2u64, 3];
iter.next().unwrap().copy_from(&host_buf).unwrap();
assert_eq!(iter.next().unwrap().len(), 1);
}
let mut host_buf = [0u64, 0, 0, 0, 0];
slice.copy_to(&mut host_buf).unwrap();
assert_eq!([0u64, 0, 2, 3, 0], host_buf);
sourcepub fn as_device_ptr(&mut self) -> DevicePointer<T>
pub fn as_device_ptr(&mut self) -> DevicePointer<T>
Returns a DevicePointer<T>
to the buffer.
The caller must ensure that the buffer outlives the returned pointer, or it will end up pointing to garbage.
Modifying DeviceBuffer
is guaranteed not to cause its buffer to be reallocated, so pointers
cannot be invalidated in that manner, but other types may be added in the future which can
reallocate.