#![allow(missing_docs)]
pub mod bound;
#[doc(hidden)]
pub mod thread {
use crate::*;
#[inline]
pub fn join_raw(op_a: impl Send + FnOnce(Par), op_b: impl Send + FnOnce(Par), parallelism: Par) {
fn implementation<'a>(op_a: &'a mut (dyn Send + FnMut(Par)), op_b: &'a mut (dyn Send + FnMut(Par)), parallelism: Par) {
match parallelism {
Par::Seq => {
(op_a(parallelism), op_b(parallelism));
},
#[cfg(feature = "rayon")]
Par::Rayon(n_threads) => {
let n_threads = n_threads.get();
if n_threads == 1 {
(op_a(Par::Seq), op_b(Par::Seq));
} else {
let parallelism = Par::Rayon(core::num::NonZeroUsize::new(n_threads - n_threads / 2).unwrap());
spindle::for_each(2, [op_a, op_b], |op| op(parallelism));
}
},
};
}
let mut op_a = Some(op_a);
let mut op_b = Some(op_b);
implementation(
&mut |parallelism| (op_a.take().unwrap())(parallelism),
&mut |parallelism| (op_b.take().unwrap())(parallelism),
parallelism,
)
}
pub struct Ptr<T>(pub *mut T);
unsafe impl<T> Send for Ptr<T> {}
unsafe impl<T> Sync for Ptr<T> {}
impl<T> Copy for Ptr<T> {}
impl<T> Clone for Ptr<T> {
#[inline]
fn clone(&self) -> Self {
*self
}
}
#[inline]
pub fn parallelism_degree(parallelism: Par) -> usize {
match parallelism {
Par::Seq => 1,
#[cfg(feature = "rayon")]
Par::Rayon(n_threads) => n_threads.get(),
}
}
#[inline]
pub fn par_split_indices(n: usize, idx: usize, chunk_count: usize) -> (usize, usize) {
let chunk_size = n / chunk_count;
let rem = n % chunk_count;
let idx_to_col_start = move |idx| {
if idx < rem { idx * (chunk_size + 1) } else { rem + idx * chunk_size }
};
let start = idx_to_col_start(idx);
let end = idx_to_col_start(idx + 1);
(start, end - start)
}
}
pub mod simd;
pub mod approx;