code wiki / (root) / nx_f32_activations_test.nx

nx_f32_activations_test.nx source

↩ module page · 75 lines · 2579 B

1// nx_f32_activations_test.nx -- smoke for nx_f32_activations.nx. 2 3import "nx_syscalls.nx" 4import "nx_tier.nx" 5import "nx_f32.nx" 6import "nx_f32_div.nx" 7import "nx_f32_exp.nx" 8import "nx_f32_activations.nx" 9 10func _ulp_diff_pos(a: i64, b: i64) -> i64 { 11 if a >= b { return a - b } 12 return b - a 13} 14 15func main() -> i64 { 16 // ===== sigmoid ===== 17 // sigmoid(0) = 0.5 = 0x3F000000 (1/(1+1) = 0.5 exact in principle) 18 // exp(0) = 1.0 exact, 1+1 = 2.0 exact, 1/2 = 0.5 exact 19 let s0: i64 = nx_f32_sigmoid(0x00000000) 20 if _ulp_diff_pos(s0, 0x3F000000) > 1024 { return 10 } 21 22 // sigmoid(10) ~= 0.99995 (very close to 1) 23 let s10: i64 = nx_f32_sigmoid(0x41200000) 24 // Check positive + magnitude close to 1 25 if (s10 >> 31) & 1 != 0 { return 11 } 26 // 0.999 = 0x3F7FBE77. sigmoid(10) > 0.999. 27 if s10 < 0x3F7FBE77 { return 12 } 28 // sigmoid(10) <= 1.0 29 if s10 > 0x3F800000 { return 13 } 30 31 // sigmoid(-10) ~= 0.0000454 (very small) 32 // Test: result positive, magnitude < 0.001 33 let s_neg10: i64 = nx_f32_sigmoid(0xC1200000) 34 if (s_neg10 >> 31) & 1 != 0 { return 20 } 35 if s_neg10 > 0x3A83126F { return 21 } // < 1e-3 36 37 // ===== SiLU ===== 38 // silu(0) = 0 * 0.5 = 0 (exact) 39 let silu0: i64 = nx_f32_silu(0) 40 if silu0 != 0 { return 30 } 41 42 // silu(1) = 1 * sigma(1) ~= 0.7311 = 0x3F3B2417 43 let silu1: i64 = nx_f32_silu(0x3F800000) 44 // Reference: 0.73105857863 -> nearest f32 ~= 0x3F3B2417 45 if _ulp_diff_pos(silu1, 0x3F3B2417) > 8192 { return 31 } 46 47 // silu(large positive) ~= x (since sigma -> 1) 48 // silu(10) ~= 10 * 0.99995 ~= 9.9995 49 let silu10: i64 = nx_f32_silu(0x41200000) 50 // Just check positive + magnitude close to 10 (0x41200000 = 10.0) 51 if (silu10 >> 31) & 1 != 0 { return 40 } 52 // silu(10) > 9.99 ~= 0x411FD70A 53 if silu10 < 0x411FD70A { return 41 } 54 55 // ===== tanh ===== 56 // tanh(0) = 0 (2*sigma(0)-1 = 2*0.5-1 = 0 exact) 57 let t0: i64 = nx_f32_tanh(0) 58 // Allow 1024 ULPs due to subtraction near 0 59 if _ulp_diff_pos(t0, 0) > 1024 { return 50 } 60 61 // tanh(very large positive) ~= 1 62 let t_big: i64 = nx_f32_tanh(0x41200000) // tanh(10) 63 // Should be close to 1 64 if (t_big >> 31) & 1 != 0 { return 60 } 65 if t_big < 0x3F7FBE77 { return 61 } // > 0.999 66 67 // tanh(very large negative) ~= -1 68 let t_neg: i64 = nx_f32_tanh(0xC1200000) // tanh(-10) 69 // Should be close to -1 (sign bit set) 70 if (t_neg >> 31) & 1 != 1 { return 70 } 71 let abs_t_neg: i64 = t_neg & 0x7FFFFFFF 72 if abs_t_neg < 0x3F7FBE77 { return 71 } 73 74 return 0 75}