p3_matrix/
util.rs

1use p3_maybe_rayon::prelude::*;
2use p3_util::{log2_strict_usize, reverse_bits_len};
3use tracing::instrument;
4
5use crate::dense::RowMajorMatrix;
6use crate::Matrix;
7
8#[instrument(level = "debug", skip_all)]
9pub fn reverse_matrix_index_bits<F: Clone + Send + Sync>(mat: &mut RowMajorMatrix<F>) {
10    let w = mat.width();
11    let h = mat.height();
12    let log_h = log2_strict_usize(h);
13    let values = mat.values.as_mut_ptr() as usize;
14
15    (0..h).into_par_iter().for_each(|i| {
16        let values = values as *mut F;
17        let j = reverse_bits_len(i, log_h);
18        if i < j {
19            unsafe { swap_rows_raw(values, w, i, j) };
20        }
21    });
22}
23
24/// Assumes `i < j`.
25pub fn swap_rows<F: Clone + Send + Sync>(mat: &mut RowMajorMatrix<F>, i: usize, j: usize) {
26    let w = mat.width();
27    let (upper, lower) = mat.values.split_at_mut(j * w);
28    let row_i = &mut upper[i * w..(i + 1) * w];
29    let row_j = &mut lower[..w];
30    row_i.swap_with_slice(row_j);
31}
32
33/// Assumes `i < j`.
34///
35/// SAFETY: The caller must ensure `i < j < h`, where `h` is the height of the matrix.
36pub(crate) unsafe fn swap_rows_raw<F>(mat: *mut F, w: usize, i: usize, j: usize) {
37    let row_i = core::slice::from_raw_parts_mut(mat.add(i * w), w);
38    let row_j = core::slice::from_raw_parts_mut(mat.add(j * w), w);
39    row_i.swap_with_slice(row_j);
40}