Struct custos_math::custos::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) -> Twhere 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, Global>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, D, ()>,

Sets all elements in Buffer to the default value.

source§

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

source

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

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, CPU, ()>

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> Buffer<'a, T, CUDA, ()>

source

pub fn cu_ptr(&self) -> u64

Returns a non null CUDA pointer

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

source§

impl<'a, T> Buffer<'a, T, CPU, ()>where T: Clone,

source

pub fn to_dev<D>(self) -> Buffer<'static, T, D, ()>where D: StaticGPU + Alloc<'static, T, ()> + IsShapeIndep, <D as Device>::Ptr<T, ()>: Default,

Moves the buffer Buffer to a static device.
This device is chosen via the type parameter D -> [OpenCL], [CUDA].
It is recommended to use the to_gpu() method of Buffer.

Example

use custos::prelude::*;

let cpu_buffer = Buffer::from(&[1., 2., 3.]);

let cl_buf = cpu_buffer.to_dev::<OpenCL>();
assert_eq!(cl_buf.read(), vec![1., 2., 3.]);
source

pub fn to_cuda(self) -> Buffer<'a, T, CUDA, ()>

Moves a Buffer to a [CUDA] device.
It is recommended to use the to_gpu() method of Buffer.

Example

use custos::prelude::*;

let cpu_buffer = Buffer::from(&[1., 2., 3.]);

let cu_buf = cpu_buffer.to_cuda();
assert_eq!(cu_buf.read(), vec![1., 2., 3.]);
source

pub fn to_cl(self) -> Buffer<'a, T, OpenCL, ()>

Converts a Buffer to an OpenCL device buffer.
It is recommended to use the to_gpu() method of Buffer.

Example

use custos::prelude::*;

let cpu_buffer = Buffer::from(&[1., 2., 3.]);

let cl_buf = cpu_buffer.to_cl();
assert_eq!(cl_buf.read(), vec![1., 2., 3.]);
source

pub fn to_gpu(self) -> Buffer<'a, T, CUDA, ()>

Converts a Buffer to a CUDA device buffer.

This method depends on the feature configuration.
If the ‘cuda’ feature is disabled, this function will return an OpenCL device buffer.

Example
use custos::prelude::*;

let cpu_buf = Buffer::from(&[4., 3., 5.]);
let cuda_buf = cpu_buf.to_gpu();

assert_eq!(cuda_buf.read(), vec![4., 3., 5.]);
source§

impl<'a, T, D> Buffer<'a, T, D, ()>where T: Clone + Default, D: Device + Read<T, D, ()>,

source

pub fn to_cpu(self) -> Buffer<'a, T, CPU, ()>

Moves the Buffer back to a CPU buffer.

Example

use custos::prelude::*;

let gpu_buf = Buffer::from(&[1, 2, 3]).to_gpu();

// ... some operations ...

let cpu_buf = gpu_buf.to_cpu();
assert_eq!(cpu_buf.as_slice(), &[1, 2, 3]);

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<'a, T> AsCudaCvoidPtr for &Buffer<'a, T, CUDA, ()>

source§

impl<'a, T> AsCudaCvoidPtr for Buffer<'a, T, CUDA, ()>

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 copy 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, D, ()> + Device + 'a, <D as Read<T, D, ()>>::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.,]);
§

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, (), ()>

§

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> From<&[T]> for Buffer<'a, T, CPU, ()>where T: Clone,

source§

fn from(slice: &[T]) -> Buffer<'a, T, CPU, ()>

Converts to this type from the input type.
source§

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

source§

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

Converts to this type from the input type.
source§

impl<'a, T, const N: usize> From<[T; N]> for Buffer<'a, T, CPU, ()>where T: Clone,

source§

fn from(slice: [T; N]) -> Buffer<'a, T, CPU, ()>

Converts to this type from the input type.
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, Global>)> for Buffer<'a, T, D, S>where S: Shape, T: Clone, D: Alloc<'a, T, S> + IsShapeIndep,

source§

fn from(_: (&'a D, &Vec<T, Global>)) -> 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, Global>)> for Buffer<'a, T, D, S>where S: Shape, T: Clone, D: Alloc<'a, T, S> + IsShapeIndep,

source§

fn from(_: (&'a D, Vec<T, Global>)) -> 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> From<Vec<T, Global>> for Buffer<'a, T, CPU, ()>where T: Clone,

source§

fn from(data: Vec<T, Global>) -> Buffer<'a, T, CPU, ()>

Converts to this type from the input type.
source§

impl<'a, A> FromIterator<A> for Buffer<'a, A, CPU, ()>where A: Clone + Default,

source§

fn from_iter<T>(iter: T) -> Buffer<'a, A, CPU, ()>where T: IntoIterator<Item = A>,

Creates a value from an iterator. Read more
source§

impl<'a, A> FromIterator<A> for Buffer<'a, A, CUDA, ()>where A: Clone + Default,

source§

fn from_iter<T>(iter: T) -> Buffer<'a, A, CUDA, ()>where T: IntoIterator<Item = A>,

Creates a value from an iterator. Read more
source§

impl<'a, A> FromIterator<A> for Buffer<'a, A, OpenCL, ()>where A: Clone + Default,

source§

fn from_iter<T>(iter: T) -> Buffer<'a, A, OpenCL, ()>where T: IntoIterator<Item = A>,

Creates a value from an iterator. Read more
source§

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

§

type Item = &'a T

The type of the elements being iterated over.
§

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,

§

type Item = &'a mut T

The type of the elements being iterated over.
§

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<T, S: Shape, D: RandOp<T, S>> RandBuf<T> for Buffer<'_, T, D, S>

source§

fn rand(&mut self, lo: T, hi: T)

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

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

const: unstable · source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

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

const: unstable · 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<T> ToOwned for Twhere T: Clone,

§

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 Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

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

Performs the conversion.
source§

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

§

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

The type returned in the event of a conversion error.
const: unstable · source§

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

Performs the conversion.