#cuda #open-cl #arrays #deep-learning #array-manipulation

custos

A minimal OpenCL, CUDA and host CPU array manipulation engine / framework

11 unstable releases (3 breaking)

Uses new Rust 2021

new 0.4.5 Aug 14, 2022
0.4.4 Aug 7, 2022
0.4.0 Jul 31, 2022
0.3.0 Jul 29, 2022
0.1.1 Jun 28, 2022

#32 in Machine learning

Download history 22/week @ 2022-06-20 27/week @ 2022-06-27 6/week @ 2022-07-04 76/week @ 2022-07-11 79/week @ 2022-07-18 122/week @ 2022-07-25 173/week @ 2022-08-01 61/week @ 2022-08-08

454 downloads per month
Used in 2 crates

MIT license

140KB
4K SLoC

custos logo


Crates.io version Docs

A minimal OpenCL, CUDA and host CPU array manipulation engine / framework written in Rust. This crate provides the tools for executing custom array operations with the CPU, as well as with CUDA and OpenCL devices.
This guide demonstrates how operations can be implemented for the compute devices: implement_operations.md
or to see it at a larger scale, look here: custos-math

Installation

Add "custos" as a dependency:

[dependencies]
custos = "0.4.5"

# to disable the default features (cuda, opencl) and use an own set of features:
#custos = {version = "0.4.5", default-features=false, features=["opencl"]}

Available features:

  • "opencl" ... adds OpenCL features, where the CLDevice (feature) is the most important one.
  • "cuda" ... adds CUDA features. (CudaDevice)
  • "realloc" ... disables caching for all devices.
  • using no features at all ... CPU with BLAS

Examples

These examples show how to use the implemented operations.
custos only implements three buffer operations. These would be the write, read, and clear operations.
On the other hand, custos-math implements a lot more operations, including Matrix operations for a custom Matrix struct.
If you want to implement your own operations for all compute devices, look here: implement_operations.md

Using the host CPU as the compute device:

cpu_readme.rs

use custos::{Buffer, ClearBuf, VecRead, CPU};

fn main() {
    let device = CPU::new();
    let mut a = Buffer::from((&device, [1, 2, 3, 4, 5, 6]));

    // specify device for operation
    device.clear(&mut a);
    assert_eq!(device.read(&a), [0; 6]);

    let device = CPU::new();

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

    // no need to specify the device
    a.clear();
    assert_eq!(a.read(), vec![0; 6]);
}

Using an OpenCL device as the compute device:

cl_readme.rs

use custos::{Buffer, CLDevice};

fn main() -> custos::Result<()> {
    let device = CLDevice::new(0)?;

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

    assert_eq!(a.read(), [0; 6]);
    Ok(())
}

Using a CUDA device as the compute device:

cuda_readme.rs

use custos::{Buffer, CudaDevice};

fn main() -> custos::Result<()> {
    let device = CudaDevice::new(0)?;

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

    assert_eq!(a.read(), [0; 6]);
    Ok(())
}

A lot more examples can be found in the 'tests' and 'examples' folder.

Dependencies