use cbtop::{matrix_working_set, CacheConfig, CacheLevel, WorkingSetAnalysis};
#[test]
fn f1121_l1_classification() {
let config = CacheConfig::default();
assert_eq!(config.classify(1024), CacheLevel::L1);
assert_eq!(config.classify(20 * 1024), CacheLevel::L1);
}
#[test]
fn f1121_l2_classification() {
let config = CacheConfig::default();
assert_eq!(config.classify(100 * 1024), CacheLevel::L2);
assert_eq!(config.classify(300 * 1024), CacheLevel::L2);
}
#[test]
fn f1121_l3_classification() {
let config = CacheConfig::default();
assert_eq!(config.classify(10 * 1024 * 1024), CacheLevel::L3);
assert_eq!(config.classify(20 * 1024 * 1024), CacheLevel::L3);
}
#[test]
fn f1121_ram_classification() {
let config = CacheConfig::default();
assert_eq!(config.classify(100 * 1024 * 1024), CacheLevel::Ram);
assert_eq!(config.classify(1024 * 1024 * 1024), CacheLevel::Ram);
}
#[test]
fn f1121_cache_level_names() {
assert_eq!(CacheLevel::L1.name(), "L1 cache");
assert_eq!(CacheLevel::L2.name(), "L2 cache");
assert_eq!(CacheLevel::L3.name(), "L3 cache");
assert_eq!(CacheLevel::Ram.name(), "main memory");
}
#[test]
fn f1121_latency_ordering() {
let l1_lat = CacheLevel::L1.typical_latency_cycles();
let l2_lat = CacheLevel::L2.typical_latency_cycles();
let l3_lat = CacheLevel::L3.typical_latency_cycles();
let ram_lat = CacheLevel::Ram.typical_latency_cycles();
assert!(l1_lat < l2_lat);
assert!(l2_lat < l3_lat);
assert!(l3_lat < ram_lat);
}
#[test]
fn f1121_bandwidth_ordering() {
let l1_bw = CacheLevel::L1.relative_bandwidth();
let l2_bw = CacheLevel::L2.relative_bandwidth();
let l3_bw = CacheLevel::L3.relative_bandwidth();
let ram_bw = CacheLevel::Ram.relative_bandwidth();
assert!(l1_bw >= l2_bw);
assert!(l2_bw >= l3_bw);
assert!(l3_bw >= ram_bw);
assert_eq!(l1_bw, 1.0); }
#[test]
fn f1122_default_config() {
let config = CacheConfig::default();
assert_eq!(config.l1_size, 32 * 1024);
assert_eq!(config.l2_size, 512 * 1024);
assert_eq!(config.l3_size, 32 * 1024 * 1024);
assert_eq!(config.line_size, 64);
}
#[test]
fn f1122_zen4_config() {
let config = CacheConfig::zen4();
assert_eq!(config.l1_size, 32 * 1024);
assert_eq!(config.l2_size, 1024 * 1024);
assert_eq!(config.l3_size, 32 * 1024 * 1024);
assert_eq!(config.l3_sharing, 8);
}
#[test]
fn f1122_sapphire_rapids_config() {
let config = CacheConfig::sapphire_rapids();
assert_eq!(config.l1_size, 48 * 1024);
assert_eq!(config.l2_size, 2 * 1024 * 1024);
assert_eq!(config.l3_size, 60 * 1024 * 1024);
assert_eq!(config.l3_sharing, 16);
}
#[test]
fn f1122_apple_m2_config() {
let config = CacheConfig::apple_m2();
assert_eq!(config.l1_size, 128 * 1024);
assert_eq!(config.l2_size, 16 * 1024 * 1024);
assert_eq!(config.l3_size, 0); assert_eq!(config.line_size, 128); }
#[test]
fn f1122_m2_skips_l3() {
let config = CacheConfig::apple_m2();
assert_eq!(config.classify(20 * 1024 * 1024), CacheLevel::Ram);
}
#[test]
fn f1122_l3_per_core() {
let config = CacheConfig::default();
assert_eq!(config.l3_per_core(), 4 * 1024 * 1024);
}
#[test]
fn f1123_small_working_set() {
let config = CacheConfig::default();
let analysis = WorkingSetAnalysis::analyze(1000, 4, 1.0, &config);
assert_eq!(analysis.working_set_bytes, 4000);
assert_eq!(analysis.cache_level, CacheLevel::L1);
assert!(!analysis.tiling_recommended);
assert!(analysis.recommended_tile_bytes.is_none());
}
#[test]
fn f1123_large_working_set_tiling() {
let config = CacheConfig::default();
let analysis = WorkingSetAnalysis::analyze(1_000_000, 4, 2.0, &config);
assert!(analysis.tiling_recommended);
assert!(analysis.recommended_tile_bytes.is_some());
let expected_tile = config.l2_size * 3 / 4;
assert_eq!(analysis.recommended_tile_bytes.unwrap(), expected_tile);
}
#[test]
fn f1123_access_factor() {
let config = CacheConfig::default();
let analysis1 = WorkingSetAnalysis::analyze(1000, 4, 1.0, &config);
let analysis2 = WorkingSetAnalysis::analyze(1000, 4, 3.0, &config);
assert_eq!(analysis1.working_set_bytes * 3, analysis2.working_set_bytes);
}
#[test]
fn f1123_utilization_percent() {
let config = CacheConfig::default();
let analysis = WorkingSetAnalysis::analyze(4096, 4, 1.0, &config);
assert!(analysis.utilization_percent > 45.0);
assert!(analysis.utilization_percent < 55.0);
}
#[test]
fn f1123_expected_efficiency() {
let config = CacheConfig::default();
let l1_analysis = WorkingSetAnalysis::analyze(1000, 4, 1.0, &config);
let ram_analysis = WorkingSetAnalysis::analyze(100_000_000, 4, 1.0, &config);
assert!(l1_analysis.expected_efficiency > ram_analysis.expected_efficiency);
}
#[test]
fn f1123_recommendation_message() {
let config = CacheConfig::default();
let analysis = WorkingSetAnalysis::analyze(1000, 4, 1.0, &config);
let rec = analysis.recommendation();
assert!(rec.contains("4000"));
assert!(rec.contains("fits"));
}
#[test]
fn f1124_square_matrix() {
let ws = matrix_working_set(1024, 1024, 1024, 4);
assert_eq!(ws, 3 * 1024 * 1024 * 4);
}
#[test]
fn f1124_rectangular_matrix() {
let ws = matrix_working_set(100, 50, 200, 4);
assert_eq!(ws, 140_000);
}
#[test]
fn f1124_double_precision() {
let ws_f32 = matrix_working_set(512, 512, 512, 4);
let ws_f64 = matrix_working_set(512, 512, 512, 8);
assert_eq!(ws_f64, ws_f32 * 2);
}