24#if defined(__AVX__) || defined(__AVX2__) || defined(__AVX512F__)
44 for (
int i = 0; i <
QK4_0 / 2; i++) {
45 const uint8_t packed = block->
qs[i];
48 const int8_t q0 = (packed & 0x0F) - 8;
50 const int8_t q1 = (packed >> 4) - 8;
52 output[i] = d * (float)q0;
53 output[i +
QK4_0 / 2] = d * (float)q1;
66 const size_t n_blocks = n_elements /
QK4_0;
68 for (
size_t b = 0; b < n_blocks; b++) {
80void dequant_q4_0_block_avx512(
const block_q4_0 *block,
81 __m512 *out_lo, __m512 *out_hi)
84 const __m512i offset = _mm512_set1_epi32(8);
87 __m128i packed = _mm_loadu_si128((
const __m128i *)block->
qs);
90 __m512i lo_nibbles = _mm512_cvtepu8_epi32(packed);
91 lo_nibbles = _mm512_and_epi32(lo_nibbles, _mm512_set1_epi32(0x0F));
92 lo_nibbles = _mm512_sub_epi32(lo_nibbles, offset);
95 __m512i hi_nibbles = _mm512_cvtepu8_epi32(packed);
96 hi_nibbles = _mm512_srli_epi32(hi_nibbles, 4);
97 hi_nibbles = _mm512_sub_epi32(hi_nibbles, offset);
100 *out_lo = _mm512_mul_ps(_mm512_cvtepi32_ps(lo_nibbles), scale);
101 *out_hi = _mm512_mul_ps(_mm512_cvtepi32_ps(hi_nibbles), scale);
124 for (
int i = 0; i <
QK4_1 / 2; i++) {
125 const uint8_t packed = block->
qs[i];
128 const int q0 = (packed & 0x0F);
130 const int q1 = (packed >> 4);
133 output[i] = d * (float)q0 + m;
134 output[i +
QK4_1 / 2] = d * (float)q1 + m;
144 const size_t n_blocks = n_elements /
QK4_1;
146 for (
size_t b = 0; b < n_blocks; b++) {
169 memcpy(&qh, block->
qh,
sizeof(qh));
175 for (
int j = 0; j <
QK5_0 / 2; j++) {
176 const uint8_t packed = block->
qs[j];
179 const int lo = (packed & 0x0F);
180 const int hi = (packed >> 4);
183 const int xh_0 = ((qh >> (j + 0)) << 4) & 0x10;
184 const int xh_1 = ((qh >> (j + 12))) & 0x10;
187 const int q0 = (lo | xh_0) - 16;
188 const int q1 = (hi | xh_1) - 16;
190 output[j] = d * (float)q0;
191 output[j + 16] = d * (float)q1;
201 const size_t n_blocks = n_elements /
QK5_0;
203 for (
size_t b = 0; b < n_blocks; b++) {
227 memcpy(&qh, block->
qh,
sizeof(qh));
233 for (
int j = 0; j <
QK5_1 / 2; j++) {
234 const uint8_t packed = block->
qs[j];
237 const int lo = (packed & 0x0F);
238 const int hi = (packed >> 4);
241 const int xh_0 = ((qh >> (j + 0)) << 4) & 0x10;
242 const int xh_1 = ((qh >> (j + 12))) & 0x10;
245 const int q0 = (lo | xh_0);
246 const int q1 = (hi | xh_1);
249 output[j] = d * (float)q0 + m;
250 output[j + 16] = d * (float)q1 + m;
260 const size_t n_blocks = n_elements /
QK5_1;
262 for (
size_t b = 0; b < n_blocks; b++) {
280 for (
int i = 0; i <
QK8_0; i++) {
281 output[i] = d * (float)block->
qs[i];
291 const size_t n_blocks = n_elements /
QK8_0;
293 for (
size_t b = 0; b < n_blocks; b++) {
302void dequant_q8_0_block_avx512(
const block_q8_0 *block,
303 __m512 *out0, __m512 *out1)
308 __m128i q0 = _mm_loadu_si128((
const __m128i *)&block->
qs[0]);
309 __m128i q1 = _mm_loadu_si128((
const __m128i *)&block->
qs[16]);
312 __m512i i0 = _mm512_cvtepi8_epi32(q0);
313 __m512i i1 = _mm512_cvtepi8_epi32(q1);
315 *out0 = _mm512_mul_ps(_mm512_cvtepi32_ps(i0), scale);
316 *out1 = _mm512_mul_ps(_mm512_cvtepi32_ps(i1), scale);
346 for (
int iter = 0; iter < 4; iter++) {
347 const float d1 = d * (float)sc[2 * iter];
348 const float m1 = dmin * (float)m[2 * iter];
349 const float d2 = d * (float)sc[2 * iter + 1];
350 const float m2 = dmin * (float)m[2 * iter + 1];
352 const uint8_t *qs = &block->
qs[iter * 32];
353 float *out = &output[iter * 64];
356 for (
int l = 0; l < 32; l++) {
357 const int q = (qs[l] & 0x0F);
358 out[l] = d1 * (float)q - m1;
362 for (
int l = 0; l < 32; l++) {
363 const int q = (qs[l] >> 4);
364 out[32 + l] = d2 * (float)q - m2;
375 const size_t n_blocks = n_elements /
QK_K;
377 for (
size_t b = 0; b < n_blocks; b++) {
394 const uint8_t *ql = block->
ql;
395 const uint8_t *qh = block->
qh;
396 const int8_t *sc = block->
scales;
399 for (
int n = 0; n <
QK_K; n += 128) {
400 for (
int l = 0; l < 32; ++l) {
401 const int is = l / 16;
402 const int8_t q1 = (int8_t)((ql[l + 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32;
403 const int8_t q2 = (int8_t)((ql[l + 32] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32;
404 const int8_t q3 = (int8_t)((ql[l + 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32;
405 const int8_t q4 = (int8_t)((ql[l + 32] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32;
407 y[l + 0] = d * (float)sc[is + 0] * (
float)q1;
408 y[l + 32] = d * (float)sc[is + 2] * (
float)q2;
409 y[l + 64] = d * (float)sc[is + 4] * (
float)q3;
410 y[l + 96] = d * (float)sc[is + 6] * (
float)q4;
425 const size_t n_blocks = n_elements /
QK_K;
427 for (
size_t b = 0; b < n_blocks; b++) {
451void dequant_q4_k_block_avx512(
const block_q4_K *block,
float *output)
459 const __m512i mask_lo = _mm512_set1_epi32(0x0F);
462 for (
int iter = 0; iter < 4; iter++) {
463 const float d1 = d * (float)sc[2 * iter];
464 const float m1 = dmin * (float)m[2 * iter];
465 const float d2 = d * (float)sc[2 * iter + 1];
466 const float m2 = dmin * (float)m[2 * iter + 1];
468 const __m512 vd1 = _mm512_set1_ps(d1);
469 const __m512 vm1 = _mm512_set1_ps(m1);
470 const __m512 vd2 = _mm512_set1_ps(d2);
471 const __m512 vm2 = _mm512_set1_ps(m2);
473 const uint8_t *qs = &block->
qs[iter * 32];
474 float *out = &output[iter * 64];
477 for (
int chunk = 0; chunk < 2; chunk++) {
478 __m128i packed = _mm_loadu_si128((
const __m128i *)&qs[chunk * 16]);
479 __m512i bytes = _mm512_cvtepu8_epi32(packed);
480 __m512i lo = _mm512_and_epi32(bytes, mask_lo);
482 __m512 w = _mm512_fnmadd_ps(_mm512_set1_ps(1.0f), vm1,
483 _mm512_mul_ps(_mm512_cvtepi32_ps(lo), vd1));
484 _mm512_storeu_ps(&out[chunk * 16], w);
488 for (
int chunk = 0; chunk < 2; chunk++) {
489 __m128i packed = _mm_loadu_si128((
const __m128i *)&qs[chunk * 16]);
490 __m512i bytes = _mm512_cvtepu8_epi32(packed);
491 __m512i hi = _mm512_srli_epi32(bytes, 4);
493 __m512 w = _mm512_fnmadd_ps(_mm512_set1_ps(1.0f), vm2,
494 _mm512_mul_ps(_mm512_cvtepi32_ps(hi), vd2));
495 _mm512_storeu_ps(&out[32 + chunk * 16], w);
CKDataType
Supported data types in C-Kernel-Engine.
Quantization block structures for weight-only quantization.
#define GGML_FP16_TO_FP32
static void unpack_q4_k_scales(const uint8_t *scales, uint8_t *sc, uint8_t *m)
Unpack Q4_K sub-block scales and mins.
void dequant_q4_0_row(const void *src, float *dst, size_t n_elements)
Dequantize Q4_0 row (multiple blocks)
void dequant_q5_0_block(const block_q5_0 *block, float *output)
Dequantize a single Q5_0 block to FP32.
void dequant_q5_0_row(const void *src, float *dst, size_t n_elements)
Dequantize Q5_0 row (multiple blocks)
void dequant_q8_0_block(const block_q8_0 *block, float *output)
Dequantize a single Q8_0 block to FP32.
void dequant_q4_1_block(const block_q4_1 *block, float *output)
Dequantize a single Q4_1 block to FP32.
void dequant_q6_k_block(const block_q6_K *block, float *output)
Dequantize a single Q6_K block to FP32.
void dequant_q4_k_block(const block_q4_K *block, float *output)
Dequantize a single Q4_K block to FP32.
void dequant_q4_0_block(const block_q4_0 *block, float *output)
Dequantize a single Q4_0 block to FP32.
void dequant_row(CKDataType dtype, const void *src, float *dst, size_t n_elements)
Dequantize a row of quantized data to FP32.
void dequant_q8_0_row(const void *src, float *dst, size_t n_elements)
Dequantize Q8_0 row (multiple blocks)
void dequant_q5_1_block(const block_q5_1 *block, float *output)
Dequantize a single Q5_1 block to FP32.
void dequant_q5_1_row(const void *src, float *dst, size_t n_elements)
Dequantize Q5_1 row (multiple blocks)
void dequant_q4_1_row(const void *src, float *dst, size_t n_elements)
Dequantize Q4_1 row (multiple blocks)
void dequant_q6_k_row(const void *src, float *dst, size_t n_elements)
Dequantize Q6_K row (multiple blocks)
void dequant_q4_k_row(const void *src, float *dst, size_t n_elements)
Dequantize Q4_K row (multiple blocks)