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}