diff --git a/Cargo.lock b/Cargo.lock index c86a244..5bbfa80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -299,6 +299,7 @@ dependencies = [ "criterion", "getset", "itertools 0.12.0", + "ndarray", "num", "rand", "serde", @@ -307,12 +308,35 @@ dependencies = [ "thiserror", ] +[[package]] +name = "matrixmultiply" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +dependencies = [ + "autocfg", + "rawpointer", +] + [[package]] name = "memchr" version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +[[package]] +name = "ndarray" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "rawpointer", +] + [[package]] name = "num" version = "0.4.1" @@ -507,6 +531,12 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rayon" version = "1.8.0" diff --git a/Cargo.toml b/Cargo.toml index 6de2db9..22566c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,3 +27,8 @@ rand = "0.8.5" criterion = "0.5.1" serde_json = "1.0.108" static_assertions = "1.1.0" +ndarray = "0.15.6" + +[[bench]] +name = "manifold_benchmark" +harness = false diff --git a/benches/manifold_benchmark.rs b/benches/manifold_benchmark.rs new file mode 100644 index 0000000..c88f9d2 --- /dev/null +++ b/benches/manifold_benchmark.rs @@ -0,0 +1,60 @@ +use manifold::*; +use rand::Rng; +use criterion::Throughput; +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; + +fn random_tensor_r2_manifold() -> Tensor { + let mut rng = rand::thread_rng(); + let mut tensor = tensor!([[0.0; 1000]; 1000]); + for i in 0..tensor.len() { + tensor[i] = rng.gen(); + } + tensor +} + +fn random_tensor_r2_ndarray() -> ndarray::Array2 { + let mut rng = rand::thread_rng(); + let (rows, cols) = (1000, 1000); + let mut tensor = ndarray::Array2::::zeros((rows, cols)); + for i in 0..rows { + for j in 0..cols { + tensor[[i, j]] = rng.gen(); + } + } + tensor +} + +fn tensor_product(c: &mut Criterion) { + let b = 1000; + + let mut group = c.benchmark_group("element-wise addition"); + + for (i, size) in [b].iter().enumerate() { + group.throughput(Throughput::Elements(*size as u64)); + + group.bench_with_input(BenchmarkId::new("manifold", size), &i, |b, _| { + b.iter(|| { + let a = random_tensor_r2_manifold(); + let b = random_tensor_r2_manifold(); + let c = a + b; + assert!(c.shape().as_array() == &[1000, 1000]); + }) + }); + + group.bench_with_input(BenchmarkId::new("ndarray", size), &i, |b, _| { + b.iter(|| { + let a = random_tensor_r2_ndarray(); + let b = random_tensor_r2_ndarray(); + let c = a + b; + assert!(c.shape() == &[1000, 1000]); + }) + }); + } + group.finish(); +} + +criterion_group!( + benches, + tensor_product +); +criterion_main!(benches); \ No newline at end of file