DeviceBuffer

Struct 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>

Source

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();
Source

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);
Source

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 via DeviceBuffer or cuda_malloc.
  • ptr’s T 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) };
Source

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>

Source

pub fn from_slice(slice: &[T]) -> CudaResult<Self>

Allocate a new device buffer of the same size as slice, initialized with a clone of the data in slice.

§Errors

If the allocation fails, returns the error from CUDA.

§Examples
use rustacuda::memory::*;
let values = [0u64; 5];
let mut buffer = DeviceBuffer::from_slice(&values).unwrap();
Source

pub unsafe fn from_slice_async(slice: &[T], stream: &Stream) -> CudaResult<Self>

Asynchronously allocate a new buffer of the same size as slice, initialized with a clone of the data in slice.

§Safety

For why this function is unsafe, see AsyncCopyDestination

§Errors

If the allocation fails, returns the error from CUDA.

§Examples
use rustacuda::memory::*;
use rustacuda::stream::{Stream, StreamFlags};

let stream = Stream::new(StreamFlags::NON_BLOCKING, None).unwrap();
let values = [0u64; 5];
unsafe {
    let mut buffer = DeviceBuffer::from_slice_async(&values, &stream).unwrap();
    stream.synchronize();
    // Perform some operation on the buffer
}

Methods from Deref<Target = DeviceSlice<T>>§

Source

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);
Source

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());
Source

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());
Source

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());
Source

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);
Source

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);
Source

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);
Source

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);
Source

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.

Trait Implementations§

Source§

impl<T: DeviceCopy> AsyncCopyDestination<DeviceBuffer<T>> for DeviceSlice<T>

Source§

unsafe fn async_copy_from( &mut self, val: &DeviceBuffer<T>, stream: &Stream, ) -> CudaResult<()>

Asynchronously copy data from source. source must be the same size as self. Read more
Source§

unsafe fn async_copy_to( &self, val: &mut DeviceBuffer<T>, stream: &Stream, ) -> CudaResult<()>

Asynchronously copy data to dest. dest must be the same size as self. Read more
Source§

impl<T: DeviceCopy> CopyDestination<DeviceBuffer<T>> for DeviceSlice<T>

Source§

fn copy_from(&mut self, val: &DeviceBuffer<T>) -> CudaResult<()>

Copy data from source. source must be the same size as self. Read more
Source§

fn copy_to(&self, val: &mut DeviceBuffer<T>) -> CudaResult<()>

Copy data to dest. dest must be the same size as self. Read more
Source§

impl<T: Debug> Debug for DeviceBuffer<T>

Source§

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

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

impl<T> Deref for DeviceBuffer<T>

Source§

type Target = DeviceSlice<T>

The resulting type after dereferencing.
Source§

fn deref(&self) -> &DeviceSlice<T>

Dereferences the value.
Source§

impl<T> DerefMut for DeviceBuffer<T>

Source§

fn deref_mut(&mut self) -> &mut DeviceSlice<T>

Mutably dereferences the value.
Source§

impl<T> Drop for DeviceBuffer<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<T> Freeze for DeviceBuffer<T>

§

impl<T> RefUnwindSafe for DeviceBuffer<T>
where T: RefUnwindSafe,

§

impl<T> !Send for DeviceBuffer<T>

§

impl<T> !Sync for DeviceBuffer<T>

§

impl<T> Unpin for DeviceBuffer<T>

§

impl<T> UnwindSafe for DeviceBuffer<T>
where T: RefUnwindSafe,

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<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
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.