From 0e682585530c032e2228fb3bc2ed17e113d3c340 Mon Sep 17 00:00:00 2001 From: WoojinLee Date: Thu, 26 Oct 2023 06:06:08 +0000 Subject: [PATCH] modify script --- .../assignment13/small_exercises.rs | 3 + .../assignment13/small_exercises_grade.rs | 91 +++++++++++++------ 2 files changed, 64 insertions(+), 30 deletions(-) diff --git a/src/assignments/assignment13/small_exercises.rs b/src/assignments/assignment13/small_exercises.rs index 893bba0..f37e52a 100644 --- a/src/assignments/assignment13/small_exercises.rs +++ b/src/assignments/assignment13/small_exercises.rs @@ -5,6 +5,9 @@ use rayon::prelude::*; +// Use this function if you want. +use crate::assignments::assignment09::matmul::dot_product; + /// Returns the sum of `f(v)` for all element `v` the given array. /// /// # Exmaple diff --git a/src/assignments/assignment13/small_exercises_grade.rs b/src/assignments/assignment13/small_exercises_grade.rs index 494acd9..72318d5 100644 --- a/src/assignments/assignment13/small_exercises_grade.rs +++ b/src/assignments/assignment13/small_exercises_grade.rs @@ -72,13 +72,26 @@ mod test { } #[test] - fn vec_add_test() { + fn vec_add_correctness() { + // small test let vec1 = vec![1.0, 2.0, 3.0, 4.0, 5.0]; let vec2 = vec![1.0, 2.0, 3.0, 4.0, 5.0]; - let res = vec_add(&vec1, &vec2); + let res = vec_add_par(&vec1, &vec2); assert_eq!(res, vec![2.0, 4.0, 6.0, 8.0, 10.0]); - for _ in 0..5 { + // random test + let vec1 = Array::random(1000, Uniform::new(0., 10.)); + let vec2 = Array::random(1000, Uniform::new(0., 10.)); + + let res_par = vec_add_par(vec1.as_slice().unwrap(), vec2.as_slice().unwrap()); + + let ans = vec1 + vec2; + assert_eq!(Array::from_vec(res_par), ans); + } + + #[test] + fn vec_add_test_performance() { + for _ in 0..2 { let vec1 = Array::random(500000, Uniform::new(0., 10.)); let vec2 = Array::random(500000, Uniform::new(0., 10.)); @@ -90,23 +103,30 @@ mod test { let res_par = vec_add_par(vec1.as_slice().unwrap(), vec2.as_slice().unwrap()); let elapsed_par = now_par.elapsed(); - let ans = vec1 + vec2; - assert_eq!(Array::from_vec(res_seq), ans); - assert_eq!(Array::from_vec(res_par), ans); assert!(elapsed_par < elapsed_seq); } } #[test] - fn dot_product_test() { + fn dot_product_correctness() { + // small test let vec1 = vec![1.0, 2.0, 3.0, 4.0, 5.0]; let vec2 = vec![1.0, 2.0, 3.0, 4.0, 5.0]; - let res_seq = dot_product(&vec1, &vec2); let res_par = dot_product_par(&vec1, &vec2); - assert_eq!(res_seq, 55.0); assert_eq!(res_par, 55.0); - for _ in 0..5 { + // random test + let vec1 = Array::random(1000, Uniform::new(0., 10.)); + let vec2 = Array::random(1000, Uniform::new(0., 10.)); + + let res_par = dot_product_par(vec1.as_slice().unwrap(), vec2.as_slice().unwrap()); + + let _res = relative_eq!(res_par, vec1.dot(&vec2), epsilon = f64::EPSILON); + } + + #[test] + fn dot_product_performance() { + for _ in 0..2 { let vec1 = Array::random(1000000, Uniform::new(0., 10.)); let vec2 = Array::random(1000000, Uniform::new(0., 10.)); @@ -118,8 +138,6 @@ mod test { let res_par = dot_product_par(vec1.as_slice().unwrap(), vec2.as_slice().unwrap()); let elapsed_par = now_par.elapsed(); - let _res = relative_eq!(res_seq, vec1.dot(&vec2), epsilon = f64::EPSILON); - let _res = relative_eq!(res_par, vec1.dot(&vec2), epsilon = f64::EPSILON); assert!(elapsed_par < elapsed_seq); } } @@ -145,7 +163,8 @@ mod test { } #[test] - fn matmul_test() { + fn matmul_correctness() { + // small case let mat1 = vec![vec![1.0, 2.0, 3.0], vec![4.0, 5.0, 6.0]]; let mat2 = vec![ vec![7.0, 8.0, 9.0], @@ -157,15 +176,40 @@ mod test { vec![50.0, 68.0, 86.0, 104.0], vec![122.0, 167.0, 212.0, 257.0], ]; - let res_seq = matmul(&mat1, &mat2); let res_par = matmul_par(&mat1, &mat2); - assert_eq!(ans, res_seq); assert_eq!(ans, res_par); - for _ in 0..5 { + let mat1 = Array::random((10, 10), Uniform::new(0., 10.)); + let mat2 = Array::random((10, 10), Uniform::new(0., 10.)); + let ans = mat1.dot(&mat2); + let mat2_transposed = mat2.t(); + + // Run parallel matrix multiplication + let now_par = Instant::now(); + let res_par = matmul_par( + mat1.axis_iter(Axis(0)) + .map(|row| row.to_vec()) + .collect::>() + .as_slice(), + mat2_transposed + .axis_iter(Axis(0)) + .map(|row| row.to_vec()) + .collect::>() + .as_slice(), + ); + let elapsed_par = now_par.elapsed(); + + for it in ans.iter().zip(vec_to_array(res_par).iter()) { + let (ans, par) = it; + let _res = relative_eq!(ans, par); + } + } + + #[test] + fn matmul_performance() { + for _ in 0..2 { let mat1 = Array::random((500, 500), Uniform::new(0., 10.)); let mat2 = Array::random((500, 500), Uniform::new(0., 10.)); - let ans = mat1.dot(&mat2); let mat2_transposed = mat2.t(); // Run sequential matrix multiplication @@ -198,19 +242,6 @@ mod test { ); let elapsed_par = now_par.elapsed(); - // Check answer - for it in ans.iter().zip(vec_to_array(res_seq).iter()) { - let (ans, seq) = it; - let _res = relative_eq!(ans, seq); - } - for it in ans.iter().zip(vec_to_array(res_par).iter()) { - let (ans, par) = it; - let _res = relative_eq!(ans, par); - } - - // Check time - // println!("Sequential: {:?}", elapsed_seq); - // println!("Parallel: {:?}", elapsed_par); assert!(elapsed_par < elapsed_seq); } }