use celox::SimulatorBuilder;
#[path = "test_utils/mod.rs"]
#[macro_use]
#[allow(unused_macros)]
mod test_utils;
fn process_cpu_time() -> std::time::Duration {
#[cfg(unix)]
unsafe {
let mut usage: libc::rusage = std::mem::zeroed();
assert_eq!(libc::getrusage(libc::RUSAGE_SELF, &mut usage), 0);
std::time::Duration::from_micros(
(usage.ru_utime.tv_sec as u64) * 1_000_000
+ usage.ru_utime.tv_usec as u64
+ (usage.ru_stime.tv_sec as u64) * 1_000_000
+ usage.ru_stime.tv_usec as u64,
)
}
#[cfg(not(unix))]
{
use std::sync::OnceLock;
static START: std::sync::OnceLock<std::time::Instant> = std::sync::OnceLock::new();
START.get_or_init(std::time::Instant::now).elapsed()
}
}
fn load_sorter_sources() -> String {
[
include_str!("fixtures/sorter_tree/sorter_item.veryl"),
include_str!("fixtures/sorter_tree/dist_entry.veryl"),
include_str!("fixtures/sorter_tree/min_reduction_tree.veryl"),
include_str!("fixtures/sorter_tree/linear_sorter_pull.veryl"),
include_str!("fixtures/sorter_tree/linear_sorter.veryl"),
include_str!("fixtures/sorter_tree/sorter_tree.veryl"),
]
.join("\n")
}
fn build_sorter(n: u64) -> std::time::Duration {
let code = load_sorter_sources();
let start = process_cpu_time();
SimulatorBuilder::new(&code, "SorterTreeDistEntry")
.param("N", n)
.param("LEAF_DEPTH", 4)
.param("OUT_DEPTH", 16)
.build()
.unwrap();
process_cpu_time() - start
}
#[test]
fn sorter_tree_compilation_scales() {
let t4 = build_sorter(4);
let t8 = build_sorter(8);
let t16 = build_sorter(16);
let t32 = build_sorter(32);
let t64 = build_sorter(64);
let t128 = build_sorter(128);
let ratio_4_8 = t8.as_secs_f64() / t4.as_secs_f64();
let ratio_16_64 = t64.as_secs_f64() / t16.as_secs_f64();
let ratio_32_128 = t128.as_secs_f64() / t32.as_secs_f64();
println!(
"SorterTreeDistEntry compile CPU times: N=4 {t4:?}, N=8 {t8:?}, N=16 {t16:?}, \
N=32 {t32:?}, N=64 {t64:?}, N=128 {t128:?}; ratios: \
N=8/N=4 {ratio_4_8:.2}x, N=64/N=16 {ratio_16_64:.2}x, \
N=128/N=32 {ratio_32_128:.2}x"
);
assert!(
ratio_4_8 < 4.0,
"N=8/N=4 ratio is {ratio_4_8:.2}x, expected < 4.0x (linear scaling)"
);
assert!(
ratio_16_64 < 10.0,
"N=64/N=16 ratio is {ratio_16_64:.2}x, expected < 10.0x"
);
assert!(
ratio_32_128 < 12.0,
"N=128/N=32 ratio is {ratio_32_128:.2}x, expected < 12.0x"
);
}