1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#if defined(LIB_JXL_QUANTIZER_INL_H_) == defined(HWY_TARGET_TOGGLE)
#ifdef LIB_JXL_QUANTIZER_INL_H_
#undef LIB_JXL_QUANTIZER_INL_H_
#else
#define LIB_JXL_QUANTIZER_INL_H_
#endif
#include <stddef.h>
#include <hwy/highway.h>
HWY_BEFORE_NAMESPACE();
namespace jxl {
namespace HWY_NAMESPACE {
namespace {
// These templates are not found via ADL.
using hwy::HWY_NAMESPACE::Rebind;
using hwy::HWY_NAMESPACE::Vec;
template <class DI>
HWY_INLINE HWY_MAYBE_UNUSED Vec<Rebind<float, DI>> AdjustQuantBias(
DI di, const size_t c, const Vec<DI> quant_i,
const float* HWY_RESTRICT biases) {
const Rebind<float, DI> df;
#if JXL_HIGH_PRECISION
const auto quant = ConvertTo(df, quant_i);
// Compare |quant|, keep sign bit for negating result.
const auto kSign = BitCast(df, Set(di, INT32_MIN));
const auto sign = And(quant, kSign); // TODO(janwas): = abs ^ orig
const auto abs_quant = AndNot(kSign, quant);
// If |x| is 1, kZeroBias creates a different bias for each channel.
// We're implementing the following:
// if (quant == 0) return 0;
// if (quant == 1) return biases[c];
// if (quant == -1) return -biases[c];
// return quant - biases[3] / quant;
// Integer comparison is not helpful because Clang incurs bypass penalties
// from unnecessarily mixing integer and float.
const auto is_01 = abs_quant < Set(df, 1.125f);
const auto not_0 = abs_quant > Zero(df);
// Bitwise logic is faster than quant * biases[c].
const auto one_bias = IfThenElseZero(not_0, Xor(Set(df, biases[c]), sign));
// About 2E-5 worse than ReciprocalNR or division.
const auto bias =
NegMulAdd(Set(df, biases[3]), ApproximateReciprocal(quant), quant);
return IfThenElse(is_01, one_bias, bias);
#else
auto sign = IfThenElseZero(quant_i < Zero(di), Set(di, INT32_MIN));
return BitCast(df, IfThenElse(Abs(quant_i) == Set(di, 1),
sign | BitCast(di, Set(df, biases[c])),
BitCast(di, ConvertTo(df, quant_i))));
#endif
}
} // namespace
// NOLINTNEXTLINE(google-readability-namespace-comments)
} // namespace HWY_NAMESPACE
} // namespace jxl
HWY_AFTER_NAMESPACE();
#endif // LIB_JXL_QUANTIZER_INL_H_
|