// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. //! Benchmarks use criterion::*; use mwa_rust_core::{c64, pos::xyz, HADec, Jones, XyzGeodetic}; use ndarray::{Array1, Array3}; #[inline] fn mul(j1: [c64; 4], j2: [c64; 4]) -> [c64; 4] { [ j1[0] * j2[0] + j1[1] * j2[2], j1[0] * j2[1] + j1[1] * j2[3], j1[2] * j2[0] + j1[3] * j2[2], j1[2] * j2[1] + j1[3] * j2[3], ] } #[inline] fn mul2(j1: &[c64; 4], j2: &[c64; 4]) -> [c64; 4] { [ j1[0] * j2[0] + j1[1] * j2[2], j1[0] * j2[1] + j1[1] * j2[3], j1[2] * j2[0] + j1[3] * j2[2], j1[2] * j2[1] + j1[3] * j2[3], ] } fn misc(c: &mut Criterion) { // Is the parallel xyzs_to_uvws really worth it? c.bench_function("xyzs_to_uvws", |b| { // The values are irrelevant. let xyzs = vec![XyzGeodetic::default(); 8128]; let phase_centre = HADec::new(0.0, -27.0); b.iter(|| xyz::xyzs_to_uvws(&xyzs, phase_centre)) }); c.bench_function("xyzs_to_uvws_parallel", |b| { // The values are irrelevant. let xyzs = vec![XyzGeodetic::default(); 8128]; let phase_centre = HADec::new(0.0, -27.0); b.iter(|| xyz::xyzs_to_uvws_parallel(&xyzs, phase_centre)) }); // Sanity check that allocating Jones has no overhead compared to [f64; // 8]. c.bench_function("allocating many Jones", |b| { b.iter(|| { let shape = (20, 8128, 384); let _a: Array3> = Array3::from_elem(shape, Jones::default()); }) }); c.bench_function("allocating many [c64; 4]", |b| { b.iter(|| { let shape = (20, 8128, 384); let _a: Array3<[c64; 4]> = Array3::from_elem(shape, [c64::new(0.0, 0.0); 4]); }) }); // Sanity check that multiplying Jones has no overhead compared to // multiplying [c64; 4]. c.bench_function("multiply Jones", |b| { let i = c64::new(1.0, 2.0); let j1 = Jones::from([i, i + 1.0, i + 2.0, i + 3.0]); let j2 = Jones::from([i * 2.0, i * 3.0, i * 4.0, i * 5.0]); b.iter(|| { let _j3 = black_box(j1 * j2); }) }); c.bench_function("multiply [c64; 4]", |b| { let i = c64::new(1.0, 2.0); let j1 = [i, i + 1.0, i + 2.0, i + 3.0]; let j2 = [i * 2.0, i * 3.0, i * 4.0, i * 5.0]; b.iter(|| { let _j3 = black_box(mul(j1, j2)); }) }); c.bench_function("multiply Array1>", |b| { let i = c64::new(1.0, 2.0); let a1 = Array1::from_elem(1000000, Jones::from([i, i + 1.0, i + 2.0, i + 3.0])); let a2 = Array1::from_elem(1000000, Jones::from([i * 2.0, i * 3.0, i * 4.0, i * 5.0])); b.iter(|| { let _a3 = black_box(&a1 * &a2); }) }); c.bench_function("multiply Array1<[c64; 4]>", |b| { let i = c64::new(1.0, 2.0); let a1 = Array1::from_elem(1000000, [i, i + 1.0, i + 2.0, i + 3.0]); let a2 = Array1::from_elem(1000000, [i * 2.0, i * 3.0, i * 4.0, i * 5.0]); b.iter(|| { let _a3: Array1<[c64; 4]> = a1 .iter() .zip(a2.iter()) .map(|(a1, a2)| black_box(mul2(a1, a2))) .collect(); }) }); } criterion_group!(benches, misc); criterion_main!(benches);