Skip to content

Commit

Permalink
FIX: Move all parallels into parallel feature (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
Axect committed Oct 19, 2024
2 parents 1ee62dc + a0bcb33 commit ec47ac7
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 49 deletions.
13 changes: 4 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,14 @@ anyhow = "1.0"
paste = "1.0"
#num-complex = "0.3"
netcdf = { version = "0.7", optional = true, default-features = false }
pyo3 = { version = "0.22", optional = true, features = [
"auto-initialize",
"gil-refs",
] }
pyo3 = { version = "0.22", optional = true, features = ["auto-initialize", "gil-refs"] }
blas = { version = "0.22", optional = true }
lapack = { version = "0.19", optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }
json = { version = "0.12", optional = true }
arrow2 = { version = "0.18", features = [
"io_parquet",
"io_parquet_compression",
], optional = true }
arrow2 = { version = "0.18", features = ["io_parquet", "io_parquet_compression"], optional = true }
num-complex = { version = "0.4", optional = true }
rayon = "1.10"
rayon = { version = "1.10", optional = true }

[package.metadata.docs.rs]
rustdoc-args = ["--html-in-header", "katex-header.html", "--cfg", "docsrs"]
Expand All @@ -65,6 +59,7 @@ plot = ["pyo3"]
nc = ["netcdf"]
parquet = ["arrow2"]
complex = ["num-complex", "matrixmultiply/cgemm"]
parallel = ["rayon"]

[[bench]]
path = "benches/parallel_rayon/matrix_benchmark.rs"
Expand Down
7 changes: 7 additions & 0 deletions src/fuga/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,13 @@ pub use crate::traits::{
sugar::{Scalable, ScalableMut, VecOps, ConvToMat},
};

#[cfg(feature = "parallel")]
pub use crate::traits::{
fp::{ParallelFPVector, ParallelFPMatrix},
math::{ParallelInnerProduct, ParallelMatrixProduct, ParallelNormed, ParallelVector, ParallelVectorProduct},
mutable::ParallelMutFP,
};

#[allow(unused_imports)]
pub use crate::structure::{
matrix::*,
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,5 @@ pub mod util;
#[cfg(feature = "complex")]
pub mod complex;

#[cfg(feature = "parallel")]
extern crate rayon;
69 changes: 47 additions & 22 deletions src/structure/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,21 +610,23 @@ extern crate lapack;
use blas::{daxpy, dgemm, dgemv};
#[cfg(feature = "O3")]
use lapack::{dgecon, dgeqrf, dgesvd, dgetrf, dgetri, dgetrs, dorgqr, dpotrf};
#[cfg(feature = "parallel")]
use rayon::iter::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

pub use self::Shape::{Col, Row};
use crate::numerical::eigen::{eigen, EigenMethod};
use crate::structure::dataframe::{Series, TypedVector};
use crate::traits::math::{ParallelInnerProduct, ParallelNormed};
use crate::traits::sugar::ScalableMut;
use crate::traits::{
fp::{FPMatrix, FPVector},
general::Algorithm,
math::{InnerProduct, LinearOp, MatrixProduct, Norm, Normed, Vector},
mutable::MutMatrix,
};
#[cfg(feature = "parallel")]
use crate::traits::math::{ParallelInnerProduct, ParallelNormed};
use crate::util::{
low_level::{copy_vec_ptr, swap_vec_ptr},
non_macro::{cbind, eye, rbind, zeros},
Expand Down Expand Up @@ -1342,27 +1344,6 @@ impl Matrix {
mat
}

/// From index operations in parallel
pub fn par_from_index<F, G>(f: F, size: (usize, usize)) -> Matrix
where
F: Fn(usize, usize) -> G + Copy + Send + Sync,
G: Into<f64>,
{
let row = size.0;
let col = size.1;

let data = (0..row)
.into_par_iter()
.flat_map(|i| {
(0..col)
.into_par_iter()
.map(|j| f(i, j).into())
.collect::<Vec<f64>>()
})
.collect::<Vec<f64>>();
matrix(data, row, col, Row)
}

/// Matrix to `Vec<Vec<f64>>`
///
/// To send `Matrix` to `inline-python`
Expand Down Expand Up @@ -1480,6 +1461,28 @@ impl Matrix {
let v: Vec<f64> = series.to_vec();
matrix(v, row, col, shape)
}

/// From index operations in parallel
#[cfg(feature = "parallel")]
fn par_from_index<F, G>(f: F, size: (usize, usize)) -> Matrix
where
F: Fn(usize, usize) -> G + Copy + Send + Sync,
G: Into<f64>,
{
let row = size.0;
let col = size.1;

let data = (0..row)
.into_par_iter()
.flat_map(|i| {
(0..col)
.into_par_iter()
.map(|j| f(i, j).into())
.collect::<Vec<f64>>()
})
.collect::<Vec<f64>>();
matrix(data, row, col, Row)
}
}

// =============================================================================
Expand Down Expand Up @@ -1573,6 +1576,16 @@ impl Vector for Matrix {

impl Normed for Matrix {
type UnsignedScalar = f64;

/// Norm of Matrix
///
/// # Example
/// ```
/// use peroxide::fuga::*;
///
/// let a = ml_matrix("1 2;3 4");
/// assert_eq!(a.norm(Norm::F), (1f64 + 4f64 + 9f64 + 16f64).sqrt());
/// ```
fn norm(&self, kind: Norm) -> f64 {
match kind {
Norm::F => {
Expand Down Expand Up @@ -1639,9 +1652,20 @@ impl Normed for Matrix {
}
}

#[cfg(feature = "parallel")]
impl ParallelNormed for Matrix {
type UnsignedScalar = f64;

/// Parallel version of norm
///
/// # Example
/// ```
/// use peroxide::fuga::*;
///
/// let a = ml_matrix("1 2;3 4");
/// assert_eq!(a.par_norm(Norm::F), (1f64 + 4f64 + 9f64 + 16f64).sqrt());
/// ```
///
fn par_norm(&self, kind: Norm) -> f64 {
match kind {
Norm::F => {
Expand Down Expand Up @@ -1716,6 +1740,7 @@ impl InnerProduct for Matrix {
}

/// Frobenius inner product in parallel
#[cfg(feature = "parallel")]
impl ParallelInnerProduct for Matrix {
fn par_dot(&self, rhs: &Self) -> f64 {
if self.shape == rhs.shape {
Expand Down
21 changes: 15 additions & 6 deletions src/structure/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,13 +266,16 @@
extern crate blas;
#[cfg(feature = "O3")]
use blas::{daxpy, ddot, dnrm2, idamax};

use crate::rayon::prelude::*;
#[cfg(feature = "parallel")]
use crate::rayon::iter::{ParallelIterator, IntoParallelIterator, IntoParallelRefIterator, IndexedParallelIterator, IntoParallelRefMutIterator};

use crate::structure::matrix::{matrix, Matrix, Row};
use crate::traits::fp::ParallelFPVector;
use crate::traits::math::{ParallelInnerProduct, ParallelNormed, ParallelVectorProduct};
use crate::traits::mutable::ParallelMutFP;
#[cfg(feature = "parallel")]
use crate::traits::{
fp::ParallelFPVector,
math::{ParallelInnerProduct, ParallelNormed, ParallelVectorProduct},
mutable::ParallelMutFP,
};
use crate::traits::{
fp::FPVector,
general::Algorithm,
Expand Down Expand Up @@ -414,6 +417,7 @@ impl FPVector for Vec<f64> {
}
}

#[cfg(feature = "parallel")]
impl ParallelFPVector for Vec<f64> {
type Scalar = f64;

Expand Down Expand Up @@ -516,6 +520,7 @@ where
}

/// Explicit version of `map` in parallel
#[cfg(feature = "parallel")]
pub fn par_map<F, T>(f: F, xs: &[T]) -> Vec<T>
where
F: Fn(T) -> T + Send + Sync,
Expand All @@ -537,7 +542,6 @@ where
s = f(s, x);
}
s
// Parallel version: !unimplemented()
}

/// Explicit version of `zip_with`
Expand All @@ -555,6 +559,7 @@ where
}

/// Explicit version of `zip_with` in parallel
#[cfg(feature = "parallel")]
pub fn par_zip_with<F, T>(f: F, xs: &[T], ys: &[T]) -> Vec<T>
where
F: Fn(T, T) -> T + Send + Sync,
Expand Down Expand Up @@ -588,6 +593,7 @@ impl MutFP for Vec<f64> {
}
}

#[cfg(feature = "parallel")]
impl ParallelMutFP for Vec<f64> {
type Scalar = f64;

Expand Down Expand Up @@ -831,6 +837,7 @@ impl Normed for Vec<f64> {
}
}

#[cfg(feature = "parallel")]
impl ParallelNormed for Vec<f64> {
type UnsignedScalar = f64;

Expand Down Expand Up @@ -896,6 +903,7 @@ impl InnerProduct for Vec<f64> {
}
}

#[cfg(feature = "parallel")]
impl ParallelInnerProduct for Vec<f64> {
fn par_dot(&self, rhs: &Self) -> f64 {
#[cfg(feature = "O3")]
Expand Down Expand Up @@ -959,6 +967,7 @@ impl VectorProduct for Vec<f64> {
}
}

#[cfg(feature = "parallel")]
impl ParallelVectorProduct for Vec<f64> {
fn par_cross(&self, other: &Self) -> Self {
assert_eq!(self.len(), other.len());
Expand Down
26 changes: 15 additions & 11 deletions src/traits/fp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ pub trait FPMatrix {
}

/// Functional Programming tools for Vector in Parallel (Uses Rayon crate)
#[cfg(feature = "parallel")]
pub trait ParallelFPVector {
type Scalar;

Expand All @@ -79,21 +80,24 @@ pub trait ParallelFPVector {
}

/// Functional Programming for Matrix in Parallel (Uses Rayon crate)
#[cfg(feature = "parallel")]
pub trait ParallelFPMatrix {
fn par_fmap<F>(&self, f: F) -> Matrix
type Scalar;

fn par_fmap<F>(&self, f: F) -> Self
where
F: Fn(f64) -> f64 + Send + Sync;
fn par_reduce<F, T>(&self, init: T, f: F) -> f64
F: Fn(Self::Scalar) -> Self::Scalar + Send + Sync;
fn par_reduce<F, T>(&self, init: T, f: F) -> Self::Scalar
where
F: Fn(f64, f64) -> f64 + Send + Sync,
T: Into<f64> + Copy + Clone + Send + Sync;
fn par_zip_with<F>(&self, f: F, other: &Matrix) -> Matrix
F: Fn(Self::Scalar, Self::Scalar) -> Self::Scalar + Send + Sync,
T: Into<Self::Scalar> + Copy + Clone + Send + Sync;
fn par_zip_with<F>(&self, f: F, other: &Self) -> Self
where
F: Fn(f64, f64) -> f64 + Send + Sync;
fn par_col_reduce<F>(&self, f: F) -> Vec<f64>
F: Fn(Self::Scalar, Self::Scalar) -> Self::Scalar + Send + Sync;
fn par_col_reduce<F>(&self, f: F) -> Vec<Self::Scalar>
where
F: Fn(Vec<f64>) -> f64 + Send + Sync;
fn par_row_reduce<F>(&self, f: F) -> Vec<f64>
F: Fn(Vec<Self::Scalar>) -> Self::Scalar + Send + Sync;
fn par_row_reduce<F>(&self, f: F) -> Vec<Self::Scalar>
where
F: Fn(Vec<f64>) -> f64 + Send + Sync;
F: Fn(Vec<Self::Scalar>) -> Self::Scalar + Send + Sync;
}
7 changes: 6 additions & 1 deletion src/traits/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ impl Normed for f64 {
// =============================================================================

/// Mathematical Vector in Parallel
#[cfg(feature = "parallel")]
pub trait ParallelVector {
type Scalar;
fn par_add_vec(&self, rhs: &Self) -> Self;
Expand All @@ -111,22 +112,26 @@ pub trait ParallelVector {
}

/// Normed Vector in Parallel
#[cfg(feature = "parallel")]
pub trait ParallelNormed: Vector {
type UnsignedScalar;
fn par_norm(&self, kind: Norm) -> Self::UnsignedScalar;
}

/// Inner product Vector in Parallel
#[cfg(feature = "parallel")]
pub trait ParallelInnerProduct: ParallelNormed {
fn par_dot(&self, rhs: &Self) -> Self::Scalar;
}

/// Matrix Products in Parallel
#[cfg(feature = "parallel")]
pub trait ParallelMatrixProduct {
fn par_hadamard(&self, other: &Self) -> Matrix;
fn par_hadamard(&self, other: &Self) -> Self;
}

/// Vector Products in Parallel
#[cfg(feature = "parallel")]
pub trait ParallelVectorProduct: Vector {
fn par_cross(&self, other: &Self) -> Self;
}

0 comments on commit ec47ac7

Please sign in to comment.