首页 > 解决方案 > Rust 中的安全并行高斯消元

问题描述

我正在尝试并行化高斯消除的实现。我知道像 rayon 这样的 crate 可能会使这更容易,但我的目标是使用基于 mpsc::channel 的实现,所以我选择使用 threadpool

这是代码库的概述。有些功能是多余的,但是这段代码是从 C 移植过来的,所以我尝试维护结构。

传递过来的数据结构包含矩阵的大小(冗余)、矩阵、四个验证向量(用来判断正确性)和线程数:

pub struct Data {
    pub nsize: usize,
    pub matrix: Vec<Vec<f64>>,
    pub b: Vec<f64>,
    pub c: Vec<f64>,
    pub v: Vec<f64>,
    pub swap: Vec<u64>,
    pub num_threads: usize,
}

顺序算法:

pub fn compute_gauss(data: &mut Data) {
    for i in 0..data.nsize {
        pivot(data, i);

        let mut pivot_val;

        for j in i + 1..data.nsize {
            pivot_val = data.matrix[j][i];
            data.matrix[j][i] = 0.0;
            for k in i + 1..data.nsize {
                data.matrix[j][k] -= pivot_val * data.matrix[i][k];
            }
            data.b[j] -= pivot_val * data.b[i];
        }
    }
}

pivot(matrix,index)函数改变数据中的矩阵

我当前的并行高斯实现:

pub fn compute_gauss_p(data: Data) -> Data {
    let num_threads = data.num_threads;
    let pool = ThreadPool::new(data.num_threads);
    let nsize = data.nsize;
    let sdata = Arc::new(data);

    for i in 0..nsize {
        pivot(&mut *sdata, i); //compile error, as Arc does not implement DerefMut
        for n in 0..num_threads {
            let sdatacpy = Arc::clone(&sdata);
            pool.execute(move || {
                do_calc(sdatacpy, i + n);
            });
        }
        pool.join();
    }

    Arc::try_unwrap(sdata).unwrap()
}
fn do_calc(data: Arc<Data>, i: usize) { //cannot derefence mut from Arc
    let mut pivot_val;
    let num_threads = data.num_threads; 
    for j in (i + 1..data.matrix.len()).step_by(num_threads) {
        pivot_val = data.matrix[j][i];
        data.matrix[j][i] = 0.0;
        for k in i + 1..data.matrix.len() {
            data.matrix[j][k] -= pivot_val * data.matrix[i][k];
        }
        data.b[j] -= pivot_val * data.b[i];
    }
}

我曾考虑过使用互斥锁来排除矩阵,但这会使工作顺序化。我的下一个想法是将矩阵视为互斥体的向量,每个向量都包含一行。这样我就可以分工。矩阵将是:

Vec<Mutex<Vec<f64>>>

但是,我想知道这是否是正确的路径。我想避免使用不安全的指针引用(我可以只使用我的 C 版本),同时继续使用具有 mpsc::channel 的范例(没有人造丝或其他不使用通道的库)。

标签: rustparallel-processinglinear-algebra

解决方案


推荐阅读