diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 2caab29..d08356c 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -2,17 +2,10 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - [[package]] name = "blazr" version = "0.1.0" dependencies = [ - "num-complex", "savvy", ] @@ -25,24 +18,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - [[package]] name = "once_cell" version = "1.20.2" @@ -80,7 +55,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cf7cda5d3886a972506ccaf904274b5ac6aed444ae0de9215b72465bc57c074" dependencies = [ "cc", - "num-complex", "once_cell", "rustversion", "savvy-ffi", @@ -103,9 +77,6 @@ name = "savvy-ffi" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc41ea3d0dcba6f162e7e7148e1f0dcc9ae6a7b480d24727b2b17f9500e4c2bc" -dependencies = [ - "num-complex", -] [[package]] name = "savvy-macro" diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index b1d0e68..8958fd3 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -1,4 +1,4 @@ -use savvy::{savvy, NumericSexp, Sexp}; +use savvy::{savvy, NumericSexp, NumericTypedSexp, IntegerSexp, RealSexp, Sexp}; use std::thread; /// Calculate the sum of a vector of integers using multiple threads. @@ -10,15 +10,53 @@ use std::thread; /// /// @export #[savvy] -fn sum_with_threads(x: NumericSexp, n: i32) -> savvy::Result { +fn sum_with_threads(x: NumericSexp, n: i32) -> savvy::Result { + match x.into_typed() { + NumericTypedSexp::Integer(i) => sum_with_threads_int(i,n), + NumericTypedSexp::Real(r) => sum_with_threads_rel(r, n), + } +} + +fn sum_with_threads_int(x: IntegerSexp, n: i32) -> savvy::Result { let x_rust = x.to_vec(); let n_usize: usize = n as usize; - let out = sum_with_threads_impl(x_rust, n_usize); + let out = sum_with_threads_int_impl(x_rust, n_usize); out.try_into() } -fn sum_with_threads_impl(x: Vec, n: usize) -> f64 { +fn sum_with_threads_rel(x: RealSexp, n: i32) -> savvy::Result { + let x_rust = x.to_vec(); + let n_usize: usize = n as usize; + + let out = sum_with_threads_rel_impl(x_rust, n_usize); + out.try_into() +} + +fn sum_with_threads_int_impl(x: Vec, n: usize) -> i32 { + if x.is_empty() { + eprintln!("Input vector is empty. Returning 0."); + return 0; + } + + let n = n.min(x.len()); + let chunk_size = (x.len() + n - 1) / n; + + let mut handles = Vec::new(); + for i in 0..n { + let chunk = x[i * chunk_size..((i + 1) * chunk_size).min(x.len())].to_vec(); + handles.push(thread::spawn(move || chunk.iter().sum::())); + } + + let mut total_sum = 0; + for handle in handles { + total_sum += handle.join().expect("Thread panicked"); + } + + total_sum +} + +fn sum_with_threads_rel_impl(x: Vec, n: usize) -> f64 { if x.is_empty() { eprintln!("Input vector is empty. Returning 0."); return 0.0; @@ -43,8 +81,9 @@ fn sum_with_threads_impl(x: Vec, n: usize) -> f64 { #[cfg(test)] mod tests { - use crate::sum_with_threads_impl; + use crate::{sum_with_threads_int_impl, sum_with_threads_rel_impl}; + // Integers #[test] fn test_single_thread() { let numbers = vec![1, 2, 3, 4, 5]; @@ -96,11 +135,6 @@ mod tests { assert_eq!(sum_with_threads_impl(numbers, n), 3); } - #[test] - fn test_doubles_numbers() { - let numbers = vec![-1.5, 2.0, -3.5, 4.0, -5.0, 6.5]; - let n = 3; - assert_eq!(sum_with_threads_impl(numbers, n), 2.5); } #[test]