use std::hint::black_box;
use std::time::Instant;
use strided_basic::{zip_map2_into, StridedView, StridedViewMut};
use strided_basic::{Exec, Pool};
const WARMUPS: usize = 4;
const SAMPLES: usize = 15;
const THREAD_COUNTS: [usize; 2] = [1, 4];
const SAMPLE_ELEMENTS: usize = 1 << 20;
fn repeats(elements: usize) -> usize {
(SAMPLE_ELEMENTS / elements.max(1)).max(1)
}
fn time_ms(repeats: usize, operation: &mut impl FnMut()) -> f64 {
let start = Instant::now();
for _ in 0..repeats {
operation();
}
start.elapsed().as_secs_f64() * 1e3 / repeats as f64
}
fn median(samples: &[f64]) -> f64 {
let mut ordered = samples.to_vec();
ordered.sort_by(f64::total_cmp);
ordered[ordered.len() / 2]
}
fn measure(label: &str, rows: usize, cols: usize, threads: usize) {
let dims = [rows, cols];
let out_strides = [1isize, rows as isize];
let broadcast_strides = [0isize, 1isize];
let peer_strides = [1isize, rows as isize];
let len = rows * cols;
let a: Vec<f64> = (0..cols).map(|c| c as f64 * 0.25 - 1.0).collect();
let b: Vec<f64> = (0..len).map(|index| (index % 17) as f64 - 8.0).collect();
let mut out = vec![0.0f64; len];
let pool = Pool::builder().threads(threads).build().unwrap();
{
{
let repeats = repeats(len);
let mut run = || {
let a_view = StridedView::<f64>::new(&a, &dims, &broadcast_strides, 0).unwrap();
let b_view = StridedView::<f64>::new(&b, &dims, &peer_strides, 0).unwrap();
let mut dest =
StridedViewMut::<f64>::new(&mut out, &dims, &out_strides, 0).unwrap();
zip_map2_into(
&mut dest,
&a_view,
&b_view,
|x, y| x + y,
Exec::new(&pool, threads).unwrap(),
)
.unwrap();
};
for _ in 0..WARMUPS {
run();
}
let mut samples = Vec::with_capacity(SAMPLES);
for _ in 0..SAMPLES {
samples.push(time_ms(repeats, &mut run));
}
let ms = median(&samples);
println!(
"SUMMARY f64 {threads}T n={len:<9} {label:<18} ms={ms:>9.4} ns/el={:>7.3}",
ms * 1e6 / len as f64,
);
};
};
}
fn main() {
println!("zip_map2_into with a stride-0 inner broadcast operand");
for threads in THREAD_COUNTS {
for (rows, cols) in [(1024usize, 64usize), (4096, 256), (1023, 67)] {
measure("broadcast_add", rows, cols, threads);
}
}
black_box(());
}