• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2021 Google LLC
2//
3// This source code is licensed under the BSD-style license found in the
4// LICENSE file in the root directory of this source tree.
5
6$assert BATCH_TILE >= 1
7#include <assert.h>
8
9#include <xnnpack/common.h>
10#include <xnnpack/math.h>
11#include <xnnpack/vcvt.h>
12
13
14$XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
15void xnn_f32_${DATATYPE.lower()}_vcvt_ukernel__scalar_imagic_x${BATCH_TILE}(
16    size_t n,
17    const float* x,
18    ${XINT8_T}* y,
19    const union xnn_f32_${DATATYPE.lower()}_cvt_params params[restrict XNN_MIN_ELEMENTS(1)])
20{
21  assert(n != 0);
22  assert(n % sizeof(float) == 0);
23  assert(x != NULL);
24  assert(y != NULL);
25
26  const float vscale = params->scalar_imagic.scale;
27  const float vmagic_bias = params->scalar_imagic.magic_bias;
28  const int32_t vmagic_min = params->scalar_imagic.magic_min;
29  const int32_t vmagic_max = params->scalar_imagic.magic_max;
30  const int32_t vmagic_bias_less_zero_point = params->scalar_imagic.magic_bias_less_zero_point;
31
32  $if BATCH_TILE > 1:
33    for (; n >= ${BATCH_TILE} * sizeof(float); n -= ${BATCH_TILE} * sizeof(float)) {
34      $for N in range(BATCH_TILE):
35        float vx${N} = x[${N}];
36      x += ${BATCH_TILE};
37
38      $for N in range(BATCH_TILE):
39        vx${N} *= vscale;
40
41      $for N in range(BATCH_TILE):
42        vx${N} += vmagic_bias;
43
44      $for N in range(BATCH_TILE):
45        int32_t vy${N} = (int32_t) float_as_uint32(vx${N});
46
47      $for N in range(BATCH_TILE):
48        vy${N} = math_max_s32(vy${N}, vmagic_min);
49
50      $for N in range(BATCH_TILE):
51        vy${N} = math_min_s32(vy${N}, vmagic_max);
52
53      $for N in range(BATCH_TILE):
54        vy${N} -= vmagic_bias_less_zero_point;
55
56      $for N in range(BATCH_TILE):
57        y[${N}] = (${XINT8_T}) vy${N};
58      y += ${BATCH_TILE};
59    }
60  $if BATCH_TILE == 1:
61    do {
62      float vx = *x++;
63      vx *= vscale;
64      vx += vmagic_bias;
65
66      int32_t vy = (int32_t) float_as_uint32(vx);
67      vy = math_max_s32(vy, vmagic_min);
68      vy = math_min_s32(vy, vmagic_max);
69      vy -= vmagic_bias_less_zero_point;
70
71      *y++ = (${XINT8_T}) vy;
72
73      n -= sizeof(float);
74    } while (n != 0);
75  $elif BATCH_TILE == 2:
76    if XNN_UNLIKELY(n != 0) {
77      float vx = *x;
78      vx *= vscale;
79      vx += vmagic_bias;
80
81      int32_t vy = (int32_t) float_as_uint32(vx);
82      vy = math_max_s32(vy, vmagic_min);
83      vy = math_min_s32(vy, vmagic_max);
84      vy -= vmagic_bias_less_zero_point;
85
86      *y = (${XINT8_T}) vy;
87    }
88  $else:
89    if XNN_UNLIKELY(n != 0) {
90      do {
91        float vx = *x++;
92        vx *= vscale;
93        vx += vmagic_bias;
94
95        int32_t vy = (int32_t) float_as_uint32(vx);
96        vy = math_max_s32(vy, vmagic_min);
97        vy = math_min_s32(vy, vmagic_max);
98        vy -= vmagic_bias_less_zero_point;
99
100        *y++ = (${XINT8_T}) vy;
101
102        n -= sizeof(float);
103      } while (n != 0);
104    }
105}
106