1#ifndef EVE_TENSOR_QUANT_H
2#define EVE_TENSOR_QUANT_H
31 default:
return count * 4;
40 std::memcpy(&
b, &
x, 4);
41 const uint32_t sign = (
b >> 16) & 0x8000u;
42 const int32_t e = int32_t((
b >> 23) & 0xFFu) - 127 + 15;
43 uint32_t
m =
b & 0x7FFFFFu;
44 if (e >= 0x1F)
return uint16_t(sign | 0x7C00u);
46 if (e < -10)
return uint16_t(sign);
48 const uint32_t shift = uint32_t(14 - e);
49 uint32_t half =
m >> shift;
50 const uint32_t rem =
m & ((1u << shift) - 1u);
51 if (rem > (1u << (shift - 1)) || (rem == (1u << (shift - 1)) && (half & 1u))) ++half;
53 return uint16_t(sign | half);
55 uint32_t half = (uint32_t(e) << 10) | (
m >> 13);
56 const uint32_t rem =
m & 0x1FFFu;
57 if (rem > 0x1000u || (rem == 0x1000u && (half & 1u))) ++half;
59 return uint16_t(sign | half);
64 const uint32_t sign = uint32_t(
h & 0x8000u) << 16;
65 uint32_t e = (
h >> 10) & 0x1Fu;
66 uint32_t
m =
h & 0x3FFu;
71 while (!(
m & 0x400u)) {
76 bits = sign | (e << 23) | (
m << 13);
79 bits = sign | 0x7F800000u | (
m << 13);
81 bits = sign | ((e + (127 - 15)) << 23) | (
m << 13);
85 std::memcpy(&
f, &bits, 4);
92 const uint32_t sign = uint32_t(
v & 0x80u) << 24;
93 const uint32_t e = (
v >> 3) & 0xFu;
94 const uint32_t
m =
v & 0x7u;
97 bits =
m == 0 ? sign : (sign | (uint32_t(127 - 6) << 23) | (
m << 20));
99 bits = sign | (uint32_t(e + 120) << 23) | (
m << 20);
103 std::memcpy(&
f, &bits, 4);
110 const float sign = (nib & 0x8u) ? -1.f : 1.f;
111 const int e = int((nib >> 1) & 0x3u);
112 const int m = int(nib & 0x1u);
113 const float v = e == 0 ? 0.5f * float(
m) : std::ldexp(1.0f, e - 1) * (1.0f + 0.5f * float(
m));
128 static std::vector<EfmEntry> *cache =
nullptr;
129 static int cacheExp = 0, cacheMan = 0, cacheBias = 0;
130 if (!cache || cacheExp != expBits || cacheMan != manBits || cacheBias !=
bias) {
132 cache =
new std::vector<EfmEntry>();
133 const int expCount = 1 << expBits;
134 const int manCount = 1 << manBits;
135 for (uint32_t e = 0; e < uint32_t(expCount); ++e) {
136 for (uint32_t
m = 0;
m < uint32_t(manCount); ++
m) {
138 ? std::ldexp(
float(
m), 1 -
bias - manBits)
140 : std::ldexp(1.0f +
float(
m) /
float(manCount),
int(e) -
bias);
141 cache->push_back({
v, (e << manBits) |
m});
145 std::sort(cache->begin(), cache->end(),
146 [](
const EfmEntry &
a,
const EfmEntry &
b) { return a.value < b.value; });
151 if (std::isnan(
x) || std::isinf(
x)) {
152 const uint32_t maxExp = (1u << expBits) - 2u;
153 const uint32_t maxBits = (maxExp << manBits) | ((1u << manBits) - 1u);
154 const uint32_t signBit = 1u << (expBits + manBits);
155 return x < 0 ? (signBit | maxBits) : maxBits;
157 const float ax = std::fabs(
x);
158 size_t lo = 0, hi = cache->size();
159 while (lo + 1 < hi) {
160 const size_t mid = (lo + hi) / 2;
161 if ((*cache)[
mid].value <=
ax) lo =
mid;
165 if (lo + 1 < cache->size() &&
167 std::fabs((*cache)[lo + 1].
value -
ax) < std::fabs((*cache)[lo].
value -
ax))
169 const uint32_t bits = (*cache)[
best].bits;
170 const uint32_t signBit = 1u << (expBits + manBits);
171 return x < 0 ? (signBit | bits) : bits;
189 const int maxExp = (1 << expBits) - 2;
190 const int maxMan = (1 << manBits) - 1;
192 return std::ldexp(1.0f +
float(maxMan) /
float(1 << manBits), maxExp -
bias);
203 std::memcpy(&
h,
bytes +
size_t(
idx) * 2, 2);
212 const int8_t
v = int8_t(
bytes[
static_cast<size_t>(
idx)]);
217 const uint8_t
byte =
bytes[
static_cast<size_t>(
idx) / 2];
218 const uint8_t nib = (
idx & 1) ? uint8_t(
byte >> 4) : uint8_t(
byte & 0xFu);
223 const uint8_t
byte =
bytes[
static_cast<size_t>(
idx) / 2];
224 int nib = (
idx & 1) ?
int(
byte >> 4) : int(
byte & 0xFu);
225 if (nib >= 8) nib -= 16;
227 return float(nib) *
scales[
static_cast<size_t>(
idx) /
size_t(
group)];
235 int count,
float *out) {
265 p.scales.resize(
static_cast<size_t>(
groups));
270 for (
int i =
begin; i < end; ++i) maxAbs = std::max(maxAbs, std::fabs(src[static_cast<size_t>(i)]));
271 float scale = maxAbs / float(maxQ);
273 p.scales[
static_cast<size_t>(
g)] =
scale;
275 const float norm = src[
static_cast<size_t>(i)] /
scale;
282 uint8_t &
byte =
p.bytes[
static_cast<size_t>(i) / 2];
283 if (i & 1)
byte = uint8_t((
byte & 0x0Fu) | uint8_t(nib << 4));
284 else byte = uint8_t((
byte & 0xF0u) | nib);
287 int qv = int(std::floor(norm + 0.5f));
288 const int qBound = int(maxQ);
289 qv = std::max(-qBound - 1, std::min(qBound, qv));
291 p.bytes[
static_cast<size_t>(i)] = uint8_t(int8_t(qv));
293 const int nib = qv & 0xFu;
294 uint8_t &
byte =
p.bytes[
static_cast<size_t>(i) / 2];
295 if (i & 1)
byte = uint8_t((
byte & 0x0Fu) | uint8_t(nib << 4));
296 else byte = uint8_t((
byte & 0xF0u) | uint8_t(nib));
302 for (
int i = 0; i <
count; ++i) {
303 const float v = src[
static_cast<size_t>(i)];
308 std::memcpy(
p.bytes.data() +
size_t(i) * 2, &
h, 2);
314 uint8_t &
byte =
p.bytes[
static_cast<size_t>(i) / 2];
315 if (i & 1)
byte = uint8_t((
byte & 0x0Fu) | uint8_t(nib << 4));
316 else byte = uint8_t((
byte & 0xF0u) | nib);
building::EdgeCurveGroup group
std::array< double, 10 > q
std::array< float, 3 > scale
std::vector< float > scales
std::map< Cell, int > best
void dequantizeAll(DType dt, const uint8_t *bytes, const float *scales, int group, int count, float *out)
Dequantize all.
float fp4E2M1ToF32(uint8_t nib)
Fp 4 e 2 m 1 to f 32.
QuantPayload quantize(const float *src, int count, DType dt, int group)
Quantize.
float f16ToF32(uint16_t h)
F 16 to f 32.
uint32_t floatToEfm(float x, int expBits, int manBits, int bias)
Float to efm.
uint8_t f32ToFp8E4M3(float x)
F 32 to fp 8 e 4 m 3.
float efmMaxMagnitude(int expBits, int manBits, int bias)
Efm max magnitude.
float dequantValue(DType dt, const uint8_t *bytes, const float *scales, int group, int idx)
Dequant value.
uint8_t f32ToFp4E2M1(float x)
F 32 to fp 4 e 2 m 1.
int quantByteSize(DType dt, int count)
Quant byte size.
float fp8E4M3ToF32(uint8_t v)
Fp 8 e 4 m 3 to f 32.
bool isQuantDType(DType dt)
True when quant d type.
uint16_t f32ToF16(float x)
F 32 to f 16.
DType
Tensor element types.
std::vector< float > scales
std::vector< uint8_t > bytes