use crate::gguf::test_helpers::create_test_model_with_config;
use crate::gguf::GGUFConfig;
#[test]
#[cfg(feature = "gpu")]
#[serial_test::serial]
fn test_imp_109a_fused_dequant_matmul_correctness() {
use crate::quantize::{dequantize_q4_k_simd, fused_q4k_parallel_matvec};
let config = GGUFConfig {
architecture: "test".to_string(),
constraints: crate::gguf::ArchConstraints::from_architecture("test"),
hidden_dim: 256, intermediate_dim: 512,
num_layers: 1,
num_heads: 4,
num_kv_heads: 4,
vocab_size: 100,
context_length: 1024,
rope_theta: 10000.0,
eps: 1e-5,
rope_type: 0,
explicit_head_dim: None,
query_pre_attn_scalar: None,
bos_token_id: None,
eos_token_id: None,
};
let model = create_test_model_with_config(&config);
let in_dim = config.hidden_dim;
let out_dim = config.intermediate_dim;
let weight_data = &model.layers[0].ffn_up_weight.data;
let activations: Vec<f32> = (0..in_dim).map(|i| ((i % 13) as f32 - 6.0) * 0.1).collect();
let weight_dequant = dequantize_q4_k_simd(weight_data).expect("test");
let reference: Vec<f32> = (0..out_dim)
.map(|row| {
(0..in_dim)
.map(|col| weight_dequant[row * in_dim + col] * activations[col])
.sum()
})
.collect();
let fused_result = fused_q4k_parallel_matvec(weight_data, &activations, in_dim, out_dim)
.expect("IMP-109a: Fused operation should succeed");
assert_eq!(
fused_result.len(),
out_dim,
"IMP-109a: Fused result should have out_dim elements"
);
for i in 0..out_dim {
let diff = (fused_result[i] - reference[i]).abs();
let tolerance = reference[i].abs() * 0.02 + 1e-4;
assert!(
diff < tolerance,
"IMP-109a: Row {} differs: fused={}, reference={}, diff={}",
i,
fused_result[i],
reference[i],
diff
);
}
}
#[test]
#[cfg(feature = "gpu")]
#[serial_test::serial]
fn test_imp_109b_fused_batch_matmul_gpu() {
use crate::gpu::HybridScheduler;
let config = GGUFConfig {
architecture: "test".to_string(),
constraints: crate::gguf::ArchConstraints::from_architecture("test"),
hidden_dim: 256, intermediate_dim: 512,
num_layers: 1,
num_heads: 4,
num_kv_heads: 4,
vocab_size: 100,
context_length: 1024,
rope_theta: 10000.0,
eps: 1e-5,
rope_type: 0,
explicit_head_dim: None,
query_pre_attn_scalar: None,
bos_token_id: None,
eos_token_id: None,
};
let model = create_test_model_with_config(&config);
let batch_size = 8;
let activations: Vec<f32> = (0..batch_size * config.hidden_dim)
.map(|i| ((i % 17) as f32 - 8.0) * 0.05)
.collect();
let fused_output = model
.fused_batch_matmul_gpu(&activations, &model.layers[0].ffn_up_weight, batch_size)
.expect("IMP-109b: Fused batch matmul should succeed");
assert_eq!(
fused_output.len(),
batch_size * config.intermediate_dim,
"IMP-109b: Fused batch output should be batch_size * intermediate_dim"
);
assert!(
fused_output.iter().all(|x| x.is_finite()),
"IMP-109b: All fused outputs should be finite"
);
let sum: f32 = fused_output.iter().map(|x| x.abs()).sum();
assert!(
sum > 0.1,
"IMP-109b: Fused output should have non-zero values"
);
let fused_output2 = model
.fused_batch_matmul_gpu(&activations, &model.layers[0].ffn_up_weight, batch_size)
.expect("IMP-109b: Repeated call should succeed");
for i in 0..fused_output.len() {
assert!(
(fused_output[i] - fused_output2[i]).abs() < 1e-6,
"IMP-109b: Fused batch matmul should be deterministic at position {}: run1={}, run2={}",
i,
fused_output[i],
fused_output2[i]
);
}
let weight = &model.layers[0].ffn_up_weight;
let weight_f32 = {
use crate::quantize::{dequantize_q4_k_simd, QK_K};
let in_dim = weight.in_dim;
let out_dim = weight.out_dim;
let super_blocks_per_row = in_dim.div_ceil(QK_K);
let mut output = Vec::with_capacity(in_dim * out_dim);
for row in 0..out_dim {
let row_start = row * super_blocks_per_row * 144;
let row_end = row_start + super_blocks_per_row * 144;
let row_data = &weight.data[row_start..row_end];
let row_dequant = dequantize_q4_k_simd(row_data).expect("test");
output.extend_from_slice(&row_dequant[..in_dim.min(row_dequant.len())]);
}
output
};
let mut scheduler = HybridScheduler::with_threshold(1000).expect("test");
let reference = scheduler
.matmul(
&activations,
&weight_f32,
batch_size,
config.hidden_dim,
config.intermediate_dim,
)
.expect("Reference matmul should succeed");
for i in 0..fused_output.len() {
let diff = (fused_output[i] - reference[i]).abs();
assert!(
diff < 1e-4,
"IMP-109b: Fused should match reference at position {}: fused={}, ref={}",
i,
fused_output[i],
reference[i]
);
}
}
#[test]
#[cfg(feature = "gpu")]
#[serial_test::serial]
fn test_imp_109c_fused_vs_separate_performance_baseline() {
use crate::quantize::{dequantize_q4_k_simd, fused_q4k_parallel_matvec};
let config = GGUFConfig {
architecture: "test".to_string(),
constraints: crate::gguf::ArchConstraints::from_architecture("test"),
hidden_dim: 512, intermediate_dim: 1024,
num_layers: 1,
num_heads: 8,
num_kv_heads: 8,
vocab_size: 100,
context_length: 2048,
rope_theta: 10000.0,
eps: 1e-5,
rope_type: 0,
explicit_head_dim: None,
query_pre_attn_scalar: None,
bos_token_id: None,
eos_token_id: None,
};
let model = create_test_model_with_config(&config);
let weight_data = &model.layers[0].ffn_up_weight.data;
let in_dim = config.hidden_dim;
let out_dim = config.intermediate_dim;
for batch in 0..4 {
let activations: Vec<f32> = (0..in_dim)
.map(|i| {
let x = ((i + batch * 100) as f32 * 0.3141) % 1.0;
(x - 0.5) * 2.0
})
.collect();
let dequant = dequantize_q4_k_simd(weight_data).expect("test");
let separate_result: Vec<f32> = (0..out_dim)
.map(|row| {
(0..in_dim)
.map(|col| dequant[row * in_dim + col] * activations[col])
.sum()
})
.collect();
let fused_result = fused_q4k_parallel_matvec(weight_data, &activations, in_dim, out_dim)
.expect("Fused should succeed");
let max_diff: f32 = separate_result
.iter()
.zip(fused_result.iter())
.map(|(s, f)| (s - f).abs())
.fold(0.0f32, f32::max);
let max_val = separate_result
.iter()
.map(|x| x.abs())
.fold(0.0f32, f32::max);
let relative_error = max_diff / (max_val + 1e-6);
assert!(
relative_error < 0.02, "IMP-109c: Batch {} has excessive error: max_diff={}, relative={}",
batch,
max_diff,
relative_error
);
}
}
#[test]
#[cfg(feature = "gpu")]
#[serial_test::serial]
fn test_imp_110a_parallel_heads_correctness() {
let config = GGUFConfig {
architecture: "test".to_string(),
constraints: crate::gguf::ArchConstraints::from_architecture("test"),
hidden_dim: 64,
intermediate_dim: 128,
num_layers: 1,
num_heads: 4, num_kv_heads: 4,
vocab_size: 100,
context_length: 256,
rope_theta: 10000.0,
eps: 1e-5,
rope_type: 0,
explicit_head_dim: None,
query_pre_attn_scalar: None,
bos_token_id: None,
eos_token_id: None,
};
let model = create_test_model_with_config(&config);
let seq_len = 8;
let hidden_dim = config.hidden_dim;
let q: Vec<f32> = (0..seq_len * hidden_dim)
.map(|i| ((i % 13) as f32 - 6.0) * 0.1)
.collect();
let k: Vec<f32> = (0..seq_len * hidden_dim)
.map(|i| ((i % 11) as f32 - 5.0) * 0.1)
.collect();
let v: Vec<f32> = (0..seq_len * hidden_dim)
.map(|i| ((i % 7) as f32 - 3.0) * 0.1)
.collect();
let sequential_output = model
.batched_causal_attention_gpu(&q, &k, &v, seq_len)
.expect("Sequential attention should succeed");
let parallel_output = model
.parallel_multihead_attention_gpu(&q, &k, &v, seq_len)
.expect("IMP-110a: Parallel attention should succeed");
assert_eq!(
parallel_output.len(),
sequential_output.len(),
"IMP-110a: Parallel and sequential should have same output size"
);
for i in 0..parallel_output.len() {
let diff = (parallel_output[i] - sequential_output[i]).abs();
assert!(
diff < 1e-4,
"IMP-110a: Position {} differs: parallel={}, sequential={}, diff={}",
i,
parallel_output[i],
sequential_output[i],
diff
);
}
}
#[test]
#[cfg(feature = "gpu")]
#[serial_test::serial]
fn test_imp_110b_batched_qkv_reshape() {
let config = GGUFConfig {
architecture: "test".to_string(),
constraints: crate::gguf::ArchConstraints::from_architecture("test"),
hidden_dim: 32,
intermediate_dim: 64,
num_layers: 1,
num_heads: 4,
num_kv_heads: 4,
vocab_size: 50,
context_length: 128,
rope_theta: 10000.0,
eps: 1e-5,
rope_type: 0,
explicit_head_dim: None,
query_pre_attn_scalar: None,
bos_token_id: None,
eos_token_id: None,
};
let model = create_test_model_with_config(&config);
let seq_len = 4;
let hidden_dim = config.hidden_dim;
let num_heads = config.num_heads;
let head_dim = hidden_dim / num_heads;
let q: Vec<f32> = (0..seq_len * hidden_dim).map(|i| i as f32 * 0.1).collect();
let reshaped = model
.reshape_for_parallel_heads(&q, seq_len, num_heads, head_dim)
.expect("IMP-110b: Reshape should succeed");
assert_eq!(
reshaped.len(),
num_heads * seq_len * head_dim,
"IMP-110b: Reshaped tensor should have num_heads * seq_len * head_dim elements"
);
for h in 0..num_heads {
for pos in 0..seq_len {
for d in 0..head_dim {
let orig_idx = pos * hidden_dim + h * head_dim + d;
let new_idx = h * seq_len * head_dim + pos * head_dim + d;
assert!(
(reshaped[new_idx] - q[orig_idx]).abs() < 1e-6,
"IMP-110b: Head {} pos {} dim {} mismatch: reshaped={}, original={}",
h,
pos,
d,
reshaped[new_idx],
q[orig_idx]
);
}
}
}
}
#[test]
#[cfg(feature = "gpu")]
#[serial_test::serial]
fn test_imp_110c_parallel_batched_scores() {
let config = GGUFConfig {
architecture: "test".to_string(),
constraints: crate::gguf::ArchConstraints::from_architecture("test"),
hidden_dim: 32,
intermediate_dim: 64,
num_layers: 1,
num_heads: 4,
num_kv_heads: 4,
vocab_size: 50,
context_length: 128,
rope_theta: 10000.0,
eps: 1e-5,
rope_type: 0,
explicit_head_dim: None,
query_pre_attn_scalar: None,
bos_token_id: None,
eos_token_id: None,
};
let model = create_test_model_with_config(&config);
let seq_len = 4;
let hidden_dim = config.hidden_dim;
let num_heads = config.num_heads;
let head_dim = hidden_dim / num_heads;
let scale = 1.0 / (head_dim as f32).sqrt();
let q: Vec<f32> = (0..seq_len * hidden_dim)
.map(|i| ((i % 7) as f32 - 3.0) * 0.1)
.collect();
let k: Vec<f32> = (0..seq_len * hidden_dim)
.map(|i| ((i % 5) as f32 - 2.0) * 0.1)
.collect();
let batched_scores = model
.parallel_batched_qk_scores(&q, &k, seq_len, num_heads, head_dim, scale)
.expect("IMP-110c: Parallel batched scores should succeed");
assert_eq!(
batched_scores.len(),
num_heads * seq_len * seq_len,
"IMP-110c: Batched scores should have num_heads * seq_len * seq_len elements"
);
for h in 0..num_heads {
for i in 0..seq_len {
for j in 0..seq_len {
let mut expected_score = 0.0f32;
for d in 0..head_dim {
let q_val = q[i * hidden_dim + h * head_dim + d];
let k_val = k[j * hidden_dim + h * head_dim + d];
expected_score += q_val * k_val;
}
expected_score *= scale;
let batch_idx = h * seq_len * seq_len + i * seq_len + j;
let diff = (batched_scores[batch_idx] - expected_score).abs();
assert!(
diff < 1e-4,
"IMP-110c: Head {} score[{},{}] differs: batched={}, expected={}, diff={}",
h,
i,
j,
batched_scores[batch_idx],
expected_score,
diff
);
}
}
}
}