#simd #nan #ndarray #array #index #traits #max

argminmax

ArgMinMax (1 个函数中的 argmin & argmax) 支持 SIMD 浮点数和整数

11 个不稳定版本

0.6.2 2024年3月4日
0.6.1 2023年4月14日
0.5.0 2023年3月23日
0.4.0 2023年2月13日
0.1.1 2022年10月2日

#64算法

Download history 17593/week @ 2024-04-08 19160/week @ 2024-04-15 18064/week @ 2024-04-22 13923/week @ 2024-04-29 16181/week @ 2024-05-06 19881/week @ 2024-05-13 19243/week @ 2024-05-20 24530/week @ 2024-05-27 24025/week @ 2024-06-03 24946/week @ 2024-06-10 27980/week @ 2024-06-17 29244/week @ 2024-06-24 30142/week @ 2024-07-01 27837/week @ 2024-07-08 31226/week @ 2024-07-15 35131/week @ 2024-07-22

126,729 每月下载量
用于 146 个 crate(通过 polars-ops

MIT 许可证

475KB
9K SLoC

ArgMinMax

高效的 argmin & argmax(1 个函数)支持 SIMD(SSE、AVX(2)、AVX5121、NEON1)⚡

🚀 函数是泛型类型,因此可以用于 &[T]Vec<T>,其中 T 可以是 f162f322f643i8i16i32i64u8u16u32u64

🤝 该 trait 对 sliceVec、1D ndarray::ArrayBase4、apache arrow::PrimitiveArray5arrow2::PrimitiveArray6 进行了实现。

运行时 CPU 功能检测 用于选择当前 CPU 上最有效的实现。这意味着相同的二进制文件可以在不同的 CPU 上使用,无需重新编译。

👀 SIMD 实现不包含 if 检查,确保函数的运行时间与其输入数据的顺序无关(最佳情况 = 最坏情况 = 平均情况)。

🪄 对f16和uint的高效支持:通过(双射即对称)位运算,f16(可选1)和uints转换为有序整数,允许使用整数SIMD指令。

1 对于 AVX512 和大多数 NEON,您应该启用(默认)"nightly_simd" 功能(需要nightly Rust)。
2 对于 f16,您应该启用 "half" 功能。
3 对于 f32f64,您应该启用(默认)"float" 功能。
4 对于 ndarray::ArrayBase,您应该启用 "ndarray" 功能。
5 对于 arrow::PrimitiveArray,您应该启用 "arrow" 功能。
6 对于 arrow2::PrimitiveArray,您应该启用 "arrow2" 功能。

安装

将以下内容添加到您的 Cargo.toml

[dependencies]
argminmax = "0.6.1"

示例用法

use argminmax::ArgMinMax;  // import trait

let arr: Vec<i32> = (0..200_000).collect();  // create a vector

let (min, max) = arr.argminmax();  // apply extension

println!("min: {}, max: {}", min, max);
println!("arr[min]: {}, arr[max]: {}", arr[min], arr[max]);

特质

ArgMinMax

实现了对 intsuintsfloats 的支持(如果启用了 "float" 功能)。

提供以下功能

  • argminmax:返回数组中最小和最大元素的索引。

处理NaN时,ArgMinMax 的函数会忽略NaN。更多信息请参阅 限制

NaNArgMinMax

实现了对 floats 的支持(如果启用了 "float" 功能)。

提供以下功能

  • nanargminmax:返回数组中最小和最大元素的索引。

处理NaN时,NaNArgMinMax 的函数返回第一个NaN的索引。更多信息请参阅 限制

提示 💡:如果您知道数组中没有NaN,我们建议您使用 ArgMinMax,因为这应该比 NaNArgMinMax 快5-30%。

功能

  • [默认] "nightly_simd":启用非稳定SIMD内嵌函数的使用(AVX512 和大多数 NEON),这些只在nightly Rust中可用。
  • [默认] "float":支持 f32f64 argminmax(使用NaN处理 - 见下文)。
  • "half":支持 f16 argminmax(通过使用 half crate)。
  • "ndarray":将 ArgMinMax 特质添加到 ndarrayArray1ArrayView1
  • "箭头":将 ArgMinMax 特性添加到 arrowPrimitiveArray

基准测试

在我的笔记本电脑上(AMD Ryzen 7 4800U,1.8 GHz,16GB RAM)使用 criterion 进行的基准测试表明,该函数的速度比标量实现快 3-20 倍(取决于数据类型)。

请参阅 /benches/results

使用以下命令运行基准测试

cargo bench --quiet --message-format=short --features half | grep "time:"

测试

要运行测试,请使用以下命令

cargo test --message-format=short --all-features

局限性

该库处理 NaN 值!🚀

一些(较小的)局限性

  • ArgMinMax 的函数忽略 NaN 值。
    • ❗ 当数组只包含 NaN 和/或无穷大时,可能会出现意外的行为(返回索引 0)。
  • NaNArgMinMax 的函数返回第一个 NaN 的索引(如果有的话)。
    • ❗ 当使用多个 NaN 的位表示时,不能保证返回第一个 NaN。

致谢

本库的一些部分受到了 minimalrustargmm 项目的杰出工作的启发。

依赖关系

~0.1–8.5MB
~67K SLoC