#![feature(test)]
extern crate test;
use test::Bencher;
use ndarray::prelude::*;
use ndarray_einsum::*;
use ndarray_rand::RandomExt;
use rand::distributions::Uniform;
fn rand_array<Sh, D: Dimension>(shape: Sh) -> ArrayBase<ndarray::OwnedRepr<f64>, D>
where
Sh: ShapeBuilder<Dim = D>,
{
Array::random(shape, Uniform::new(-5., 5.))
}
#[bench]
fn bench_multiply_builtin_tiny(b: &mut Bencher) {
let m1 = rand_array((3, 4));
let m2 = rand_array((4, 5));
b.iter(|| m1.dot(&m2));
}
#[bench]
fn bench_multiply_tiny(b: &mut Bencher) {
let m1 = rand_array((3, 4));
let m2 = rand_array((4, 5));
b.iter(|| einsum("ij,jk->ik", &[&m1, &m2]));
}
#[bench]
fn bench_multiply_tiny_reuse_path(b: &mut Bencher) {
let m1 = rand_array((3, 4));
let m2 = rand_array((4, 5));
let ep = einsum_path("ij,jk->ik", &[&m1, &m2], OptimizationMethod::Naive).unwrap();
b.iter(|| ep.contract_operands(&[&m1, &m2]));
}
#[bench]
fn bench_multiply_builtin_medium(b: &mut Bencher) {
let m1 = rand_array((30, 40));
let m2 = rand_array((40, 50));
b.iter(|| m1.dot(&m2));
}
#[bench]
fn bench_multiply_medium(b: &mut Bencher) {
let m1 = rand_array((30, 40));
let m2 = rand_array((40, 50));
b.iter(|| einsum("ij,jk->ik", &[&m1, &m2]));
}
#[bench]
fn bench_multiply_builtin_large(b: &mut Bencher) {
let m1 = rand_array((300, 400));
let m2 = rand_array((400, 500));
b.iter(|| m1.dot(&m2));
}
#[bench]
fn bench_multiply_large(b: &mut Bencher) {
let m1 = rand_array((300, 400));
let m2 = rand_array((400, 500));
b.iter(|| einsum("ij,jk->ik", &[&m1, &m2]));
}
#[bench]
fn bench_hadamard_builtin_large(b: &mut Bencher) {
let m1 = rand_array((300, 400));
let m2 = rand_array((300, 400));
b.iter(|| (&m1 * &m2));
}
#[bench]
fn bench_hadamard_transpose_builtin_large(b: &mut Bencher) {
let m1 = rand_array((300, 400));
let m2 = rand_array((400, 300));
b.iter(|| (&m1 * &m2.t()));
}
#[bench]
fn bench_hadamard_large(b: &mut Bencher) {
let m1 = rand_array((300, 400));
let m2 = rand_array((300, 400));
b.iter(|| einsum("ij,ij->ij", &[&m1, &m2]));
}
#[bench]
fn bench_hadamard_transpose_large(b: &mut Bencher) {
let m1 = rand_array((300, 400));
let m2 = rand_array((400, 300));
b.iter(|| einsum("ij,ji->ij", &[&m1, &m2]));
}
#[bench]
fn bench_hadamard_transpose_large_reuse_path(b: &mut Bencher) {
let m1 = rand_array((300, 400));
let m2 = rand_array((400, 300));
let ep = einsum_path("ij,ji->ij", &[&m1, &m2], OptimizationMethod::Naive).unwrap();
b.iter(|| ep.contract_operands(&[&m1, &m2]));
}
#[bench]
fn bench_sum_builtin_huge(b: &mut Bencher) {
let m1 = rand_array((3000, 4000));
b.iter(|| m1.sum());
}
#[bench]
fn bench_sum_huge(b: &mut Bencher) {
let m1 = rand_array((3000, 4000));
b.iter(|| einsum("ij->", &[&m1]));
}
#[bench]
fn bench_outer_product_medium(b: &mut Bencher) {
let m1 = rand_array((300,));
let m2 = rand_array((400,));
b.iter(|| einsum("i,j->ij", &[&m1, &m2]));
}
#[bench]
fn bench_stacked_outer_product_medium(b: &mut Bencher) {
let m1 = rand_array((100, 30));
let m2 = rand_array((100, 40));
b.iter(|| einsum("ij,ik->ijk", &[&m1, &m2]));
}
#[bench]
fn bench_double_outer_product_medium(b: &mut Bencher) {
let m1 = rand_array((30, 10));
let m2 = rand_array((40, 10));
b.iter(|| einsum("ij,kl->lkij", &[&m1, &m2]));
}
#[bench]
fn bench_stacked_double_outer_product_large(b: &mut Bencher) {
let m1 = rand_array((50, 30, 10));
let m2 = rand_array((50, 40, 10));
b.iter(|| einsum("ijk,ilm->ijklm", &[&m1, &m2]));
}