Coverage Report

Created: 2026-01-15 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xnnpack/src/f32-gemm/gen/f32-gemm-1x8-minmax-fma3-broadcast.c
Line
Count
Source
1
// clang-format off
2
// Auto-generated file. Do not edit!
3
//   Template: src/f32-gemm/avx-broadcast.c.in
4
//   Generator: tools/xngen
5
//
6
// Copyright 2019 Google LLC
7
//
8
// This source code is licensed under the BSD-style license found in the
9
// LICENSE file in the root directory of this source tree.
10
11
#include <assert.h>
12
#include <stddef.h>
13
#include <stdint.h>
14
15
#include <immintrin.h>
16
17
#include "src/xnnpack/common.h"
18
#include "src/xnnpack/gemm.h"
19
#include "src/xnnpack/microparams.h"
20
21
22
void xnn_f32_gemm_minmax_ukernel_1x8__fma3_broadcast(
23
    size_t mr,
24
    size_t nc,
25
    size_t kc,
26
    const float* restrict a,
27
    size_t a_stride,
28
    const float* restrict w,
29
    float* restrict c,
30
    size_t cm_stride,
31
    size_t cn_stride,
32
    const struct xnn_f32_minmax_params* restrict params)
33
0
{
34
0
  assert(mr != 0);
35
0
  assert(mr <= 1);
36
0
  assert(nc != 0);
37
0
  assert(kc != 0);
38
0
  assert(kc % sizeof(float) == 0);
39
0
  assert(a != NULL);
40
0
  assert(w != NULL);
41
0
  assert(c != NULL);
42
43
0
  const float* a0 = a;
44
0
  float* c0 = c;
45
46
0
  const __m256 vmin = _mm256_set1_ps(params->scalar.min);
47
0
  const __m256 vmax = _mm256_set1_ps(params->scalar.max);
48
0
  XNN_FORCE_REALIZATION(vmin);
49
0
  XNN_FORCE_REALIZATION(vmax);
50
51
0
  do {
52
0
    __m256 vacc0x01234567 = _mm256_load_ps(w + 0);
53
0
    w += 8;
54
55
0
    size_t k = kc;
56
0
    do {
57
0
      const __m256 va0 = _mm256_broadcast_ss(a0);
58
0
      a0 += 1;
59
60
0
      const __m256 vb01234567 = _mm256_load_ps(w);
61
0
      w += 8;
62
63
0
      vacc0x01234567 = _mm256_fmadd_ps(va0, vb01234567, vacc0x01234567);
64
65
0
      k -= sizeof(float);
66
0
    } while (k != 0);
67
68
0
    vacc0x01234567 = _mm256_max_ps(vmin, vacc0x01234567);
69
70
0
    vacc0x01234567 = _mm256_min_ps(vmax, vacc0x01234567);
71
72
0
    if XNN_LIKELY(nc >= 8) {
73
0
      _mm256_storeu_ps(c0, vacc0x01234567);
74
0
      c0 = (float*) ((uintptr_t) c0 + cn_stride);
75
76
0
      a0 = (const float*) ((uintptr_t) a0 - kc);
77
78
0
      nc -= 8;
79
0
    } else {
80
0
      __m128 vacc0x0123 = _mm256_castps256_ps128(vacc0x01234567);
81
0
      if (nc & 4) {
82
0
        _mm_storeu_ps(c0, vacc0x0123);
83
84
0
        vacc0x0123 = _mm256_extractf128_ps(vacc0x01234567, 1);
85
86
0
        c0 += 4;
87
0
      }
88
0
      if (nc & 2) {
89
0
        _mm_storel_pi((__m64*) c0, vacc0x0123);
90
91
0
        vacc0x0123 = _mm_movehl_ps(vacc0x0123, vacc0x0123);
92
93
0
        c0 += 2;
94
0
      }
95
0
      if (nc & 1) {
96
0
        _mm_store_ss(c0, vacc0x0123);
97
0
      }
98
99
0
      nc = 0;
100
0
    }
101
0
  } while (nc != 0);
102
0
}