1#[cfg(target_arch = "x86_64")]
7use std::arch::x86_64::*;
8
9#[cfg(target_arch = "x86_64")]
11#[target_feature(enable = "avx2", enable = "fma")]
12pub unsafe fn dot_product_avx2_fma(a: &[f32], b: &[f32]) -> f32 {
13 debug_assert_eq!(a.len(), b.len());
14
15 let mut sum = _mm256_setzero_ps();
16 let chunks = a.len() / 8;
17
18 for i in 0..chunks {
19 let va = _mm256_loadu_ps(a.as_ptr().add(i * 8));
20 let vb = _mm256_loadu_ps(b.as_ptr().add(i * 8));
21 sum = _mm256_fmadd_ps(va, vb, sum);
22 }
23
24 let sum128 = _mm_add_ps(_mm256_extractf128_ps(sum, 0), _mm256_extractf128_ps(sum, 1));
26 let sum64 = _mm_add_ps(sum128, _mm_movehl_ps(sum128, sum128));
27 let sum32 = _mm_add_ss(sum64, _mm_shuffle_ps(sum64, sum64, 1));
28
29 let mut result = 0.0f32;
30 _mm_store_ss(&mut result, sum32);
31
32 for i in (chunks * 8)..a.len() {
34 result += a[i] * b[i];
35 }
36
37 result
38}
39
40#[cfg(target_arch = "x86_64")]
42#[target_feature(enable = "avx2")]
43pub unsafe fn dot_product_avx2(a: &[f32], b: &[f32]) -> f32 {
44 debug_assert_eq!(a.len(), b.len());
45
46 let mut sum = _mm256_setzero_ps();
47 let chunks = a.len() / 8;
48
49 for i in 0..chunks {
50 let va = _mm256_loadu_ps(a.as_ptr().add(i * 8));
51 let vb = _mm256_loadu_ps(b.as_ptr().add(i * 8));
52 let prod = _mm256_mul_ps(va, vb);
53 sum = _mm256_add_ps(sum, prod);
54 }
55
56 let sum128 = _mm_add_ps(_mm256_extractf128_ps(sum, 0), _mm256_extractf128_ps(sum, 1));
58 let sum64 = _mm_add_ps(sum128, _mm_movehl_ps(sum128, sum128));
59 let sum32 = _mm_add_ss(sum64, _mm_shuffle_ps(sum64, sum64, 1));
60
61 let mut result = 0.0f32;
62 _mm_store_ss(&mut result, sum32);
63
64 for i in (chunks * 8)..a.len() {
66 result += a[i] * b[i];
67 }
68
69 result
70}
71
72#[cfg(target_arch = "x86_64")]
74#[target_feature(enable = "avx512f")]
75pub unsafe fn dot_product_avx512(a: &[f32], b: &[f32]) -> f32 {
76 debug_assert_eq!(a.len(), b.len());
77
78 let mut sum = _mm512_setzero_ps();
79 let chunks = a.len() / 16;
80
81 for i in 0..chunks {
82 let va = _mm512_loadu_ps(a.as_ptr().add(i * 16));
83 let vb = _mm512_loadu_ps(b.as_ptr().add(i * 16));
84 sum = _mm512_fmadd_ps(va, vb, sum);
85 }
86
87 let mut result = _mm512_reduce_add_ps(sum);
88
89 for i in (chunks * 16)..a.len() {
91 result += a[i] * b[i];
92 }
93
94 result
95}
96
97#[cfg(target_arch = "x86_64")]
99#[target_feature(enable = "avx2")]
100pub unsafe fn relu_avx2(input: &[f32], output: &mut [f32]) {
101 debug_assert_eq!(input.len(), output.len());
102
103 let zero = _mm256_setzero_ps();
104 let chunks = input.len() / 8;
105
106 for i in 0..chunks {
107 let v = _mm256_loadu_ps(input.as_ptr().add(i * 8));
108 let result = _mm256_max_ps(v, zero);
109 _mm256_storeu_ps(output.as_mut_ptr().add(i * 8), result);
110 }
111
112 for i in (chunks * 8)..input.len() {
114 output[i] = input[i].max(0.0);
115 }
116}
117
118#[cfg(target_arch = "x86_64")]
120#[target_feature(enable = "avx2")]
121pub unsafe fn relu6_avx2(input: &[f32], output: &mut [f32]) {
122 debug_assert_eq!(input.len(), output.len());
123
124 let zero = _mm256_setzero_ps();
125 let six = _mm256_set1_ps(6.0);
126 let chunks = input.len() / 8;
127
128 for i in 0..chunks {
129 let v = _mm256_loadu_ps(input.as_ptr().add(i * 8));
130 let result = _mm256_min_ps(_mm256_max_ps(v, zero), six);
131 _mm256_storeu_ps(output.as_mut_ptr().add(i * 8), result);
132 }
133
134 for i in (chunks * 8)..input.len() {
136 output[i] = input[i].max(0.0).min(6.0);
137 }
138}
139
140#[cfg(target_arch = "x86_64")]
142#[target_feature(enable = "avx2", enable = "fma")]
143pub unsafe fn batch_norm_avx2(
144 input: &[f32],
145 output: &mut [f32],
146 gamma: &[f32],
147 beta: &[f32],
148 mean: &[f32],
149 var: &[f32],
150 epsilon: f32,
151 channels: usize,
152) {
153 debug_assert_eq!(input.len(), output.len());
154
155 let mut scale = vec![0.0f32; channels];
157 let mut shift = vec![0.0f32; channels];
158
159 for c in 0..channels {
160 let inv_std = 1.0 / (var[c] + epsilon).sqrt();
161 scale[c] = gamma[c] * inv_std;
162 shift[c] = beta[c] - mean[c] * scale[c];
163 }
164
165 let spatial = input.len() / channels;
166
167 if channels == 8 {
169 let scale_v = _mm256_loadu_ps(scale.as_ptr());
170 let shift_v = _mm256_loadu_ps(shift.as_ptr());
171
172 for s in 0..spatial {
173 let offset = s * channels;
174 let v = _mm256_loadu_ps(input.as_ptr().add(offset));
175 let result = _mm256_fmadd_ps(v, scale_v, shift_v);
176 _mm256_storeu_ps(output.as_mut_ptr().add(offset), result);
177 }
178 } else {
179 for (i, (out, &inp)) in output.iter_mut().zip(input.iter()).enumerate() {
181 let c = i % channels;
182 *out = inp * scale[c] + shift[c];
183 }
184 }
185}
186
187#[cfg(target_arch = "x86_64")]
200#[target_feature(enable = "avx2", enable = "fma")]
201pub unsafe fn conv_3x3_avx2_fma(
202 input: &[f32],
203 kernel: &[f32],
204 output: &mut [f32],
205 in_h: usize,
206 in_w: usize,
207 in_c: usize,
208 out_c: usize,
209 stride: usize,
210 padding: usize,
211) {
212 let out_h = (in_h + 2 * padding - 3) / stride + 1;
213 let out_w = (in_w + 2 * padding - 3) / stride + 1;
214
215 let out_c_chunks = out_c / 8;
217
218 let ic_chunks = in_c / 4;
220 let ic_remainder_start = ic_chunks * 4;
221
222 for oh in 0..out_h {
223 for ow in 0..out_w {
224 let out_spatial_idx = oh * out_w + ow;
225
226 for oc_chunk in 0..out_c_chunks {
228 let oc_base = oc_chunk * 8;
229
230 let mut sum0 = _mm256_setzero_ps();
232 let mut sum1 = _mm256_setzero_ps();
233 let mut sum2 = _mm256_setzero_ps();
234 let mut sum3 = _mm256_setzero_ps();
235
236 for kh in 0..3 {
238 for kw in 0..3 {
239 let ih = (oh * stride + kh) as isize - padding as isize;
240 let iw = (ow * stride + kw) as isize - padding as isize;
241
242 if ih >= 0 && ih < in_h as isize && iw >= 0 && iw < in_w as isize {
243 let ih = ih as usize;
244 let iw = iw as usize;
245 let input_base = (ih * in_w + iw) * in_c;
246 let kernel_offset = kh * 3 + kw;
247
248 for ic_chunk_idx in 0..ic_chunks {
250 let ic_base = ic_chunk_idx * 4;
251
252 let input_val0 = _mm256_set1_ps(*input.get_unchecked(input_base + ic_base));
254 let input_val1 = _mm256_set1_ps(*input.get_unchecked(input_base + ic_base + 1));
255 let input_val2 = _mm256_set1_ps(*input.get_unchecked(input_base + ic_base + 2));
256 let input_val3 = _mm256_set1_ps(*input.get_unchecked(input_base + ic_base + 3));
257
258 let mut kv0 = [0.0f32; 8];
260 let mut kv1 = [0.0f32; 8];
261 let mut kv2 = [0.0f32; 8];
262 let mut kv3 = [0.0f32; 8];
263
264 for i in 0..8 {
265 let oc_idx = oc_base + i;
266 kv0[i] = *kernel.get_unchecked((oc_idx * in_c + ic_base) * 9 + kernel_offset);
267 kv1[i] = *kernel.get_unchecked((oc_idx * in_c + ic_base + 1) * 9 + kernel_offset);
268 kv2[i] = *kernel.get_unchecked((oc_idx * in_c + ic_base + 2) * 9 + kernel_offset);
269 kv3[i] = *kernel.get_unchecked((oc_idx * in_c + ic_base + 3) * 9 + kernel_offset);
270 }
271
272 let kernel_v0 = _mm256_loadu_ps(kv0.as_ptr());
273 let kernel_v1 = _mm256_loadu_ps(kv1.as_ptr());
274 let kernel_v2 = _mm256_loadu_ps(kv2.as_ptr());
275 let kernel_v3 = _mm256_loadu_ps(kv3.as_ptr());
276
277 sum0 = _mm256_fmadd_ps(input_val0, kernel_v0, sum0);
279 sum1 = _mm256_fmadd_ps(input_val1, kernel_v1, sum1);
280 sum2 = _mm256_fmadd_ps(input_val2, kernel_v2, sum2);
281 sum3 = _mm256_fmadd_ps(input_val3, kernel_v3, sum3);
282 }
283
284 for ic in ic_remainder_start..in_c {
286 let input_val = _mm256_set1_ps(*input.get_unchecked(input_base + ic));
287
288 let mut kernel_vals = [0.0f32; 8];
289 for i in 0..8 {
290 kernel_vals[i] = *kernel.get_unchecked(((oc_base + i) * in_c + ic) * 9 + kernel_offset);
291 }
292 let kernel_v = _mm256_loadu_ps(kernel_vals.as_ptr());
293
294 sum0 = _mm256_fmadd_ps(input_val, kernel_v, sum0);
295 }
296 }
297 }
298 }
299
300 let sum01 = _mm256_add_ps(sum0, sum1);
302 let sum23 = _mm256_add_ps(sum2, sum3);
303 let sum = _mm256_add_ps(sum01, sum23);
304
305 let out_base = out_spatial_idx * out_c + oc_base;
307 _mm256_storeu_ps(output.as_mut_ptr().add(out_base), sum);
308 }
309
310 for oc in (out_c_chunks * 8)..out_c {
312 let mut sum = 0.0f32;
313
314 for kh in 0..3 {
315 for kw in 0..3 {
316 let ih = (oh * stride + kh) as isize - padding as isize;
317 let iw = (ow * stride + kw) as isize - padding as isize;
318
319 if ih >= 0 && ih < in_h as isize && iw >= 0 && iw < in_w as isize {
320 let ih = ih as usize;
321 let iw = iw as usize;
322
323 for ic in 0..in_c {
324 let input_idx = (ih * in_w + iw) * in_c + ic;
325 let kernel_idx = (oc * in_c + ic) * 9 + kh * 3 + kw;
326 sum += input[input_idx] * kernel[kernel_idx];
327 }
328 }
329 }
330 }
331
332 output[out_spatial_idx * out_c + oc] = sum;
333 }
334 }
335 }
336}
337
338#[cfg(target_arch = "x86_64")]
344#[target_feature(enable = "avx2")]
345pub unsafe fn conv_3x3_avx2(
346 input: &[f32],
347 kernel: &[f32],
348 output: &mut [f32],
349 in_h: usize,
350 in_w: usize,
351 in_c: usize,
352 out_c: usize,
353 stride: usize,
354 padding: usize,
355) {
356 let out_h = (in_h + 2 * padding - 3) / stride + 1;
357 let out_w = (in_w + 2 * padding - 3) / stride + 1;
358
359 let out_c_chunks = out_c / 8;
360 let ic_chunks = in_c / 4;
361 let ic_remainder_start = ic_chunks * 4;
362
363 for oh in 0..out_h {
364 for ow in 0..out_w {
365 let out_spatial_idx = oh * out_w + ow;
366
367 for oc_chunk in 0..out_c_chunks {
369 let oc_base = oc_chunk * 8;
370
371 let mut sum0 = _mm256_setzero_ps();
373 let mut sum1 = _mm256_setzero_ps();
374 let mut sum2 = _mm256_setzero_ps();
375 let mut sum3 = _mm256_setzero_ps();
376
377 for kh in 0..3 {
378 for kw in 0..3 {
379 let ih = (oh * stride + kh) as isize - padding as isize;
380 let iw = (ow * stride + kw) as isize - padding as isize;
381
382 if ih >= 0 && ih < in_h as isize && iw >= 0 && iw < in_w as isize {
383 let ih = ih as usize;
384 let iw = iw as usize;
385 let input_base = (ih * in_w + iw) * in_c;
386 let kernel_offset = kh * 3 + kw;
387
388 for ic_chunk_idx in 0..ic_chunks {
390 let ic_base = ic_chunk_idx * 4;
391
392 let input_val0 = _mm256_set1_ps(*input.get_unchecked(input_base + ic_base));
393 let input_val1 = _mm256_set1_ps(*input.get_unchecked(input_base + ic_base + 1));
394 let input_val2 = _mm256_set1_ps(*input.get_unchecked(input_base + ic_base + 2));
395 let input_val3 = _mm256_set1_ps(*input.get_unchecked(input_base + ic_base + 3));
396
397 let mut kv0 = [0.0f32; 8];
398 let mut kv1 = [0.0f32; 8];
399 let mut kv2 = [0.0f32; 8];
400 let mut kv3 = [0.0f32; 8];
401
402 for i in 0..8 {
403 let oc_idx = oc_base + i;
404 kv0[i] = *kernel.get_unchecked((oc_idx * in_c + ic_base) * 9 + kernel_offset);
405 kv1[i] = *kernel.get_unchecked((oc_idx * in_c + ic_base + 1) * 9 + kernel_offset);
406 kv2[i] = *kernel.get_unchecked((oc_idx * in_c + ic_base + 2) * 9 + kernel_offset);
407 kv3[i] = *kernel.get_unchecked((oc_idx * in_c + ic_base + 3) * 9 + kernel_offset);
408 }
409
410 let kernel_v0 = _mm256_loadu_ps(kv0.as_ptr());
411 let kernel_v1 = _mm256_loadu_ps(kv1.as_ptr());
412 let kernel_v2 = _mm256_loadu_ps(kv2.as_ptr());
413 let kernel_v3 = _mm256_loadu_ps(kv3.as_ptr());
414
415 sum0 = _mm256_add_ps(sum0, _mm256_mul_ps(input_val0, kernel_v0));
417 sum1 = _mm256_add_ps(sum1, _mm256_mul_ps(input_val1, kernel_v1));
418 sum2 = _mm256_add_ps(sum2, _mm256_mul_ps(input_val2, kernel_v2));
419 sum3 = _mm256_add_ps(sum3, _mm256_mul_ps(input_val3, kernel_v3));
420 }
421
422 for ic in ic_remainder_start..in_c {
424 let input_val = _mm256_set1_ps(*input.get_unchecked(input_base + ic));
425
426 let mut kernel_vals = [0.0f32; 8];
427 for i in 0..8 {
428 kernel_vals[i] = *kernel.get_unchecked(((oc_base + i) * in_c + ic) * 9 + kernel_offset);
429 }
430 let kernel_v = _mm256_loadu_ps(kernel_vals.as_ptr());
431
432 sum0 = _mm256_add_ps(sum0, _mm256_mul_ps(input_val, kernel_v));
433 }
434 }
435 }
436 }
437
438 let sum01 = _mm256_add_ps(sum0, sum1);
440 let sum23 = _mm256_add_ps(sum2, sum3);
441 let sum = _mm256_add_ps(sum01, sum23);
442
443 let out_base = out_spatial_idx * out_c + oc_base;
444 _mm256_storeu_ps(output.as_mut_ptr().add(out_base), sum);
445 }
446
447 for oc in (out_c_chunks * 8)..out_c {
449 let mut sum = 0.0f32;
450 for kh in 0..3 {
451 for kw in 0..3 {
452 let ih = (oh * stride + kh) as isize - padding as isize;
453 let iw = (ow * stride + kw) as isize - padding as isize;
454
455 if ih >= 0 && ih < in_h as isize && iw >= 0 && iw < in_w as isize {
456 let ih = ih as usize;
457 let iw = iw as usize;
458 for ic in 0..in_c {
459 let input_idx = (ih * in_w + iw) * in_c + ic;
460 let kernel_idx = (oc * in_c + ic) * 9 + kh * 3 + kw;
461 sum += input[input_idx] * kernel[kernel_idx];
462 }
463 }
464 }
465 }
466 output[out_spatial_idx * out_c + oc] = sum;
467 }
468 }
469 }
470}
471
472#[cfg(target_arch = "x86_64")]
477#[target_feature(enable = "avx2")]
478pub unsafe fn depthwise_conv_3x3_avx2(
479 input: &[f32],
480 kernel: &[f32],
481 output: &mut [f32],
482 h: usize,
483 w: usize,
484 c: usize,
485 stride: usize,
486 padding: usize,
487) {
488 let out_h = (h + 2 * padding - 3) / stride + 1;
489 let out_w = (w + 2 * padding - 3) / stride + 1;
490 let c_chunks = c / 8;
491
492 for oh in 0..out_h {
493 for ow in 0..out_w {
494 for c_chunk in 0..c_chunks {
496 let c_base = c_chunk * 8;
497
498 let mut sum_row0 = _mm256_setzero_ps();
500 let mut sum_row1 = _mm256_setzero_ps();
501 let mut sum_row2 = _mm256_setzero_ps();
502
503 let mut kernel_cache = [[_mm256_setzero_ps(); 3]; 3];
505 for kh in 0..3 {
506 for kw in 0..3 {
507 let mut kvals = [0.0f32; 8];
508 for i in 0..8 {
509 kvals[i] = *kernel.get_unchecked((c_base + i) * 9 + kh * 3 + kw);
510 }
511 kernel_cache[kh][kw] = _mm256_loadu_ps(kvals.as_ptr());
512 }
513 }
514
515 let ih0 = (oh * stride) as isize - padding as isize;
517 if ih0 >= 0 && ih0 < h as isize {
518 let ih0 = ih0 as usize;
519 for kw in 0..3 {
520 let iw = (ow * stride + kw) as isize - padding as isize;
521 if iw >= 0 && iw < w as isize {
522 let input_base = (ih0 * w + iw as usize) * c + c_base;
523 let input_v = _mm256_loadu_ps(input.as_ptr().add(input_base));
524 sum_row0 = _mm256_add_ps(sum_row0, _mm256_mul_ps(input_v, kernel_cache[0][kw]));
525 }
526 }
527 }
528
529 let ih1 = (oh * stride + 1) as isize - padding as isize;
531 if ih1 >= 0 && ih1 < h as isize {
532 let ih1 = ih1 as usize;
533 for kw in 0..3 {
534 let iw = (ow * stride + kw) as isize - padding as isize;
535 if iw >= 0 && iw < w as isize {
536 let input_base = (ih1 * w + iw as usize) * c + c_base;
537 let input_v = _mm256_loadu_ps(input.as_ptr().add(input_base));
538 sum_row1 = _mm256_add_ps(sum_row1, _mm256_mul_ps(input_v, kernel_cache[1][kw]));
539 }
540 }
541 }
542
543 let ih2 = (oh * stride + 2) as isize - padding as isize;
545 if ih2 >= 0 && ih2 < h as isize {
546 let ih2 = ih2 as usize;
547 for kw in 0..3 {
548 let iw = (ow * stride + kw) as isize - padding as isize;
549 if iw >= 0 && iw < w as isize {
550 let input_base = (ih2 * w + iw as usize) * c + c_base;
551 let input_v = _mm256_loadu_ps(input.as_ptr().add(input_base));
552 sum_row2 = _mm256_add_ps(sum_row2, _mm256_mul_ps(input_v, kernel_cache[2][kw]));
553 }
554 }
555 }
556
557 let sum = _mm256_add_ps(_mm256_add_ps(sum_row0, sum_row1), sum_row2);
559
560 let out_base = (oh * out_w + ow) * c + c_base;
561 _mm256_storeu_ps(output.as_mut_ptr().add(out_base), sum);
562 }
563
564 for ch in (c_chunks * 8)..c {
566 let mut sum = 0.0f32;
567 for kh in 0..3 {
568 for kw in 0..3 {
569 let ih = (oh * stride + kh) as isize - padding as isize;
570 let iw = (ow * stride + kw) as isize - padding as isize;
571
572 if ih >= 0 && ih < h as isize && iw >= 0 && iw < w as isize {
573 let ih = ih as usize;
574 let iw = iw as usize;
575 let input_idx = (ih * w + iw) * c + ch;
576 let kernel_idx = ch * 9 + kh * 3 + kw;
577 sum += input[input_idx] * kernel[kernel_idx];
578 }
579 }
580 }
581 output[(oh * out_w + ow) * c + ch] = sum;
582 }
583 }
584 }
585}
586
587#[cfg(target_arch = "x86_64")]
591#[target_feature(enable = "avx2")]
592pub unsafe fn global_avg_pool_avx2(input: &[f32], output: &mut [f32], h: usize, w: usize, c: usize) {
593 let spatial = h * w;
594 let c_chunks = c / 8;
595 let inv_spatial = _mm256_set1_ps(1.0 / spatial as f32);
596
597 for c_chunk in 0..c_chunks {
599 let c_base = c_chunk * 8;
600 let mut sum = _mm256_setzero_ps();
601
602 for s in 0..spatial {
604 let input_base = s * c + c_base;
605 let v = _mm256_loadu_ps(input.as_ptr().add(input_base));
606 sum = _mm256_add_ps(sum, v);
607 }
608
609 let avg = _mm256_mul_ps(sum, inv_spatial);
611 _mm256_storeu_ps(output.as_mut_ptr().add(c_base), avg);
612 }
613
614 let inv_spatial_scalar = 1.0 / spatial as f32;
616 for ch in (c_chunks * 8)..c {
617 let mut sum = 0.0f32;
618 for s in 0..spatial {
619 sum += input[s * c + ch];
620 }
621 output[ch] = sum * inv_spatial_scalar;
622 }
623}
624
625#[cfg(target_arch = "x86_64")]
629#[target_feature(enable = "avx2")]
630pub unsafe fn max_pool_2x2_avx2(
631 input: &[f32],
632 output: &mut [f32],
633 h: usize,
634 w: usize,
635 c: usize,
636 stride: usize,
637) {
638 let out_h = (h - 2) / stride + 1;
639 let out_w = (w - 2) / stride + 1;
640 let c_chunks = c / 8;
641
642 for oh in 0..out_h {
643 for ow in 0..out_w {
644 let ih = oh * stride;
645 let iw = ow * stride;
646
647 for c_chunk in 0..c_chunks {
649 let c_base = c_chunk * 8;
650
651 let idx00 = (ih * w + iw) * c + c_base;
653 let idx01 = (ih * w + iw + 1) * c + c_base;
654 let idx10 = ((ih + 1) * w + iw) * c + c_base;
655 let idx11 = ((ih + 1) * w + iw + 1) * c + c_base;
656
657 let v00 = _mm256_loadu_ps(input.as_ptr().add(idx00));
658 let v01 = _mm256_loadu_ps(input.as_ptr().add(idx01));
659 let v10 = _mm256_loadu_ps(input.as_ptr().add(idx10));
660 let v11 = _mm256_loadu_ps(input.as_ptr().add(idx11));
661
662 let max01 = _mm256_max_ps(v00, v01);
664 let max23 = _mm256_max_ps(v10, v11);
665 let max_all = _mm256_max_ps(max01, max23);
666
667 let out_base = (oh * out_w + ow) * c + c_base;
668 _mm256_storeu_ps(output.as_mut_ptr().add(out_base), max_all);
669 }
670
671 for ch in (c_chunks * 8)..c {
673 let v00 = input[(ih * w + iw) * c + ch];
674 let v01 = input[(ih * w + iw + 1) * c + ch];
675 let v10 = input[((ih + 1) * w + iw) * c + ch];
676 let v11 = input[((ih + 1) * w + iw + 1) * c + ch];
677 output[(oh * out_w + ow) * c + ch] = v00.max(v01).max(v10).max(v11);
678 }
679 }
680 }
681}
682
683#[cfg(not(target_arch = "x86_64"))]
685pub unsafe fn dot_product_avx2_fma(_a: &[f32], _b: &[f32]) -> f32 { 0.0 }
686#[cfg(not(target_arch = "x86_64"))]
687pub unsafe fn dot_product_avx2(_a: &[f32], _b: &[f32]) -> f32 { 0.0 }
688#[cfg(not(target_arch = "x86_64"))]
689pub unsafe fn dot_product_avx512(_a: &[f32], _b: &[f32]) -> f32 { 0.0 }
690#[cfg(not(target_arch = "x86_64"))]
691pub unsafe fn relu_avx2(_input: &[f32], _output: &mut [f32]) {}
692#[cfg(not(target_arch = "x86_64"))]
693pub unsafe fn relu6_avx2(_input: &[f32], _output: &mut [f32]) {}
694#[cfg(not(target_arch = "x86_64"))]
695pub unsafe fn batch_norm_avx2(_input: &[f32], _output: &mut [f32], _gamma: &[f32], _beta: &[f32], _mean: &[f32], _var: &[f32], _epsilon: f32, _channels: usize) {}
696#[cfg(not(target_arch = "x86_64"))]
697pub unsafe fn conv_3x3_avx2_fma(_input: &[f32], _kernel: &[f32], _output: &mut [f32], _in_h: usize, _in_w: usize, _in_c: usize, _out_c: usize, _stride: usize, _padding: usize) {}
698#[cfg(not(target_arch = "x86_64"))]
699pub unsafe fn conv_3x3_avx2(_input: &[f32], _kernel: &[f32], _output: &mut [f32], _in_h: usize, _in_w: usize, _in_c: usize, _out_c: usize, _stride: usize, _padding: usize) {}
700#[cfg(not(target_arch = "x86_64"))]
701pub unsafe fn depthwise_conv_3x3_avx2(_input: &[f32], _kernel: &[f32], _output: &mut [f32], _h: usize, _w: usize, _c: usize, _stride: usize, _padding: usize) {}
702#[cfg(not(target_arch = "x86_64"))]
703pub unsafe fn global_avg_pool_avx2(_input: &[f32], _output: &mut [f32], _h: usize, _w: usize, _c: usize) {}
704#[cfg(not(target_arch = "x86_64"))]
705pub unsafe fn max_pool_2x2_avx2(_input: &[f32], _output: &mut [f32], _h: usize, _w: usize, _c: usize, _stride: usize) {}