Skip to content

Commit d47bb38

Browse files
committed
Fused FMA scaling
1 parent e31afd3 commit d47bb38

2 files changed

Lines changed: 19 additions & 28 deletions

File tree

benchmark/bench.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414

1515
auto main() -> int {
1616
const std::size_t nt {std::max(1u, std::thread::hardware_concurrency())};
17-
volatile std::size_t numel {1024*1024*1024/4};
18-
std::vector<float> data_in {};
17+
volatile std::size_t numel {(1ull<<30)};
18+
std::vector<piquant::bfp16_t> data_in {};
1919
std::vector<piquant::uint4_t> data_out {};
2020
data_in.resize(numel);
2121
data_out.resize((numel+1)/2);
@@ -25,8 +25,11 @@ auto main() -> int {
2525
std::ranges::generate(data_in, [&] { return dist(gen); });
2626
ankerl::nanobench::Bench bench {};
2727
piquant::context ctx {nt};
28-
bench.run("requantize", [&] {
29-
ctx.quantize_generic<float, piquant::uint4_t>(data_in, data_out, 0.2f, 127, piquant::round_mode::nearest);
28+
bench.run("quantize bf16 -> uint4", [&] {
29+
ctx.quantize_generic<piquant::bfp16_t, piquant::uint4_t>(data_in, data_out, 0.2f, 127, piquant::round_mode::nearest);
30+
});
31+
bench.run("dequantize uint4 -> bf16", [&] {
32+
ctx.dequantize_generic<piquant::uint4_t, piquant::bfp16_t>(data_out, data_in, 0.2f, 127, piquant::reduce_op::set);
3033
});
3134
return 0;
3235
}

src/kernels/kernels_specialized.inl

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,7 @@ static auto PIQUANT_HOT dequant_uint4_to_bf16(
11281128
__m512i vzp {_mm512_set1_epi32(zp)};
11291129
__m512 vscale {_mm512_set1_ps(scale)};
11301130
__m512i vmaskLo {_mm512_set1_epi8(0x0f)};
1131+
__m512 vbias {_mm512_set1_ps(-static_cast<fp32_t>(zp)*scale)};
11311132
static constexpr auto expand_u8_to_s32 {[](__m512i v) noexcept -> std::array<__m512i, 4> {
11321133
__m128i l0 {_mm512_extracti32x4_epi32(v, 0)};
11331134
__m128i l1 {_mm512_extracti32x4_epi32(v, 1)};
@@ -1154,32 +1155,19 @@ static auto PIQUANT_HOT dequant_uint4_to_bf16(
11541155
v1 = _mm512_inserti32x4(v1, _mm512_extracti32x4_epi32(t1, 3), 3);
11551156
return {v0, v1};
11561157
}};
1157-
static constexpr auto load_bf16_as_ps {[](const bfp16_t* p) noexcept -> __m512 {
1158-
__m256i v16 = _mm256_loadu_si256((const __m256i*)p);
1159-
__m512i v32 = _mm512_cvtepu16_epi32(v16);
1160-
return _mm512_castsi512_ps(_mm512_slli_epi32(v32, 16));
1161-
}};
11621158
for (; i+127 < numel; i += 128) {
11631159
__m512i packed {_mm512_loadu_si512(reinterpret_cast<const std::uint8_t*>(x) + (i>>1))};
1164-
auto [nib0, nib1] = unpack_nibbles(packed);
1165-
auto [vs00, vs10, vs20, vs30] = expand_u8_to_s32(nib0);
1166-
auto [vs01, vs11, vs21, vs31] = expand_u8_to_s32(nib1);
1167-
vs00 = _mm512_sub_epi32(vs00, vzp);
1168-
vs10 = _mm512_sub_epi32(vs10, vzp);
1169-
vs20 = _mm512_sub_epi32(vs20, vzp);
1170-
vs30 = _mm512_sub_epi32(vs30, vzp);
1171-
vs01 = _mm512_sub_epi32(vs01, vzp);
1172-
vs11 = _mm512_sub_epi32(vs11, vzp);
1173-
vs21 = _mm512_sub_epi32(vs21, vzp);
1174-
vs31 = _mm512_sub_epi32(vs31, vzp);
1175-
__m512 vf00 {_mm512_mul_ps(_mm512_cvtepi32_ps(vs00), vscale)};
1176-
__m512 vf10 {_mm512_mul_ps(_mm512_cvtepi32_ps(vs10), vscale)};
1177-
__m512 vf20 {_mm512_mul_ps(_mm512_cvtepi32_ps(vs20), vscale)};
1178-
__m512 vf30 {_mm512_mul_ps(_mm512_cvtepi32_ps(vs30), vscale)};
1179-
__m512 vf01 {_mm512_mul_ps(_mm512_cvtepi32_ps(vs01), vscale)};
1180-
__m512 vf11 {_mm512_mul_ps(_mm512_cvtepi32_ps(vs11), vscale)};
1181-
__m512 vf21 {_mm512_mul_ps(_mm512_cvtepi32_ps(vs21), vscale)};
1182-
__m512 vf31 {_mm512_mul_ps(_mm512_cvtepi32_ps(vs31), vscale)};
1160+
auto [nib0, nib1] {unpack_nibbles(packed)};
1161+
auto [vs00, vs10, vs20, vs30] {expand_u8_to_s32(nib0)};
1162+
auto [vs01, vs11, vs21, vs31] {expand_u8_to_s32(nib1)};
1163+
__m512 vf00 = _mm512_fmadd_ps(_mm512_cvtepi32_ps(vs00), vscale, vbias);
1164+
__m512 vf10 = _mm512_fmadd_ps(_mm512_cvtepi32_ps(vs10), vscale, vbias);
1165+
__m512 vf20 = _mm512_fmadd_ps(_mm512_cvtepi32_ps(vs20), vscale, vbias);
1166+
__m512 vf30 = _mm512_fmadd_ps(_mm512_cvtepi32_ps(vs30), vscale, vbias);
1167+
__m512 vf01 = _mm512_fmadd_ps(_mm512_cvtepi32_ps(vs01), vscale, vbias);
1168+
__m512 vf11 = _mm512_fmadd_ps(_mm512_cvtepi32_ps(vs11), vscale, vbias);
1169+
__m512 vf21 = _mm512_fmadd_ps(_mm512_cvtepi32_ps(vs21), vscale, vbias);
1170+
__m512 vf31 = _mm512_fmadd_ps(_mm512_cvtepi32_ps(vs31), vscale, vbias);
11831171
if constexpr (ReduceOp == reduce_op::add) {
11841172
#ifdef __AVX512BF16__
11851173
vf00 = _mm512_add_ps(vf00, _mm512_cvtpbh_ps(std::bit_cast<__m256bh>(_mm256_loadu_si256(reinterpret_cast<const __m256i*>(o+i)))));

0 commit comments

Comments
 (0)