#parallel #indices #index #thread #disjoint

paradis-demo

paradis 的演示功能,不建议用于实际应用

1 个不稳定版本

0.1.0 2024年5月22日

#696并发

MIT/Apache

44KB
425

paradis

paradis crate paradis documentation

paradis 目前处于早期、实验阶段。为了便于迭代整体设计,故意降低了测试覆盖率。欢迎社区反馈!

paradis 通过提供更高级别的抽象,简化了需要访问类似多维数组的结构数据结构子集的非平凡并行算法的实现。

  1. 一个用于独立集合中独立记录的无同步访问的低级、不安全抽象。
  2. 在不可靠的基础层之上构建的高级抽象,允许在安全代码中表达许多并行访问模式,或使用最少的不可靠代码。

低级抽象由非常轻量级的 paradis-core crate 提供。鼓励库作者仅依赖于此 crate 以公开其数据结构以供并行访问。

请查看 文档 了解有关如何使用 paradis 的更多信息。

示例

这里提供的示例只是为了让您了解 API。请查看文档以获取更多上下文。

使用索引列表进行安全的并行迭代

以下示例展示了如何使用 paradis 安全地并行迭代位于切片中任意索引处的可变元素。

use paradis::index::{IndexList, narrow_access_to_indices};
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_to_indices(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_to_indices};
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_to_indices(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 是开源的,欢迎贡献。有多种方式您可以做出贡献

  1. 通过在您的应用程序中尝试 paradis 并在 论坛 中报告您的经验。
  2. 通过提交问题,如错误、改进想法或对设计的关注。
  3. 通过修复错误、改进文档或作为拉取请求的一部分贡献新功能。请注意,并非所有新功能都将被接受。在投入大量时间开发新功能之前,请提交一个问题以查看该功能是否可能被接受。

请注意,paradis不是专业开发的。尽管我,@Andlon,有跟进问题和PR的意图,但生活有时会干预,有时是长时间。

许可证

paradis根据您选择的条款在MIT许可证或Apache许可证(版本2.0)下分发。请参阅LICENSE-APACHELICENSE-MIT以获取详细信息。

通过向此存储库贡献知识产权,您同意根据相同条款许可您的贡献。

依赖项

~3MB
~57K SLoC