use super::*;
#[test]
fn test_total_memory_region_contiguous() {
let dims = [100usize];
let strides = [8u128];
let byte_strides: Vec<&[u128]> = vec![&strides];
let region = total_memory_region(&dims, &byte_strides);
assert_eq!(region, 832);
}
#[test]
fn test_compute_blocks_small() {
let dims = [10usize, 10];
let costs = [2isize, 2];
let strides = [8u128, 80];
let orders = [1usize, 2];
let byte_strides: Vec<&[u128]> = vec![&strides];
let stride_orders: Vec<&[usize]> = vec![&orders];
let blocks = compute_blocks(
&dims,
&costs,
&byte_strides,
&stride_orders,
BLOCK_MEMORY_SIZE,
);
assert_eq!(blocks, vec![10, 10]);
}
#[test]
fn test_compute_blocks_large() {
let dims = [1000usize, 1000];
let costs = [2isize, 2];
let strides = [8u128, 8000];
let orders = [1usize, 2];
let byte_strides: Vec<&[u128]> = vec![&strides];
let stride_orders: Vec<&[usize]> = vec![&orders];
let blocks = compute_blocks(
&dims,
&costs,
&byte_strides,
&stride_orders,
BLOCK_MEMORY_SIZE,
);
assert!(blocks[0] <= dims[0]);
assert!(blocks[1] <= dims[1]);
assert!(blocks[0] >= 1);
assert!(blocks[1] >= 1);
}
#[test]
fn test_compute_blocks_empty() {
let blocks = compute_blocks(&[], &[], &[], &[], BLOCK_MEMORY_SIZE);
assert!(blocks.is_empty());
}
#[test]
fn test_last_argmax_weighted_basic() {
assert_eq!(last_argmax_weighted(&[10, 5], &[2, 4]), Some(0));
}
#[test]
fn test_last_argmax_weighted_ties() {
assert_eq!(last_argmax_weighted(&[5, 5], &[2, 2]), Some(1));
}
#[test]
fn test_last_argmax_weighted_all_one() {
assert_eq!(last_argmax_weighted(&[1, 1, 1], &[1, 1, 1]), None);
}
#[test]
fn test_last_argmax_weighted_empty() {
assert_eq!(last_argmax_weighted(&[], &[]), None);
}
#[test]
fn test_total_memory_region_multi_array() {
let dims = [100usize, 100];
let s1 = [8u128, 800]; let s2 = [800u128, 8]; let byte_strides: Vec<&[u128]> = vec![&s1, &s2];
let region = total_memory_region(&dims, &byte_strides);
assert!(region > 0);
}
#[test]
fn test_total_memory_region_large_stride() {
let dims = [10usize, 10];
let strides = [8u128, 800]; let byte_strides: Vec<&[u128]> = vec![&strides];
let region = total_memory_region(&dims, &byte_strides);
assert!(region > 0);
}
#[test]
fn test_compute_blocks_min_stride_exceeds_block_size() {
let dims = [10usize, 10];
let costs = [1isize, 1];
let s1 = [100000u128, 1000000]; let s2 = [1000000u128, 100000]; let o1 = [0usize, 1];
let o2 = [1usize, 0]; let byte_strides: Vec<&[u128]> = vec![&s1, &s2];
let stride_orders: Vec<&[usize]> = vec![&o1, &o2];
let blocks = compute_blocks(&dims, &costs, &byte_strides, &stride_orders, 64);
assert_eq!(blocks, vec![1, 1]);
}
#[test]
fn test_compute_block_sizes_3d() {
let dims = [10usize, 20, 30];
let strides = [8isize, 80, 1600];
let strides_list: Vec<&[isize]> = vec![&strides];
let blocks = compute_block_sizes(&dims, &strides_list, 8);
assert_eq!(blocks.len(), 3);
for i in 0..3 {
assert!(blocks[i] >= 1 && blocks[i] <= dims[i]);
}
}
#[test]
fn test_compute_blocks_first_stride_order_matches() {
let dims = [4usize, 100, 100];
let costs = [1isize, 10, 10];
let strides = [8u128, 32, 3200];
let orders = [0usize, 1, 2];
let byte_strides: Vec<&[u128]> = vec![&strides];
let stride_orders: Vec<&[usize]> = vec![&orders];
let blocks = compute_blocks(
&dims,
&costs,
&byte_strides,
&stride_orders,
BLOCK_MEMORY_SIZE,
);
assert_eq!(blocks[0], 4);
}
mod oracle;
use oracle::{legacy_blocks, model_blocks, model_costs, LegacyCosts};
#[test]
fn compute_block_sizes_equals_the_exact_model_on_the_sweep() {
let (mut fits, mut overflows) = (0, 0);
for (dims, strides, elem_size) in oracle::sweep() {
let strides: Vec<&[isize]> = strides.iter().map(|s| s.as_slice()).collect();
let model = model_blocks(&dims, &strides, elem_size);
assert_eq!(
compute_block_sizes(&dims, &strides, elem_size),
model,
"{dims:?} {strides:?} e={elem_size}"
);
let costs: Vec<u128> = compute_costs(&strides).iter().map(|&c| c as u128).collect();
assert_eq!(costs, model_costs(&strides));
match legacy_blocks(&dims, &strides, elem_size, LegacyCosts::Unchecked) {
Some(legacy) => {
assert_eq!(legacy, model, "{dims:?} {strides:?} e={elem_size}");
fits += 1;
}
None => overflows += 1,
}
}
assert!(
fits > 0 && overflows > 0,
"{fits} fitting, {overflows} overflowing"
);
}
#[test]
fn costs_saturate_instead_of_overflowing() {
let dims = [1024usize, 1024];
let a = [1isize << 62, 1];
let b = [1isize << 62, 2];
assert_eq!(compute_costs(&[&a, &b]), [isize::MAX, 2]);
assert_eq!(compute_block_sizes(&dims, &[&a, &b], 1), [10, 1024]);
assert_eq!(model_blocks(&dims, &[&a, &b], 1), [10, 1024]);
assert_eq!(
legacy_blocks(&dims, &[&a, &b], 1, LegacyCosts::Unchecked),
None
);
assert_eq!(compute_costs(&[[isize::MIN, 1]]), [isize::MAX, 2]);
}
fn check(
dims: &[usize],
strides: &[&[isize]],
elem_size: usize,
expected: &[usize],
legacy: Option<&[usize]>,
) {
assert_eq!(compute_block_sizes(dims, strides, elem_size), expected);
assert_eq!(model_blocks(dims, strides, elem_size), expected);
assert_eq!(
legacy_blocks(dims, strides, elem_size, LegacyCosts::Unchecked).as_deref(),
legacy
);
}
#[test]
fn the_traced_overflow_fixtures_follow_the_exact_model() {
let a = [8isize, 8, 8, 8, 8, 16];
let b = [8isize, 8, 8, 8, 16, 8];
check(
&[1024; 6],
&[&a, &b],
8,
&[1024, 1024, 1024, 1024, 16, 16],
None,
);
check(&[2, 8192], &[&[1, 2], &[1 << 61, 1]], 8, &[2, 1024], None);
check(
&[3, 8192],
&[&[1 << 61, 1], &[1 << 61, 2]],
1,
&[1, 8192],
None,
);
}
#[test]
fn a_zero_element_size_keeps_every_axis_for_any_operand_count() {
let mut strides = vec![vec![1isize, 2]; 512];
strides.push(vec![2, 1]);
let strides: Vec<&[isize]> = strides.iter().map(|s| s.as_slice()).collect();
check(&[2, 2], &strides, 0, &[2, 2], Some(&[2, 2]));
}
#[test]
fn tied_and_strictly_increasing_strides() {
let dst = [1isize, 64, 4096];
for src in [[0isize, 1, 1], [1, 1, 1]] {
check(
&[64, 64, 64],
&[&dst, &src],
8,
&[64, 31, 16],
Some(&[64, 31, 16]),
);
}
check(
&[3840, 4096],
&[&[1, 3840], &[1, 4096]],
8,
&[3840, 4096],
Some(&[3840, 4096]),
);
check(
&[4096, 4096],
&[&[1, 4096], &[-1, 4096]],
8,
&[4096, 4096],
Some(&[4096, 4096]),
);
}