6 个版本
0.2.1 | 2024年6月5日 |
---|---|
0.2.0 | 2024年5月31日 |
0.1.0 | 2024年5月22日 |
0.0.3 | 2023年11月26日 |
#137 in 并发
308 每月下载量
97KB
1.5K SLoC
paradis
paradis
目前处于早期、实验阶段。为了更容易地迭代整体设计,故意降低了测试覆盖率。非常欢迎社区反馈!
paradis
通过提供更高层次的抽象,使得实现需要访问类似多维数组的数据结构子集的非平凡并行算法变得更加容易。
- 用于对集合中的独立记录进行非同步访问的低级、不安全抽象。
- 在低级不安全基础层之上构建的更高层次抽象,允许在安全代码中或使用最小的不安全代码表达许多并行访问模式。
低级抽象由非常轻量级的 paradis-core
crate 提供。鼓励库作者仅依赖于这个 crate 来暴露其数据结构以进行并行访问。
请查看文档以获取有关如何使用 paradis
的更多信息。
示例
此处提供的示例只是为了让您了解 API。请查看文档以获取更多上下文。
使用索引列表进行安全并行迭代
以下示例展示了如何使用 paradis
安全地并行迭代位于切片中任意索引处的可变元素。
use paradis::index::{IndexList, narrow_access};
use paradis::rayon::create_par_iter;
use rayon::iter::ParallelIterator;
let mut data = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let indices = vec![4, 7, 1].check_unique().expect("Indices are unique");
let access = narrow_access(data.as_mut_slice(), &indices)
.expect("Indices are in bounds of the data structure");
create_par_iter(access).for_each(|x_i| *x_i = 0);
assert_eq!(data, vec![0, 0, 2, 3, 0, 5, 6, 0, 8, 9]);
结构化索引列表
对于某些问题,索引是结构化的。在这种情况下,我们可能能够避免运行时唯一性检查,而是通过结构化构造和使用索引组合子来证明唯一性。下面的示例展示了结构化唯一性如何使我们能够修改矩阵的超对角线。
use nalgebra::dmatrix;
use paradis::index::{IndexList, narrow_access};
use paradis::rayon::create_par_iter;
use rayon::iter::ParallelIterator;
// Access implementation omitted
use paradis_demo::DMatrixParAccessMut;
let mut matrix = dmatrix![1, 1, 1, 1, 1;
1, 1, 1, 1, 1;
1, 1, 1, 1, 1];
// Superdiagonal indices are [(0, 1), (1, 2), (2, 3)]
let superdiagonal_indices = (0 .. 3).index_zip(1 .. 4);
let access = DMatrixParAccessMut::from_matrix_mut(&mut matrix);
let superdiagonal_access = narrow_access(access, &superdiagonal_indices)
.expect("Indices are in bounds");
create_par_iter(superdiagonal_access).for_each(|x_ij| *x_ij = 0);
assert_eq!(matrix,
dmatrix![1, 0, 1, 1, 1;
1, 1, 0, 1, 1;
1, 1, 1, 0, 1]);
低级不安全并行访问
paradis
的更高级特性建立在它的低级 并行访问 抽象之上。以下示例展示了我们如何使用谨慎的不同步访问在不同的线程中修改切片的偶数和奇数部分。
use paradis_core::{BoundedParAccess, IntoParAccess};
use std::thread::scope;
let mut data = vec![0; 100];
let n = data.len();
let access = data.into_par_access();
scope(|s| {
s.spawn(|| {
// The first thread touches elements at even indices
for i in (0 .. n).step_by(2) {
unsafe { *access.get_unsync(i) = 1; }
}
});
s.spawn(|| {
// The second thread touches elements at odd indices
for i in (1 .. n).step_by(2) {
unsafe { *access.get_unsync(i) = 2; }
}
});
})
贡献
paradis
是开源的,欢迎贡献。您可以通过几种方式来贡献
- 通过尝试在您的应用程序中使用
paradis
并在 论坛 上分享您的使用经验。 - 通过提交有关错误、改进想法或对设计的担忧等问题的 问题。
- 通过修复错误、改进文档或作为拉取请求的一部分贡献新功能。请注意,并非所有新功能都将被接受。在投入大量时间开发新功能之前,请提交一个问题以查看该功能是否可能被接受。
请记住,paradis
并非专业开发。尽管我,@Andlon,有跟进问题和PR的每项意图,但生活有时会干预,有时会持续很长时间。
许可证
paradis
根据您选择,以MIT许可证或Apache许可证(版本2.0)的条款分发。有关详细信息,请参阅 LICENSE-APACHE
和 LICENSE-MIT
。
通过向此存储库贡献知识产权,您同意以相同的条款许可您的贡献。
依赖项
~0–265KB