1#![allow(non_snake_case)]
29
30use teeny_core::dtype::Float;
31use teeny_macros::kernel;
32use teeny_triton::triton::{
33 types::{AddOffsets, Comparison},
34 *,
35};
36
37#[kernel]
43pub fn instance_norm_forward_inference<T: Triton, D: Float, const BLOCK_L: i32>(
44 x_ptr: T::Pointer<D>,
45 y_ptr: T::Pointer<D>,
46 weight_ptr: T::Pointer<D>,
47 bias_ptr: T::Pointer<D>,
48 _N: i32,
49 C: i32,
50 L: i32,
51 eps: f32,
52) where
53 T::I32Tensor: types::Tensor<i32, 1>,
54 T::I32Tensor: Comparison<i32, BoolTensor = T::BoolTensor>,
55 T::Pointer<D>: AddOffsets<i32, 1, T::I32Tensor, Output = T::Tensor<T::Pointer<D>>>,
56{
57 let pid = T::program_id(Axis::X);
58 let n = pid / C;
59 let c = pid - n * C;
60 let row_start = (n * C + c) * L;
61
62 let c_idx = T::arange(0, 1) + c;
63 let zeros = T::zeros::<D>(&[BLOCK_L]);
64 let zero_1 = T::zeros::<D>(&[1]);
65 let l_inv = T::cast::<f32, D>(T::full::<f32>(&[1], 1.0f32 / (L as f32)), None, false);
66
67 let mut sum = zero_1;
69 let mut l_start: i32 = 0;
70 while l_start < L {
71 let col_offs = T::arange(0, BLOCK_L) + l_start;
72 let mask = col_offs.lt(L);
73 let x_tile = T::load(
74 x_ptr.add_offsets(col_offs + row_start),
75 Some(mask),
76 Some(zeros),
77 &[],
78 None,
79 None,
80 None,
81 false,
82 );
83 sum = sum + T::sum(x_tile, None, true);
84 l_start += BLOCK_L;
85 }
86 let mean_1 = sum * l_inv;
87 let mean = T::broadcast_to(mean_1, &[BLOCK_L]);
88
89 let mut var_sum = zero_1;
91 l_start = 0;
92 while l_start < L {
93 let col_offs = T::arange(0, BLOCK_L) + l_start;
94 let mask = col_offs.lt(L);
95 let x_tile = T::load(
96 x_ptr.add_offsets(col_offs + row_start),
97 Some(mask),
98 Some(zeros),
99 &[],
100 None,
101 None,
102 None,
103 false,
104 );
105 let diff = T::where_::<D>(mask, x_tile - mean, zeros);
107 var_sum = var_sum + T::sum(diff * diff, None, true);
108 l_start += BLOCK_L;
109 }
110 let eps_t = T::cast::<f32, D>(T::full::<f32>(&[1], eps), None, false);
111 let rstd = T::broadcast_to(T::rsqrt(var_sum * l_inv + eps_t), &[BLOCK_L]);
112
113 let gamma = T::broadcast_to(
114 T::load(
115 weight_ptr.add_offsets(c_idx),
116 None,
117 None,
118 &[],
119 None,
120 None,
121 None,
122 false,
123 ),
124 &[BLOCK_L],
125 );
126 let beta = T::broadcast_to(
127 T::load(
128 bias_ptr.add_offsets(c_idx),
129 None,
130 None,
131 &[],
132 None,
133 None,
134 None,
135 false,
136 ),
137 &[BLOCK_L],
138 );
139
140 l_start = 0;
142 while l_start < L {
143 let col_offs = T::arange(0, BLOCK_L) + l_start;
144 let mask = col_offs.lt(L);
145 let x_tile = T::load(
146 x_ptr.add_offsets(col_offs + row_start),
147 Some(mask),
148 Some(zeros),
149 &[],
150 None,
151 None,
152 None,
153 false,
154 );
155 let y_tile = (x_tile - mean) * rstd * gamma + beta;
156 T::store(
157 y_ptr.add_offsets(col_offs + row_start),
158 y_tile,
159 Some(mask),
160 &[],
161 None,
162 None,
163 );
164 l_start += BLOCK_L;
165 }
166}
167
168#[cfg(feature = "training")]
174#[kernel]
175pub fn instance_norm_forward<T: Triton, D: Float, const BLOCK_L: i32>(
176 x_ptr: T::Pointer<D>,
177 y_ptr: T::Pointer<D>,
178 weight_ptr: T::Pointer<D>,
179 bias_ptr: T::Pointer<D>,
180 mean_ptr: T::Pointer<D>,
181 rstd_ptr: T::Pointer<D>,
182 _N: i32,
183 C: i32,
184 L: i32,
185 eps: f32,
186) where
187 T::I32Tensor: types::Tensor<i32, 1>,
188 T::I32Tensor: Comparison<i32, BoolTensor = T::BoolTensor>,
189 T::Pointer<D>: AddOffsets<i32, 1, T::I32Tensor, Output = T::Tensor<T::Pointer<D>>>,
190{
191 let pid = T::program_id(Axis::X);
192 let n = pid / C;
193 let c = pid - n * C;
194 let row_start = (n * C + c) * L;
195 let stat_idx = T::arange(0, 1) + pid;
196 let c_idx = T::arange(0, 1) + c;
197
198 let zeros = T::zeros::<D>(&[BLOCK_L]);
199 let zero_1 = T::zeros::<D>(&[1]);
200 let l_inv = T::cast::<f32, D>(T::full::<f32>(&[1], 1.0f32 / (L as f32)), None, false);
201
202 let mut sum = zero_1;
204 let mut l_start: i32 = 0;
205 while l_start < L {
206 let col_offs = T::arange(0, BLOCK_L) + l_start;
207 let mask = col_offs.lt(L);
208 let x_tile = T::load(
209 x_ptr.add_offsets(col_offs + row_start),
210 Some(mask),
211 Some(zeros),
212 &[],
213 None,
214 None,
215 None,
216 false,
217 );
218 sum = sum + T::sum(x_tile, None, true);
219 l_start += BLOCK_L;
220 }
221 let mean_1 = sum * l_inv;
222 let mean = T::broadcast_to(mean_1, &[BLOCK_L]);
223
224 let mut var_sum = zero_1;
226 l_start = 0;
227 while l_start < L {
228 let col_offs = T::arange(0, BLOCK_L) + l_start;
229 let mask = col_offs.lt(L);
230 let x_tile = T::load(
231 x_ptr.add_offsets(col_offs + row_start),
232 Some(mask),
233 Some(zeros),
234 &[],
235 None,
236 None,
237 None,
238 false,
239 );
240 let diff = T::where_::<D>(mask, x_tile - mean, zeros);
242 var_sum = var_sum + T::sum(diff * diff, None, true);
243 l_start += BLOCK_L;
244 }
245 let eps_t = T::cast::<f32, D>(T::full::<f32>(&[1], eps), None, false);
246 let rstd_1 = T::rsqrt(var_sum * l_inv + eps_t);
247 let rstd = T::broadcast_to(rstd_1, &[BLOCK_L]);
248
249 T::store(
250 mean_ptr.add_offsets(stat_idx),
251 mean_1,
252 None,
253 &[],
254 None,
255 None,
256 );
257 T::store(
258 rstd_ptr.add_offsets(stat_idx),
259 rstd_1,
260 None,
261 &[],
262 None,
263 None,
264 );
265
266 let gamma = T::broadcast_to(
267 T::load(
268 weight_ptr.add_offsets(c_idx),
269 None,
270 None,
271 &[],
272 None,
273 None,
274 None,
275 false,
276 ),
277 &[BLOCK_L],
278 );
279 let beta = T::broadcast_to(
280 T::load(
281 bias_ptr.add_offsets(c_idx),
282 None,
283 None,
284 &[],
285 None,
286 None,
287 None,
288 false,
289 ),
290 &[BLOCK_L],
291 );
292
293 l_start = 0;
295 while l_start < L {
296 let col_offs = T::arange(0, BLOCK_L) + l_start;
297 let mask = col_offs.lt(L);
298 let x_tile = T::load(
299 x_ptr.add_offsets(col_offs + row_start),
300 Some(mask),
301 Some(zeros),
302 &[],
303 None,
304 None,
305 None,
306 false,
307 );
308 let y_tile = (x_tile - mean) * rstd * gamma + beta;
309 T::store(
310 y_ptr.add_offsets(col_offs + row_start),
311 y_tile,
312 Some(mask),
313 &[],
314 None,
315 None,
316 );
317 l_start += BLOCK_L;
318 }
319}
320
321#[cfg(feature = "training")]
327#[kernel]
328pub fn instance_norm_backward<T: Triton, D: Float, const BLOCK_L: i32>(
329 dy_ptr: T::Pointer<D>,
330 x_ptr: T::Pointer<D>,
331 dx_ptr: T::Pointer<D>,
332 weight_ptr: T::Pointer<D>,
333 dweight_ptr: T::Pointer<D>,
334 dbias_ptr: T::Pointer<D>,
335 mean_ptr: T::Pointer<D>,
336 rstd_ptr: T::Pointer<D>,
337 _N: i32,
338 C: i32,
339 L: i32,
340) where
341 T::I32Tensor: types::Tensor<i32, 1>,
342 T::I32Tensor: Comparison<i32, BoolTensor = T::BoolTensor>,
343 T::Pointer<D>: AddOffsets<i32, 1, T::I32Tensor, Output = T::Tensor<T::Pointer<D>>>,
344{
345 let pid = T::program_id(Axis::X);
346 let n = pid / C;
347 let c = pid - n * C;
348 let row_start = (n * C + c) * L;
349 let stat_idx = T::arange(0, 1) + pid;
350 let c_idx = T::arange(0, 1) + c;
351
352 let zeros = T::zeros::<D>(&[BLOCK_L]);
353 let zero_1 = T::zeros::<D>(&[1]);
354 let l_inv = T::cast::<f32, D>(T::full::<f32>(&[1], 1.0f32 / (L as f32)), None, false);
355
356 let rstd_1 = T::load(
357 rstd_ptr.add_offsets(stat_idx),
358 None,
359 None,
360 &[],
361 None,
362 None,
363 None,
364 false,
365 );
366 let mean_1 = T::load(
367 mean_ptr.add_offsets(stat_idx),
368 None,
369 None,
370 &[],
371 None,
372 None,
373 None,
374 false,
375 );
376 let rstd = T::broadcast_to(rstd_1, &[BLOCK_L]);
377 let mean = T::broadcast_to(mean_1, &[BLOCK_L]);
378
379 let gamma = T::broadcast_to(
380 T::load(
381 weight_ptr.add_offsets(c_idx),
382 None,
383 None,
384 &[],
385 None,
386 None,
387 None,
388 false,
389 ),
390 &[BLOCK_L],
391 );
392
393 let mut sum_dy_gamma = zero_1;
395 let mut sum_dy_gamma_xhat = zero_1;
396 let mut l_start: i32 = 0;
397 while l_start < L {
398 let col_offs = T::arange(0, BLOCK_L) + l_start;
399 let mask = col_offs.lt(L);
400 let x_tile = T::load(
401 x_ptr.add_offsets(col_offs + row_start),
402 Some(mask),
403 Some(zeros),
404 &[],
405 None,
406 None,
407 None,
408 false,
409 );
410 let dy_tile = T::load(
411 dy_ptr.add_offsets(col_offs + row_start),
412 Some(mask),
413 Some(zeros),
414 &[],
415 None,
416 None,
417 None,
418 false,
419 );
420 let xhat = (x_tile - mean) * rstd;
421 sum_dy_gamma = sum_dy_gamma + T::sum(dy_tile * gamma, None, true);
422 sum_dy_gamma_xhat = sum_dy_gamma_xhat + T::sum(dy_tile * gamma * xhat, None, true);
423 l_start += BLOCK_L;
424 }
425 let c1 = T::broadcast_to(sum_dy_gamma * l_inv, &[BLOCK_L]);
426 let c2 = T::broadcast_to(sum_dy_gamma_xhat * l_inv, &[BLOCK_L]);
427
428 l_start = 0;
430 while l_start < L {
431 let col_offs = T::arange(0, BLOCK_L) + l_start;
432 let mask = col_offs.lt(L);
433 let x_tile = T::load(
434 x_ptr.add_offsets(col_offs + row_start),
435 Some(mask),
436 Some(zeros),
437 &[],
438 None,
439 None,
440 None,
441 false,
442 );
443 let dy_tile = T::load(
444 dy_ptr.add_offsets(col_offs + row_start),
445 Some(mask),
446 Some(zeros),
447 &[],
448 None,
449 None,
450 None,
451 false,
452 );
453 let dw_old = T::load(
454 dweight_ptr.add_offsets(c_idx),
455 None,
456 None,
457 &[],
458 None,
459 None,
460 None,
461 false,
462 );
463 let db_old = T::load(
464 dbias_ptr.add_offsets(c_idx),
465 None,
466 None,
467 &[],
468 None,
469 None,
470 None,
471 false,
472 );
473
474 let xhat = (x_tile - mean) * rstd;
475 let dx_tile = rstd * gamma * (dy_tile - c1 - xhat * c2);
476
477 T::store(
478 dx_ptr.add_offsets(col_offs + row_start),
479 dx_tile,
480 Some(mask),
481 &[],
482 None,
483 None,
484 );
485 T::store(
486 dweight_ptr.add_offsets(c_idx),
487 dw_old + T::sum(dy_tile * xhat, None, true),
488 None,
489 &[],
490 None,
491 None,
492 );
493 T::store(
494 dbias_ptr.add_offsets(c_idx),
495 db_old + T::sum(dy_tile, None, true),
496 None,
497 &[],
498 None,
499 None,
500 );
501 l_start += BLOCK_L;
502 }
503}