1- use savvy:: { savvy, NumericSexp , NumericTypedSexp , IntegerSexp , RealSexp , Sexp } ;
1+ use savvy:: { savvy, RealSexp } ;
22use std:: thread;
33
4- /// Calculate the sum of a vector of integers/doubles using multiple threads.
4+ /// Calculate the sum of a vector of real numbers using multiple threads.
55///
6- /// @param x A vector of integers/doubles to sum over.
6+ /// @param x A vector of real numbers to sum over.
77/// @param n The number of threads used to compute this calculation (int).
88///
99/// @return The sum of all elements of the input vector.
10- ///
11- /// @export
1210#[ savvy]
13- fn sum_with_threads ( x : NumericSexp , n : i32 ) -> savvy:: Result < savvy:: Sexp > {
14- match x. into_typed ( ) {
15- NumericTypedSexp :: Integer ( i) => sum_with_threads_int ( i, n) ,
16- NumericTypedSexp :: Real ( r) => sum_with_threads_rel ( r, n) ,
17- }
18- }
19-
20- fn sum_with_threads_int ( x : IntegerSexp , n : i32 ) -> savvy:: Result < Sexp > {
21- let x_rust = x. to_vec ( ) ;
22- let n_usize: usize = n as usize ;
23-
24- let out = sum_with_threads_int_impl ( x_rust, n_usize) ;
25- out. try_into ( )
26- }
27-
28- fn sum_with_threads_rel ( x : RealSexp , n : i32 ) -> savvy:: Result < Sexp > {
11+ fn sum_with_threads_real ( x : RealSexp , n : i32 ) -> savvy:: Result < savvy:: Sexp > {
2912 let x_rust = x. to_vec ( ) ;
30- let n_usize : usize = n as usize ;
13+ let n_size : usize = n as usize ;
3114
32- let out = sum_with_threads_rel_impl ( x_rust, n_usize ) ;
15+ let out = sum_with_threads_real_impl ( x_rust, n_size ) ;
3316 out. try_into ( )
3417}
3518
36- fn sum_with_threads_int_impl ( x : Vec < i32 > , n : usize ) -> i32 {
37- if x. is_empty ( ) {
38- eprintln ! ( "Input vector is empty. Returning 0." ) ;
39- return 0 ;
40- }
41-
42- let n = n. min ( x. len ( ) ) ;
43- let chunk_size = ( x. len ( ) + n - 1 ) / n;
44-
45- let mut handles = Vec :: new ( ) ;
46- for i in 0 ..n {
47- let chunk = x[ i * chunk_size..( ( i + 1 ) * chunk_size) . min ( x. len ( ) ) ] . to_vec ( ) ;
48- handles. push ( thread:: spawn ( move || chunk. iter ( ) . sum :: < i32 > ( ) ) ) ;
49- }
50-
51- let mut total_sum = 0 ;
52- for handle in handles {
53- total_sum += handle. join ( ) . expect ( "Thread panicked" ) ;
54- }
55-
56- total_sum
57- }
58-
59- fn sum_with_threads_rel_impl ( x : Vec < f64 > , n : usize ) -> f64 {
19+ fn sum_with_threads_real_impl ( x : Vec < f64 > , n : usize ) -> f64 {
6020 if x. is_empty ( ) {
6121 eprintln ! ( "Input vector is empty. Returning 0." ) ;
6222 return 0.0 ;
@@ -81,125 +41,65 @@ fn sum_with_threads_rel_impl(x: Vec<f64>, n: usize) -> f64 {
8141
8242#[ cfg( test) ]
8343mod tests {
84- use crate :: { sum_with_threads_int_impl , sum_with_threads_rel_impl } ;
44+ use crate :: sum_with_threads_real_impl ;
8545
86- /// Integers
46+ /// Real/doubles
8747 #[ test]
88- fn test_single_thread_int ( ) {
89- let numbers = vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
48+ fn test_single_thread_rel ( ) {
49+ let numbers = vec ! [ 1.0 , 2.0 , 3.0 , 4.0 , 5.0 ] ;
9050 let n = 1 ;
91- assert_eq ! ( sum_with_threads_int_impl ( numbers, n) , 15 ) ;
51+ assert_eq ! ( sum_with_threads_real_impl ( numbers, n) , 15.0 ) ;
9252 }
9353
9454 #[ test]
95- fn test_multiple_threads_int ( ) {
96- let x = vec ! [ 1 , 2 , 3 , 4 ] ;
55+ fn test_multiple_threads_rel ( ) {
56+ let x = vec ! [ 1.0 , 2.0 , 3.0 , 4.0 ] ;
9757 let num_threads = 2 ;
9858
99- let result = sum_with_threads_int_impl ( x, num_threads) ;
100- assert_eq ! ( result, 10 ) ;
59+ let result = sum_with_threads_real_impl ( x, num_threads) ;
60+ assert_eq ! ( result, 10.0 ) ;
10161 }
10262
10363 #[ test]
104- fn test_more_threads_than_elements_int ( ) {
105- let numbers = vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
64+ fn test_more_threads_than_elements_rel ( ) {
65+ let numbers = vec ! [ 1.0 , 2.0 , 3.0 , 4.0 , 5.0 ] ;
10666 let n = 10 ;
107- assert_eq ! ( sum_with_threads_int_impl ( numbers, n) , 15 ) ;
67+ assert_eq ! ( sum_with_threads_real_impl ( numbers, n) , 15.0 ) ;
10868 }
10969
11070 #[ test]
111- fn test_empty_vector_int ( ) {
112- let numbers: Vec < i32 > = vec ! [ ] ;
71+ fn test_empty_vector_rel ( ) {
72+ let numbers: Vec < f64 > = vec ! [ ] ;
11373 let n = 4 ;
114- assert_eq ! ( sum_with_threads_int_impl ( numbers, n) , 0 ) ;
74+ assert_eq ! ( sum_with_threads_real_impl ( numbers, n) , 0. 0) ;
11575 }
11676
11777 #[ test]
118- fn test_large_numbers_int ( ) {
119- let numbers = vec ! [ 1_000_000 , 2_000_000 , 3_000_000 ] ;
78+ fn test_large_numbers_rel ( ) {
79+ let numbers = vec ! [ 1_000_000.0 , 2_000_000.0 , 3_000_000.0 ] ;
12080 let n = 3 ;
121- assert_eq ! ( sum_with_threads_int_impl ( numbers, n) , 6_000_000 ) ;
81+ assert_eq ! ( sum_with_threads_real_impl ( numbers, n) , 6_000_000.0 ) ;
12282 }
12383
12484 #[ test]
125- fn test_negative_numbers_int ( ) {
126- let numbers = vec ! [ -1 , -2 , -3 , -4 , -5 ] ;
85+ fn test_negative_numbers_rel ( ) {
86+ let numbers = vec ! [ -1.0 , -2.0 , -3.0 , -4.0 , -5.0 ] ;
12787 let n = 2 ;
128- assert_eq ! ( sum_with_threads_int_impl ( numbers, n) , -15 ) ;
88+ assert_eq ! ( sum_with_threads_real_impl ( numbers, n) , -15.0 ) ;
12989 }
13090
13191 #[ test]
132- fn test_mixed_numbers_int ( ) {
133- let numbers = vec ! [ -1 , 2 , -3 , 4 , -5 , 6 ] ;
92+ fn test_mixed_numbers_rel ( ) {
93+ let numbers = vec ! [ -1.0 , 2.0 , -3.0 , 4.0 , -5.0 , 6.0 ] ;
13494 let n = 3 ;
135- assert_eq ! ( sum_with_threads_int_impl ( numbers, n) , 3 ) ;
95+ assert_eq ! ( sum_with_threads_real_impl ( numbers, n) , 3.0 ) ;
13696 }
13797
13898 #[ test]
139- fn test_large_vector_int ( ) {
140- let numbers: Vec < i32 > = ( 1 ..=1_000 ) . collect ( ) ;
99+ fn test_large_vector_rel ( ) {
100+ let numbers: Vec < f64 > = ( 1 ..=1000 ) . map ( |x| x as f64 ) . collect ( ) ;
141101 let n = 4 ;
142- let expected_sum: i32 = ( 1 ..= 1_000 ) . sum ( ) ;
143- assert_eq ! ( sum_with_threads_int_impl ( numbers, n) , expected_sum) ;
102+ let expected_sum: f64 = numbers . iter ( ) . sum ( ) ;
103+ assert_eq ! ( sum_with_threads_real_impl ( numbers, n) , expected_sum) ;
144104 }
145105}
146-
147- /// Real/doubles
148- #[ test]
149- fn test_single_thread_rel ( ) {
150- let numbers = vec ! [ 1.0 , 2.0 , 3.0 , 4.0 , 5.0 ] ;
151- let n = 1 ;
152- assert_eq ! ( sum_with_threads_rel_impl( numbers, n) , 15.0 ) ;
153- }
154-
155- #[ test]
156- fn test_multiple_threads_rel ( ) {
157- let x = vec ! [ 1.0 , 2.0 , 3.0 , 4.0 ] ;
158- let num_threads = 2 ;
159-
160- let result = sum_with_threads_rel_impl ( x, num_threads) ;
161- assert_eq ! ( result, 10.0 ) ;
162- }
163-
164- #[ test]
165- fn test_more_threads_than_elements_rel ( ) {
166- let numbers = vec ! [ 1.0 , 2.0 , 3.0 , 4.0 , 5.0 ] ;
167- let n = 10 ;
168- assert_eq ! ( sum_with_threads_rel_impl( numbers, n) , 15.0 ) ;
169- }
170-
171- #[ test]
172- fn test_empty_vector_rel ( ) {
173- let numbers: Vec < f64 > = vec ! [ ] ;
174- let n = 4 ;
175- assert_eq ! ( sum_with_threads_rel_impl( numbers, n) , 0 ) ;
176- }
177-
178- #[ test]
179- fn test_large_numbers_rel ( ) {
180- let numbers = vec ! [ 1_000_000 , 2_000_000 , 3_000_000 ] ;
181- let n = 3 ;
182- assert_eq ! ( sum_with_threads_rel_impl( numbers, n) , 6_000_000 ) ;
183- }
184-
185- #[ test]
186- fn test_negative_numbers_rel ( ) {
187- let numbers = vec ! [ -1.0 , -2.0 , -3.0 , -4.0 , -5.0 ] ;
188- let n = 2 ;
189- assert_eq ! ( sum_with_threads_rel_impl( numbers, n) , -15.0 ) ;
190- }
191-
192- #[ test]
193- fn test_mixed_numbers_rel ( ) {
194- let numbers = vec ! [ -1.0 , 2.0 , -3.0 , 4.0 , -5.0 , 6.0 ] ;
195- let n = 3 ;
196- assert_eq ! ( sum_with_threads_rel_impl( numbers, n) , 3.0 ) ;
197- }
198-
199- #[ test]
200- fn test_large_vector_rel ( ) {
201- let numbers: Vec < f64 > = ( 1 ..=1_000 ) . collect ( ) ;
202- let n = 4 ;
203- let expected_sum: i32 = ( 1 ..=1_000 ) . sum ( ) ;
204- assert_eq ! ( sum_with_threads_rel_impl( numbers, n) , expected_sum) ;
205- }
0 commit comments