Skip to main content

native_neural_network/
lib.rs

1#![no_std]
2#![doc = include_str!("../README.md")]
3
4// No panic handler here — as a library crate we avoid providing a
5// global panic handler so downstream binaries or runtimes control
6// panic behavior. This keeps the crate strictly `no_std`-compatible
7// without forcing a specific panic implementation.
8
9pub mod network;
10pub mod tensor;
11pub mod scratch;
12pub mod rnn_format;
13pub mod rnn_api;
14pub mod crypto;
15pub mod conv3d;
16pub mod conv5d;
17pub mod sphere5d;
18pub mod activations;
19pub mod layers;
20pub mod engine;
21pub mod model_format;
22pub mod losses;
23pub mod metrics;
24pub mod initializers;
25pub mod inference;
26pub mod trainer;
27pub mod optimizers;
28pub mod schedulers;
29pub mod normalization;
30pub mod attention;
31pub mod quantization;
32pub mod model_config;
33pub mod runtime;
34pub mod sampling;
35pub mod kv_cache;
36pub mod rope;
37pub mod embeddings;
38pub mod lora;
39pub mod moe;
40pub mod beam_search;
41pub mod gradients;
42pub mod batching;
43pub mod profiler;
44
45mod public_api;
46
47pub use public_api::*;
48
49pub mod math {
50	use core::f32::consts::{PI, LN_2};
51
52	#[inline]
53	pub fn sqrtf(x: f32) -> f32 {
54		if x == 0.0 { return 0.0; }
55		if !(x > 0.0) { return f32::NAN; }
56		let xhalf = 0.5_f32 * x;
57		let mut i = x.to_bits();
58		i = 0x5f3759dfu32.wrapping_sub(i >> 1);
59		let mut y = f32::from_bits(i);
60		y = y * (1.5 - xhalf * y * y);
61		y = y * (1.5 - xhalf * y * y);
62		x * y
63	}
64
65	#[inline]
66	fn floorf(x: f32) -> f32 {
67		if x.is_nan() { return x; }
68		let t = x as i32 as f32;
69		if t > x { t - 1.0 } else { t }
70	}
71
72	#[inline]
73	fn ldexpf(x: f32, exp: i32) -> f32 {
74		if x == 0.0 { return 0.0; }
75		let bits = x.to_bits();
76		let sign = bits & 0x8000_0000;
77		let mant = bits & 0x007f_ffff;
78		let mut e = ((bits >> 23) & 0xff) as i32 - 127;
79		e += exp;
80		if e <= -127 { return 0.0; }
81		if e >= 128 { return core::f32::INFINITY; }
82		let new_bits = sign | (((e + 127) as u32) << 23) | mant;
83		f32::from_bits(new_bits)
84	}
85
86	#[inline]
87	pub fn expf(x: f32) -> f32 {
88		if x.is_nan() { return x; }
89		let x = if x > 88.0 { 88.0 } else if x < -88.0 { -88.0 } else { x };
90		let inv_ln2: f32 = 1.4426950408889634_f32;
91		let n = floorf(x * inv_ln2) as i32;
92		let r = x - (n as f32) * LN_2;
93		let r2 = r * r;
94		let r3 = r2 * r;
95		let r4 = r3 * r;
96		let r5 = r4 * r;
97		let approx = 1.0 + r + 0.5 * r2 + (1.0/6.0) * r3 + (1.0/24.0) * r4 + (1.0/120.0) * r5;
98		ldexpf(approx, n)
99	}
100
101	#[inline]
102	pub fn lnf(x: f32) -> f32 {
103		if x <= 0.0 { return f32::NAN; }
104		let bits = x.to_bits();
105		let e = ((bits >> 23) & 0xff) as i32 - 127;
106		let mant_bits = (bits & 0x007f_ffff) | 0x3f80_0000;
107		let m = f32::from_bits(mant_bits);
108		let y = (m - 1.0) / (m + 1.0);
109		let y2 = y * y;
110		let y3 = y2 * y;
111		let y5 = y3 * y2;
112		let y7 = y5 * y2;
113		let ln_m = 2.0 * (y + y3 / 3.0 + y5 / 5.0 + y7 / 7.0);
114		ln_m + (e as f32) * LN_2
115	}
116
117	#[inline]
118	pub fn powf(x: f32, y: f32) -> f32 {
119		if x <= 0.0 { return f32::NAN; }
120		expf(y * lnf(x))
121	}
122
123	#[inline]
124	pub fn sinf(mut x: f32) -> f32 {
125		let two_pi = 2.0 * PI;
126		x = x - roundf(x / two_pi) * two_pi;
127		let x2 = x * x;
128		let x3 = x2 * x;
129		let x5 = x3 * x2;
130		let x7 = x5 * x2;
131		x - x3 / 6.0 + x5 / 120.0 - x7 / 5040.0
132	}
133
134	#[inline]
135	pub fn cosf(mut x: f32) -> f32 {
136		let two_pi = 2.0 * PI;
137		x = x - roundf(x / two_pi) * two_pi;
138		let x2 = x * x;
139		let x4 = x2 * x2;
140		let x6 = x4 * x2;
141		1.0 - x2 / 2.0 + x4 / 24.0 - x6 / 720.0
142	}
143
144	#[inline]
145	pub fn tanhf(x: f32) -> f32 {
146		let e2 = expf(2.0 * x);
147		(e2 - 1.0) / (e2 + 1.0)
148	}
149
150	#[inline]
151	pub fn roundf(x: f32) -> f32 {
152		if x.is_nan() { return x; }
153		if x >= 0.0 { (x + 0.5) as i32 as f32 } else { (x - 0.5) as i32 as f32 }
154	}
155}