use super::super::*;
#[test]
fn test_index_calculator_macro_offset() {
let config = TilingConfig::cpu_avx2_matmul();
let calc = TcbIndexCalculator::new(config.clone(), 1024, 1024, 1024);
let (row, col) = calc.macro_tile_offset(0);
assert_eq!((row, col), (0, 0));
let (_row, col) = calc.macro_tile_offset(1);
assert_eq!(col, config.macro_tile.n);
}
#[test]
fn test_index_calculator_boundary() {
let config = TilingConfig::cpu_avx2_matmul();
let calc_large = TcbIndexCalculator::new(config.clone(), 512, 512, 256);
assert!(!calc_large.is_boundary_tile(0));
let calc_small = TcbIndexCalculator::new(config, 100, 100, 256);
assert!(calc_small.is_boundary_tile(0));
let (actual_m, actual_n) = calc_small.actual_tile_dims(0);
assert_eq!(actual_m, 100);
assert_eq!(actual_n, 100);
}
#[test]
fn test_pack_a_index() {
let idx = pack_a_index(0, 0, 4, 256, 64);
assert_eq!(idx, 0);
let idx = pack_a_index(1, 0, 4, 256, 64);
assert_eq!(idx, 1);
let idx = pack_a_index(0, 1, 4, 256, 64);
assert_eq!(idx, 4);
}
#[test]
fn test_swizzle_index() {
let idx0 = swizzle_index(0);
let idx32 = swizzle_index(32);
assert_ne!(idx0 % 32, idx32 % 32);
}
#[test]
fn test_optimal_prefetch_distance() {
let geom = TcbGeometry::new(4, 8, 64);
let dist = optimal_prefetch_distance(&geom, TcbLevel::Midi);
assert!(dist >= 1);
}
#[test]
fn test_odd_sized_matrices() {
let config = TilingConfig::cpu_avx2_matmul();
for (m, n, k) in [(127, 255, 513), (1, 1, 1), (7, 13, 31)] {
let calc = TcbIndexCalculator::new(config.clone(), m, n, k);
let num_tiles = calc.num_k_blocks();
assert!(num_tiles >= 1);
}
}
#[test]
fn test_tile_count_calculation() {
let config = TilingConfig::cpu_avx2_matmul();
let calc = TcbIndexCalculator::new(config.clone(), 1024, 1024, 1024);
let num_macro = calc.config.num_macro_tiles(1024, 1024);
let num_midi = calc.config.midi_tiles_per_macro();
let num_micro = calc.config.micro_tiles_per_midi();
assert!(num_macro > 0);
assert!(num_midi > 0);
assert!(num_micro > 0);
}
#[test]
fn test_single_element_matrix() {
let config = TilingConfig::cpu_avx2_matmul();
let calc = TcbIndexCalculator::new(config, 1, 1, 256);
assert!(calc.is_boundary_tile(0));
let (actual_m, actual_n) = calc.actual_tile_dims(0);
assert_eq!(actual_m, 1);
assert_eq!(actual_n, 1);
}
#[test]
fn test_prime_sized_matrices() {
let config = TilingConfig::cpu_avx2_matmul();
for size in [127, 251] {
let calc = TcbIndexCalculator::new(config.clone(), size, size, 256);
let num_tiles = config.num_macro_tiles(size, size);
assert!(num_tiles >= 1);
assert!(calc.is_boundary_tile(0));
}
let calc = TcbIndexCalculator::new(config.clone(), 509, 509, 256);
assert!(!calc.is_boundary_tile(0));
assert!(calc.is_boundary_tile(1));
}
#[test]
fn test_tile_offset_boundaries() {
let config = TilingConfig::cpu_avx2_matmul();
let calc = TcbIndexCalculator::new(config.clone(), 1000, 1000, 256);
let num_tiles = config.num_macro_tiles(1000, 1000);
let last_idx = num_tiles - 1;
let (row, col) = calc.macro_tile_offset(last_idx);
assert!(row < 1000 + config.macro_tile.m);
assert!(col < 1000 + config.macro_tile.n);
}
#[test]
fn test_index_calculator_consistency() {
let config = TilingConfig::cpu_avx2_matmul();
let calc = TcbIndexCalculator::new(config.clone(), 512, 512, 256);
let (r0, c0) = calc.macro_tile_offset(0);
assert_eq!((r0, c0), (0, 0));
let linear = calc.block_to_linear_offset(0, 512);
assert_eq!(linear, 0);
let a_off = calc.a_offset(0, 0);
let b_off = calc.b_offset(0, 0);
assert_eq!(a_off, 0);
assert_eq!(b_off, 0);
}
#[test]
fn test_index_calculator_midi_offset() {
let config = TilingConfig::cpu_avx2_matmul();
let calc = TcbIndexCalculator::new(config, 1024, 1024, 1024);
let (row, col) = calc.midi_tile_offset(0);
assert_eq!((row, col), (0, 0));
let (row1, col1) = calc.midi_tile_offset(1);
assert_eq!(row1, 0);
assert!(col1 > 0);
}
#[test]
fn test_index_calculator_micro_offset() {
let config = TilingConfig::cpu_avx2_matmul();
let calc = TcbIndexCalculator::new(config, 1024, 1024, 1024);
let (row, col) = calc.micro_tile_offset(0);
assert_eq!((row, col), (0, 0));
let (row1, col1) = calc.micro_tile_offset(1);
assert_eq!(row1, 0);
assert!(col1 > 0);
}
#[test]
fn test_pack_b_index() {
let idx = pack_b_index(0, 0, 8, 64, 64);
assert_eq!(idx, 0);
let idx = pack_b_index(0, 1, 8, 64, 64);
assert_eq!(idx, 1);
let idx = pack_b_index(1, 0, 8, 64, 64);
assert_eq!(idx, 8);
let idx = pack_b_index(0, 8, 8, 64, 64);
assert_eq!(idx, 512);
}
#[test]
fn test_index_calculator_k_blocks() {
let config = TilingConfig::cpu_avx2_matmul();
let calc = TcbIndexCalculator::new(config.clone(), 512, 512, 1024);
assert_eq!(calc.num_k_blocks(), 4);
let calc2 = TcbIndexCalculator::new(config, 512, 512, 300);
assert_eq!(calc2.num_k_blocks(), 2);
}
#[test]
fn test_ab_offset_calculations() {
let config = TilingConfig::cpu_avx2_matmul();
let calc = TcbIndexCalculator::new(config.clone(), 512, 512, 512);
let a_off = calc.a_offset(1, 0); assert_eq!(a_off, (config.macro_tile.m * 512) as usize);
let b_off = calc.b_offset(0, 1); assert_eq!(b_off, config.macro_tile.n as usize);
}
#[test]
fn test_prefetch_all_levels() {
let geom = TcbGeometry::new(4, 8, 64);
let dist_micro = optimal_prefetch_distance(&geom, TcbLevel::Micro);
let dist_midi = optimal_prefetch_distance(&geom, TcbLevel::Midi);
let dist_macro = optimal_prefetch_distance(&geom, TcbLevel::Macro);
assert!(dist_macro >= dist_midi);
assert!(dist_midi >= dist_micro);
assert!(dist_micro >= 1);
}
#[test]
fn test_prefetch_locality_debug() {
let loc = PrefetchLocality::T0;
let debug = format!("{:?}", loc);
assert!(debug.contains("T0"));
let loc2 = PrefetchLocality::NonTemporal;
let debug2 = format!("{:?}", loc2);
assert!(debug2.contains("NonTemporal"));
}