Buffer

Struct Buffer 

Source
pub struct Buffer<'a, T = f32, D = CPU, S = ()>
where D: Device, S: Shape,
{ pub ptr: <D as Device>::Ptr<T, S>, pub device: Option<&'a D>, pub node: Node, }
Expand description

The underlying non-growable array structure. A Buffer may be encapsulated in other structs. By default, the Buffer is a f32 CPU Buffer.

§Example

use custos::prelude::*;

fn buffer_f32_cpu(buf: &Buffer) {}
fn buffer_generic<T, D: Device>(buf: &Buffer<T, D>) {}

let device = CPU::new();
let buf = Buffer::from((&device, [0.5, 1.3, 3.2, 2.43]));

buffer_f32_cpu(&buf);
buffer_generic(&buf);

Fields§

§ptr: <D as Device>::Ptr<T, S>§device: Option<&'a D>§node: Node

Implementations§

Source§

impl<'a, T> Buffer<'a, T, ()>

Source

pub fn copy(&self) -> Buffer<'a, T, ()>
where T: Copy,

Source

pub fn item(&self) -> T
where T: Copy,

Used if the Buffer contains only a single value. By derefencing this Buffer, you obtain this value as well (which is probably preferred).

§Example
use custos::Buffer;

let x: Buffer<f32, _> = 7f32.into();
assert_eq!(*x, 7.);
assert_eq!(x.item(), 7.);
Source§

impl<'a, T, D, S> Buffer<'a, T, D, S>
where D: Device, S: Shape,

Source

pub fn new(device: &'a D, len: usize) -> Buffer<'a, T, D, S>
where D: Alloc<'a, T, S>,

Creates a zeroed (or values set to default) Buffer with the given length on the specified device. This Buffer can’t outlive the device specified as a parameter.

use custos::{CPU, Buffer};

let device = CPU::new();
let mut buffer = Buffer::<i32>::new(&device, 6);

// this only works with CPU or unified memory buffers (this creates a slice with the host pointer)
for value in &mut buffer {
    *value = 2;
}

assert_eq!(buffer.as_slice(), &[2; 6]);
Source

pub fn deviceless<'b>(device: &'b D, len: usize) -> Buffer<'a, T, D, S>
where D: DevicelessAble<'b, T, S>,

Buffers created with this method can outlive the device used to create this Buffer.
No operations can be invoked on this Buffer as [get_device!] will panic.

§Examples
use custos::{CPU, Buffer};

let mut buf = {
    let device = CPU::new();
    Buffer::<u8>::deviceless(&device, 5)
};
// buf.read(); // panics
for (idx, element) in buf.iter_mut().enumerate() {
    *element = idx as u8;
}
assert_eq!(buf.as_slice(), &[0, 1, 2, 3, 4]);
Source

pub fn device(&self) -> &'a D

Source

pub fn read(&'a self) -> <D as Read<T, D, S>>::Read<'a>
where T: Clone + Default, D: Read<T, D, S>,

Source

pub fn read_to_vec(&self) -> Vec<T>
where D: Read<T, D, S>, T: Default + Clone,

Reads the contents of the buffer and writes them into a vector. If it is certain whether a CPU, or an unified CPU + OpenCL Buffer, is used, calling .as_slice() (or deref/mut to &/mut [&T]) is probably preferred.

§Example
use custos::{CPU, Buffer};

let device = CPU::new();
let buf = Buffer::from((&device, [1, 2, 3, 4]));

assert_eq!(buf.read_to_vec(), vec![1, 2, 3, 4]);
Source

pub fn write(&mut self, data: &[T])
where T: Clone, D: WriteBuf<T, D, S>,

Writes a slice to the Buffer. With a CPU buffer, the slice is just copied to the slice of the buffer.

Source

pub fn len(&self) -> usize

Returns the number of elements contained in Buffer.

§Example
use custos::{CPU, Buffer};

let device = CPU::new();
let a = Buffer::<i32, _>::new(&device, 10);
assert_eq!(a.len(), 10)
Source

pub unsafe fn shallow(&self) -> Buffer<'a, T, D, S>
where <D as Device>::Ptr<T, S>: ShallowCopy,

Creates a shallow copy of &self.

§Safety

Itself, this function does not need to be unsafe. However, declaring this function as unsafe highlights the violation of creating two or more owners for one resource. Furthermore, the resulting Buffer can outlive self.

Source

pub unsafe fn shallow_or_clone(&self) -> Buffer<'a, T, D, S>
where <D as Device>::Ptr<T, S>: ShallowCopy, T: Clone, D: CloneBuf<'a, T, S>,

Returns a shallow copy of &self, if the realloc feature is deactivated. If the realloc feature is activated, it returns a deep copy / clone.

§Safety

Itself, this function does not need to be unsafe. However, declaring this function as unsafe highlights the violation of possibly creating two or more owners for one resource. Furthermore, the resulting Buffer can outlive self.

Source

pub fn id(&self) -> Ident

Source§

impl<'a, T, D, S> Buffer<'a, T, D, S>
where D: Device, S: Shape,

Source

pub fn to_dims<O>(self) -> Buffer<'a, T, D, O>
where O: Shape, D: ToDim<T, S, O>,

Converts a (non stack allocated) Buffer with no shape to a Buffer with shape O.

Source§

impl<'a, T, D, S> Buffer<'a, T, D, S>
where D: IsShapeIndep, S: Shape,

Source

pub fn as_dims<'b, O>(&self) -> &Buffer<'b, T, D, O>
where O: Shape,

Source

pub fn as_dims_mut<'b, O>(&mut self) -> &mut Buffer<'b, T, D, O>
where O: Shape,

Source§

impl<'a, T, D, S> Buffer<'a, T, D, S>
where D: Device, S: Shape, <D as Device>::Ptr<T, S>: CommonPtrs<T>,

Source

pub fn ptrs(&self) -> (*const T, *mut c_void, u64)

Returns all types of pointers. (host, OpenCL, CUDA)

Source

pub fn ptrs_mut(&mut self) -> (*mut T, *mut c_void, u64)

Returns all types of pointers. (host, OpenCL, CUDA)

Source§

impl<'a, T, D> Buffer<'a, T, D>
where D: Device,

Source

pub fn is_empty(&self) -> bool

Returns true if Buffer is created without a slice.

§Example
use custos::{CPU, Buffer};

let a = Buffer::<i32, ()>::from(5);
assert!(a.is_empty())
Source

pub fn clear(&mut self)
where D: ClearBuf<T>,

Sets all elements in Buffer to the default value.

Source§

impl<'a, T> Buffer<'a, T>

Source

pub unsafe fn from_raw_host(ptr: *mut T, len: usize) -> Buffer<'a, T>

Constructs a deviceless Buffer out of a host pointer and a length.

§Example
use custos::{Buffer, Alloc, CPU, Read, flag::AllocFlag};
use std::ffi::c_void;

let device = CPU::new();
let mut ptr = Alloc::<f32>::alloc(&device, 10, AllocFlag::None);
let mut buf = unsafe {
    Buffer::from_raw_host(ptr.ptr, 10)
};
for (idx, value) in buf.iter_mut().enumerate() {
    *value += idx as f32;
}

assert_eq!(buf.as_slice(), &[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.,]);
§Safety

The pointer must be valid. The Buffer does not manage deallocation of the allocated memory.

Source

pub unsafe fn from_raw_host_device( device: &'a CPU, ptr: *mut T, len: usize, ) -> Buffer<'a, T>

Constructs a Buffer out of a host pointer and a length. The provided device can be used to shorten operation calls.

§Safety

The pointer must be valid. The Buffer does not manage deallocation of the allocated memory.

Source§

impl<'a, T> Buffer<'a, T, OpenCL>

Source

pub fn cl_ptr(&self) -> *mut c_void

Source§

impl<'a, T, D, S> Buffer<'a, T, D, S>
where D: MainMemory, S: Shape,

Source

pub fn as_slice(&self) -> &[T]

Returns a CPU slice. This does not work with CUDA or raw OpenCL buffers.

Source

pub fn as_mut_slice(&mut self) -> &mut [T]

Returns a mutable CPU slice.

Source§

impl<'a, T, D, S> Buffer<'a, T, D, S>
where D: MainMemory, S: Shape, <D as Device>::Ptr<T, S>: CommonPtrs<T>,

Source

pub fn host_ptr(&self) -> *const T

Returns a non null host pointer

Source

pub fn host_ptr_mut(&mut self) -> *mut T

Returns a non null host pointer

Trait Implementations§

Source§

impl<'a, T, D, S> AddGraph for &Buffer<'a, T, D, S>
where D: Device, S: Shape,

Source§

fn add(&self, graph: &mut Graph, len: usize) -> Node

Source§

impl<'a, T, D, S> AddGraph for Buffer<'a, T, D, S>
where D: Device, S: Shape,

Source§

fn add(&self, graph: &mut Graph, len: usize) -> Node

Source§

impl<'a, T, S> AsClCvoidPtr for &Buffer<'a, T, OpenCL, S>
where S: Shape,

Source§

impl<'a, T, S> AsClCvoidPtr for Buffer<'a, T, OpenCL, S>
where S: Shape,

Source§

impl<T, D> AsMut<[T]> for Buffer<'_, T, D>
where D: MainMemory,

Source§

fn as_mut(&mut self) -> &mut [T]

Converts this type into a mutable reference of the (usually inferred) input type.
Source§

impl<T, D> AsRef<[T]> for Buffer<'_, T, D>
where D: MainMemory,

Source§

fn as_ref(&self) -> &[T]

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl<'a, T, D, S> Clone for Buffer<'a, T, D, S>
where T: Clone, D: CloneBuf<'a, T, S> + Device, S: Shape,

Source§

fn clone(&self) -> Buffer<'a, T, D, S>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a, T, D> Debug for Buffer<'a, T, D>
where T: Debug + Default + Clone + 'a, D: Read<T> + Device + 'a, <D as Read<T>>::Read<'b>: for<'b> Debug, <D as Device>::Ptr<T, ()>: CommonPtrs<T>,

Source§

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

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

impl<'a, T, D, S> Default for Buffer<'a, T, D, S>
where D: Device, S: Shape, <D as Device>::Ptr<T, S>: Default,

Source§

fn default() -> Buffer<'a, T, D, S>

Returns the “default value” for a type. Read more
Source§

impl<T, D, S> Deref for Buffer<'_, T, D, S>
where D: MainMemory, S: Shape,

A Buffer dereferences into a slice.

§Examples

use custos::{Buffer, CPU};

let device = CPU::new();

let a = Buffer::from((&device, [1., 2., 3., 4.,]));
let b = Buffer::from((&device, [2., 3., 4., 5.,]));

let mut c = Buffer::from((&device, [0.; 4]));

let slice_add = |a: &[f64], b: &[f64], c: &mut [f64]| {
    for i in 0..c.len() {
        c[i] = a[i] + b[i];
    }
};

slice_add(&a, &b, &mut c);
assert_eq!(c.as_slice(), &[3., 5., 7., 9.,]);
Source§

type Target = [T]

The resulting type after dereferencing.
Source§

fn deref(&self) -> &<Buffer<'_, T, D, S> as Deref>::Target

Dereferences the value.
Source§

impl<'a, T> Deref for Buffer<'a, T, ()>

Source§

type Target = T

The resulting type after dereferencing.
Source§

fn deref(&self) -> &<Buffer<'a, T, ()> as Deref>::Target

Dereferences the value.
Source§

impl<T, D, S> DerefMut for Buffer<'_, T, D, S>
where D: MainMemory, S: Shape,

A Buffer dereferences into a slice.

§Examples

use custos::{Buffer, CPU};
  
let device = CPU::new();

let a = Buffer::from((&device, [4., 2., 3., 4.,]));
let b = Buffer::from((&device, [2., 3., 6., 5.,]));
let mut c = Buffer::from((&device, [0.; 4]));

let slice_add = |a: &[f64], b: &[f64], c: &mut [f64]| {
    for i in 0..c.len() {
        c[i] = a[i] + b[i];
    }
};
slice_add(&a, &b, &mut c);
assert_eq!(c.as_slice(), &[6., 5., 9., 9.,]);
Source§

fn deref_mut(&mut self) -> &mut <Buffer<'_, T, D, S> as Deref>::Target

Mutably dereferences the value.
Source§

impl<'a, T> DerefMut for Buffer<'a, T, ()>

Source§

fn deref_mut(&mut self) -> &mut <Buffer<'a, T, ()> as Deref>::Target

Mutably dereferences the value.
Source§

impl<'a, T, D, S> From<(&'a D, &[T])> for Buffer<'a, T, D, S>
where S: Shape, T: Clone, D: Alloc<'a, T, S> + IsShapeIndep,

Source§

fn from(_: (&'a D, &[T])) -> Buffer<'a, T, D, S>

Converts to this type from the input type.
Source§

impl<'a, T, D, const N: usize> From<(&'a D, &[T; N])> for Buffer<'a, T, D>
where T: Clone, D: Alloc<'a, T> + IsShapeIndep,

Source§

fn from(_: (&'a D, &[T; N])) -> Buffer<'a, T, D>

Converts to this type from the input type.
Source§

impl<'a, T, D, S> From<(&'a D, &Vec<T>)> for Buffer<'a, T, D, S>
where S: Shape, T: Clone, D: Alloc<'a, T, S> + IsShapeIndep,

Source§

fn from(_: (&'a D, &Vec<T>)) -> Buffer<'a, T, D, S>

Converts to this type from the input type.
Source§

impl<'a, T, D, const N: usize> From<(&'a D, [T; N])> for Buffer<'a, T, D>
where T: Clone, D: Alloc<'a, T> + IsShapeIndep,

Source§

fn from(_: (&'a D, [T; N])) -> Buffer<'a, T, D>

Converts to this type from the input type.
Source§

impl<'a, T, D, S> From<(&'a D, Vec<T>)> for Buffer<'a, T, D, S>
where S: Shape, T: Clone, D: Alloc<'a, T, S> + IsShapeIndep,

Source§

fn from(_: (&'a D, Vec<T>)) -> Buffer<'a, T, D, S>

Converts to this type from the input type.
Source§

impl<T> From<T> for Buffer<'_, T, ()>
where T: Number,

Source§

fn from(ptr: T) -> Buffer<'_, T, ()>

Converts to this type from the input type.
Source§

impl<'a, T, D> IntoIterator for &'a Buffer<'_, T, D>
where D: MainMemory,

Source§

type Item = &'a T

The type of the elements being iterated over.
Source§

type IntoIter = Iter<'a, T>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> <&'a Buffer<'_, T, D> as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'a, T, D> IntoIterator for &'a mut Buffer<'_, T, D>
where D: MainMemory,

Source§

type Item = &'a mut T

The type of the elements being iterated over.
Source§

type IntoIter = IterMut<'a, T>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> <&'a mut Buffer<'_, T, D> as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'a, T, D, const B: usize, const A: usize> WithShape<&'a D, &[[T; A]; B]> for Buffer<'a, T, D, Dim2<B, A>>
where T: Number, D: Alloc<'a, T, Dim2<B, A>>,

Source§

fn with(device: &'a D, array: &[[T; A]; B]) -> Buffer<'a, T, D, Dim2<B, A>>

Source§

impl<'a, T, D, const N: usize> WithShape<&'a D, &[T; N]> for Buffer<'a, T, D, Dim1<N>>
where T: Number, D: Alloc<'a, T, Dim1<N>>,

Source§

fn with(device: &'a D, array: &[T; N]) -> Buffer<'a, T, D, Dim1<N>>

Source§

impl<'a, T, D, const B: usize, const A: usize> WithShape<&'a D, [[T; A]; B]> for Buffer<'a, T, D, Dim2<B, A>>
where T: Number, D: Alloc<'a, T, Dim2<B, A>>,

Source§

fn with(device: &'a D, array: [[T; A]; B]) -> Buffer<'a, T, D, Dim2<B, A>>

Source§

impl<'a, T, D, const N: usize> WithShape<&'a D, [T; N]> for Buffer<'a, T, D, Dim1<N>>
where T: Number, D: Alloc<'a, T, Dim1<N>>,

Source§

fn with(device: &'a D, array: [T; N]) -> Buffer<'a, T, D, Dim1<N>>

Source§

impl<'a, T, D, S> WithShape<&'a D, ()> for Buffer<'a, T, D, S>
where S: Shape, D: Alloc<'a, T, S>,

Source§

fn with(device: &'a D, _: ()) -> Buffer<'a, T, D, S>

Source§

impl<'a, T, D, S> Send for Buffer<'a, T, D, S>
where D: Device, S: Shape,

Source§

impl<'a, T, D, S> Sync for Buffer<'a, T, D, S>
where D: Device, S: Shape,

Auto Trait Implementations§

§

impl<'a, T, D, S> Freeze for Buffer<'a, T, D, S>
where <D as Device>::Ptr<T, S>: Freeze,

§

impl<'a, T, D, S> RefUnwindSafe for Buffer<'a, T, D, S>
where <D as Device>::Ptr<T, S>: RefUnwindSafe, D: RefUnwindSafe,

§

impl<'a, T, D, S> Unpin for Buffer<'a, T, D, S>
where <D as Device>::Ptr<T, S>: Unpin,

§

impl<'a, T, D, S> UnwindSafe for Buffer<'a, T, D, S>
where <D as Device>::Ptr<T, S>: UnwindSafe, D: 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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. 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.