ferrotensor_backend/engine/
norm.rs1use super::{grid, uniform, ComputeEngine};
4use crate::{UnifiedTensor, WgpuContext};
5
6impl ComputeEngine {
7 pub fn rms_norm(
10 &self,
11 ctx: &WgpuContext,
12 input: &UnifiedTensor,
13 weight: &UnifiedTensor,
14 out: &UnifiedTensor,
15 ) {
16 self.rms_norm_eps(ctx, input, weight, out, 1e-5);
17 }
18
19 pub fn rms_norm_eps(
21 &self,
22 ctx: &WgpuContext,
23 input: &UnifiedTensor,
24 weight: &UnifiedTensor,
25 out: &UnifiedTensor,
26 eps: f32,
27 ) {
28 let size = *input.shape.last().unwrap_or(&1);
29 let rows = input.shape.iter().product::<usize>() / size;
30 let params = uniform(
31 ctx,
32 bytemuck::cast_slice(&[size as u32, rows as u32, eps.to_bits(), 0]),
33 );
34 self.run(
35 ctx,
36 &self.rms_norm,
37 &[
38 (0, input.buffer()),
39 (1, weight.buffer()),
40 (2, out.buffer()),
41 (3, ¶ms),
42 ],
43 grid(rows as u32),
44 );
45 }
46
47 pub fn rms_norm_residual(
49 &self,
50 ctx: &WgpuContext,
51 x: &UnifiedTensor,
52 residual: &UnifiedTensor,
53 weight: &UnifiedTensor,
54 out: &UnifiedTensor,
55 ) {
56 let size = x.shape.iter().product::<usize>() as u32;
57 let params = uniform(ctx, bytemuck::cast_slice(&[size]));
58 self.run(
59 ctx,
60 &self.rms_residual,
61 &[
62 (0, x.buffer()),
63 (1, residual.buffer()),
64 (2, weight.buffer()),
65 (3, out.buffer()),
66 (4, ¶ms),
67 ],
68 (1, 1, 1),
69 );
70 }
71
72 pub fn softmax(&self, ctx: &WgpuContext, input: &UnifiedTensor, out: &UnifiedTensor) {
74 let size = *input.shape.last().unwrap_or(&1);
75 let rows = input.shape.iter().product::<usize>() / size;
76 let params = uniform(ctx, bytemuck::cast_slice(&[size as u32, rows as u32]));
77 self.run(
78 ctx,
79 &self.softmax,
80 &[(0, input.buffer()), (1, out.buffer()), (2, ¶ms)],
81 grid(rows as u32),
82 );
83 }
84
85 pub fn softmax_backward(
88 &self,
89 ctx: &WgpuContext,
90 grad_out: &UnifiedTensor,
91 final_out: &UnifiedTensor,
92 grad_in: &UnifiedTensor,
93 ) {
94 let size = *grad_out.shape.last().unwrap_or(&1);
95 let rows = grad_out.shape.iter().product::<usize>() / size;
96 let params = uniform(ctx, bytemuck::cast_slice(&[size as u32, rows as u32]));
97 self.run(
98 ctx,
99 &self.softmax_bw,
100 &[
101 (2, ¶ms),
102 (3, grad_out.buffer()),
103 (4, final_out.buffer()),
104 (5, grad_in.buffer()),
105 ],
106 grid(rows as u32),
107 );
108 }
109}