From 0ffe8a89a4409b63cce686597ec43a5e97614bdf Mon Sep 17 00:00:00 2001 From: "sweep-ai[bot]" <128439645+sweep-ai[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:35:24 +0000 Subject: [PATCH 1/5] feat: Implement Linpack benchmark in Rust --- rust/linpack/Linpack.rs | 52 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 rust/linpack/Linpack.rs diff --git a/rust/linpack/Linpack.rs b/rust/linpack/Linpack.rs new file mode 100644 index 0000000..a702a95 --- /dev/null +++ b/rust/linpack/Linpack.rs @@ -0,0 +1,52 @@ +use std::time::{Duration, Instant}; + +const ARRAY_SIZE: usize = 2000; + +struct LinpackResult { + norma: f64, + residual: f64, + normalised_residual: f64, + epsilon: f64, + time: f64, + mflops: f64, +} + +fn second() -> f64 { + let now = Instant::now(); + now.elapsed().as_secs_f64() +} + +// Placeholder for utility functions (matgen, lran, dgefa, dgesl, daxpy, ddot, dscal, idamax) +// These functions will be implemented following the logic from the Go, JavaScript, and PHP versions, +// adapted to Rust's syntax and idioms. + +fn linpack(array_size: usize) -> LinpackResult { + // Implementation of the linpack benchmark, utilizing the utility functions. + // This function will closely follow the logic of the Go version, adapted to Rust. + // The calculation logic, including matrix generation, factorization, and solving, + // will be implemented here. + + // Placeholder for the linpack calculation logic + + LinpackResult { + norma: 0.0, + residual: 0.0, + normalised_residual: 0.0, + epsilon: 0.0, + time: 0.0, + mflops: 0.0, + } +} + +fn main() { + let start_time = Instant::now(); + let result = linpack(ARRAY_SIZE); + let duration = start_time.elapsed(); + + println!("Linpack Result: {:?}", result); + println!("Execution time: {:?}", duration); +} + +// Placeholder for unit tests +// Comprehensive unit tests will be implemented for all functions, covering all edge cases. +// Rust's built-in test framework will be used for this purpose. From dfb80a38d7cf7d131b38d0b05826e089c63a29ac Mon Sep 17 00:00:00 2001 From: "sweep-ai[bot]" <128439645+sweep-ai[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:35:53 +0000 Subject: [PATCH 2/5] feat: Updated rust/benchmark.yml --- rust/benchmark.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/benchmark.yml b/rust/benchmark.yml index 33d544f..abfc6bc 100644 --- a/rust/benchmark.yml +++ b/rust/benchmark.yml @@ -13,3 +13,4 @@ strategy: - collatz/MaxSequence - mandelbrot/Simple + - linpack/Linpack From a4a4277bdf1f90adfe81d5eb759b5ff915ae8bc5 Mon Sep 17 00:00:00 2001 From: "sweep-ai[bot]" <128439645+sweep-ai[bot]@users.noreply.github.com> Date: Fri, 26 Apr 2024 15:34:41 +0000 Subject: [PATCH 3/5] feat: Updated 2 files --- rust/benchmark.yml | 2 +- rust/linpack/Linpack.rs | 287 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 271 insertions(+), 18 deletions(-) diff --git a/rust/benchmark.yml b/rust/benchmark.yml index abfc6bc..76370bb 100644 --- a/rust/benchmark.yml +++ b/rust/benchmark.yml @@ -10,7 +10,7 @@ strategy: - primes/Simple - primes/Atkin - - collatz/MaxSequence + - collatz/MaxSequence - mandelbrot/Simple - linpack/Linpack diff --git a/rust/linpack/Linpack.rs b/rust/linpack/Linpack.rs index a702a95..7c6964f 100644 --- a/rust/linpack/Linpack.rs +++ b/rust/linpack/Linpack.rs @@ -16,28 +16,197 @@ fn second() -> f64 { now.elapsed().as_secs_f64() } -// Placeholder for utility functions (matgen, lran, dgefa, dgesl, daxpy, ddot, dscal, idamax) -// These functions will be implemented following the logic from the Go, JavaScript, and PHP versions, -// adapted to Rust's syntax and idioms. +use rand::Rng; + +fn matgen(a: &mut Vec>, b: &mut Vec, n: usize) { + assert_eq!(a.len(), n); + assert_eq!(a[0].len(), n); + assert_eq!(b.len(), n); + + let mut rng = rand::thread_rng(); + for i in 0..n { + for j in 0..n { + a[i][j] = rng.gen(); + } + b[i] = rng.gen(); + } +} + +fn lran(seed: &mut i32) -> f64 { + const MULTIPLIER: i32 = 1366; + const ADDEND: i32 = 150889; + const PMOD: i32 = 714025; + + *seed = (*seed * MULTIPLIER + ADDEND) % PMOD; + (*seed as f64) / PMOD as f64 - 0.5 +} + +fn dgefa(a: &mut Vec>, ipvt: &mut Vec, n: usize) { + for k in 0..n-1 { + let mut imax = k; + let mut amax = a[k][k].abs(); + for i in k+1..n { + let abs = a[i][k].abs(); + if abs > amax { + imax = i; + amax = abs; + } + } + ipvt[k] = imax; + if amax == 0.0 { + panic!("Singular matrix"); + } + if imax != k { + a.swap(imax, k); + } + for i in k+1..n { + a[i][k] /= a[k][k]; + for j in k+1..n { + a[i][j] -= a[i][k] * a[k][j]; + } + } + } + ipvt[n-1] = n-1; + if a[n-1][n-1] == 0.0 { + panic!("Singular matrix"); + } +} + +fn dgesl(a: &Vec>, ipvt: &Vec, b: &mut Vec, n: usize) { + for kb in 0..n { + let k = n - (kb + 1); + let l = ipvt[k]; + let t = b[l]; + b[l] = b[k]; + b[k] = t; + for i in (k+1)..n { + b[i] -= a[i][k] * t; + } + } + for kb in 0..n { + let k = n - (kb + 1); + b[k] /= a[k][k]; + let t = -b[k]; + for i in 0..k { + b[i] += a[i][k] * t; + } + } +} + +fn daxpy(n: usize, da: f64, dx: &[f64], incx: usize, dy: &mut [f64], incy: usize) { + let mut ix = 0; + let mut iy = 0; + for _ in 0..n { + dy[iy] += da * dx[ix]; + ix += incx; + iy += incy; + } +} + +fn ddot(n: usize, dx: &[f64], incx: usize, dy: &[f64], incy: usize) -> f64 { + let mut ix = 0; + let mut iy = 0; + let mut dot = 0.0; + for _ in 0..n { + dot += dx[ix] * dy[iy]; + ix += incx; + iy += incy; + } + dot +} + +fn dscal(n: usize, da: f64, dx: &mut [f64], incx: usize) { + let mut ix = 0; + for _ in 0..n { + dx[ix] *= da; + ix += incx; + } +} + +fn idamax(n: usize, dx: &[f64], incx: usize) -> usize { + let mut ix = 0; + let mut imax = 0; + let mut dmax = 0.0; + for _ in 0..n { + let abs = dx[ix].abs(); + if abs > dmax { + imax = ix; + dmax = abs; + } + ix += incx; + } + imax +} fn linpack(array_size: usize) -> LinpackResult { - // Implementation of the linpack benchmark, utilizing the utility functions. - // This function will closely follow the logic of the Go version, adapted to Rust. - // The calculation logic, including matrix generation, factorization, and solving, - // will be implemented here. + let mut a = vec![vec![0.0; array_size]; array_size]; + let mut b = vec![0.0; array_size]; + let mut x = vec![0.0; array_size]; + let mut ipvt = vec![0; array_size]; + let mut norma = 0.0; + let mut resid = 0.0; + let mut residn = 0.0; + let mut eps = 0.0; + let mut time = 0.0; + let mut mflops = 0.0; + + let mut seed = 1325; + let mut kase = 0; + let mut n = array_size; - // Placeholder for the linpack calculation logic + while n <= array_size { + kase += 1; + matgen(&mut a, &mut b, n); + let start = second(); + dgefa(&mut a, &mut ipvt, n); + dgesl(&a, &ipvt, &mut b, n); + time += second() - start; + for i in 0..n { + x[i] = b[i]; + } + norma = 0.0; + for i in 0..n { + for j in 0..n { + norma = f64::max(norma, a[i][j].abs()); + } + } + for i in 0..n { + b[i] = 0.0; + for j in 0..n { + b[i] += a[i][j] * x[j]; + } + } + resid = 0.0; + for i in 0..n { + resid = f64::max(resid, (x[i] - b[i]).abs()); + } + eps = epslon(&1.0); + residn = resid / (n as f64 * norma * eps); + time = time / kase as f64; + mflops = 2.0 * n as f64 * n as f64 * n as f64 / 3.0 / 1e6 / time; + n += 1000; + } LinpackResult { - norma: 0.0, - residual: 0.0, - normalised_residual: 0.0, - epsilon: 0.0, - time: 0.0, - mflops: 0.0, + norma, + residual: resid, + normalised_residual: residn, + epsilon: eps, + time, + mflops, } } +fn epslon(x: &f64) -> f64 { + let mut a = 1.0; + let mut b = 1.0; + while (a + 1.0) != 1.0 { + b /= 2.0; + a = b + 1.0; + } + b * 2.0 +} + fn main() { let start_time = Instant::now(); let result = linpack(ARRAY_SIZE); @@ -47,6 +216,90 @@ fn main() { println!("Execution time: {:?}", duration); } -// Placeholder for unit tests -// Comprehensive unit tests will be implemented for all functions, covering all edge cases. -// Rust's built-in test framework will be used for this purpose. +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_matgen() { + let mut a = vec![vec![0.0; 3]; 3]; + let mut b = vec![0.0; 3]; + matgen(&mut a, &mut b, 3); + assert_eq!(a.len(), 3); + assert_eq!(a[0].len(), 3); + assert_eq!(b.len(), 3); + } + + #[test] + fn test_lran() { + let mut seed = 1325; + let r = lran(&mut seed); + assert!(r >= -0.5 && r < 0.5); + } + + #[test] + fn test_dgefa() { + let mut a = vec![ + vec![1.0, 2.0, 3.0], + vec![4.0, 5.0, 6.0], + vec![7.0, 8.0, 9.0], + ]; + let mut ipvt = vec![0; 3]; + dgefa(&mut a, &mut ipvt, 3); + assert_eq!(ipvt, vec![2, 2, 2]); + } + + #[test] + fn test_dgesl() { + let a = vec![ + vec![1.0, 2.0, 3.0], + vec![4.0, 5.0, 6.0], + vec![7.0, 8.0, 9.0], + ]; + let ipvt = vec![2, 2, 2]; + let mut b = vec![1.0, 2.0, 3.0]; + dgesl(&a, &ipvt, &mut b, 3); + assert_eq!(b, vec![-0.5, 1.0, 0.0]); + } + + #[test] + fn test_daxpy() { + let mut dy = vec![1.0, 2.0, 3.0]; + let dx = vec![1.0, 2.0, 3.0]; + daxpy(3, 2.0, &dx, 1, &mut dy, 1); + assert_eq!(dy, vec![3.0, 6.0, 9.0]); + } + + #[test] + fn test_ddot() { + let dx = vec![1.0, 2.0, 3.0]; + let dy = vec![1.0, 2.0, 3.0]; + let dot = ddot(3, &dx, 1, &dy, 1); + assert_eq!(dot, 14.0); + } + + #[test] + fn test_dscal() { + let mut dx = vec![1.0, 2.0, 3.0]; + dscal(3, 2.0, &mut dx, 1); + assert_eq!(dx, vec![2.0, 4.0, 6.0]); + } + + #[test] + fn test_idamax() { + let dx = vec![1.0, 2.0, 3.0]; + let imax = idamax(3, &dx, 1); + assert_eq!(imax, 2); + } + + #[test] + fn test_linpack() { + let result = linpack(100); + assert!(result.norma > 0.0); + assert!(result.residual > 0.0); + assert!(result.normalised_residual > 0.0); + assert!(result.epsilon > 0.0); + assert!(result.time > 0.0); + assert!(result.mflops > 0.0); + } +} From 20b9b4d03a27b86727ee7c01f537df3ca1342d7e Mon Sep 17 00:00:00 2001 From: "sweep-ai[bot]" <128439645+sweep-ai[bot]@users.noreply.github.com> Date: Fri, 26 Apr 2024 16:02:40 +0000 Subject: [PATCH 4/5] feat: Updated 1 files --- rust/benchmark.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/rust/benchmark.yml b/rust/benchmark.yml index 76370bb..96f5ce6 100644 --- a/rust/benchmark.yml +++ b/rust/benchmark.yml @@ -5,6 +5,15 @@ strategy: command: - title: 'Rust' command: './%s' + + benchmark: + - primes/Simple + - primes/Atkin + + - collatz/MaxSequence + + - mandelbrot/Simple + - linpack/Linpack files: - primes/Simple @@ -13,4 +22,3 @@ strategy: - collatz/MaxSequence - mandelbrot/Simple - - linpack/Linpack From d919b0203e4d2bb8262ba9698591ae89ac0f948b Mon Sep 17 00:00:00 2001 From: "sweep-ai[bot]" <128439645+sweep-ai[bot]@users.noreply.github.com> Date: Fri, 26 Apr 2024 16:20:34 +0000 Subject: [PATCH 5/5] feat: Updated 1 files --- rust/benchmark.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/benchmark.yml b/rust/benchmark.yml index 96f5ce6..6aed7c3 100644 --- a/rust/benchmark.yml +++ b/rust/benchmark.yml @@ -13,6 +13,7 @@ strategy: - collatz/MaxSequence - mandelbrot/Simple + - linpack/Linpack files: