From 019e0f3bea9d99390761fe0ab28a3edd1f9cb7d5 Mon Sep 17 00:00:00 2001 From: Axect Date: Sat, 19 Oct 2024 14:55:13 +0900 Subject: [PATCH] FIX: Move all parallels into `parallel` feature (#72) --- Cargo.toml | 13 ++++------- src/lib.rs | 1 + src/structure/matrix.rs | 49 +++++++++++++++++++++++------------------ src/structure/vector.rs | 21 +++++++++++++----- src/traits/fp.rs | 2 ++ 5 files changed, 49 insertions(+), 37 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 579192d3..8473744e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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"] @@ -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" diff --git a/src/lib.rs b/src/lib.rs index 916878b5..4ee752c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -209,4 +209,5 @@ pub mod util; #[cfg(feature = "complex")] pub mod complex; +#[cfg(feature = "parallel")] extern crate rayon; diff --git a/src/structure/matrix.rs b/src/structure/matrix.rs index 9cad5cfe..16d68478 100644 --- a/src/structure/matrix.rs +++ b/src/structure/matrix.rs @@ -610,6 +610,7 @@ 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}; @@ -617,7 +618,6 @@ 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}, @@ -625,6 +625,8 @@ use crate::traits::{ 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}, @@ -1342,27 +1344,6 @@ impl Matrix { mat } - /// From index operations in parallel - pub fn par_from_index(f: F, size: (usize, usize)) -> Matrix - where - F: Fn(usize, usize) -> G + Copy + Send + Sync, - G: Into, - { - 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::>() - }) - .collect::>(); - matrix(data, row, col, Row) - } - /// Matrix to `Vec>` /// /// To send `Matrix` to `inline-python` @@ -1480,6 +1461,28 @@ impl Matrix { let v: Vec = series.to_vec(); matrix(v, row, col, shape) } + + /// From index operations in parallel + #[cfg(feature = "parallel")] + fn par_from_index(f: F, size: (usize, usize)) -> Matrix + where + F: Fn(usize, usize) -> G + Copy + Send + Sync, + G: Into, + { + 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::>() + }) + .collect::>(); + matrix(data, row, col, Row) + } } // ============================================================================= @@ -1639,6 +1642,7 @@ impl Normed for Matrix { } } +#[cfg(feature = "parallel")] impl ParallelNormed for Matrix { type UnsignedScalar = f64; @@ -1716,6 +1720,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 { diff --git a/src/structure/vector.rs b/src/structure/vector.rs index 3f5e4630..068a66fe 100644 --- a/src/structure/vector.rs +++ b/src/structure/vector.rs @@ -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::ParalleIterator; 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, @@ -414,6 +417,7 @@ impl FPVector for Vec { } } +#[cfg(feature = "parallel")] impl ParallelFPVector for Vec { type Scalar = f64; @@ -516,6 +520,7 @@ where } /// Explicit version of `map` in parallel +#[cfg(feature = "parallel")] pub fn par_map(f: F, xs: &[T]) -> Vec where F: Fn(T) -> T + Send + Sync, @@ -537,7 +542,6 @@ where s = f(s, x); } s - // Parallel version: !unimplemented() } /// Explicit version of `zip_with` @@ -555,6 +559,7 @@ where } /// Explicit version of `zip_with` in parallel +#[cfg(feature = "parallel")] pub fn par_zip_with(f: F, xs: &[T], ys: &[T]) -> Vec where F: Fn(T, T) -> T + Send + Sync, @@ -588,6 +593,7 @@ impl MutFP for Vec { } } +#[cfg(feature = "parallel")] impl ParallelMutFP for Vec { type Scalar = f64; @@ -831,6 +837,7 @@ impl Normed for Vec { } } +#[cfg(feature = "parallel")] impl ParallelNormed for Vec { type UnsignedScalar = f64; @@ -896,6 +903,7 @@ impl InnerProduct for Vec { } } +#[cfg(feature = "parallel")] impl ParallelInnerProduct for Vec { fn par_dot(&self, rhs: &Self) -> f64 { #[cfg(feature = "O3")] @@ -959,6 +967,7 @@ impl VectorProduct for Vec { } } +#[cfg(feature = "parallel")] impl ParallelVectorProduct for Vec { fn par_cross(&self, other: &Self) -> Self { assert_eq!(self.len(), other.len()); diff --git a/src/traits/fp.rs b/src/traits/fp.rs index a0c58609..bedc8917 100644 --- a/src/traits/fp.rs +++ b/src/traits/fp.rs @@ -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; @@ -79,6 +80,7 @@ pub trait ParallelFPVector { } /// Functional Programming for Matrix in Parallel (Uses Rayon crate) +#[cfg(feature = "parallel")] pub trait ParallelFPMatrix { fn par_fmap(&self, f: F) -> Matrix where