#[cfg(test)]
mod tests {
use super::super::functions::*;
use crate::Tensor;
#[test]
fn test_relu() {
let input = Tensor::<f32>::from_vec(vec![-2.0, -1.0, 0.0, 1.0, 2.0], &[5])
.expect("test: from_vec should succeed");
let output = relu(&input).expect("test: relu should succeed");
if let Some(data) = output.as_slice() {
assert_eq!(data, &[0.0, 0.0, 0.0, 1.0, 2.0]);
}
}
#[test]
fn test_sigmoid() {
let input = Tensor::<f32>::from_vec(vec![-2.0, -1.0, 0.0, 1.0, 2.0], &[5])
.expect("test: from_vec should succeed");
let output = sigmoid(&input).expect("test: sigmoid should succeed");
if let Some(data) = output.as_slice() {
assert!((data[0] - 0.1192).abs() < 0.001); assert!((data[1] - 0.2689).abs() < 0.001); assert!((data[2] - 0.5).abs() < 0.001); assert!((data[3] - 0.7311).abs() < 0.001); assert!((data[4] - 0.8808).abs() < 0.001); }
}
#[test]
fn test_tanh() {
let input = Tensor::<f32>::from_vec(vec![-2.0, -1.0, 0.0, 1.0, 2.0], &[5])
.expect("test: from_vec should succeed");
let output = tanh(&input).expect("test: tanh should succeed");
if let Some(data) = output.as_slice() {
assert!((data[0] - (-0.9640)).abs() < 0.001); assert!((data[1] - (-0.7616)).abs() < 0.001); assert!((data[2] - 0.0).abs() < 0.001); assert!((data[3] - 0.7616).abs() < 0.001); assert!((data[4] - 0.9640).abs() < 0.001); }
}
#[test]
fn test_softmax_1d() {
let input = Tensor::<f32>::from_vec(vec![1.0, 2.0, 3.0], &[3])
.expect("test: from_vec should succeed");
let output = softmax(&input, None).expect("test: softmax should succeed");
if let Some(data) = output.as_slice() {
let sum: f32 = data.iter().sum();
assert!((sum - 1.0).abs() < 0.001);
assert!(data[0] < data[1]);
assert!(data[1] < data[2]);
}
}
#[test]
fn test_softmax_2d() {
let input = Tensor::<f32>::from_vec(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0], &[2, 3])
.expect("test: from_vec should succeed");
let output = softmax(&input, Some(1)).expect("test: operation should succeed");
if let Some(data) = output.as_slice() {
let row1_sum: f32 = data[0..3].iter().sum();
let row2_sum: f32 = data[3..6].iter().sum();
assert!((row1_sum - 1.0).abs() < 0.001);
assert!((row2_sum - 1.0).abs() < 0.001);
}
let output = softmax(&input, Some(0)).expect("test: operation should succeed");
if let Some(data) = output.as_slice() {
let col1_sum = data[0] + data[3];
let col2_sum = data[1] + data[4];
let col3_sum = data[2] + data[5];
assert!((col1_sum - 1.0).abs() < 0.001);
assert!((col2_sum - 1.0).abs() < 0.001);
assert!((col3_sum - 1.0).abs() < 0.001);
}
}
#[test]
fn test_relu_2d() {
let input = Tensor::<f32>::from_vec(vec![-2.0, -1.0, 0.0, 1.0, 2.0, 3.0], &[2, 3])
.expect("test: from_vec should succeed");
let output = relu(&input).expect("test: relu should succeed");
if let Some(data) = output.as_slice() {
assert_eq!(data, &[0.0, 0.0, 0.0, 1.0, 2.0, 3.0]);
}
}
#[test]
fn test_gelu() {
let input = Tensor::<f32>::from_vec(vec![-2.0, -1.0, 0.0, 1.0, 2.0], &[5])
.expect("test: from_vec should succeed");
let output = gelu(&input).expect("test: gelu should succeed");
if let Some(data) = output.as_slice() {
assert!((data[0] - (-0.0454)).abs() < 0.01); assert!((data[1] - (-0.1587)).abs() < 0.01); assert!((data[2] - 0.0).abs() < 0.001); assert!((data[3] - 0.8413).abs() < 0.01); assert!((data[4] - 1.9545).abs() < 0.01); }
}
#[test]
fn test_swish() {
let input = Tensor::<f32>::from_vec(vec![-2.0, -1.0, 0.0, 1.0, 2.0], &[5])
.expect("test: from_vec should succeed");
let output = swish(&input).expect("test: swish should succeed");
if let Some(data) = output.as_slice() {
assert!((data[0] - (-0.2384)).abs() < 0.01); assert!((data[1] - (-0.2689)).abs() < 0.01); assert!((data[2] - 0.0).abs() < 0.001); assert!((data[3] - 0.7311).abs() < 0.01); assert!((data[4] - 1.7616).abs() < 0.01); }
}
#[test]
fn test_mish() {
let input = Tensor::<f32>::from_vec(vec![-2.0, -1.0, 0.0, 1.0, 2.0], &[5])
.expect("test: from_vec should succeed");
let output = mish(&input).expect("test: mish should succeed");
if let Some(data) = output.as_slice() {
assert!((data[0] - (-0.2525)).abs() < 0.01); assert!((data[1] - (-0.3034)).abs() < 0.01); assert!((data[2] - 0.0).abs() < 0.001); assert!((data[3] - 0.8651).abs() < 0.01); assert!((data[4] - 1.9440).abs() < 0.01); }
}
#[test]
fn test_elu() {
let input = Tensor::<f32>::from_vec(vec![-2.0, -1.0, 0.0, 1.0, 2.0], &[5])
.expect("test: from_vec should succeed");
let output = elu(&input, 1.0).expect("test: elu should succeed");
if let Some(data) = output.as_slice() {
assert!((data[0] - (-0.8647)).abs() < 0.01); assert!((data[1] - (-0.6321)).abs() < 0.01); assert!((data[2] - 0.0).abs() < 0.001); assert!((data[3] - 1.0).abs() < 0.001); assert!((data[4] - 2.0).abs() < 0.001); }
}
#[test]
fn test_leaky_relu() {
let input = Tensor::<f32>::from_vec(vec![-2.0, -1.0, 0.0, 1.0, 2.0], &[5])
.expect("test: from_vec should succeed");
let output = leaky_relu(&input, 0.01).expect("test: leaky_relu should succeed");
if let Some(data) = output.as_slice() {
assert_eq!(data[0], -0.02); assert_eq!(data[1], -0.01); assert_eq!(data[2], 0.0); assert_eq!(data[3], 1.0); assert_eq!(data[4], 2.0); }
}
#[test]
fn test_hard_swish() {
let input = Tensor::<f32>::from_vec(vec![-3.0, -1.5, 0.0, 1.5, 3.0], &[5])
.expect("test: from_vec should succeed");
let output = hard_swish(&input).expect("test: hard_swish should succeed");
if let Some(data) = output.as_slice() {
assert_eq!(data[0], 0.0); assert!((data[1] - (-0.375)).abs() < 0.001); assert_eq!(data[2], 0.0); assert!((data[3] - 1.125).abs() < 0.001); assert_eq!(data[4], 3.0); }
}
#[test]
fn test_prelu_scalar() {
let input = Tensor::<f32>::from_vec(vec![-2.0, -1.0, 0.0, 1.0, 2.0], &[5])
.expect("test: from_vec should succeed");
let alpha =
Tensor::<f32>::from_vec(vec![0.1], &[1]).expect("test: from_vec should succeed");
let output = prelu(&input, &alpha).expect("test: prelu should succeed");
if let Some(data) = output.as_slice() {
assert_eq!(data[0], -0.2); assert_eq!(data[1], -0.1); assert_eq!(data[2], 0.0); assert_eq!(data[3], 1.0); assert_eq!(data[4], 2.0); }
}
#[test]
fn test_prelu_channelwise() {
let input = Tensor::<f32>::from_vec(
vec![
-1.0, 1.0, -2.0, 2.0, ],
&[1, 2, 2],
)
.expect("test: operation should succeed");
let alpha =
Tensor::<f32>::from_vec(vec![0.1, 0.2], &[2]).expect("test: from_vec should succeed");
let output = prelu(&input, &alpha).expect("test: prelu should succeed");
if let Some(data) = output.as_slice() {
assert_eq!(data[0], -0.1); assert_eq!(data[1], 1.0); assert_eq!(data[2], -0.4); assert_eq!(data[3], 2.0); }
}
#[test]
fn test_relu_f32_optimized() {
let input = Tensor::<f32>::from_vec(vec![-5.0, -2.0, -1.0, 0.0, 1.0, 2.0, 5.0], &[7])
.expect("test: from_vec should succeed");
let output = relu_f32(&input).expect("test: relu_f32 should succeed");
if let Some(data) = output.as_slice() {
assert_eq!(data, &[0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 5.0]);
}
}
#[test]
fn test_sigmoid_f32_optimized() {
let input = Tensor::<f32>::from_vec(vec![-2.0, -1.0, 0.0, 1.0, 2.0], &[5])
.expect("test: from_vec should succeed");
let output = sigmoid_f32(&input).expect("test: sigmoid_f32 should succeed");
if let Some(data) = output.as_slice() {
assert!((data[0] - 0.1192).abs() < 0.01); assert!((data[1] - 0.2689).abs() < 0.01); assert!((data[2] - 0.5).abs() < 0.01); assert!((data[3] - 0.7311).abs() < 0.01); assert!((data[4] - 0.8808).abs() < 0.01); }
}
#[test]
fn test_gelu_f32_optimized() {
let input = Tensor::<f32>::from_vec(vec![-2.0, -1.0, 0.0, 1.0, 2.0], &[5])
.expect("test: from_vec should succeed");
let output = gelu_f32(&input).expect("test: gelu_f32 should succeed");
if let Some(data) = output.as_slice() {
assert!((data[0] - (-0.0454)).abs() < 0.1); assert!((data[1] - (-0.1587)).abs() < 0.1); assert!((data[2] - 0.0).abs() < 0.01); assert!((data[3] - 0.8413).abs() < 0.1); assert!((data[4] - 1.9545).abs() < 0.1); }
}
#[test]
fn test_large_tensor_performance() {
let size = 10000;
let input_data: Vec<f32> = (0..size)
.map(|i| (i as f32 - size as f32 / 2.0) / 1000.0)
.collect();
let input =
Tensor::<f32>::from_vec(input_data, &[size]).expect("test: from_vec should succeed");
let relu_result = relu_f32(&input).expect("test: relu_f32 should succeed");
let sigmoid_result = sigmoid_f32(&input).expect("test: sigmoid_f32 should succeed");
let gelu_result = gelu_f32(&input).expect("test: gelu_f32 should succeed");
assert_eq!(relu_result.shape().dims(), &[size]);
assert_eq!(sigmoid_result.shape().dims(), &[size]);
assert_eq!(gelu_result.shape().dims(), &[size]);
}
#[test]
fn test_activation_performance_analytics() {
use super::super::core::{get_activation_performance_report, reset_activation_counters};
reset_activation_counters();
let input = Tensor::<f32>::from_vec(vec![1.0, 2.0, 3.0, 4.0], &[4])
.expect("test: from_vec should succeed");
let _relu_out = relu_f32(&input).expect("test: relu_f32 should succeed");
let _sigmoid_out = sigmoid_f32(&input).expect("test: sigmoid_f32 should succeed");
let report = get_activation_performance_report();
assert!(report.function_counts.len() > 0);
}
#[test]
fn test_edge_cases() {
let extreme_input = Tensor::<f32>::from_vec(
vec![f32::NEG_INFINITY, -1000.0, 0.0, 1000.0, f32::INFINITY],
&[5],
)
.expect("test: operation should succeed");
let relu_result = relu(&extreme_input);
let sigmoid_result = sigmoid(&extreme_input);
assert!(relu_result.is_ok());
assert!(sigmoid_result.is_ok());
if let Ok(sigmoid_output) = sigmoid_result {
if let Some(data) = sigmoid_output.as_slice() {
for &val in data {
assert!(
val >= 0.0 && val <= 1.0,
"Sigmoid output out of bounds: {}",
val
);
}
}
}
}
}