use native_neural_network_std as nn;
mod utils {
include!("test_utils.rs");
}
#[test]
fn cpu_backend_abstraction_real() {
let previous = native_neural_network_std::std::engine_std::get_compute_backend();
native_neural_network_std::std::engine_std::set_compute_backend(
native_neural_network_std::std::engine_std::ComputeBackend::Cpu,
);
assert_eq!(
native_neural_network_std::std::engine_std::get_compute_backend(),
native_neural_network_std::std::engine_std::ComputeBackend::Cpu
);
let layers = vec![
native_neural_network_std::std::layers_std::LayerSpec::Dense(
native_neural_network_std::std::layers_std::DenseLayerDesc {
input_size: 2,
output_size: 1,
weight_offset: 0,
bias_offset: 0,
activation:
native_neural_network_std::std::activations_std::ActivationKind::Identity,
},
),
];
let plan = native_neural_network_std::std::layers_std::LayerPlanStd::new(
layers,
vec![2.0f32, 3.0f32],
vec![1.0f32],
);
let input = vec![1.0f32, 2.0f32];
let mut output = vec![0.0f32; 1];
let mut scratch =
vec![
0.0f32;
native_neural_network_std::std::engine_std::required_batch_scratch_len(&plan, 1)
.unwrap_or(0)
];
native_neural_network_std::std::engine_std::forward_plan_big_kernel(
&plan,
&input,
&mut output,
1,
&mut scratch,
)
.expect("cpu forward");
assert!((output[0] - 9.0).abs() < 1e-6);
native_neural_network_std::std::engine_std::set_compute_backend(previous);
}
#[test]
fn differential_softmax_vs_stable() {
let mut rng = utils::XorShift32::new(0x12345678);
for _ in 0..1000 {
let len = 1 + (rng.next_u32() % 32) as usize;
let mut v1 = vec![0f32; len];
for i in 0..len {
v1[i] = rng.next_f32() * 20.0;
}
let mut out1 = vec![0f32; len];
let mut out2 = vec![0f32; len];
nn::std::inference_std::softmax(&v1, &mut out1).ok();
nn::std::inference_std::softmax_stable(&v1, &mut out2).ok();
for i in 0..len {
assert!(
utils::approx_eq(out1[i], out2[i], 1e-4),
"softmax mismatch at {}: {} vs {}",
i,
out1[i],
out2[i]
);
}
}
}