#const-generics #linear-algebra #simd #matrix #specialization #no-std #bug

nightly no-std optimath

使用 const generics 实现无 std 和专用化以启用 SIMD 的线性代数

5 个版本 (3 个破坏性更新)

0.3.1 2021年6月22日
0.3.0 2020年1月13日
0.2.0 2020年1月5日
0.1.0 2020年1月1日
0.0.0 2019年12月28日

#1678 in 算法

每月下载量 33
用于 blasters

Apache-2.0

52KB
845

Optimath

一个使用 const generics 实现无 std 和专用化以启用 SIMD 的线性代数库。

*simd 由于编译器错误而受阻,但自动向量化工作良好。

注意:现在 nalgebra 支持const generics,并且比这个crate功能更全面。也许它更适合您的需求。

示例

逐元素相加

use optimath::{Vector, Stupidity};
use rand::{thread_rng, Rng};
let mut rng = thread_rng();

// Vectors can be initalized from an rng,
let a: Vector<i32, 2000> = rng.gen();
// from iterators
let b: Vector<i32, 2000> = (0..2000).collect();
// with an initalizer function
let c: Vector<i32, 2000> = Vector::build_with_fn(|i| i as i32);
// or using Default
let d: Vector<i32, 2000> = Default::default();

let e = &a + &b;
let f = &c + &d;
let h = &e + &f;

矩阵乘法

use optimath::Matrix;
let a: Matrix<f32, 2, 3> = Default::default();
let b: Matrix<f32, 3, 4> = Default::default();

// matrix size is checked at compile time!
let c: Matrix<f32, 2, 4> = a.matrix_multiply(&b);

设计

整个库都是围绕一个类型构建的,即 Vector,它表示类型为 T 的 N 个元素的向量。

如果 T 支持某些数学运算(如加法,实现 Add 特性),则 Vector 也支持逐元素操作。因此,Vector, M> 也支持加法,因为 Vector 是一个实现 Add 的类型。

因此,矩阵和张量只是向量中的向量(向量中的向量)

无 std

使用 const generics 来使向量能够包含任意(固定)数量的元素,因此不需要在堆上分配。

SIMD

向量为任何实现该操作的 T 提供通用的数学运算。专用化用于为特定的 T 提供优化的实现,例如浮点数和整数。

目前 SIMD 支持 已禁用,我们正在等待 rustc 修复一些 ICE :).

目标

除了作为一个希望有用的库外,它也是对 Rust 新的先进类型系统特性的探索。因此,明确的目标是为这些特性的开发者提供反馈。[见解] 模块包含一些这方面的内容。

它还旨在探索利用这些特性的线性代数库的设计空间。因此,它可能为更大的 linalg 库如何采用它们提供灵感。

变更日志(及未来)

0.1.0

  • 能够进行逐元素数学运算的 Vector 类型
  • 基本的线性代数操作
  • 为未来改进提供了坚实的基础设计

0.2.0

  • 支持 serde
  • 支持 rand

0.3.0(当前版本)

  • 将更多迭代转移到 ConstIterator
  • 添加 templatemetamaths(构建一个计算,然后逐元素构建结果)

0.X.0

  • 对架构进行一些重构,使得向量可以泛型地应用于容器
  • 对矩阵进行跨步迭代
  • 窗口函数

0.X.0

  • 在向量上使用SIMD(由于rust编译器的bug而受阻,但自动向量化工作得非常好)
  • 向量和矩阵上的附加操作(接受功能请求!)

0.X.0

  • 与动态大小向量交互
    • 在动态大小向量上使用窗口函数

0.X.0

  • 针对非常大的工作负载进行多线程

0.X.0

  • 为sse、avx和avx512提供完全优化的SIMD
  • 在向量、动态向量和向量视图中实现完全的SIMD

0.X.0

  • 一个与BLAS兼容的接口,包括一个C接口。可能基于这个接口在另一个crate中实现
  • 有2位额外的贡献者 :) 加入我们,一起享受关于奇怪的编译器bug和指针偏移计算的乐趣和烦恼

1.0.0

  • 在其他人的crate中使用/测试过,被认为是可用的

想法部分

目前该crate是从向量构建起来的,可以改为从维度“向下”构建。请参阅(私有)维度模块,了解该方案的草图。目前由于rust无法实际使用任何用于const泛型数组大小的计算而受阻。优点:使迭代/跨步迭代更容易,因为这仅仅是普通的指针数学。缺点:更难/不可能明确表达SIMD。

自动构建向量以准备SIMD和/或多处理。也由于同样的rust功能(计算数组大小)而受阻。请参阅(私有)布局模块的预览。我不确定这是否是必要的,因为当大小在编译时已知时,rust可以生成非常好的SIMD和展开。优点:每次在所有平台上都完美进行SIMD。缺点:工作负载更高,需要关注每个操作和每个平台。缺点:转置和跨步迭代变得更难

为了互操作性,最好表达事物是有大小还是无大小的。特别是对于矩阵乘法等维度,U x S(3) * S(3) x U = U x U 可能是一个常见的案例,即用未知数量但已知特性的列表进行自乘(这可能是由于同样的rust bug而受阻,但我尚未测试)

贡献

请将钩子符号链接到您的本地 .git/hooks/ 目录,以便在提交之前运行一些自动检查。

ln -s ../../hooks/pre-commit .git/hooks/

请安装rustfmt和cargo-sync-readme,以便运行这些检查。

rustup component add rustfmt
cargo install cargo-sync-readme

当您更改顶级文档时,请执行 cargo-sync-readme。当您更改代码时,请运行 cargo fmt。如果可能,请配置您的编辑器为您执行此操作。

依赖关系

~0.6–0.9MB
~17K SLoC