char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

ragz4125ggml-cpu: add AVX2 optimization for nvfp4 dot product and use UE4M3 LUT (#23961)6dbc1174b

char/aliceai-t5-moe
192.8 KiB4108 linesraw
1#define GGML_COMMON_IMPL_C
2#include "ggml-common.h"
3#include "ggml-quants.h"
4#include "ggml-impl.h"
5#include "ggml-cpu.h"
6#include "simd-mappings.h"
7
8#include "../../quants.h"
9#include "../../ggml-cpu-impl.h"
10
11#include <math.h>
12#include <string.h>
13#include <assert.h>
14#include <stdlib.h> // for qsort
15#include <stdio.h>  // for GGML_ASSERT
16
17#define GROUP_MAX_EPS 1e-15f
18#define GROUP_MAX_EPS_IQ3_XXS 1e-8f
19#define GROUP_MAX_EPS_IQ2_S 1e-8f
20#define GROUP_MAX_EPS_IQ1_M 1e-7f
21#define GROUP_MAX_EPS_IQ1_S 1e-12f
22
23#define UNUSED GGML_UNUSED
24
25// some compilers don't provide _mm256_set_m128i, e.g. gcc 7
26#define MM256_SET_M128I(a, b) _mm256_insertf128_si256(_mm256_castsi128_si256(b), (a), 1)
27
28#if defined(__AVX__) || defined(__AVX2__) || defined(__AVX512F__) || defined(__SSSE3__)
29// multiply int8_t, add results pairwise twice
30static inline __m128i mul_sum_i8_pairs(const __m128i x, const __m128i y) {
31    // Get absolute values of x vectors
32    const __m128i ax = _mm_sign_epi8(x, x);
33    // Sign the values of the y vectors
34    const __m128i sy = _mm_sign_epi8(y, x);
35    // Perform multiplication and create 16-bit values
36    const __m128i dot = _mm_maddubs_epi16(ax, sy);
37    const __m128i ones = _mm_set1_epi16(1);
38    return _mm_madd_epi16(ones, dot);
39}
40
41#if __AVX__ || __AVX2__ || __AVX512F__
42// horizontally add 8 floats
43static inline float hsum_float_8(const __m256 x) {
44    __m128 res = _mm256_extractf128_ps(x, 1);
45    res = _mm_add_ps(res, _mm256_castps256_ps128(x));
46    res = _mm_add_ps(res, _mm_movehl_ps(res, res));
47    res = _mm_add_ss(res, _mm_movehdup_ps(res));
48    return _mm_cvtss_f32(res);
49}
50
51// horizontally add 8 int32_t
52static inline int hsum_i32_8(const __m256i a) {
53    const __m128i sum128 = _mm_add_epi32(_mm256_castsi256_si128(a), _mm256_extractf128_si256(a, 1));
54    const __m128i hi64 = _mm_unpackhi_epi64(sum128, sum128);
55    const __m128i sum64 = _mm_add_epi32(hi64, sum128);
56    const __m128i hi32  = _mm_shuffle_epi32(sum64, _MM_SHUFFLE(2, 3, 0, 1));
57    return _mm_cvtsi128_si32(_mm_add_epi32(sum64, hi32));
58}
59
60// horizontally add 4 int32_t
61static inline int hsum_i32_4(const __m128i a) {
62    const __m128i hi64 = _mm_unpackhi_epi64(a, a);
63    const __m128i sum64 = _mm_add_epi32(hi64, a);
64    const __m128i hi32  = _mm_shuffle_epi32(sum64, _MM_SHUFFLE(2, 3, 0, 1));
65    return _mm_cvtsi128_si32(_mm_add_epi32(sum64, hi32));
66}
67
68#if defined(__AVX2__) || defined(__AVX512F__)
69static inline __m256i mul_add_epi8(const __m256i x, const __m256i y) {
70    const __m256i ax = _mm256_sign_epi8(x, x);
71    const __m256i sy = _mm256_sign_epi8(y, x);
72    return _mm256_maddubs_epi16(ax, sy);
73}
74
75// spread 32 bits to 32 bytes { 0x00, 0xFF }
76static inline __m256i bytes_from_bits_32(const uint8_t * x) {
77    uint32_t x32;
78    memcpy(&x32, x, sizeof(uint32_t));
79    const __m256i shuf_mask = _mm256_set_epi64x(
80            0x0303030303030303, 0x0202020202020202,
81            0x0101010101010101, 0x0000000000000000);
82    __m256i bytes = _mm256_shuffle_epi8(_mm256_set1_epi32(x32), shuf_mask);
83    const __m256i bit_mask = _mm256_set1_epi64x(0x7fbfdfeff7fbfdfe);
84    bytes = _mm256_or_si256(bytes, bit_mask);
85    return _mm256_cmpeq_epi8(bytes, _mm256_set1_epi64x(-1));
86}
87
88// Unpack 32 4-bit fields into 32 bytes
89// The output vector contains 32 bytes, each one in [ 0 .. 15 ] interval
90static inline __m256i bytes_from_nibbles_32(const uint8_t * rsi)
91{
92    const __m128i tmp = _mm_loadu_si128((const __m128i *)rsi);
93    const __m256i bytes = MM256_SET_M128I(_mm_srli_epi16(tmp, 4), tmp);
94    const __m256i lowMask = _mm256_set1_epi8( 0xF );
95    return _mm256_and_si256(lowMask, bytes);
96}
97
98// add int16_t pairwise and return as float vector
99static inline __m256 sum_i16_pairs_float(const __m256i x) {
100    const __m256i ones = _mm256_set1_epi16(1);
101    const __m256i summed_pairs = _mm256_madd_epi16(ones, x);
102    return _mm256_cvtepi32_ps(summed_pairs);
103}
104
105static inline __m256 mul_sum_us8_pairs_float(const __m256i ax, const __m256i sy) {
106#if defined(__AVX512VNNI__) && defined(__AVX512VL__)
107    const __m256i zero = _mm256_setzero_si256();
108    const __m256i summed_pairs = _mm256_dpbusd_epi32(zero, ax, sy);
109    return _mm256_cvtepi32_ps(summed_pairs);
110#elif defined(__AVXVNNI__)
111    const __m256i zero = _mm256_setzero_si256();
112    const __m256i summed_pairs = _mm256_dpbusd_avx_epi32(zero, ax, sy);
113    return _mm256_cvtepi32_ps(summed_pairs);
114#else
115    // Perform multiplication and create 16-bit values
116    const __m256i dot = _mm256_maddubs_epi16(ax, sy);
117    return sum_i16_pairs_float(dot);
118#endif
119}
120
121// multiply int8_t, add results pairwise twice and return as float vector
122static inline __m256 mul_sum_i8_pairs_float(const __m256i x, const __m256i y) {
123#if __AVXVNNIINT8__
124    const __m256i zero = _mm256_setzero_si256();
125    const __m256i summed_pairs = _mm256_dpbssd_epi32(zero, x, y);
126    return _mm256_cvtepi32_ps(summed_pairs);
127#else
128    // Get absolute values of x vectors
129    const __m256i ax = _mm256_sign_epi8(x, x);
130    // Sign the values of the y vectors
131    const __m256i sy = _mm256_sign_epi8(y, x);
132    return mul_sum_us8_pairs_float(ax, sy);
133#endif
134}
135
136static inline __m128i packNibbles( __m256i bytes )
137{
138    // Move bits within 16-bit lanes from 0000_abcd_0000_efgh into 0000_0000_abcd_efgh
139#if __AVX512F__
140    const __m256i bytes_srli_4 = _mm256_srli_epi16(bytes, 4);   // 0000_0000_abcd_0000
141    bytes = _mm256_or_si256(bytes, bytes_srli_4);               // 0000_abcd_abcd_efgh
142    return _mm256_cvtepi16_epi8(bytes);                         // abcd_efgh
143#else
144    const __m256i lowByte = _mm256_set1_epi16( 0xFF );
145    __m256i high = _mm256_andnot_si256( lowByte, bytes );
146    __m256i low = _mm256_and_si256( lowByte, bytes );
147    high = _mm256_srli_epi16( high, 4 );
148    bytes = _mm256_or_si256( low, high );
149
150    // Compress uint16_t lanes into bytes
151    __m128i r0 = _mm256_castsi256_si128( bytes );
152    __m128i r1 = _mm256_extracti128_si256( bytes, 1 );
153    return _mm_packus_epi16( r0, r1 );
154#endif
155}
156#elif defined(__AVX__)
157static inline __m128i packNibbles( __m128i bytes1, __m128i bytes2 )
158{
159    // Move bits within 16-bit lanes from 0000_abcd_0000_efgh into 0000_0000_abcd_efgh
160    const __m128i lowByte = _mm_set1_epi16( 0xFF );
161    __m128i high = _mm_andnot_si128( lowByte, bytes1 );
162    __m128i low = _mm_and_si128( lowByte, bytes1 );
163    high = _mm_srli_epi16( high, 4 );
164    bytes1 = _mm_or_si128( low, high );
165    high = _mm_andnot_si128( lowByte, bytes2 );
166    low = _mm_and_si128( lowByte, bytes2 );
167    high = _mm_srli_epi16( high, 4 );
168    bytes2 = _mm_or_si128( low, high );
169
170    return _mm_packus_epi16( bytes1, bytes2);
171}
172
173static inline __m128i mul_add_epi8_sse(const __m128i x, const __m128i y) {
174    const __m128i ax = _mm_sign_epi8(x, x);
175    const __m128i sy = _mm_sign_epi8(y, x);
176    return _mm_maddubs_epi16(ax, sy);
177}
178
179// spread 32 bits to 32 bytes { 0x00, 0xFF }
180static inline __m256i bytes_from_bits_32(const uint8_t * x) {
181    uint32_t x32;
182    memcpy(&x32, x, sizeof(uint32_t));
183    const __m128i shuf_maskl = _mm_set_epi64x(0x0101010101010101, 0x0000000000000000);
184    const __m128i shuf_maskh = _mm_set_epi64x(0x0303030303030303, 0x0202020202020202);
185    __m128i bytesl = _mm_shuffle_epi8(_mm_set1_epi32(x32), shuf_maskl);
186    __m128i bytesh = _mm_shuffle_epi8(_mm_set1_epi32(x32), shuf_maskh);
187    const __m128i bit_mask = _mm_set1_epi64x(0x7fbfdfeff7fbfdfe);
188    bytesl = _mm_or_si128(bytesl, bit_mask);
189    bytesh = _mm_or_si128(bytesh, bit_mask);
190    bytesl = _mm_cmpeq_epi8(bytesl, _mm_set1_epi64x(-1));
191    bytesh = _mm_cmpeq_epi8(bytesh, _mm_set1_epi64x(-1));
192    return MM256_SET_M128I(bytesh, bytesl);
193}
194
195// Unpack 32 4-bit fields into 32 bytes
196// The output vector contains 32 bytes, each one in [ 0 .. 15 ] interval
197static inline __m256i bytes_from_nibbles_32(const uint8_t * rsi)
198{
199    // Load 16 bytes from memory
200    __m128i tmpl = _mm_loadu_si128((const __m128i *)rsi);
201    __m128i tmph = _mm_srli_epi16(tmpl, 4);
202    const __m128i lowMask = _mm_set1_epi8(0xF);
203    tmpl = _mm_and_si128(lowMask, tmpl);
204    tmph = _mm_and_si128(lowMask, tmph);
205    return MM256_SET_M128I(tmph, tmpl);
206}
207
208// add int16_t pairwise and return as float vector
209static inline __m256 sum_i16_pairs_float(const __m128i xh, const __m128i xl) {
210    const __m128i ones = _mm_set1_epi16(1);
211    const __m128i summed_pairsl = _mm_madd_epi16(ones, xl);
212    const __m128i summed_pairsh = _mm_madd_epi16(ones, xh);
213    const __m256i summed_pairs = MM256_SET_M128I(summed_pairsh, summed_pairsl);
214    return _mm256_cvtepi32_ps(summed_pairs);
215}
216
217static inline __m256 mul_sum_us8_pairs_float(const __m256i ax, const __m256i sy) {
218    const __m128i axl = _mm256_castsi256_si128(ax);
219    const __m128i axh = _mm256_extractf128_si256(ax, 1);
220    const __m128i syl = _mm256_castsi256_si128(sy);
221    const __m128i syh = _mm256_extractf128_si256(sy, 1);
222    // Perform multiplication and create 16-bit values
223    const __m128i dotl = _mm_maddubs_epi16(axl, syl);
224    const __m128i doth = _mm_maddubs_epi16(axh, syh);
225    return sum_i16_pairs_float(doth, dotl);
226}
227
228// multiply int8_t, add results pairwise twice and return as float vector
229static inline __m256 mul_sum_i8_pairs_float(const __m256i x, const __m256i y) {
230    const __m128i xl = _mm256_castsi256_si128(x);
231    const __m128i xh = _mm256_extractf128_si256(x, 1);
232    const __m128i yl = _mm256_castsi256_si128(y);
233    const __m128i yh = _mm256_extractf128_si256(y, 1);
234    // Get absolute values of x vectors
235    const __m128i axl = _mm_sign_epi8(xl, xl);
236    const __m128i axh = _mm_sign_epi8(xh, xh);
237    // Sign the values of the y vectors
238    const __m128i syl = _mm_sign_epi8(yl, xl);
239    const __m128i syh = _mm_sign_epi8(yh, xh);
240    // Perform multiplication and create 16-bit values
241    const __m128i dotl = _mm_maddubs_epi16(axl, syl);
242    const __m128i doth = _mm_maddubs_epi16(axh, syh);
243    return sum_i16_pairs_float(doth, dotl);
244}
245
246// larger version of mul_sum_i8_pairs_float where x and y are each represented by four 128-bit vectors
247static inline __m256 mul_sum_i8_quad_float(const __m128i x_1_0, const __m128i x_1_1, const __m128i x_2_0, const __m128i x_2_1,
248                                           const __m128i y_1_0, const __m128i y_1_1, const __m128i y_2_0, const __m128i y_2_1) {
249    const __m128i mone = _mm_set1_epi16(1);
250
251    const __m128i p16_1_0 = mul_add_epi8_sse(x_1_0, y_1_0);
252    const __m128i p16_1_1 = mul_add_epi8_sse(x_1_1, y_1_1);
253    const __m128i p16_2_0 = mul_add_epi8_sse(x_2_0, y_2_0);
254    const __m128i p16_2_1 = mul_add_epi8_sse(x_2_1, y_2_1);
255    const __m128i p_1_0 = _mm_madd_epi16(p16_1_0, mone);
256    const __m128i p_1_1 = _mm_madd_epi16(p16_1_1, mone);
257    const __m128i p_2_0 = _mm_madd_epi16(p16_2_0, mone);
258    const __m128i p_2_1 = _mm_madd_epi16(p16_2_1, mone);
259    const __m128i p_1 = _mm_add_epi32(p_1_0, p_1_1);
260    const __m128i p_2 = _mm_add_epi32(p_2_0, p_2_1);
261    return _mm256_cvtepi32_ps(MM256_SET_M128I(p_2, p_1));
262}
263
264// quad fp16 delta calculation
265static inline __m256 quad_fp16_delta_float(const float x0, const float y0, const float x1, const float y1) {
266    // GGML_CPU_FP16_TO_FP32 is faster than Intel F16C
267    return _mm256_set_m128(_mm_set1_ps(GGML_CPU_FP16_TO_FP32(x1) * GGML_CPU_FP16_TO_FP32(y1)),
268                           _mm_set1_ps(GGML_CPU_FP16_TO_FP32(x0) * GGML_CPU_FP16_TO_FP32(y0)));
269}
270
271static inline __m256 quad_mx_delta_float(const uint8_t x0, const float y0, const uint8_t x1, const float y1) {
272    return _mm256_set_m128(_mm_set1_ps(GGML_CPU_E8M0_TO_FP32_HALF(x1) * GGML_CPU_FP16_TO_FP32(y1)),
273                           _mm_set1_ps(GGML_CPU_E8M0_TO_FP32_HALF(x0) * GGML_CPU_FP16_TO_FP32(y0)));
274}
275#endif
276#elif defined(__SSSE3__)
277static inline __m128i bytes_from_bits_16(const uint8_t * x) {
278    uint16_t x16;
279    memcpy(&x16, x, sizeof(uint16_t));
280
281    const __m128i shuf_mask = _mm_set_epi64x(0x0101010101010101, 0x0000000000000000);
282    __m128i bytes = _mm_shuffle_epi8(_mm_set1_epi16((short) x16), shuf_mask);
283    const __m128i bit_mask = _mm_set_epi64x(0x7fbfdfeff7fbfdfe, 0x7fbfdfeff7fbfdfe);
284    bytes = _mm_or_si128(bytes, bit_mask);
285
286    return _mm_cmpeq_epi8(bytes, _mm_set1_epi64x(-1));
287}
288
289// horizontally add 4x4 floats
290static inline float hsum_float_4x4(const __m128 a, const __m128 b, const __m128 c, const __m128 d) {
291    __m128 res_0 =_mm_hadd_ps(a, b);
292    __m128 res_1 =_mm_hadd_ps(c, d);
293    __m128 res =_mm_hadd_ps(res_0, res_1);
294    res =_mm_hadd_ps(res, res);
295    res =_mm_hadd_ps(res, res);
296
297    return _mm_cvtss_f32(res);
298}
299#endif // __AVX__ || __AVX2__ || __AVX512F__
300#endif // defined(__AVX__) || defined(__AVX2__) || defined(__AVX512F__) || defined(__SSSE3__)
301
302void quantize_row_q8_0(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
303    assert(QK8_0 == 32);
304    assert(k % QK8_0 == 0);
305    const int nb = k / QK8_0;
306
307    block_q8_0 * GGML_RESTRICT y = vy;
308
309#if defined(__AVX2__) || defined(__AVX__)
310    for (int i = 0; i < nb; i++) {
311        // Load elements into 4 AVX vectors
312        __m256 v0 = _mm256_loadu_ps( x );
313        __m256 v1 = _mm256_loadu_ps( x + 8 );
314        __m256 v2 = _mm256_loadu_ps( x + 16 );
315        __m256 v3 = _mm256_loadu_ps( x + 24 );
316        x += 32;
317
318        // Compute max(abs(e)) for the block
319        const __m256 signBit = _mm256_set1_ps( -0.0f );
320        __m256 maxAbs = _mm256_andnot_ps( signBit, v0 );
321        maxAbs = _mm256_max_ps( maxAbs, _mm256_andnot_ps( signBit, v1 ) );
322        maxAbs = _mm256_max_ps( maxAbs, _mm256_andnot_ps( signBit, v2 ) );
323        maxAbs = _mm256_max_ps( maxAbs, _mm256_andnot_ps( signBit, v3 ) );
324
325        __m128 max4 = _mm_max_ps( _mm256_extractf128_ps( maxAbs, 1 ), _mm256_castps256_ps128( maxAbs ) );
326        max4 = _mm_max_ps( max4, _mm_movehl_ps( max4, max4 ) );
327        max4 = _mm_max_ss( max4, _mm_movehdup_ps( max4 ) );
328        const float maxScalar = _mm_cvtss_f32( max4 );
329
330        // Quantize these floats
331        const float d = maxScalar / 127.f;
332        y[i].d = GGML_CPU_FP32_TO_FP16(d);
333        const float id = ( maxScalar != 0.0f ) ? 127.f / maxScalar : 0.0f;
334        const __m256 mul = _mm256_set1_ps( id );
335
336        // Apply the multiplier
337        v0 = _mm256_mul_ps( v0, mul );
338        v1 = _mm256_mul_ps( v1, mul );
339        v2 = _mm256_mul_ps( v2, mul );
340        v3 = _mm256_mul_ps( v3, mul );
341
342        // Round to nearest integer
343        v0 = _mm256_round_ps( v0, _MM_ROUND_NEAREST );
344        v1 = _mm256_round_ps( v1, _MM_ROUND_NEAREST );
345        v2 = _mm256_round_ps( v2, _MM_ROUND_NEAREST );
346        v3 = _mm256_round_ps( v3, _MM_ROUND_NEAREST );
347
348        // Convert floats to integers
349        __m256i i0 = _mm256_cvtps_epi32( v0 );
350        __m256i i1 = _mm256_cvtps_epi32( v1 );
351        __m256i i2 = _mm256_cvtps_epi32( v2 );
352        __m256i i3 = _mm256_cvtps_epi32( v3 );
353
354#if defined(__AVX2__)
355        // Convert int32 to int16
356        i0 = _mm256_packs_epi32( i0, i1 );	// 0, 1, 2, 3,  8, 9, 10, 11,  4, 5, 6, 7, 12, 13, 14, 15
357        i2 = _mm256_packs_epi32( i2, i3 );	// 16, 17, 18, 19,  24, 25, 26, 27,  20, 21, 22, 23, 28, 29, 30, 31
358                                            // Convert int16 to int8
359        i0 = _mm256_packs_epi16( i0, i2 );	// 0, 1, 2, 3,  8, 9, 10, 11,  16, 17, 18, 19,  24, 25, 26, 27,  4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31
360
361        // We got our precious signed bytes, but the order is now wrong
362        // These AVX2 pack instructions process 16-byte pieces independently
363        // The following instruction is fixing the order
364        const __m256i perm = _mm256_setr_epi32( 0, 4, 1, 5, 2, 6, 3, 7 );
365        i0 = _mm256_permutevar8x32_epi32( i0, perm );
366
367        _mm256_storeu_si256((__m256i *)y[i].qs, i0);
368#else
369        // Since we don't have in AVX some necessary functions,
370        // we split the registers in half and call AVX2 analogs from SSE
371        __m128i ni0 = _mm256_castsi256_si128( i0 );
372        __m128i ni1 = _mm256_extractf128_si256( i0, 1);
373        __m128i ni2 = _mm256_castsi256_si128( i1 );
374        __m128i ni3 = _mm256_extractf128_si256( i1, 1);
375        __m128i ni4 = _mm256_castsi256_si128( i2 );
376        __m128i ni5 = _mm256_extractf128_si256( i2, 1);
377        __m128i ni6 = _mm256_castsi256_si128( i3 );
378        __m128i ni7 = _mm256_extractf128_si256( i3, 1);
379
380        // Convert int32 to int16
381        ni0 = _mm_packs_epi32( ni0, ni1 );
382        ni2 = _mm_packs_epi32( ni2, ni3 );
383        ni4 = _mm_packs_epi32( ni4, ni5 );
384        ni6 = _mm_packs_epi32( ni6, ni7 );
385        // Convert int16 to int8
386        ni0 = _mm_packs_epi16( ni0, ni2 );
387        ni4 = _mm_packs_epi16( ni4, ni6 );
388
389        _mm_storeu_si128((__m128i *)(y[i].qs +  0), ni0);
390        _mm_storeu_si128((__m128i *)(y[i].qs + 16), ni4);
391#endif
392    }
393#else
394    GGML_UNUSED(nb);
395    // scalar
396    quantize_row_q8_0_ref(x, y, k);
397#endif
398}
399
400void quantize_row_q8_1(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
401    assert(k % QK8_1 == 0);
402    const int nb = k / QK8_1;
403
404    block_q8_1 * GGML_RESTRICT y = vy;
405#if defined(__AVX2__) || defined(__AVX__)
406    for (int i = 0; i < nb; i++) {
407        // Load elements into 4 AVX vectors
408        __m256 v0 = _mm256_loadu_ps( x );
409        __m256 v1 = _mm256_loadu_ps( x + 8 );
410        __m256 v2 = _mm256_loadu_ps( x + 16 );
411        __m256 v3 = _mm256_loadu_ps( x + 24 );
412        x += 32;
413
414        // Compute max(abs(e)) for the block
415        const __m256 signBit = _mm256_set1_ps( -0.0f );
416        __m256 maxAbs = _mm256_andnot_ps( signBit, v0 );
417        maxAbs = _mm256_max_ps( maxAbs, _mm256_andnot_ps( signBit, v1 ) );
418        maxAbs = _mm256_max_ps( maxAbs, _mm256_andnot_ps( signBit, v2 ) );
419        maxAbs = _mm256_max_ps( maxAbs, _mm256_andnot_ps( signBit, v3 ) );
420
421        __m128 max4 = _mm_max_ps( _mm256_extractf128_ps( maxAbs, 1 ), _mm256_castps256_ps128( maxAbs ) );
422        max4 = _mm_max_ps( max4, _mm_movehl_ps( max4, max4 ) );
423        max4 = _mm_max_ss( max4, _mm_movehdup_ps( max4 ) );
424        const float max_scalar = _mm_cvtss_f32( max4 );
425
426        // Quantize these floats
427        const float d = max_scalar / 127.f;
428        y[i].d = GGML_CPU_FP32_TO_FP16(d);
429        const float id = ( max_scalar != 0.0f ) ? 127.f / max_scalar : 0.0f;
430        const __m256 mul = _mm256_set1_ps( id );
431
432        // Apply the multiplier
433        v0 = _mm256_mul_ps( v0, mul );
434        v1 = _mm256_mul_ps( v1, mul );
435        v2 = _mm256_mul_ps( v2, mul );
436        v3 = _mm256_mul_ps( v3, mul );
437
438        // Round to nearest integer
439        v0 = _mm256_round_ps( v0, _MM_ROUND_NEAREST );
440        v1 = _mm256_round_ps( v1, _MM_ROUND_NEAREST );
441        v2 = _mm256_round_ps( v2, _MM_ROUND_NEAREST );
442        v3 = _mm256_round_ps( v3, _MM_ROUND_NEAREST );
443
444        // Convert floats to integers
445        __m256i i0 = _mm256_cvtps_epi32( v0 );
446        __m256i i1 = _mm256_cvtps_epi32( v1 );
447        __m256i i2 = _mm256_cvtps_epi32( v2 );
448        __m256i i3 = _mm256_cvtps_epi32( v3 );
449
450#if defined(__AVX2__)
451        // Compute the sum of the quants and set y[i].s
452        y[i].s = GGML_CPU_FP32_TO_FP16(d * hsum_i32_8(_mm256_add_epi32(_mm256_add_epi32(i0, i1), _mm256_add_epi32(i2, i3))));
453
454        // Convert int32 to int16
455        i0 = _mm256_packs_epi32( i0, i1 );	// 0, 1, 2, 3,  8, 9, 10, 11,  4, 5, 6, 7, 12, 13, 14, 15
456        i2 = _mm256_packs_epi32( i2, i3 );	// 16, 17, 18, 19,  24, 25, 26, 27,  20, 21, 22, 23, 28, 29, 30, 31
457                                            // Convert int16 to int8
458        i0 = _mm256_packs_epi16( i0, i2 );	// 0, 1, 2, 3,  8, 9, 10, 11,  16, 17, 18, 19,  24, 25, 26, 27,  4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31
459
460        // We got our precious signed bytes, but the order is now wrong
461        // These AVX2 pack instructions process 16-byte pieces independently
462        // The following instruction is fixing the order
463        const __m256i perm = _mm256_setr_epi32( 0, 4, 1, 5, 2, 6, 3, 7 );
464        i0 = _mm256_permutevar8x32_epi32( i0, perm );
465
466        _mm256_storeu_si256((__m256i *)y[i].qs, i0);
467#else
468        // Since we don't have in AVX some necessary functions,
469        // we split the registers in half and call AVX2 analogs from SSE
470        __m128i ni0 = _mm256_castsi256_si128( i0 );
471        __m128i ni1 = _mm256_extractf128_si256( i0, 1);
472        __m128i ni2 = _mm256_castsi256_si128( i1 );
473        __m128i ni3 = _mm256_extractf128_si256( i1, 1);
474        __m128i ni4 = _mm256_castsi256_si128( i2 );
475        __m128i ni5 = _mm256_extractf128_si256( i2, 1);
476        __m128i ni6 = _mm256_castsi256_si128( i3 );
477        __m128i ni7 = _mm256_extractf128_si256( i3, 1);
478
479        // Compute the sum of the quants and set y[i].s
480        const __m128i s0 = _mm_add_epi32(_mm_add_epi32(ni0, ni1), _mm_add_epi32(ni2, ni3));
481        const __m128i s1 = _mm_add_epi32(_mm_add_epi32(ni4, ni5), _mm_add_epi32(ni6, ni7));
482        y[i].s = GGML_CPU_FP32_TO_FP16(d * hsum_i32_4(_mm_add_epi32(s0, s1)));
483
484        // Convert int32 to int16
485        ni0 = _mm_packs_epi32( ni0, ni1 );
486        ni2 = _mm_packs_epi32( ni2, ni3 );
487        ni4 = _mm_packs_epi32( ni4, ni5 );
488        ni6 = _mm_packs_epi32( ni6, ni7 );
489        // Convert int16 to int8
490        ni0 = _mm_packs_epi16( ni0, ni2 );
491        ni4 = _mm_packs_epi16( ni4, ni6 );
492
493        _mm_storeu_si128((__m128i *)(y[i].qs +  0), ni0);
494        _mm_storeu_si128((__m128i *)(y[i].qs + 16), ni4);
495#endif
496    }
497#else
498    GGML_UNUSED(nb);
499    // scalar
500    quantize_row_q8_1_ref(x, y, k);
501#endif
502}
503
504// placeholder implementation for Apple targets
505void quantize_row_q8_K(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
506    quantize_row_q8_K_ref(x, y, k);
507}
508
509//===================================== Dot products =================================
510
511//
512// Helper functions
513//
514
515#if __AVX__ || __AVX2__ || __AVX512F__
516
517// shuffles to pick the required scales in dot products
518static inline __m256i get_scale_shuffle_q3k(int i) {
519    static const uint8_t k_shuffle[128] = {
520         0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,     2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
521         4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5,     6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7,
522         8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9,    10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,
523        12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,    14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,
524    };
525    return _mm256_loadu_si256((const __m256i*)k_shuffle + i);
526}
527static inline __m256i get_scale_shuffle_k4(int i) {
528    static const uint8_t k_shuffle[256] = {
529         0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
530         2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
531         4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5,
532         6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7,
533         8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9,
534        10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,
535        12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,
536        14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15
537    };
538    return _mm256_loadu_si256((const __m256i*)k_shuffle + i);
539}
540static inline __m128i get_scale_shuffle(int i) {
541    static const uint8_t k_shuffle[128] = {
542         0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
543         2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
544         4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
545         6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7,
546         8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
547        10,10,10,10,10,10,10,10, 11,11,11,11,11,11,11,11,
548        12,12,12,12,12,12,12,12, 13,13,13,13,13,13,13,13,
549        14,14,14,14,14,14,14,14, 15,15,15,15,15,15,15,15
550    };
551    return _mm_loadu_si128((const __m128i*)k_shuffle + i);
552}
553#endif
554
555void ggml_vec_dot_q1_0_q8_0(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
556    const int qk = QK1_0;
557    const int nb = n / qk;
558
559    assert(n % qk == 0);
560    assert(nrc == 1);
561    UNUSED(nrc);
562    UNUSED(bx);
563    UNUSED(by);
564    UNUSED(bs);
565
566    const block_q1_0 * GGML_RESTRICT x = vx;
567    const block_q8_0 * GGML_RESTRICT y = vy;
568
569#if defined(__AVX2__)
570    const __m256i ones_8 = _mm256_set1_epi8(1);
571    const __m256i ones_16 = _mm256_set1_epi16(1);
572    const __m256i byte_shuf = _mm256_setr_epi8(
573            0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
574            2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3);
575    const __m256i bit_masks = _mm256_setr_epi8(
576            1, 2, 4, 8, 16, 32, 64, (char) -128, 1, 2, 4, 8, 16, 32, 64, (char) -128,
577            1, 2, 4, 8, 16, 32, 64, (char) -128, 1, 2, 4, 8, 16, 32, 64, (char) -128);
578    const __m256i zero = _mm256_setzero_si256();
579    __m256 acc = _mm256_setzero_ps();
580
581    for (int ib = 0; ib < nb; ++ib) {
582        const float d0 = GGML_CPU_FP16_TO_FP32(x[ib].d);
583        const uint32_t * GGML_RESTRICT qs32 = (const uint32_t *) x[ib].qs;
584        const block_q8_0 * GGML_RESTRICT y_ptr = &y[ib * 4];
585
586        __m256 acc_block;
587        {
588            const __m256i qy = _mm256_loadu_si256((const __m256i *) y_ptr[0].qs);
589            const __m256i sm = _mm256_cmpeq_epi8(
590                    _mm256_and_si256(_mm256_shuffle_epi8(_mm256_set1_epi32((int) qs32[0]), byte_shuf), bit_masks), zero);
591            const __m256i sy = _mm256_sub_epi8(_mm256_xor_si256(qy, sm), sm);
592            const __m256i s32 = _mm256_madd_epi16(_mm256_maddubs_epi16(ones_8, sy), ones_16);
593            acc_block = _mm256_mul_ps(_mm256_set1_ps(GGML_CPU_FP16_TO_FP32(y_ptr[0].d)), _mm256_cvtepi32_ps(s32));
594        }
595        for (int K = 1; K < 4; ++K) {
596            const __m256i qy = _mm256_loadu_si256((const __m256i *) y_ptr[K].qs);
597            const __m256i sm = _mm256_cmpeq_epi8(
598                    _mm256_and_si256(_mm256_shuffle_epi8(_mm256_set1_epi32((int) qs32[K]), byte_shuf), bit_masks), zero);
599            const __m256i sy = _mm256_sub_epi8(_mm256_xor_si256(qy, sm), sm);
600            const __m256i s32 = _mm256_madd_epi16(_mm256_maddubs_epi16(ones_8, sy), ones_16);
601            acc_block = _mm256_fmadd_ps(_mm256_set1_ps(GGML_CPU_FP16_TO_FP32(y_ptr[K].d)), _mm256_cvtepi32_ps(s32), acc_block);
602        }
603        acc = _mm256_fmadd_ps(_mm256_set1_ps(d0), acc_block, acc);
604    }
605
606    *s = hsum_float_8(acc);
607#elif defined(__AVX__)
608    const __m128i ones_8 = _mm_set1_epi8(1);
609    const __m128i ones_16 = _mm_set1_epi16(1);
610    const __m128i zero = _mm_setzero_si128();
611    __m256 acc = _mm256_setzero_ps();
612
613    for (int ib = 0; ib < nb; ++ib) {
614        const float d0 = GGML_CPU_FP16_TO_FP32(x[ib].d);
615        const block_q8_0 * GGML_RESTRICT y_ptr = &y[ib * 4];
616        __m256 acc_block;
617        {
618            const __m256i bit_mask = bytes_from_bits_32(&x[ib].qs[0]);
619            const __m128i bit_mask_0 = _mm256_castsi256_si128(bit_mask);
620            const __m128i bit_mask_1 = _mm256_extractf128_si256(bit_mask, 1);
621            const __m128i qy_0 = _mm_loadu_si128((const __m128i *) &y_ptr[0].qs[0]);
622            const __m128i qy_1 = _mm_loadu_si128((const __m128i *) &y_ptr[0].qs[16]);
623            const __m128i sign_mask_0 = _mm_cmpeq_epi8(bit_mask_0, zero);
624            const __m128i sign_mask_1 = _mm_cmpeq_epi8(bit_mask_1, zero);
625            const __m128i sy_0 = _mm_sub_epi8(_mm_xor_si128(qy_0, sign_mask_0), sign_mask_0);
626            const __m128i sy_1 = _mm_sub_epi8(_mm_xor_si128(qy_1, sign_mask_1), sign_mask_1);
627            const __m128i sum16_0 = _mm_maddubs_epi16(ones_8, sy_0);
628            const __m128i sum16_1 = _mm_maddubs_epi16(ones_8, sy_1);
629            const __m128i sum32_0 = _mm_madd_epi16(sum16_0, ones_16);
630            const __m128i sum32_1 = _mm_madd_epi16(sum16_1, ones_16);
631            const __m256 q = _mm256_cvtepi32_ps(MM256_SET_M128I(sum32_1, sum32_0));
632            acc_block = _mm256_mul_ps(_mm256_set1_ps(GGML_CPU_FP16_TO_FP32(y_ptr[0].d)), q);
633        }
634        for(int K = 1; K < 4; ++K) {
635            const __m256i bit_mask = bytes_from_bits_32(&x[ib].qs[(K) * 4]);
636            const __m128i bit_mask_0 = _mm256_castsi256_si128(bit_mask);
637            const __m128i bit_mask_1 = _mm256_extractf128_si256(bit_mask, 1);
638            const __m128i qy_0 = _mm_loadu_si128((const __m128i *) &y_ptr[(K)].qs[0]);
639            const __m128i qy_1 = _mm_loadu_si128((const __m128i *) &y_ptr[(K)].qs[16]);
640            const __m128i sign_mask_0 = _mm_cmpeq_epi8(bit_mask_0, zero);
641            const __m128i sign_mask_1 = _mm_cmpeq_epi8(bit_mask_1, zero);
642            const __m128i sy_0 = _mm_sub_epi8(_mm_xor_si128(qy_0, sign_mask_0), sign_mask_0);
643            const __m128i sy_1 = _mm_sub_epi8(_mm_xor_si128(qy_1, sign_mask_1), sign_mask_1);
644            const __m128i sum16_0 = _mm_maddubs_epi16(ones_8, sy_0);
645            const __m128i sum16_1 = _mm_maddubs_epi16(ones_8, sy_1);
646            const __m128i sum32_0 = _mm_madd_epi16(sum16_0, ones_16);
647            const __m128i sum32_1 = _mm_madd_epi16(sum16_1, ones_16);
648            const __m256 q = _mm256_cvtepi32_ps(MM256_SET_M128I(sum32_1, sum32_0));
649            acc_block = _mm256_add_ps(acc_block, _mm256_mul_ps(_mm256_set1_ps(GGML_CPU_FP16_TO_FP32(y_ptr[(K)].d)), q));
650        }
651#undef Q1_AVX_BLOCK
652
653        acc = _mm256_add_ps(acc, _mm256_mul_ps(_mm256_set1_ps(d0), acc_block));
654    }
655
656    *s = hsum_float_8(acc);
657#elif defined(__SSSE3__)
658    const __m128i ones_8 = _mm_set1_epi8(1);
659    const __m128i ones_16 = _mm_set1_epi16(1);
660    const __m128i zero = _mm_setzero_si128();
661    __m128 acc_0 = _mm_setzero_ps();
662    __m128 acc_1 = _mm_setzero_ps();
663    __m128 acc_2 = _mm_setzero_ps();
664    __m128 acc_3 = _mm_setzero_ps();
665
666    for (int ib = 0; ib < nb; ++ib) {
667        const __m128 d0 = _mm_set1_ps(GGML_CPU_FP16_TO_FP32(x[ib].d));
668        const block_q8_0 * GGML_RESTRICT y_ptr = &y[ib * 4];
669
670#define Q1_SSSE3_BLOCK(QS_OFF, Y_IDX, ACC) \
671        { \
672            const __m128i bit_mask_0 = bytes_from_bits_16(&x[ib].qs[(QS_OFF) + 0]); \
673            const __m128i bit_mask_1 = bytes_from_bits_16(&x[ib].qs[(QS_OFF) + 2]); \
674            const __m128i qy_0 = _mm_loadu_si128((const __m128i *) &y_ptr[(Y_IDX)].qs[0]); \
675            const __m128i qy_1 = _mm_loadu_si128((const __m128i *) &y_ptr[(Y_IDX)].qs[16]); \
676            const __m128i sign_mask_0 = _mm_cmpeq_epi8(bit_mask_0, zero); \
677            const __m128i sign_mask_1 = _mm_cmpeq_epi8(bit_mask_1, zero); \
678            const __m128i sy_0 = _mm_sub_epi8(_mm_xor_si128(qy_0, sign_mask_0), sign_mask_0); \
679            const __m128i sy_1 = _mm_sub_epi8(_mm_xor_si128(qy_1, sign_mask_1), sign_mask_1); \
680            const __m128i sum_0 = _mm_madd_epi16(_mm_maddubs_epi16(ones_8, sy_0), ones_16); \
681            const __m128i sum_1 = _mm_madd_epi16(_mm_maddubs_epi16(ones_8, sy_1), ones_16); \
682            const __m128 q = _mm_cvtepi32_ps(_mm_add_epi32(sum_0, sum_1)); \
683            (ACC) = _mm_add_ps((ACC), _mm_mul_ps(_mm_mul_ps(d0, _mm_set1_ps(GGML_CPU_FP16_TO_FP32(y_ptr[(Y_IDX)].d))), q)); \
684        }
685        Q1_SSSE3_BLOCK(0,  0, acc_0)
686        Q1_SSSE3_BLOCK(4,  1, acc_1)
687        Q1_SSSE3_BLOCK(8,  2, acc_2)
688        Q1_SSSE3_BLOCK(12, 3, acc_3)
689#undef Q1_SSSE3_BLOCK
690    }
691
692    *s = hsum_float_4x4(acc_0, acc_1, acc_2, acc_3);
693#else
694    UNUSED(nb);
695    UNUSED(x);
696    UNUSED(y);
697    ggml_vec_dot_q1_0_q8_0_generic(n, s, bs, vx, bx, vy, by, nrc);
698#endif
699}
700
701void ggml_vec_dot_q4_0_q8_0(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
702    const int qk = QK8_0;
703    const int nb = n / qk;
704
705    assert(n % qk == 0);
706    assert(nrc == 1);
707    UNUSED(nrc);
708    UNUSED(bx);
709    UNUSED(by);
710    UNUSED(bs);
711
712    const block_q4_0 * GGML_RESTRICT x = vx;
713    const block_q8_0 * GGML_RESTRICT y = vy;
714
715    int ib = 0;
716    float sumf = 0;
717
718#if defined(__AVX2__)
719    // Initialize accumulator with zeros
720    __m256 acc = _mm256_setzero_ps();
721
722    // Main loop
723    for (; ib < nb; ++ib) {
724        /* Compute combined scale for the block */
725        const __m256 d = _mm256_set1_ps( GGML_CPU_FP16_TO_FP32(x[ib].d) * GGML_CPU_FP16_TO_FP32(y[ib].d) );
726
727        __m256i qx = bytes_from_nibbles_32(x[ib].qs);
728
729        // Now we have a vector with bytes in [ 0 .. 15 ] interval. Offset them into [ -8 .. +7 ] interval.
730        const __m256i off = _mm256_set1_epi8( 8 );
731        qx = _mm256_sub_epi8( qx, off );
732
733        __m256i qy = _mm256_loadu_si256((const __m256i *)y[ib].qs);
734
735        const __m256 q = mul_sum_i8_pairs_float(qx, qy);
736
737        /* Multiply q with scale and accumulate */
738        acc = _mm256_fmadd_ps( d, q, acc );
739    }
740
741    sumf = hsum_float_8(acc);
742#elif defined(__AVX__)
743    __m256 accum = _mm256_setzero_ps();
744    for (; ib + 1 < nb; ib += 2) {
745        const __m128i q4bits_1 = _mm_loadu_si128((const __m128i *)x[ib + 0].qs);
746        const __m128i q4bits_2 = _mm_loadu_si128((const __m128i *)x[ib + 1].qs);
747        const __m128i q8b_1_0 = _mm_loadu_si128((const __m128i *)y[ib + 0].qs);
748        const __m128i q8b_1_1 = _mm_loadu_si128((const __m128i *)y[ib + 0].qs + 1);
749        const __m128i q8b_2_0 = _mm_loadu_si128((const __m128i *)y[ib + 1].qs);
750        const __m128i q8b_2_1 = _mm_loadu_si128((const __m128i *)y[ib + 1].qs + 1);
751
752        const __m128i q4b_1_0 = _mm_sub_epi8(_mm_and_si128(_mm_set1_epi8(15), q4bits_1), _mm_set1_epi8(8));
753        const __m128i q4b_1_1 = _mm_sub_epi8(_mm_and_si128(_mm_set1_epi8(15), _mm_srli_epi16(q4bits_1, 4)), _mm_set1_epi8(8));
754        const __m128i q4b_2_0 = _mm_sub_epi8(_mm_and_si128(_mm_set1_epi8(15), q4bits_2), _mm_set1_epi8(8));
755        const __m128i q4b_2_1 = _mm_sub_epi8(_mm_and_si128(_mm_set1_epi8(15), _mm_srli_epi16(q4bits_2, 4)), _mm_set1_epi8(8));
756
757        const __m128i p16_1_0 = mul_add_epi8_sse(q4b_1_0, q8b_1_0);
758        const __m128i p16_1_1 = mul_add_epi8_sse(q4b_1_1, q8b_1_1);
759        const __m128i p16_2_0 = mul_add_epi8_sse(q4b_2_0, q8b_2_0);
760        const __m128i p16_2_1 = mul_add_epi8_sse(q4b_2_1, q8b_2_1);
761        const __m128i p_1 = _mm_add_epi16(p16_1_0, p16_1_1);
762        const __m128i p_2 = _mm_add_epi16(p16_2_0, p16_2_1);
763        const __m256 p =  sum_i16_pairs_float(p_2, p_1);
764
765        const __m256 deltas = quad_fp16_delta_float(x[ib].d, y[ib].d, x[ib + 1].d, y[ib + 1].d);
766        accum = _mm256_add_ps(_mm256_mul_ps(deltas, p), accum);
767    }
768
769    sumf = hsum_float_8(accum);
770#elif defined(__SSSE3__)
771    // set constants
772    const __m128i lowMask = _mm_set1_epi8(0xF);
773    const __m128i off = _mm_set1_epi8(8);
774
775    // Initialize accumulator with zeros
776    __m128 acc_0 = _mm_setzero_ps();
777    __m128 acc_1 = _mm_setzero_ps();
778    __m128 acc_2 = _mm_setzero_ps();
779    __m128 acc_3 = _mm_setzero_ps();
780
781    for (; ib + 1 < nb; ib += 2) {
782        _mm_prefetch(&x[ib] + sizeof(block_q4_0), _MM_HINT_T0);
783        _mm_prefetch(&y[ib] + sizeof(block_q8_0), _MM_HINT_T0);
784
785        // Compute combined scale for the block 0 and 1
786        const __m128 d_0_1 = _mm_set1_ps( GGML_CPU_FP16_TO_FP32(x[ib].d) * GGML_CPU_FP16_TO_FP32(y[ib].d) );
787
788        const __m128i tmp_0_1 = _mm_loadu_si128((const __m128i *)x[ib].qs);
789
790        __m128i bx_0 = _mm_and_si128(lowMask, tmp_0_1);
791        __m128i by_0 = _mm_loadu_si128((const __m128i *)y[ib].qs);
792        bx_0 = _mm_sub_epi8(bx_0, off);
793        const __m128i i32_0 = mul_sum_i8_pairs(bx_0, by_0);
794
795        __m128i bx_1 = _mm_and_si128(lowMask, _mm_srli_epi64(tmp_0_1, 4));
796        __m128i by_1 = _mm_loadu_si128((const __m128i *)(y[ib].qs + 16));
797        bx_1 = _mm_sub_epi8(bx_1, off);
798        const __m128i i32_1 = mul_sum_i8_pairs(bx_1, by_1);
799
800        _mm_prefetch(&x[ib] + 2 * sizeof(block_q4_0), _MM_HINT_T0);
801        _mm_prefetch(&y[ib] + 2 * sizeof(block_q8_0), _MM_HINT_T0);
802
803        // Compute combined scale for the block 2 and 3
804        const __m128 d_2_3 = _mm_set1_ps( GGML_CPU_FP16_TO_FP32(x[ib + 1].d) * GGML_CPU_FP16_TO_FP32(y[ib + 1].d) );
805
806        const __m128i tmp_2_3 = _mm_loadu_si128((const __m128i *)x[ib + 1].qs);
807
808        __m128i bx_2 = _mm_and_si128(lowMask, tmp_2_3);
809        __m128i by_2 = _mm_loadu_si128((const __m128i *)y[ib + 1].qs);
810        bx_2 = _mm_sub_epi8(bx_2, off);
811        const __m128i i32_2 = mul_sum_i8_pairs(bx_2, by_2);
812
813        __m128i bx_3 = _mm_and_si128(lowMask, _mm_srli_epi64(tmp_2_3, 4));
814        __m128i by_3 = _mm_loadu_si128((const __m128i *)(y[ib + 1].qs + 16));
815        bx_3 = _mm_sub_epi8(bx_3, off);
816        const __m128i i32_3 = mul_sum_i8_pairs(bx_3, by_3);
817
818        // Convert int32_t to float
819        __m128 p0 = _mm_cvtepi32_ps(i32_0);
820        __m128 p1 = _mm_cvtepi32_ps(i32_1);
821        __m128 p2 = _mm_cvtepi32_ps(i32_2);
822        __m128 p3 = _mm_cvtepi32_ps(i32_3);
823
824        // Apply the scale
825        __m128 p0_d = _mm_mul_ps( d_0_1, p0 );
826        __m128 p1_d = _mm_mul_ps( d_0_1, p1 );
827        __m128 p2_d = _mm_mul_ps( d_2_3, p2 );
828        __m128 p3_d = _mm_mul_ps( d_2_3, p3 );
829
830        // Acummulate
831        acc_0 = _mm_add_ps(p0_d, acc_0);
832        acc_1 = _mm_add_ps(p1_d, acc_1);
833        acc_2 = _mm_add_ps(p2_d, acc_2);
834        acc_3 = _mm_add_ps(p3_d, acc_3);
835    }
836
837    sumf = hsum_float_4x4(acc_0, acc_1, acc_2, acc_3);
838
839#endif
840    for (; ib < nb; ++ib) {
841        int sumi0 = 0;
842        int sumi1 = 0;
843
844        for (int j = 0; j < qk/2; ++j) {
845            const int v0 = (x[ib].qs[j] & 0x0F) - 8;
846            const int v1 = (x[ib].qs[j] >>   4) - 8;
847
848            sumi0 += (v0 * y[ib].qs[j]);
849            sumi1 += (v1 * y[ib].qs[j + qk/2]);
850        }
851
852        int sumi = sumi0 + sumi1;
853        sumf += sumi*GGML_CPU_FP16_TO_FP32(x[ib].d)*GGML_CPU_FP16_TO_FP32(y[ib].d);
854    }
855
856    *s = sumf;
857}
858
859void ggml_vec_dot_q4_1_q8_1(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
860    const int qk = QK8_1;
861    const int nb = n / qk;
862
863    assert(n % qk == 0);
864    assert(nrc == 1);
865    UNUSED(nrc);
866    UNUSED(bx);
867    UNUSED(by);
868    UNUSED(bs);
869
870    const block_q4_1 * GGML_RESTRICT x = vx;
871    const block_q8_1 * GGML_RESTRICT y = vy;
872
873    int ib = 0;
874
875#if defined(__AVX2__) || defined(__AVX__)
876    // Initialize accumulator with zeros
877    __m256 acc = _mm256_setzero_ps();
878
879    float summs = 0;
880
881    // Main loop
882    for (; ib < nb; ++ib) {
883        const float d0 = GGML_CPU_FP16_TO_FP32(x[ib].d);
884        const float d1 = GGML_CPU_FP16_TO_FP32(y[ib].d);
885
886        summs += GGML_CPU_FP16_TO_FP32(x[ib].m) * GGML_CPU_FP16_TO_FP32(y[ib].s);
887
888        const __m256 d0v = _mm256_set1_ps( d0 );
889        const __m256 d1v = _mm256_set1_ps( d1 );
890
891        // Compute combined scales
892        const __m256 d0d1 = _mm256_mul_ps( d0v, d1v );
893
894        // Load 16 bytes, and unpack 4 bit fields into bytes, making 32 bytes
895        const __m256i qx = bytes_from_nibbles_32(x[ib].qs);
896        const __m256i qy = _mm256_loadu_si256( (const __m256i *)y[ib].qs );
897
898        const __m256 xy = mul_sum_us8_pairs_float(qx, qy);
899
900        // Accumulate d0*d1*x*y
901#if defined(__AVX2__)
902        acc = _mm256_fmadd_ps( d0d1, xy, acc );
903#else
904        acc = _mm256_add_ps( _mm256_mul_ps( d0d1, xy ), acc );
905#endif
906    }
907
908    *s = hsum_float_8(acc) + summs;
909#else
910    UNUSED(nb);
911    UNUSED(x);
912    UNUSED(y);
913    UNUSED(ib);
914    ggml_vec_dot_q4_1_q8_1_generic(n, s, bs, vx, bx, vy, by, nrc);
915#endif
916}
917
918void ggml_vec_dot_mxfp4_q8_0(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
919    assert(nrc == 1);
920    UNUSED(nrc);
921    UNUSED(bx);
922    UNUSED(by);
923    UNUSED(bs);
924    assert(n % QK_MXFP4 == 0);
925    static_assert(QK_MXFP4 == QK8_0, "QK_MXFP4 and QK8_0 must be the same");
926
927    const block_mxfp4 * GGML_RESTRICT x = vx;
928    const block_q8_0 * GGML_RESTRICT y = vy;
929
930    const int nb = n / QK_MXFP4;
931
932    int ib = 0;
933    float sumf = 0;
934
935#if defined __AVX2__
936
937    const __m128i values128 = _mm_loadu_si128((const __m128i*)kvalues_fp4);
938    const __m128i m4b  = _mm_set1_epi8(0x0f);
939    const __m256i mone = _mm256_set1_epi16(1);
940
941    __m256 accum1 = _mm256_setzero_ps();
942    __m256 accum2 = _mm256_setzero_ps();
943
944    for (; ib + 1 < nb; ib += 2) {
945        const __m128i q4bits_1 = _mm_loadu_si128((const __m128i*)x[ib + 0].qs);
946        const __m128i q4bits_2 = _mm_loadu_si128((const __m128i*)x[ib + 1].qs);
947        const __m256i q8b_1 = _mm256_loadu_si256((const __m256i *)y[ib + 0].qs);
948        const __m256i q8b_2 = _mm256_loadu_si256((const __m256i *)y[ib + 1].qs);
949        const __m256i q4b_1 = MM256_SET_M128I(_mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_1, 4), m4b)),
950                                              _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_1, m4b)));
951        const __m256i q4b_2 = MM256_SET_M128I(_mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_2, 4), m4b)),
952                                              _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_2, m4b)));
953        const __m256i p16_1 = mul_add_epi8(q4b_1, q8b_1);
954        const __m256i p16_2 = mul_add_epi8(q4b_2, q8b_2);
955        const __m256i p_1 = _mm256_madd_epi16(p16_1, mone);
956        const __m256i p_2 = _mm256_madd_epi16(p16_2, mone);
957        const __m256 scale0 = _mm256_set1_ps(GGML_CPU_FP16_TO_FP32(y[ib + 0].d)*GGML_CPU_E8M0_TO_FP32_HALF(x[ib + 0].e));
958        const __m256 scale1 = _mm256_set1_ps(GGML_CPU_FP16_TO_FP32(y[ib + 1].d)*GGML_CPU_E8M0_TO_FP32_HALF(x[ib + 1].e));
959        accum1 = _mm256_fmadd_ps(scale0, _mm256_cvtepi32_ps(p_1), accum1);
960        accum2 = _mm256_fmadd_ps(scale1, _mm256_cvtepi32_ps(p_2), accum2);
961    }
962
963    sumf = hsum_float_8(_mm256_add_ps(accum1, accum2));
964
965#elif defined __AVX__
966    const __m128i values128 = _mm_loadu_si128((const __m128i*)kvalues_fp4);
967    const __m128i m4b  = _mm_set1_epi8(0x0f);
968
969    __m256 accum = _mm256_setzero_ps();
970    for (; ib + 1 < nb; ib += 2) {
971        const __m128i q4bits_1 = _mm_loadu_si128((const __m128i *)x[ib + 0].qs);
972        const __m128i q4bits_2 = _mm_loadu_si128((const __m128i *)x[ib + 1].qs);
973        const __m128i q8b_1_0 = _mm_loadu_si128((const __m128i *)y[ib + 0].qs);
974        const __m128i q8b_1_1 = _mm_loadu_si128((const __m128i *)y[ib + 0].qs + 1);
975        const __m128i q8b_2_0 = _mm_loadu_si128((const __m128i *)y[ib + 1].qs);
976        const __m128i q8b_2_1 = _mm_loadu_si128((const __m128i *)y[ib + 1].qs + 1);
977
978        const __m128i q4b_1_0 = _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_1, m4b));
979        const __m128i q4b_1_1 = _mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_1, 4), m4b));
980        const __m128i q4b_2_0 = _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_2, m4b));
981        const __m128i q4b_2_1 = _mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_2, 4), m4b));
982
983        const __m256 p = mul_sum_i8_quad_float(q4b_1_0, q4b_1_1, q4b_2_0, q4b_2_1, q8b_1_0, q8b_1_1, q8b_2_0, q8b_2_1);
984        const __m256 deltas = quad_mx_delta_float(x[ib].e, y[ib].d, x[ib + 1].e, y[ib + 1].d);
985        accum = _mm256_add_ps(_mm256_mul_ps(deltas, p), accum);
986    }
987
988    sumf = hsum_float_8(accum);
989
990#endif
991    for (; ib < nb; ++ib) {
992        const float d = GGML_CPU_FP16_TO_FP32(y[ib].d)*GGML_CPU_E8M0_TO_FP32_HALF(x[ib].e);
993        int sumi1 = 0;
994        int sumi2 = 0;
995        for (int j = 0; j < QK_MXFP4/2; ++j) {
996            sumi1 += y[ib].qs[j +          0] * kvalues_fp4[x[ib].qs[j] & 0xf];
997            sumi2 += y[ib].qs[j + QK_MXFP4/2] * kvalues_fp4[x[ib].qs[j] >>  4];
998        }
999        sumf += d * (sumi1 + sumi2);
1000    }
1001    *s = sumf;
1002}
1003
1004void ggml_vec_dot_nvfp4_q8_0(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1005    assert(nrc == 1);
1006    UNUSED(nrc);
1007    UNUSED(bx);
1008    UNUSED(by);
1009    UNUSED(bs);
1010    assert(n % QK_NVFP4 == 0);
1011
1012    const block_nvfp4 * GGML_RESTRICT x = vx;
1013    const block_q8_0 * GGML_RESTRICT y = vy;
1014
1015    const int nb = n / QK_NVFP4;
1016    int ib = 0;
1017    float sumf = 0;
1018
1019#if defined(__AVX2__)
1020
1021    const __m128i values128 = _mm_loadu_si128((const __m128i*)kvalues_fp4);
1022    const __m128i m4b  = _mm_set1_epi8(0x0f);
1023    const __m256i mone = _mm256_set1_epi16(1);
1024
1025    __m256 accum = _mm256_setzero_ps();
1026    for(; ib < nb; ib++){
1027
1028        const __m128i q4bits_01 = _mm_loadu_si128((const __m128i *)(x[ib].qs + 0));
1029        const __m128i q4bits_23 = _mm_loadu_si128((const __m128i *)(x[ib].qs + 16));
1030
1031        const __m256i q8_01 = _mm256_loadu_si256((const __m256i *)y[2*ib + 0].qs);
1032        const __m256i q8_23 = _mm256_loadu_si256((const __m256i *)y[2*ib + 1].qs);
1033
1034        const __m128i q4_01_lo = _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_01, m4b));
1035        const __m128i q4_01_hi = _mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_01, 4), m4b));
1036        const __m128i q4_23_lo = _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_23, m4b));
1037        const __m128i q4_23_hi = _mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_23, 4), m4b));
1038
1039        //reordering
1040        const __m256i q4_01 = MM256_SET_M128I(_mm_unpackhi_epi64(q4_01_lo,q4_01_hi), _mm_unpacklo_epi64(q4_01_lo,q4_01_hi));
1041        const __m256i q4_23 = MM256_SET_M128I(_mm_unpackhi_epi64(q4_23_lo,q4_23_hi),_mm_unpacklo_epi64(q4_23_lo,q4_23_hi));
1042
1043        const __m256i p01 = mul_add_epi8(q4_01,q8_01);
1044        const __m256i p_1 = _mm256_madd_epi16(p01, mone);
1045
1046        const __m256i p23 = mul_add_epi8(q4_23,q8_23);
1047        const __m256i p_2 = _mm256_madd_epi16(p23, mone);
1048
1049        const float dy0 = GGML_CPU_FP16_TO_FP32(y[2*ib].d);
1050        const float dy1 = GGML_CPU_FP16_TO_FP32(y[2*ib+1].d);
1051
1052        const float s0 = GGML_CPU_UE4M3_TO_FP32(x[ib].d[0]) * dy0;
1053        const float s1 = GGML_CPU_UE4M3_TO_FP32(x[ib].d[1]) * dy0;
1054        const float s2 = GGML_CPU_UE4M3_TO_FP32(x[ib].d[2]) * dy1;
1055        const float s3 = GGML_CPU_UE4M3_TO_FP32(x[ib].d[3]) * dy1;
1056
1057        const __m256 scales01 = _mm256_set_m128(_mm_set1_ps(s1), _mm_set1_ps(s0));
1058        const __m256 scales23 = _mm256_set_m128(_mm_set1_ps(s3), _mm_set1_ps(s2));
1059
1060        accum = _mm256_fmadd_ps(scales01, _mm256_cvtepi32_ps(p_1), accum);
1061        accum = _mm256_fmadd_ps(scales23, _mm256_cvtepi32_ps(p_2), accum);
1062    }
1063    sumf = hsum_float_8(accum);
1064
1065#elif defined(__AVX__)
1066
1067    const __m128i values128 = _mm_loadu_si128((const __m128i*)kvalues_fp4);
1068    const __m128i m4b  = _mm_set1_epi8(0x0f);
1069
1070    __m256 accum = _mm256_setzero_ps();
1071    for(; ib < nb; ib++){
1072
1073        const __m128i q4bits_01 = _mm_loadu_si128((const __m128i *)(x[ib].qs + 0));
1074        const __m128i q4bits_23 = _mm_loadu_si128((const __m128i *)(x[ib].qs + 16));
1075
1076        const __m128i q8_0 = _mm_loadu_si128((const __m128i *)(y[2*ib + 0].qs + 0));
1077        const __m128i q8_1 = _mm_loadu_si128((const __m128i *)(y[2*ib + 0].qs + 16));
1078        const __m128i q8_2 = _mm_loadu_si128((const __m128i *)(y[2*ib + 1].qs + 0));
1079        const __m128i q8_3 = _mm_loadu_si128((const __m128i *)(y[2*ib + 1].qs + 16));
1080
1081        const __m128i q4_01_lo = _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_01, m4b));
1082        const __m128i q4_01_hi = _mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_01, 4), m4b));
1083        const __m128i q4_23_lo = _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_23, m4b));
1084        const __m128i q4_23_hi = _mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_23, 4), m4b));
1085
1086        const __m128i q4_0 = _mm_unpacklo_epi64(q4_01_lo, q4_01_hi);
1087        const __m128i q4_1 = _mm_unpackhi_epi64(q4_01_lo, q4_01_hi);
1088        const __m128i q4_2 = _mm_unpacklo_epi64(q4_23_lo, q4_23_hi);
1089        const __m128i q4_3 = _mm_unpackhi_epi64(q4_23_lo, q4_23_hi);
1090
1091        const __m128i p0_i32 = mul_sum_i8_pairs(q4_0, q8_0);
1092        const __m128i p1_i32 = mul_sum_i8_pairs(q4_1, q8_1);
1093        const __m128i p2_i32 = mul_sum_i8_pairs(q4_2, q8_2);
1094        const __m128i p3_i32 = mul_sum_i8_pairs(q4_3, q8_3);
1095
1096        const __m128 p0 = _mm_cvtepi32_ps(p0_i32);
1097        const __m128 p1 = _mm_cvtepi32_ps(p1_i32);
1098        const __m128 p2 = _mm_cvtepi32_ps(p2_i32);
1099        const __m128 p3 = _mm_cvtepi32_ps(p3_i32);
1100
1101        const __m256 p01 = _mm256_set_m128(p1, p0);
1102        const __m256 p23 = _mm256_set_m128(p3, p2);
1103
1104        const float dy0 = GGML_CPU_FP16_TO_FP32(y[2*ib].d);
1105        const float dy1 = GGML_CPU_FP16_TO_FP32(y[2*ib+1].d);
1106
1107        const float s0 = GGML_CPU_UE4M3_TO_FP32(x[ib].d[0]) * dy0;
1108        const float s1 = GGML_CPU_UE4M3_TO_FP32(x[ib].d[1]) * dy0;
1109        const float s2 = GGML_CPU_UE4M3_TO_FP32(x[ib].d[2]) * dy1;
1110        const float s3 = GGML_CPU_UE4M3_TO_FP32(x[ib].d[3]) * dy1;
1111
1112        const __m256 scales01 = _mm256_set_m128(_mm_set1_ps(s1), _mm_set1_ps(s0));
1113        const __m256 scales23 = _mm256_set_m128(_mm_set1_ps(s3), _mm_set1_ps(s2));
1114
1115        accum = _mm256_add_ps(accum, _mm256_mul_ps(p01, scales01));
1116        accum = _mm256_add_ps(accum, _mm256_mul_ps(p23, scales23));
1117    }
1118    sumf = hsum_float_8(accum);
1119
1120#endif
1121
1122    for (;ib < nb; ++ib) {
1123        for (int s_idx = 0; s_idx < 4; ++s_idx) {
1124            const float d = GGML_CPU_UE4M3_TO_FP32(x[ib].d[s_idx]);
1125            const int q8_block = s_idx / 2;
1126            const int q8_off   = (s_idx % 2) * QK_NVFP4_SUB;
1127            const float dy = GGML_CPU_FP16_TO_FP32(y[2*ib + q8_block].d);
1128
1129            int sumi_lo = 0, sumi_hi = 0;
1130            for (int j = 0; j < QK_NVFP4_SUB/2; ++j) {
1131                const uint8_t qv = x[ib].qs[s_idx*(QK_NVFP4_SUB/2) + j];
1132                sumi_lo += y[2*ib + q8_block].qs[q8_off + j +               0] * kvalues_fp4[qv & 0xf];
1133                sumi_hi += y[2*ib + q8_block].qs[q8_off + j + QK_NVFP4_SUB/2] * kvalues_fp4[qv >>  4];
1134            }
1135
1136            sumf += dy * d * (sumi_lo + sumi_hi);
1137        }
1138    }
1139    *s = sumf;
1140}
1141
1142void ggml_vec_dot_q5_0_q8_0(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1143    const int qk = QK8_0;
1144    const int nb = n / qk;
1145
1146    int ib = 0;
1147
1148    assert(n % qk == 0);
1149    assert(qk == QK5_0);
1150    assert(nrc == 1);
1151    UNUSED(nrc);
1152    UNUSED(bx);
1153    UNUSED(by);
1154    UNUSED(bs);
1155
1156    const block_q5_0 * GGML_RESTRICT x = vx;
1157    const block_q8_0 * GGML_RESTRICT y = vy;
1158
1159#if defined(__AVX2__)
1160    // Initialize accumulator with zeros
1161    __m256 acc = _mm256_setzero_ps();
1162
1163    // Main loop
1164    for (; ib < nb; ++ib) {
1165        /* Compute combined scale for the block */
1166        const __m256 d = _mm256_set1_ps(GGML_CPU_FP16_TO_FP32(x[ib].d) * GGML_CPU_FP16_TO_FP32(y[ib].d));
1167
1168        __m256i qx = bytes_from_nibbles_32(x[ib].qs);
1169        __m256i bxhi = bytes_from_bits_32(x[ib].qh);
1170        bxhi = _mm256_andnot_si256(bxhi, _mm256_set1_epi8((char)0xF0));
1171        qx = _mm256_or_si256(qx, bxhi);
1172
1173        __m256i qy = _mm256_loadu_si256((const __m256i *)y[ib].qs);
1174
1175        const __m256 q = mul_sum_i8_pairs_float(qx, qy);
1176
1177        /* Multiply q with scale and accumulate */
1178        acc = _mm256_fmadd_ps(d, q, acc);
1179    }
1180
1181    *s = hsum_float_8(acc);
1182#elif defined(__AVX__)
1183    // Initialize accumulator with zeros
1184    __m256 acc = _mm256_setzero_ps();
1185    __m128i mask = _mm_set1_epi8((char)0xF0);
1186
1187    // Main loop
1188    for (; ib < nb; ++ib) {
1189        /* Compute combined scale for the block */
1190        const __m256 d = _mm256_set1_ps(GGML_CPU_FP16_TO_FP32(x[ib].d) * GGML_CPU_FP16_TO_FP32(y[ib].d));
1191
1192        __m256i bx_0 = bytes_from_nibbles_32(x[ib].qs);
1193        const __m256i bxhi = bytes_from_bits_32(x[ib].qh);
1194        __m128i bxhil = _mm256_castsi256_si128(bxhi);
1195        __m128i bxhih = _mm256_extractf128_si256(bxhi, 1);
1196        bxhil = _mm_andnot_si128(bxhil, mask);
1197        bxhih = _mm_andnot_si128(bxhih, mask);
1198        __m128i bxl = _mm256_castsi256_si128(bx_0);
1199        __m128i bxh = _mm256_extractf128_si256(bx_0, 1);
1200        bxl = _mm_or_si128(bxl, bxhil);
1201        bxh = _mm_or_si128(bxh, bxhih);
1202        bx_0 = MM256_SET_M128I(bxh, bxl);
1203
1204        const __m256i by_0 = _mm256_loadu_si256((const __m256i *)y[ib].qs);
1205
1206        const __m256 q = mul_sum_i8_pairs_float(bx_0, by_0);
1207
1208        /* Multiply q with scale and accumulate */
1209        acc = _mm256_add_ps(_mm256_mul_ps(d, q), acc);
1210    }
1211
1212    *s = hsum_float_8(acc);
1213#else
1214    UNUSED(nb);
1215    UNUSED(ib);
1216    UNUSED(x);
1217    UNUSED(y);
1218    ggml_vec_dot_q5_0_q8_0_generic(n, s, bs, vx, bx, vy, by, nrc);
1219#endif
1220}
1221
1222void ggml_vec_dot_q5_1_q8_1(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1223    const int qk = QK8_1;
1224    const int nb = n / qk;
1225
1226    int ib = 0;
1227
1228    assert(n % qk == 0);
1229    assert(qk == QK5_1);
1230    assert(nrc == 1);
1231    UNUSED(nrc);
1232    UNUSED(bx);
1233    UNUSED(by);
1234    UNUSED(bs);
1235
1236    const block_q5_1 * GGML_RESTRICT x = vx;
1237    const block_q8_1 * GGML_RESTRICT y = vy;
1238
1239#if defined(__AVX2__)
1240    // Initialize accumulator with zeros
1241    __m256 acc = _mm256_setzero_ps();
1242
1243    float summs = 0.0f;
1244
1245    // Main loop
1246    for (; ib < nb; ++ib) {
1247        const __m256 dx = _mm256_set1_ps(GGML_CPU_FP16_TO_FP32(x[ib].d));
1248
1249        summs += GGML_CPU_FP16_TO_FP32(x[ib].m) * GGML_CPU_FP16_TO_FP32(y[ib].s);
1250
1251        __m256i qx = bytes_from_nibbles_32(x[ib].qs);
1252        __m256i bxhi = bytes_from_bits_32(x[ib].qh);
1253        bxhi = _mm256_and_si256(bxhi, _mm256_set1_epi8(0x10));
1254        qx = _mm256_or_si256(qx, bxhi);
1255
1256        const __m256 dy = _mm256_set1_ps(GGML_CPU_FP16_TO_FP32(y[ib].d));
1257        const __m256i qy = _mm256_loadu_si256((const __m256i *)y[ib].qs);
1258
1259        const __m256 q = mul_sum_us8_pairs_float(qx, qy);
1260
1261        acc = _mm256_fmadd_ps(q, _mm256_mul_ps(dx, dy), acc);
1262    }
1263
1264    *s = hsum_float_8(acc) + summs;
1265#elif defined(__AVX__)
1266    // Initialize accumulator with zeros
1267    __m256 acc = _mm256_setzero_ps();
1268    __m128i mask = _mm_set1_epi8(0x10);
1269
1270    float summs = 0.0f;
1271
1272    // Main loop
1273    for (; ib < nb; ++ib) {
1274        const __m256 dx = _mm256_set1_ps(GGML_CPU_FP16_TO_FP32(x[ib].d));
1275
1276        summs += GGML_CPU_FP16_TO_FP32(x[ib].m) * GGML_CPU_FP16_TO_FP32(y[ib].s);
1277
1278        __m256i bx_0 = bytes_from_nibbles_32(x[ib].qs);
1279        const __m256i bxhi = bytes_from_bits_32(x[ib].qh);
1280        __m128i bxhil = _mm256_castsi256_si128(bxhi);
1281        __m128i bxhih = _mm256_extractf128_si256(bxhi, 1);
1282        bxhil = _mm_and_si128(bxhil, mask);
1283        bxhih = _mm_and_si128(bxhih, mask);
1284        __m128i bxl = _mm256_castsi256_si128(bx_0);
1285        __m128i bxh = _mm256_extractf128_si256(bx_0, 1);
1286        bxl = _mm_or_si128(bxl, bxhil);
1287        bxh = _mm_or_si128(bxh, bxhih);
1288        bx_0 = MM256_SET_M128I(bxh, bxl);
1289
1290        const __m256 dy = _mm256_set1_ps(GGML_CPU_FP16_TO_FP32(y[ib].d));
1291        const __m256i by_0 = _mm256_loadu_si256((const __m256i *)y[ib].qs);
1292
1293        const __m256 q = mul_sum_us8_pairs_float(bx_0, by_0);
1294
1295        acc = _mm256_add_ps(_mm256_mul_ps(q, _mm256_mul_ps(dx, dy)), acc);
1296    }
1297
1298    *s = hsum_float_8(acc) + summs;
1299#else
1300    UNUSED(nb);
1301    UNUSED(ib);
1302    UNUSED(x);
1303    UNUSED(y);
1304    ggml_vec_dot_q5_1_q8_1_generic(n, s, bs, vx, bx, vy, by, nrc);
1305#endif
1306}
1307
1308void ggml_vec_dot_q8_0_q8_0(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1309    const int qk = QK8_0;
1310    const int nb = n / qk;
1311
1312    assert(n % qk == 0);
1313    assert(nrc == 1);
1314    UNUSED(nrc);
1315    UNUSED(bx);
1316    UNUSED(by);
1317    UNUSED(bs);
1318
1319    const block_q8_0 * GGML_RESTRICT x = vx;
1320    const block_q8_0 * GGML_RESTRICT y = vy;
1321
1322    int ib = 0;
1323    float sumf = 0;
1324
1325#if defined(__AVX2__)
1326    // Initialize accumulator with zeros
1327    __m256 acc = _mm256_setzero_ps();
1328
1329    // Main loop
1330    for (; ib < nb; ++ib) {
1331        // Compute combined scale for the block
1332        const __m256 d = _mm256_set1_ps(GGML_CPU_FP16_TO_FP32(x[ib].d) * GGML_CPU_FP16_TO_FP32(y[ib].d));
1333        __m256i qx = _mm256_loadu_si256((const __m256i *)x[ib].qs);
1334        __m256i qy = _mm256_loadu_si256((const __m256i *)y[ib].qs);
1335
1336        const __m256 q = mul_sum_i8_pairs_float(qx, qy);
1337
1338        // Multiply q with scale and accumulate
1339        acc = _mm256_fmadd_ps( d, q, acc );
1340    }
1341
1342    sumf = hsum_float_8(acc);
1343#elif defined(__AVX__)
1344    __m256 accum = _mm256_setzero_ps();
1345
1346    for (; ib + 1 < nb; ib += 2) {
1347        const __m128i qx_1_0 = _mm_loadu_si128((const __m128i *)x[ib].qs);
1348        const __m128i qx_1_1 = _mm_loadu_si128((const __m128i *)x[ib].qs + 1);
1349        const __m128i qx_2_0 = _mm_loadu_si128((const __m128i *)x[ib + 1].qs);
1350        const __m128i qx_2_1 = _mm_loadu_si128((const __m128i *)x[ib + 1].qs + 1);
1351        const __m128i qy_1_0 = _mm_loadu_si128((const __m128i *)y[ib].qs);
1352        const __m128i qy_1_1 = _mm_loadu_si128((const __m128i *)y[ib].qs + 1);
1353        const __m128i qy_2_0 = _mm_loadu_si128((const __m128i *)y[ib + 1].qs);
1354        const __m128i qy_2_1 = _mm_loadu_si128((const __m128i *)y[ib + 1].qs + 1);
1355
1356        const __m256 p = mul_sum_i8_quad_float(qx_1_0, qx_1_1, qx_2_0, qx_2_1, qy_1_0, qy_1_1, qy_2_0, qy_2_1);
1357        const __m256 deltas = quad_fp16_delta_float(x[ib].d, y[ib].d, x[ib + 1].d, y[ib + 1].d);
1358        accum = _mm256_add_ps(_mm256_mul_ps(deltas, p), accum);
1359    }
1360
1361    sumf = hsum_float_8(accum);
1362#endif
1363    for (; ib < nb; ++ib) {
1364        int sumi = 0;
1365
1366        for (int j = 0; j < qk; j++) {
1367            sumi += x[ib].qs[j]*y[ib].qs[j];
1368        }
1369
1370        sumf += sumi*(GGML_CPU_FP16_TO_FP32(x[ib].d)*GGML_CPU_FP16_TO_FP32(y[ib].d));
1371    }
1372
1373    *s = sumf;
1374}
1375
1376void ggml_vec_dot_tq1_0_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1377    assert(nrc == 1);
1378    UNUSED(nrc);
1379    UNUSED(bx);
1380    UNUSED(by);
1381    UNUSED(bs);
1382
1383    const block_tq1_0 * GGML_RESTRICT x = vx;
1384    const block_q8_K  * GGML_RESTRICT y = vy;
1385
1386    const int nb = n / QK_K;
1387
1388#if defined(__AVX2__)
1389    __m256 sumf = _mm256_setzero_ps();
1390
1391    for (int i = 0; i < nb; ++i) {
1392        // 16-bit sums
1393        __m256i sumi0 = _mm256_setzero_si256();
1394        __m256i sumi1 = _mm256_setzero_si256();
1395        __m256i sumi2 = _mm256_setzero_si256();
1396
1397        // first 32 bytes of 5 elements
1398        {
1399            __m256i qx0 = _mm256_loadu_si256((const __m256i *) (x[i].qs));
1400            // 8-bit multiplies with shifts, masks and adds
1401            __m256i qx1 = _mm256_add_epi8(qx0, _mm256_add_epi8(qx0, qx0)); // 1 * 3
1402            __m256i qx2 = _mm256_add_epi8(_mm256_and_si256(_mm256_slli_epi16(qx0, 3), _mm256_set1_epi8(-8)), qx0); // 1 * 9
1403            __m256i qx3 = _mm256_add_epi8(_mm256_and_si256(_mm256_slli_epi16(qx1, 3), _mm256_set1_epi8(-8)), qx1); // 3 * 9
1404            __m256i qx4 = _mm256_add_epi8(_mm256_and_si256(_mm256_slli_epi16(qx2, 3), _mm256_set1_epi8(-8)), qx2); // 9 * 9
1405
1406            // TODO: can _mm256_mulhi_epu16 be faster even if 16-bits?
1407
1408            // Cancel the +1 from avg so that it behaves like a halving add
1409            qx0 = _mm256_subs_epu8(qx0, _mm256_set1_epi8(1));
1410            qx1 = _mm256_subs_epu8(qx1, _mm256_set1_epi8(1));
1411            qx2 = _mm256_subs_epu8(qx2, _mm256_set1_epi8(1));
1412            qx3 = _mm256_subs_epu8(qx3, _mm256_set1_epi8(1));
1413            qx4 = _mm256_subs_epu8(qx4, _mm256_set1_epi8(1));
1414            // Multiply by 3 and get the top 2 bits
1415            qx0 = _mm256_avg_epu8(qx0, _mm256_avg_epu8(qx0, _mm256_setzero_si256()));
1416            qx1 = _mm256_avg_epu8(qx1, _mm256_avg_epu8(qx1, _mm256_setzero_si256()));
1417            qx2 = _mm256_avg_epu8(qx2, _mm256_avg_epu8(qx2, _mm256_setzero_si256()));
1418            qx3 = _mm256_avg_epu8(qx3, _mm256_avg_epu8(qx3, _mm256_setzero_si256()));
1419            qx4 = _mm256_avg_epu8(qx4, _mm256_avg_epu8(qx4, _mm256_setzero_si256()));
1420            qx0 = _mm256_and_si256(_mm256_srli_epi16(qx0, 6), _mm256_set1_epi8(3));
1421            qx1 = _mm256_and_si256(_mm256_srli_epi16(qx1, 6), _mm256_set1_epi8(3));
1422            qx2 = _mm256_and_si256(_mm256_srli_epi16(qx2, 6), _mm256_set1_epi8(3));
1423            qx3 = _mm256_and_si256(_mm256_srli_epi16(qx3, 6), _mm256_set1_epi8(3));
1424            qx4 = _mm256_and_si256(_mm256_srli_epi16(qx4, 6), _mm256_set1_epi8(3));
1425
1426            const __m256i qy0 = _mm256_loadu_si256((const __m256i *) (y[i].qs +   0));
1427            const __m256i qy1 = _mm256_loadu_si256((const __m256i *) (y[i].qs +  32));
1428            const __m256i qy2 = _mm256_loadu_si256((const __m256i *) (y[i].qs +  64));
1429            const __m256i qy3 = _mm256_loadu_si256((const __m256i *) (y[i].qs +  96));
1430            const __m256i qy4 = _mm256_loadu_si256((const __m256i *) (y[i].qs + 128));
1431
1432            qx0 = _mm256_maddubs_epi16(qx0, qy0);
1433            qx1 = _mm256_maddubs_epi16(qx1, qy1);
1434            qx2 = _mm256_maddubs_epi16(qx2, qy2);
1435            qx3 = _mm256_maddubs_epi16(qx3, qy3);
1436            qx4 = _mm256_maddubs_epi16(qx4, qy4);
1437
1438            sumi0 = _mm256_add_epi16(sumi0, _mm256_add_epi16(qx0, qx1));
1439            sumi1 = _mm256_add_epi16(sumi1, _mm256_add_epi16(qx2, qx3));
1440            sumi2 = _mm256_add_epi16(sumi2, qx4);
1441        }
1442
1443        // last 16 bytes of 5-element, along with the 4 bytes of 4 elements
1444        {
1445            __m128i qx0 = _mm_loadu_si128((const __m128i *) (x[i].qs + 32));
1446            uint32_t qh;
1447            memcpy(&qh, x[i].qh, sizeof(qh)); // potentially unaligned
1448            __m256i qx5_l = _mm256_cvtepu8_epi16(_mm_set1_epi32(qh));
1449            __m128i qx1 = _mm_add_epi8(qx0, _mm_add_epi8(qx0, qx0)); // 1 * 3
1450            __m128i qx2 = _mm_add_epi8(_mm_and_si128(_mm_slli_epi16(qx0, 3), _mm_set1_epi8(-8)), qx0); // 1 * 9
1451            __m128i qx3 = _mm_add_epi8(_mm_and_si128(_mm_slli_epi16(qx1, 3), _mm_set1_epi8(-8)), qx1); // 3 * 9
1452            __m128i qx4 = _mm_add_epi8(_mm_and_si128(_mm_slli_epi16(qx2, 3), _mm_set1_epi8(-8)), qx2); // 9 * 9
1453            __m256i qx01 = MM256_SET_M128I(qx1, qx0);
1454            __m256i qx23 = MM256_SET_M128I(qx3, qx2);
1455
1456            // avx2 does not have 8-bit multiplies, so 16-bit it is.
1457            qx5_l = _mm256_mullo_epi16(qx5_l, _mm256_set_epi16(27, 27, 27, 27, 9, 9, 9, 9, 3, 3, 3, 3, 1, 1, 1, 1));
1458            qx5_l = _mm256_and_si256(qx5_l, _mm256_set1_epi16(0xFF));
1459            __m128i qx5 = _mm_packus_epi16(_mm256_castsi256_si128(qx5_l), _mm256_extracti128_si256(qx5_l, 1));
1460
1461            __m256i qx45 = MM256_SET_M128I(qx5, qx4);
1462
1463            // Cancel the +1 from avg so that it behaves like a halving add
1464            qx01 = _mm256_subs_epu8(qx01, _mm256_set1_epi8(1));
1465            qx23 = _mm256_subs_epu8(qx23, _mm256_set1_epi8(1));
1466            qx45 = _mm256_subs_epu8(qx45, _mm256_set1_epi8(1));
1467            // Multiply by 3 and get the top 2 bits
1468            qx01 = _mm256_avg_epu8(qx01, _mm256_avg_epu8(qx01, _mm256_setzero_si256()));
1469            qx23 = _mm256_avg_epu8(qx23, _mm256_avg_epu8(qx23, _mm256_setzero_si256()));
1470            qx45 = _mm256_avg_epu8(qx45, _mm256_avg_epu8(qx45, _mm256_setzero_si256()));
1471            qx01 = _mm256_and_si256(_mm256_srli_epi16(qx01, 6), _mm256_set1_epi8(3));
1472            qx23 = _mm256_and_si256(_mm256_srli_epi16(qx23, 6), _mm256_set1_epi8(3));
1473            qx45 = _mm256_and_si256(_mm256_srli_epi16(qx45, 6), _mm256_set1_epi8(3));
1474
1475            const __m256i qy01 = _mm256_loadu_si256((const __m256i *) (y[i].qs + 160));
1476            const __m256i qy23 = _mm256_loadu_si256((const __m256i *) (y[i].qs + 192));
1477            const __m256i qy45 = _mm256_loadu_si256((const __m256i *) (y[i].qs + 224));
1478
1479            qx01 = _mm256_maddubs_epi16(qx01, qy01);
1480            qx23 = _mm256_maddubs_epi16(qx23, qy23);
1481            qx45 = _mm256_maddubs_epi16(qx45, qy45);
1482
1483            sumi0 = _mm256_add_epi16(sumi0, qx01);
1484            sumi1 = _mm256_add_epi16(sumi1, qx23);
1485            sumi2 = _mm256_add_epi16(sumi2, qx45);
1486        }
1487
1488        const __m256i ysum = _mm256_loadu_si256((const __m256i *) y[i].bsums);
1489        const __m256 d = _mm256_set1_ps(y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d));
1490
1491        sumi0 = _mm256_sub_epi16(sumi0, ysum);
1492        sumi0 = _mm256_add_epi16(sumi0, _mm256_add_epi16(sumi1, sumi2));
1493        sumi0 = _mm256_madd_epi16(sumi0, _mm256_set1_epi16(1));
1494
1495        sumf = _mm256_add_ps(_mm256_mul_ps(_mm256_cvtepi32_ps(sumi0), d), sumf);
1496    }
1497
1498    *s = hsum_float_8(sumf);
1499
1500#else
1501    UNUSED(x);
1502    UNUSED(y);
1503    UNUSED(nb);
1504    ggml_vec_dot_tq1_0_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
1505#endif
1506}
1507
1508void ggml_vec_dot_tq2_0_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1509    assert(nrc == 1);
1510    UNUSED(nrc);
1511    UNUSED(bx);
1512    UNUSED(by);
1513    UNUSED(bs);
1514
1515    const block_tq2_0 * GGML_RESTRICT x = vx;
1516    const block_q8_K  * GGML_RESTRICT y = vy;
1517
1518    const int nb = n / QK_K;
1519
1520#if defined(__AVX2__)
1521    __m256 sumf = _mm256_setzero_ps();
1522
1523    for (int i = 0; i < nb; ++i) {
1524        // 16-bit sums, because 256*127 still fits
1525        __m256i sumi0 = _mm256_setzero_si256();
1526        __m256i sumi1 = _mm256_setzero_si256();
1527
1528        for (size_t j = 0; j < sizeof(x->qs); j += 32) {
1529            __m256i qx0 = _mm256_loadu_si256((const __m256i *) (x[i].qs + j));
1530            __m256i qx1 = _mm256_srli_epi16(qx0, 2);
1531            __m256i qx2 = _mm256_srli_epi16(qx0, 4);
1532            __m256i qx3 = _mm256_srli_epi16(qx0, 6);
1533
1534            // 0, 1, 2 (should not be 3)
1535            qx0 = _mm256_and_si256(qx0, _mm256_set1_epi8(3));
1536            qx1 = _mm256_and_si256(qx1, _mm256_set1_epi8(3));
1537            qx2 = _mm256_and_si256(qx2, _mm256_set1_epi8(3));
1538            qx3 = _mm256_and_si256(qx3, _mm256_set1_epi8(3));
1539
1540            const __m256i qy0 = _mm256_loadu_si256((const __m256i *) (y[i].qs + j*4 +  0));
1541            const __m256i qy1 = _mm256_loadu_si256((const __m256i *) (y[i].qs + j*4 + 32));
1542            const __m256i qy2 = _mm256_loadu_si256((const __m256i *) (y[i].qs + j*4 + 64));
1543            const __m256i qy3 = _mm256_loadu_si256((const __m256i *) (y[i].qs + j*4 + 96));
1544
1545            qx0 = _mm256_maddubs_epi16(qx0, qy0);
1546            qx1 = _mm256_maddubs_epi16(qx1, qy1);
1547            qx2 = _mm256_maddubs_epi16(qx2, qy2);
1548            qx3 = _mm256_maddubs_epi16(qx3, qy3);
1549
1550            sumi0 = _mm256_add_epi16(sumi0, _mm256_add_epi16(qx0, qx1));
1551            sumi1 = _mm256_add_epi16(sumi1, _mm256_add_epi16(qx2, qx3));
1552        }
1553
1554        const __m256i ysum = _mm256_loadu_si256((const __m256i *) y[i].bsums);
1555        const __m256 d = _mm256_set1_ps(y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d));
1556
1557        sumi0 = _mm256_add_epi16(sumi0, sumi1);
1558        sumi0 = _mm256_sub_epi16(sumi0, ysum);
1559        sumi0 = _mm256_madd_epi16(sumi0, _mm256_set1_epi16(1));
1560
1561        sumf = _mm256_add_ps(_mm256_mul_ps(_mm256_cvtepi32_ps(sumi0), d), sumf);
1562    }
1563
1564    *s = hsum_float_8(sumf);
1565
1566#else
1567    UNUSED(x);
1568    UNUSED(y);
1569    UNUSED(nb);
1570    ggml_vec_dot_tq2_0_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
1571#endif
1572}
1573
1574void ggml_vec_dot_q2_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1575    assert(nrc == 1);
1576    UNUSED(nrc);
1577    UNUSED(bx);
1578    UNUSED(by);
1579    UNUSED(bs);
1580
1581    const block_q2_K * GGML_RESTRICT x = vx;
1582    const block_q8_K * GGML_RESTRICT y = vy;
1583
1584    const int nb = n / QK_K;
1585
1586#if defined __AVX2__
1587
1588    const __m256i m3 = _mm256_set1_epi8(3);
1589    const __m128i m4 = _mm_set1_epi8(0xF);
1590
1591    __m256 acc = _mm256_setzero_ps();
1592
1593    for (int i = 0; i < nb; ++i) {
1594
1595        const float d = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
1596        const float dmin = -y[i].d * GGML_CPU_FP16_TO_FP32(x[i].dmin);
1597
1598        const uint8_t * GGML_RESTRICT q2 = x[i].qs;
1599        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
1600
1601        const __m128i mins_and_scales = _mm_loadu_si128((const __m128i*)x[i].scales);
1602        const __m128i scales8 = _mm_and_si128(mins_and_scales, m4);
1603        const __m128i mins8 = _mm_and_si128(_mm_srli_epi16(mins_and_scales, 4), m4);
1604        const __m256i mins = _mm256_cvtepi8_epi16(mins8);
1605        const __m256i prod = _mm256_madd_epi16(mins, _mm256_loadu_si256((const __m256i*)y[i].bsums));
1606
1607        acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&dmin), _mm256_cvtepi32_ps(prod), acc);
1608
1609        const __m256i all_scales = _mm256_cvtepi8_epi16(scales8);
1610        const __m128i l_scales = _mm256_extracti128_si256(all_scales, 0);
1611        const __m128i h_scales = _mm256_extracti128_si256(all_scales, 1);
1612        const __m256i scales[2] = {MM256_SET_M128I(l_scales, l_scales), MM256_SET_M128I(h_scales, h_scales)};
1613
1614        __m256i sumi = _mm256_setzero_si256();
1615
1616        for (int j = 0; j < QK_K/128; ++j) {
1617
1618            const __m256i q2bits = _mm256_loadu_si256((const __m256i*)q2); q2 += 32;
1619
1620            const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
1621            const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
1622            const __m256i q8_2 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
1623            const __m256i q8_3 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
1624
1625            const __m256i q2_0 = _mm256_and_si256(q2bits, m3);
1626            const __m256i q2_1 = _mm256_and_si256(_mm256_srli_epi16(q2bits, 2), m3);
1627            const __m256i q2_2 = _mm256_and_si256(_mm256_srli_epi16(q2bits, 4), m3);
1628            const __m256i q2_3 = _mm256_and_si256(_mm256_srli_epi16(q2bits, 6), m3);
1629
1630            __m256i p0 = _mm256_maddubs_epi16(q2_0, q8_0);
1631            __m256i p1 = _mm256_maddubs_epi16(q2_1, q8_1);
1632            __m256i p2 = _mm256_maddubs_epi16(q2_2, q8_2);
1633            __m256i p3 = _mm256_maddubs_epi16(q2_3, q8_3);
1634
1635            p0 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(0)), p0);
1636            p1 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(1)), p1);
1637            p2 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(2)), p2);
1638            p3 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(3)), p3);
1639
1640            p0 = _mm256_add_epi32(p0, p1);
1641            p2 = _mm256_add_epi32(p2, p3);
1642
1643            sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p0, p2));
1644        }
1645
1646        acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc);
1647
1648    }
1649
1650    *s = hsum_float_8(acc);
1651
1652#elif defined __AVX__
1653
1654    const __m128i m3 = _mm_set1_epi8(0x3);
1655    const __m128i m4 = _mm_set1_epi8(0xF);
1656    const __m128i m2 = _mm_set1_epi8(0x2);
1657
1658    __m256 acc = _mm256_setzero_ps();
1659
1660    for (int i = 0; i < nb; ++i) {
1661
1662        const float dall = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
1663        const float dmin = -y[i].d * GGML_CPU_FP16_TO_FP32(x[i].dmin);
1664
1665        const uint8_t * GGML_RESTRICT q2 = x[i].qs;
1666        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
1667
1668        // load mins and scales from block_q2_K.scales[QK_K/16]
1669        const __m128i mins_and_scales = _mm_loadu_si128((const __m128i*)x[i].scales);
1670        const __m128i scales16 = _mm_and_si128(mins_and_scales, m4);
1671        const __m128i mins16 = _mm_and_si128(_mm_srli_epi16(mins_and_scales, 4), m4);
1672        const __m128i mins_0 = _mm_cvtepi8_epi16(mins16);
1673        const __m128i mins_1 = _mm_cvtepi8_epi16(_mm_unpackhi_epi64(mins16, mins16));
1674
1675        // summs = y[i].bsums * (x[i].scales >> 4) in 16bits*8*2 to 32bits*4*2
1676        const __m128i summs_0 = _mm_madd_epi16(mins_0, _mm_loadu_si128((const __m128i*)&y[i].bsums[0]));
1677        const __m128i summs_1 = _mm_madd_epi16(mins_1, _mm_loadu_si128((const __m128i*)&y[i].bsums[8]));
1678
1679        // sumf += -dmin * summs in 32bits*8
1680        acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&dmin), _mm256_cvtepi32_ps(MM256_SET_M128I(summs_1, summs_0))), acc);
1681
1682        const __m128i scales_0 = _mm_cvtepi8_epi16(scales16);
1683        const __m128i scales_1 = _mm_cvtepi8_epi16(_mm_unpackhi_epi64(scales16, scales16));
1684        const __m128i scales[2] = { scales_0, scales_1 };
1685
1686        __m128i sumi_0 = _mm_setzero_si128();
1687        __m128i sumi_1 = _mm_setzero_si128();
1688
1689        for (int j = 0; j < QK_K/128; ++j) {
1690
1691            // load Q8 quants int8*16*8 from block_q8_K.qs[QK_K]
1692            const __m128i q8_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1693            const __m128i q8_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1694            const __m128i q8_2 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1695            const __m128i q8_3 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1696            const __m128i q8_4 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1697            const __m128i q8_5 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1698            const __m128i q8_6 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1699            const __m128i q8_7 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1700
1701            // load 2bits*16*8 from block_q2_K.qs[QK_K/4]
1702            __m128i q2bits = _mm_loadu_si128((const __m128i*)q2); q2 += 16;
1703            const __m128i q2_0 = _mm_and_si128(q2bits, m3);
1704            const __m128i q2_2 = _mm_and_si128(_mm_srli_epi16(q2bits, 2), m3);
1705            const __m128i q2_4 = _mm_and_si128(_mm_srli_epi16(q2bits, 4), m3);
1706            const __m128i q2_6 = _mm_and_si128(_mm_srli_epi16(q2bits, 6), m3);
1707            q2bits = _mm_loadu_si128((const __m128i*)q2); q2 += 16;
1708            const __m128i q2_1 = _mm_and_si128(q2bits, m3);
1709            const __m128i q2_3 = _mm_and_si128(_mm_srli_epi16(q2bits, 2), m3);
1710            const __m128i q2_5 = _mm_and_si128(_mm_srli_epi16(q2bits, 4), m3);
1711            const __m128i q2_7 = _mm_and_si128(_mm_srli_epi16(q2bits, 6), m3);
1712
1713            // isuml = q8[l] * ((q2[l] >> shift) & 3) in 8bits*16*8 to 16bits*8*8
1714            __m128i p0 = _mm_maddubs_epi16(q2_0, q8_0);
1715            __m128i p1 = _mm_maddubs_epi16(q2_1, q8_1);
1716            __m128i p2 = _mm_maddubs_epi16(q2_2, q8_2);
1717            __m128i p3 = _mm_maddubs_epi16(q2_3, q8_3);
1718            __m128i p4 = _mm_maddubs_epi16(q2_4, q8_4);
1719            __m128i p5 = _mm_maddubs_epi16(q2_5, q8_5);
1720            __m128i p6 = _mm_maddubs_epi16(q2_6, q8_6);
1721            __m128i p7 = _mm_maddubs_epi16(q2_7, q8_7);
1722
1723            // isum += (x[i].scales[is++] & 0xF) * isuml in 16bits*8*8 to 32bits*4*8
1724            __m128i shuffle = _mm_set1_epi16(0x0100);
1725            p0 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p0);
1726            shuffle = _mm_add_epi16(shuffle, m2);
1727            p1 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p1);
1728            shuffle = _mm_add_epi16(shuffle, m2);
1729            p2 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p2);
1730            shuffle = _mm_add_epi16(shuffle, m2);
1731            p3 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p3);
1732            shuffle = _mm_add_epi16(shuffle, m2);
1733            p4 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p4);
1734            shuffle = _mm_add_epi16(shuffle, m2);
1735            p5 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p5);
1736            shuffle = _mm_add_epi16(shuffle, m2);
1737            p6 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p6);
1738            shuffle = _mm_add_epi16(shuffle, m2);
1739            p7 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p7);
1740
1741            p0 = _mm_add_epi32(p0, p1);
1742            p2 = _mm_add_epi32(p2, p3);
1743            p4 = _mm_add_epi32(p4, p5);
1744            p6 = _mm_add_epi32(p6, p7);
1745
1746            // isum in 32bits*4*2
1747            sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p0, p2));
1748            sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p4, p6));
1749        }
1750
1751        // sumf += dall * isum - dmin * summs in 32bits
1752        __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0);
1753        acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&dall), _mm256_cvtepi32_ps(sumi)), acc);
1754    }
1755
1756    *s = hsum_float_8(acc);
1757
1758#else
1759    UNUSED(x);
1760    UNUSED(y);
1761    UNUSED(nb);
1762    ggml_vec_dot_q2_K_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
1763#endif
1764}
1765
1766void ggml_vec_dot_q3_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1767    assert(n % QK_K == 0);
1768    assert(nrc == 1);
1769    UNUSED(nrc);
1770    UNUSED(bx);
1771    UNUSED(by);
1772    UNUSED(bs);
1773
1774    const uint32_t kmask1 = 0x03030303;
1775    const uint32_t kmask2 = 0x0f0f0f0f;
1776
1777    const block_q3_K * GGML_RESTRICT x = vx;
1778    const block_q8_K * GGML_RESTRICT y = vy;
1779
1780    const int nb = n / QK_K;
1781
1782#if defined __AVX2__
1783
1784    const __m256i m3 = _mm256_set1_epi8(3);
1785    const __m256i mone = _mm256_set1_epi8(1);
1786    const __m128i m32 = _mm_set1_epi8(32);
1787
1788    __m256 acc = _mm256_setzero_ps();
1789
1790    uint32_t aux[3];
1791
1792    for (int i = 0; i < nb; ++i) {
1793
1794        const float d = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
1795
1796        const uint8_t * GGML_RESTRICT q3 = x[i].qs;
1797        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
1798
1799        // Set up scales
1800        memcpy(aux, x[i].scales, 12);
1801        __m128i scales128 = _mm_set_epi32(
1802                ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4),
1803                ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4),
1804                (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4),
1805                (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4));
1806        scales128 = _mm_sub_epi8(scales128, m32);
1807        const __m256i all_scales = _mm256_cvtepi8_epi16(scales128);
1808        const __m128i l_scales = _mm256_extracti128_si256(all_scales, 0);
1809        const __m128i h_scales = _mm256_extracti128_si256(all_scales, 1);
1810        const __m256i scales[2] = {MM256_SET_M128I(l_scales, l_scales), MM256_SET_M128I(h_scales, h_scales)};
1811
1812        // high bit
1813        const __m256i hbits = _mm256_loadu_si256((const __m256i*)x[i].hmask);
1814
1815        // integer accumulator
1816        __m256i sumi = _mm256_setzero_si256();
1817
1818        int bit = 0;
1819        int is  = 0;
1820
1821        for (int j = 0; j < QK_K/128; ++j) {
1822            // load low 2 bits
1823            const __m256i q3bits = _mm256_loadu_si256((const __m256i*)q3); q3 += 32;
1824
1825            // prepare low and high bits
1826            const __m256i q3l_0 = _mm256_and_si256(q3bits, m3);
1827            const __m256i q3h_0 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2);
1828            ++bit;
1829
1830            const __m256i q3l_1 = _mm256_and_si256(_mm256_srli_epi16(q3bits, 2), m3);
1831            const __m256i q3h_1 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2);
1832            ++bit;
1833
1834            const __m256i q3l_2 = _mm256_and_si256(_mm256_srli_epi16(q3bits, 4), m3);
1835            const __m256i q3h_2 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2);
1836            ++bit;
1837
1838            const __m256i q3l_3 = _mm256_and_si256(_mm256_srli_epi16(q3bits, 6), m3);
1839            const __m256i q3h_3 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2);
1840            ++bit;
1841
1842            // load Q8 quants
1843            const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
1844            const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
1845            const __m256i q8_2 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
1846            const __m256i q8_3 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
1847
1848            // Dot product: we multiply the 2 low bits and 1 high bit part separately, so we can use _mm256_maddubs_epi16,
1849            // and then subtract. The high bit part has the 2 already subtracted (and so, it is zero if the high bit was not set,
1850            // and 2 if the high bit was set)
1851            __m256i q8s_0 = _mm256_maddubs_epi16(q3h_0, q8_0);
1852            __m256i q8s_1 = _mm256_maddubs_epi16(q3h_1, q8_1);
1853            __m256i q8s_2 = _mm256_maddubs_epi16(q3h_2, q8_2);
1854            __m256i q8s_3 = _mm256_maddubs_epi16(q3h_3, q8_3);
1855
1856            __m256i p16_0 = _mm256_maddubs_epi16(q3l_0, q8_0);
1857            __m256i p16_1 = _mm256_maddubs_epi16(q3l_1, q8_1);
1858            __m256i p16_2 = _mm256_maddubs_epi16(q3l_2, q8_2);
1859            __m256i p16_3 = _mm256_maddubs_epi16(q3l_3, q8_3);
1860
1861            p16_0 = _mm256_sub_epi16(p16_0, q8s_0);
1862            p16_1 = _mm256_sub_epi16(p16_1, q8s_1);
1863            p16_2 = _mm256_sub_epi16(p16_2, q8s_2);
1864            p16_3 = _mm256_sub_epi16(p16_3, q8s_3);
1865
1866            // multiply with scales
1867            p16_0 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 0)), p16_0);
1868            p16_1 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 1)), p16_1);
1869            p16_2 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 2)), p16_2);
1870            p16_3 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 3)), p16_3);
1871
1872            // accumulate
1873            p16_0 = _mm256_add_epi32(p16_0, p16_1);
1874            p16_2 = _mm256_add_epi32(p16_2, p16_3);
1875            sumi  = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_0, p16_2));
1876
1877        }
1878
1879        // multiply with block scale and accumulate
1880        acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc);
1881
1882    }
1883
1884    *s = hsum_float_8(acc);
1885
1886#elif defined __AVX__
1887
1888    const __m128i m3 = _mm_set1_epi8(3);
1889    const __m128i mone = _mm_set1_epi8(1);
1890    const __m128i m32 = _mm_set1_epi8(32);
1891    const __m128i m2 = _mm_set1_epi8(2);
1892
1893    __m256 acc = _mm256_setzero_ps();
1894
1895    const uint32_t *aux;
1896
1897    for (int i = 0; i < nb; ++i) {
1898
1899        const float d = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
1900
1901        const uint8_t * GGML_RESTRICT q3 = x[i].qs;
1902        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
1903
1904        // Set up scales
1905        aux = (const uint32_t *)x[i].scales;
1906        __m128i scales128 = _mm_set_epi32(
1907                ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4),
1908                ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4),
1909                (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4),
1910                (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4));
1911        scales128 = _mm_sub_epi8(scales128, m32);
1912        const __m128i scales_0 = _mm_cvtepi8_epi16(scales128);
1913        const __m128i scales_1 = _mm_cvtepi8_epi16(_mm_unpackhi_epi64(scales128, scales128));
1914        const __m128i scales[2] = { scales_0, scales_1 };
1915
1916        // high bit *128*2 from block_q3_K.hmask[QK_K/8]
1917        const __m128i hbits_0 = _mm_loadu_si128((const __m128i*)&x[i].hmask[0]);
1918        const __m128i hbits_1 = _mm_loadu_si128((const __m128i*)&x[i].hmask[16]);
1919
1920        // integer accumulator
1921        __m128i sumi_0 = _mm_setzero_si128();
1922        __m128i sumi_1 = _mm_setzero_si128();
1923
1924        for (int j = 0; j < QK_K/128; ++j) {
1925            // load low 2 bits *64*2 from block_q3_K.qs[QK_K/4]
1926            const __m128i q3bits_0 = _mm_loadu_si128((const __m128i*)q3); q3 += 16;
1927            const __m128i q3bits_1 = _mm_loadu_si128((const __m128i*)q3); q3 += 16;
1928
1929            // prepare low and high bits
1930            const int bit = j << 2;
1931
1932            const __m128i q3l_0 = _mm_and_si128(q3bits_0, m3);
1933            const __m128i q3l_1 = _mm_and_si128(q3bits_1, m3);
1934            const __m128i q3h_0 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit)), bit), 2);
1935            const __m128i q3h_1 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit)), bit), 2);
1936
1937            const __m128i q3l_2 = _mm_and_si128(_mm_srli_epi16(q3bits_0, 2), m3);
1938            const __m128i q3l_3 = _mm_and_si128(_mm_srli_epi16(q3bits_1, 2), m3);
1939            const __m128i q3h_2 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit+1)), bit+1), 2);
1940            const __m128i q3h_3 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit+1)), bit+1), 2);
1941
1942            const __m128i q3l_4 = _mm_and_si128(_mm_srli_epi16(q3bits_0, 4), m3);
1943            const __m128i q3l_5 = _mm_and_si128(_mm_srli_epi16(q3bits_1, 4), m3);
1944            const __m128i q3h_4 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit+2)), bit+2), 2);
1945            const __m128i q3h_5 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit+2)), bit+2), 2);
1946
1947            const __m128i q3l_6 = _mm_and_si128(_mm_srli_epi16(q3bits_0, 6), m3);
1948            const __m128i q3l_7 = _mm_and_si128(_mm_srli_epi16(q3bits_1, 6), m3);
1949            const __m128i q3h_6 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit+3)), bit+3), 2);
1950            const __m128i q3h_7 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit+3)), bit+3), 2);
1951
1952            // load Q8 quants from block_q8_K.qs[QK_K]
1953            const __m128i q8_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1954            const __m128i q8_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1955            const __m128i q8_2 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1956            const __m128i q8_3 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1957            const __m128i q8_4 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1958            const __m128i q8_5 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1959            const __m128i q8_6 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1960            const __m128i q8_7 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
1961
1962            // Dot product: we multiply the 2 low bits and 1 high bit part separately, so we can use _mm256_maddubs_epi16,
1963            // and then subtract. The high bit part has the 2 already subtracted (and so, it is zero if the high bit was not set,
1964            // and 2 if the high bit was set)
1965            __m128i q8s_0 = _mm_maddubs_epi16(q3h_0, q8_0);
1966            __m128i q8s_1 = _mm_maddubs_epi16(q3h_1, q8_1);
1967            __m128i q8s_2 = _mm_maddubs_epi16(q3h_2, q8_2);
1968            __m128i q8s_3 = _mm_maddubs_epi16(q3h_3, q8_3);
1969            __m128i q8s_4 = _mm_maddubs_epi16(q3h_4, q8_4);
1970            __m128i q8s_5 = _mm_maddubs_epi16(q3h_5, q8_5);
1971            __m128i q8s_6 = _mm_maddubs_epi16(q3h_6, q8_6);
1972            __m128i q8s_7 = _mm_maddubs_epi16(q3h_7, q8_7);
1973
1974            __m128i p16_0 = _mm_maddubs_epi16(q3l_0, q8_0);
1975            __m128i p16_1 = _mm_maddubs_epi16(q3l_1, q8_1);
1976            __m128i p16_2 = _mm_maddubs_epi16(q3l_2, q8_2);
1977            __m128i p16_3 = _mm_maddubs_epi16(q3l_3, q8_3);
1978            __m128i p16_4 = _mm_maddubs_epi16(q3l_4, q8_4);
1979            __m128i p16_5 = _mm_maddubs_epi16(q3l_5, q8_5);
1980            __m128i p16_6 = _mm_maddubs_epi16(q3l_6, q8_6);
1981            __m128i p16_7 = _mm_maddubs_epi16(q3l_7, q8_7);
1982
1983            p16_0 = _mm_sub_epi16(p16_0, q8s_0);
1984            p16_1 = _mm_sub_epi16(p16_1, q8s_1);
1985            p16_2 = _mm_sub_epi16(p16_2, q8s_2);
1986            p16_3 = _mm_sub_epi16(p16_3, q8s_3);
1987            p16_4 = _mm_sub_epi16(p16_4, q8s_4);
1988            p16_5 = _mm_sub_epi16(p16_5, q8s_5);
1989            p16_6 = _mm_sub_epi16(p16_6, q8s_6);
1990            p16_7 = _mm_sub_epi16(p16_7, q8s_7);
1991
1992            // multiply with scales
1993            __m128i shuffle = _mm_set1_epi16(0x0100);
1994            p16_0 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_0);
1995            shuffle = _mm_add_epi16(shuffle, m2);
1996            p16_1 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_1);
1997            shuffle = _mm_add_epi16(shuffle, m2);
1998            p16_2 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_2);
1999            shuffle = _mm_add_epi16(shuffle, m2);
2000            p16_3 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_3);
2001            shuffle = _mm_add_epi16(shuffle, m2);
2002            p16_4 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_4);
2003            shuffle = _mm_add_epi16(shuffle, m2);
2004            p16_5 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_5);
2005            shuffle = _mm_add_epi16(shuffle, m2);
2006            p16_6 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_6);
2007            shuffle = _mm_add_epi16(shuffle, m2);
2008            p16_7 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_7);
2009
2010            // accumulate
2011            p16_0 = _mm_add_epi32(p16_0, p16_1);
2012            p16_2 = _mm_add_epi32(p16_2, p16_3);
2013            p16_4 = _mm_add_epi32(p16_4, p16_5);
2014            p16_6 = _mm_add_epi32(p16_6, p16_7);
2015            sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_0, p16_2));
2016            sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_4, p16_6));
2017
2018        }
2019
2020        // multiply with block scale and accumulate
2021        __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0);
2022        acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi)), acc);
2023
2024    }
2025
2026    *s = hsum_float_8(acc);
2027
2028#else
2029    UNUSED(kmask1);
2030    UNUSED(kmask2);
2031    UNUSED(x);
2032    UNUSED(y);
2033    UNUSED(nb);
2034    ggml_vec_dot_q3_K_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
2035#endif
2036}
2037
2038void ggml_vec_dot_q4_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
2039    assert(n % QK_K == 0);
2040    assert(nrc == 1);
2041    UNUSED(nrc);
2042    UNUSED(bx);
2043    UNUSED(by);
2044    UNUSED(bs);
2045
2046    const block_q4_K * GGML_RESTRICT x = vx;
2047    const block_q8_K * GGML_RESTRICT y = vy;
2048
2049    const int nb = n / QK_K;
2050
2051    static const uint32_t kmask1 = 0x3f3f3f3f;
2052    static const uint32_t kmask2 = 0x0f0f0f0f;
2053    static const uint32_t kmask3 = 0x03030303;
2054
2055    uint32_t utmp[4];
2056
2057#if defined __AVX2__
2058
2059    const __m256i m4 = _mm256_set1_epi8(0xF);
2060
2061    __m256 acc = _mm256_setzero_ps();
2062    __m128 acc_m = _mm_setzero_ps();
2063
2064   for (int i = 0; i < nb; ++i) {
2065
2066        const float d = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
2067        const float dmin = -y[i].d * GGML_CPU_FP16_TO_FP32(x[i].dmin);
2068
2069        memcpy(utmp, x[i].scales, 12);
2070        utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4);
2071        const uint32_t uaux = utmp[1] & kmask1;
2072        utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4);
2073        utmp[2] = uaux;
2074        utmp[0] &= kmask1;
2075
2076        const uint8_t * GGML_RESTRICT q4 = x[i].qs;
2077        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
2078
2079        const __m256i mins_and_scales = _mm256_cvtepu8_epi16(_mm_set_epi32(utmp[3], utmp[2], utmp[1], utmp[0]));
2080
2081        const __m256i q8sums = _mm256_loadu_si256((const __m256i*)y[i].bsums);
2082        const __m128i q8s = _mm_hadd_epi16(_mm256_extracti128_si256(q8sums, 0), _mm256_extracti128_si256(q8sums, 1));
2083        const __m128i prod = _mm_madd_epi16(_mm256_extracti128_si256(mins_and_scales, 1), q8s);
2084        acc_m = _mm_fmadd_ps(_mm_set1_ps(dmin), _mm_cvtepi32_ps(prod), acc_m);
2085
2086        const __m128i sc128  = _mm256_extracti128_si256(mins_and_scales, 0);
2087        const __m256i scales = MM256_SET_M128I(sc128, sc128);
2088
2089        __m256i sumi = _mm256_setzero_si256();
2090
2091        for (int j = 0; j < QK_K/64; ++j) {
2092
2093            const __m256i scale_l = _mm256_shuffle_epi8(scales, get_scale_shuffle_k4(2*j+0));
2094            const __m256i scale_h = _mm256_shuffle_epi8(scales, get_scale_shuffle_k4(2*j+1));
2095
2096            const __m256i q4bits = _mm256_loadu_si256((const __m256i*)q4); q4 += 32;
2097            const __m256i q4l = _mm256_and_si256(q4bits, m4);
2098            const __m256i q4h = _mm256_and_si256(_mm256_srli_epi16(q4bits, 4), m4);
2099
2100            const __m256i q8l = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
2101            __m256i p16l = _mm256_maddubs_epi16(q4l, q8l);
2102            p16l = _mm256_madd_epi16(scale_l, p16l);
2103
2104            const __m256i q8h = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
2105            __m256i p16h = _mm256_maddubs_epi16(q4h, q8h);
2106            p16h = _mm256_madd_epi16(scale_h, p16h);
2107            const __m256i sumj = _mm256_add_epi32(p16l, p16h);
2108
2109            sumi = _mm256_add_epi32(sumi, sumj);
2110        }
2111
2112        __m256 vd = _mm256_set1_ps(d);
2113        acc = _mm256_fmadd_ps(vd, _mm256_cvtepi32_ps(sumi), acc);
2114
2115    }
2116
2117    acc_m = _mm_add_ps(acc_m, _mm_movehl_ps(acc_m, acc_m));
2118    acc_m = _mm_add_ss(acc_m, _mm_movehdup_ps(acc_m));
2119
2120    *s = hsum_float_8(acc) + _mm_cvtss_f32(acc_m);
2121
2122#elif defined __AVX__
2123
2124    const __m128i m4 = _mm_set1_epi8(0xF);
2125    const __m128i m2 = _mm_set1_epi8(0x2);
2126
2127    __m256 acc = _mm256_setzero_ps();
2128    __m128 acc_m = _mm_setzero_ps();
2129
2130   for (int i = 0; i < nb; ++i) {
2131
2132        const float d = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
2133        const float dmin = -y[i].d * GGML_CPU_FP16_TO_FP32(x[i].dmin);
2134
2135        const uint8_t * GGML_RESTRICT q4 = x[i].qs;
2136        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
2137
2138        memcpy(utmp, x[i].scales, 12);
2139        utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4);
2140        const uint32_t uaux = utmp[1] & kmask1;
2141        utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4);
2142        utmp[2] = uaux;
2143        utmp[0] &= kmask1;
2144
2145        const __m128i utmps = _mm_set_epi32(utmp[3], utmp[2], utmp[1], utmp[0]);
2146        const __m128i scales = _mm_cvtepu8_epi16(utmps);
2147        const __m128i mins = _mm_cvtepu8_epi16(_mm_unpackhi_epi64(utmps, utmps));
2148
2149        const __m128i q8sums_0 = _mm_loadu_si128((const __m128i*)&y[i].bsums[0]);
2150        const __m128i q8sums_1 = _mm_loadu_si128((const __m128i*)&y[i].bsums[8]);
2151        const __m128i q8s = _mm_hadd_epi16(q8sums_0, q8sums_1);
2152        const __m128i prod = _mm_madd_epi16(mins, q8s);
2153        acc_m = _mm_add_ps(_mm_mul_ps(_mm_set1_ps(dmin), _mm_cvtepi32_ps(prod)), acc_m);
2154
2155        __m128i sumi_0 = _mm_setzero_si128();
2156        __m128i sumi_1 = _mm_setzero_si128();
2157
2158        __m128i shuffle = _mm_set1_epi16(0x0100);
2159        for (int j = 0; j < QK_K/64; ++j) {
2160
2161            const __m128i scale_l = _mm_shuffle_epi8(scales, shuffle);
2162            shuffle = _mm_add_epi16(shuffle, m2);
2163            const __m128i scale_h = _mm_shuffle_epi8(scales, shuffle);
2164            shuffle = _mm_add_epi16(shuffle, m2);
2165
2166            __m128i q4bits = _mm_loadu_si128((const __m128i*)q4); q4 += 16;
2167            const __m128i q4l_0 = _mm_and_si128(q4bits, m4);
2168            const __m128i q4h_0 = _mm_and_si128(_mm_srli_epi16(q4bits, 4), m4);
2169            q4bits = _mm_loadu_si128((const __m128i*)q4); q4 += 16;
2170            const __m128i q4l_1 = _mm_and_si128(q4bits, m4);
2171            const __m128i q4h_1 = _mm_and_si128(_mm_srli_epi16(q4bits, 4), m4);
2172
2173            const __m128i q8l_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2174            __m128i p16l = _mm_maddubs_epi16(q4l_0, q8l_0);
2175            p16l = _mm_madd_epi16(scale_l, p16l);
2176            sumi_0 = _mm_add_epi32(sumi_0, p16l);
2177            const __m128i q8l_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2178            p16l = _mm_maddubs_epi16(q4l_1, q8l_1);
2179            p16l = _mm_madd_epi16(scale_l, p16l);
2180            sumi_1 = _mm_add_epi32(sumi_1, p16l);
2181
2182            const __m128i q8h_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2183            __m128i p16h = _mm_maddubs_epi16(q4h_0, q8h_0);
2184            p16h = _mm_madd_epi16(scale_h, p16h);
2185            sumi_0 = _mm_add_epi32(sumi_0, p16h);
2186            const __m128i q8h_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2187            p16h = _mm_maddubs_epi16(q4h_1, q8h_1);
2188            p16h = _mm_madd_epi16(scale_h, p16h);
2189            sumi_1 = _mm_add_epi32(sumi_1, p16h);
2190
2191        }
2192
2193        __m256 vd = _mm256_set1_ps(d);
2194        __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0);
2195        acc = _mm256_add_ps(_mm256_mul_ps(vd, _mm256_cvtepi32_ps(sumi)), acc);
2196
2197    }
2198
2199    acc_m = _mm_add_ps(acc_m, _mm_movehl_ps(acc_m, acc_m));
2200    acc_m = _mm_add_ss(acc_m, _mm_movehdup_ps(acc_m));
2201
2202    *s = hsum_float_8(acc) + _mm_cvtss_f32(acc_m);
2203
2204#else
2205    UNUSED(x);
2206    UNUSED(y);
2207    UNUSED(nb);
2208    UNUSED(kmask1);
2209    UNUSED(kmask2);
2210    UNUSED(kmask3);
2211    UNUSED(utmp);
2212    ggml_vec_dot_q4_K_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
2213#endif
2214}
2215
2216void ggml_vec_dot_q5_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy,  size_t by, int nrc) {
2217    assert(n % QK_K == 0);
2218    assert(nrc == 1);
2219    UNUSED(nrc);
2220    UNUSED(bx);
2221    UNUSED(by);
2222    UNUSED(bs);
2223
2224    const block_q5_K * GGML_RESTRICT x = vx;
2225    const block_q8_K * GGML_RESTRICT y = vy;
2226
2227    const int nb = n / QK_K;
2228
2229    static const uint32_t kmask1 = 0x3f3f3f3f;
2230    static const uint32_t kmask2 = 0x0f0f0f0f;
2231    static const uint32_t kmask3 = 0x03030303;
2232
2233    uint32_t utmp[4];
2234
2235#if defined __AVX2__
2236
2237    const __m256i m4 = _mm256_set1_epi8(0xF);
2238    const __m128i mzero = _mm_setzero_si128();
2239    const __m256i mone  = _mm256_set1_epi8(1);
2240
2241    __m256 acc = _mm256_setzero_ps();
2242
2243    float summs = 0.f;
2244
2245    for (int i = 0; i < nb; ++i) {
2246        const uint8_t * GGML_RESTRICT q5 = x[i].qs;
2247        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
2248
2249        const float d = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
2250        const float dmin = -y[i].d * GGML_CPU_FP16_TO_FP32(x[i].dmin);
2251
2252        memcpy(utmp, x[i].scales, 12);
2253        utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4);
2254        const uint32_t uaux = utmp[1] & kmask1;
2255        utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4);
2256        utmp[2] = uaux;
2257        utmp[0] &= kmask1;
2258
2259        const __m256i mins_and_scales = _mm256_cvtepu8_epi16(_mm_set_epi32(utmp[3], utmp[2], utmp[1], utmp[0]));
2260
2261        const __m256i q8sums = _mm256_loadu_si256((const __m256i*)y[i].bsums);
2262        const __m128i q8s = _mm_hadd_epi16(_mm256_extracti128_si256(q8sums, 0), _mm256_extracti128_si256(q8sums, 1));
2263        const __m128i prod = _mm_madd_epi16(_mm256_extracti128_si256(mins_and_scales, 1), q8s);
2264        const __m128i hsum = _mm_hadd_epi32(_mm_hadd_epi32(prod, mzero), mzero);
2265        summs += dmin * _mm_extract_epi32(hsum, 0);
2266
2267        const __m128i sc128  = _mm256_extracti128_si256(mins_and_scales, 0);
2268        const __m256i scales = MM256_SET_M128I(sc128, sc128);
2269
2270        const __m256i hbits = _mm256_loadu_si256((const __m256i*)x[i].qh);
2271        __m256i hmask = mone;
2272
2273        __m256i sumi = _mm256_setzero_si256();
2274
2275        int bit = 0;
2276
2277        for (int j = 0; j < QK_K/64; ++j) {
2278
2279            const __m256i scale_0 = _mm256_shuffle_epi8(scales, get_scale_shuffle_k4(2*j+0));
2280            const __m256i scale_1 = _mm256_shuffle_epi8(scales, get_scale_shuffle_k4(2*j+1));
2281
2282            const __m256i q5bits = _mm256_loadu_si256((const __m256i*)q5); q5 += 32;
2283
2284            const __m256i q5l_0 = _mm256_and_si256(q5bits, m4);
2285            const __m256i q5h_0 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_and_si256(hbits, hmask), bit++), 4);
2286            const __m256i q5_0  = _mm256_add_epi8(q5l_0, q5h_0);
2287            hmask = _mm256_slli_epi16(hmask, 1);
2288
2289            const __m256i q5l_1 = _mm256_and_si256(_mm256_srli_epi16(q5bits, 4), m4);
2290            const __m256i q5h_1 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_and_si256(hbits, hmask), bit++), 4);
2291            const __m256i q5_1  = _mm256_add_epi8(q5l_1, q5h_1);
2292            hmask = _mm256_slli_epi16(hmask, 1);
2293
2294            const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
2295            const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
2296
2297            __m256i p16_0 = _mm256_maddubs_epi16(q5_0, q8_0);
2298            __m256i p16_1 = _mm256_maddubs_epi16(q5_1, q8_1);
2299
2300            p16_0 = _mm256_madd_epi16(scale_0, p16_0);
2301            p16_1 = _mm256_madd_epi16(scale_1, p16_1);
2302
2303            sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_0, p16_1));
2304
2305        }
2306
2307        __m256 vd = _mm256_set1_ps(d);
2308        acc = _mm256_fmadd_ps(vd, _mm256_cvtepi32_ps(sumi), acc);
2309
2310    }
2311
2312    *s = hsum_float_8(acc) + summs;
2313
2314#elif defined __AVX__
2315
2316    const __m128i m4 = _mm_set1_epi8(0xF);
2317    const __m128i mzero = _mm_setzero_si128();
2318    const __m128i mone  = _mm_set1_epi8(1);
2319    const __m128i m2 = _mm_set1_epi8(2);
2320
2321    __m256 acc = _mm256_setzero_ps();
2322
2323    float summs = 0.f;
2324
2325    for (int i = 0; i < nb; ++i) {
2326
2327        const float d = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
2328        const float dmin = -y[i].d * GGML_CPU_FP16_TO_FP32(x[i].dmin);
2329
2330        const uint8_t * GGML_RESTRICT q5 = x[i].qs;
2331        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
2332
2333        memcpy(utmp, x[i].scales, 12);
2334        utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4);
2335        const uint32_t uaux = utmp[1] & kmask1;
2336        utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4);
2337        utmp[2] = uaux;
2338        utmp[0] &= kmask1;
2339
2340        const __m128i utmps = _mm_set_epi32(utmp[3], utmp[2], utmp[1], utmp[0]);
2341        const __m128i scales = _mm_cvtepu8_epi16(utmps);
2342        const __m128i mins = _mm_cvtepu8_epi16(_mm_unpackhi_epi64(utmps, utmps));
2343
2344        const __m128i q8sums_0 = _mm_loadu_si128((const __m128i*)&y[i].bsums[0]);
2345        const __m128i q8sums_1 = _mm_loadu_si128((const __m128i*)&y[i].bsums[8]);
2346        const __m128i q8s = _mm_hadd_epi16(q8sums_0, q8sums_1);
2347        const __m128i prod = _mm_madd_epi16(mins, q8s);
2348        const __m128i hsum = _mm_hadd_epi32(_mm_hadd_epi32(prod, mzero), mzero);
2349        summs += dmin * _mm_extract_epi32(hsum, 0);
2350
2351        const __m128i hbits_0 = _mm_loadu_si128((const __m128i*)&x[i].qh[0]);
2352        const __m128i hbits_1 = _mm_loadu_si128((const __m128i*)&x[i].qh[16]);
2353        __m128i hmask = mone;
2354
2355        __m128i sumi_0 = _mm_setzero_si128();
2356        __m128i sumi_1 = _mm_setzero_si128();
2357
2358        int bit = 0;
2359
2360        __m128i shuffle = _mm_set1_epi16(0x0100);
2361        for (int j = 0; j < QK_K/64; ++j) {
2362
2363            const __m128i scale_0 = _mm_shuffle_epi8(scales, shuffle);
2364            shuffle = _mm_add_epi16(shuffle, m2);
2365            const __m128i scale_1 = _mm_shuffle_epi8(scales, shuffle);
2366            shuffle = _mm_add_epi16(shuffle, m2);
2367
2368            const __m128i q5bits_0 = _mm_loadu_si128((const __m128i*)q5); q5 += 16;
2369            const __m128i q5bits_1 = _mm_loadu_si128((const __m128i*)q5); q5 += 16;
2370
2371            __m128i q5l_0 = _mm_and_si128(q5bits_0, m4);
2372            __m128i q5l_1 = _mm_and_si128(q5bits_1, m4);
2373            __m128i q5h_0 = _mm_slli_epi16(_mm_srli_epi16(_mm_and_si128(hbits_0, hmask), bit), 4);
2374            __m128i q5h_1 = _mm_slli_epi16(_mm_srli_epi16(_mm_and_si128(hbits_1, hmask), bit++), 4);
2375            __m128i q5_0  = _mm_add_epi8(q5l_0, q5h_0);
2376            __m128i q5_1  = _mm_add_epi8(q5l_1, q5h_1);
2377            hmask = _mm_slli_epi16(hmask, 1);
2378
2379            __m128i q8_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2380            __m128i q8_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2381            __m128i p16_0 = _mm_maddubs_epi16(q5_0, q8_0);
2382            __m128i p16_1 = _mm_maddubs_epi16(q5_1, q8_1);
2383            p16_0 = _mm_madd_epi16(scale_0, p16_0);
2384            p16_1 = _mm_madd_epi16(scale_0, p16_1);
2385
2386            q5l_0 = _mm_and_si128(_mm_srli_epi16(q5bits_0, 4), m4);
2387            q5l_1 = _mm_and_si128(_mm_srli_epi16(q5bits_1, 4), m4);
2388            q5h_0 = _mm_slli_epi16(_mm_srli_epi16(_mm_and_si128(hbits_0, hmask), bit), 4);
2389            q5h_1 = _mm_slli_epi16(_mm_srli_epi16(_mm_and_si128(hbits_1, hmask), bit++), 4);
2390            q5_0  = _mm_add_epi8(q5l_0, q5h_0);
2391            q5_1  = _mm_add_epi8(q5l_1, q5h_1);
2392            hmask = _mm_slli_epi16(hmask, 1);
2393
2394            q8_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2395            q8_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2396            __m128i p16_2 = _mm_maddubs_epi16(q5_0, q8_0);
2397            __m128i p16_3 = _mm_maddubs_epi16(q5_1, q8_1);
2398            p16_2 = _mm_madd_epi16(scale_1, p16_2);
2399            p16_3 = _mm_madd_epi16(scale_1, p16_3);
2400
2401            sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_0, p16_2));
2402            sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_1, p16_3));
2403
2404        }
2405
2406        __m256 vd = _mm256_set1_ps(d);
2407        __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0);
2408        acc = _mm256_add_ps(_mm256_mul_ps(vd, _mm256_cvtepi32_ps(sumi)), acc);
2409
2410    }
2411
2412    *s = hsum_float_8(acc) + summs;
2413
2414#else
2415    UNUSED(x);
2416    UNUSED(y);
2417    UNUSED(nb);
2418    UNUSED(kmask1);
2419    UNUSED(kmask2);
2420    UNUSED(kmask3);
2421    UNUSED(utmp);
2422    ggml_vec_dot_q5_K_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
2423#endif
2424}
2425
2426void ggml_vec_dot_q6_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
2427    assert(n % QK_K == 0);
2428    assert(nrc == 1);
2429    UNUSED(nrc);
2430    UNUSED(bx);
2431    UNUSED(by);
2432    UNUSED(bs);
2433
2434    const block_q6_K * GGML_RESTRICT x = vx;
2435    const block_q8_K * GGML_RESTRICT y = vy;
2436
2437    const int nb = n / QK_K;
2438
2439#if defined __AVX2__
2440
2441    const __m256i m3 = _mm256_set1_epi8(3);
2442    const __m256i m15 = _mm256_set1_epi8(15);
2443
2444    __m256 acc = _mm256_setzero_ps();
2445
2446    for (int i = 0; i < nb; ++i) {
2447
2448        const float d = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
2449
2450        const uint8_t * GGML_RESTRICT q4 = x[i].ql;
2451        const uint8_t * GGML_RESTRICT qh = x[i].qh;
2452        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
2453
2454        const __m256i q8sums = _mm256_loadu_si256((const __m256i*)y[i].bsums);
2455        const __m128i scales = _mm_loadu_si128((const __m128i*)x[i].scales);
2456        const __m256i scales_16 = _mm256_cvtepi8_epi16(scales);
2457        const __m256i q8sclsub = _mm256_slli_epi32(_mm256_madd_epi16(q8sums, scales_16), 5);
2458
2459        __m256i sumi = _mm256_setzero_si256();
2460
2461        int is = 0;
2462
2463        for (int j = 0; j < QK_K/128; ++j) {
2464            const __m256i q4bits1 = _mm256_loadu_si256((const __m256i*)q4); q4 += 32;
2465            const __m256i q4bits2 = _mm256_loadu_si256((const __m256i*)q4); q4 += 32;
2466            const __m256i q4bitsH = _mm256_loadu_si256((const __m256i*)qh); qh += 32;
2467
2468            const __m256i q4h_0 = _mm256_slli_epi16(_mm256_and_si256(q4bitsH, m3), 4);
2469            const __m256i q4h_1 = _mm256_slli_epi16(_mm256_and_si256(q4bitsH, _mm256_set1_epi8(12)), 2);
2470            const __m256i q4h_2 = _mm256_and_si256(q4bitsH, _mm256_set1_epi8(48));
2471            const __m256i q4h_3 = _mm256_srli_epi16(_mm256_and_si256(q4bitsH, _mm256_set1_epi8(-64)), 2);
2472
2473            const __m256i q4_0 = _mm256_or_si256(_mm256_and_si256(q4bits1, m15), q4h_0);
2474            const __m256i q4_1 = _mm256_or_si256(_mm256_and_si256(q4bits2, m15), q4h_1);
2475            const __m256i q4_2 = _mm256_or_si256(_mm256_and_si256(_mm256_srli_epi16(q4bits1, 4), m15), q4h_2);
2476            const __m256i q4_3 = _mm256_or_si256(_mm256_and_si256(_mm256_srli_epi16(q4bits2, 4), m15), q4h_3);
2477
2478            const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
2479            const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
2480            const __m256i q8_2 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
2481            const __m256i q8_3 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
2482
2483            __m256i p16_0 = _mm256_maddubs_epi16(q4_0, q8_0);
2484            __m256i p16_1 = _mm256_maddubs_epi16(q4_1, q8_1);
2485            __m256i p16_2 = _mm256_maddubs_epi16(q4_2, q8_2);
2486            __m256i p16_3 = _mm256_maddubs_epi16(q4_3, q8_3);
2487
2488            const __m128i scale_0 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 0));
2489            const __m128i scale_1 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 1));
2490            const __m128i scale_2 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 2));
2491            const __m128i scale_3 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 3));
2492            is += 4;
2493
2494            p16_0 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_0), p16_0);
2495            p16_1 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_1), p16_1);
2496            p16_2 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_2), p16_2);
2497            p16_3 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_3), p16_3);
2498
2499            sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_0, p16_1));
2500            sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_2, p16_3));
2501
2502        }
2503
2504        sumi = _mm256_sub_epi32(sumi, q8sclsub);
2505        acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc);
2506    }
2507
2508    *s = hsum_float_8(acc);
2509
2510#elif defined __AVX__
2511
2512    const __m128i m3 = _mm_set1_epi8(3);
2513    const __m128i m15 = _mm_set1_epi8(15);
2514
2515    __m256 acc = _mm256_setzero_ps();
2516
2517    for (int i = 0; i < nb; ++i) {
2518
2519        const float d = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
2520
2521        const uint8_t * GGML_RESTRICT q4 = x[i].ql;
2522        const uint8_t * GGML_RESTRICT qh = x[i].qh;
2523        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
2524
2525        // handle the q6_k -32 offset separately using bsums
2526        const __m128i q8sums_0 = _mm_loadu_si128((const __m128i*)y[i].bsums);
2527        const __m128i q8sums_1 = _mm_loadu_si128((const __m128i*)y[i].bsums + 1);
2528        const __m128i scales = _mm_loadu_si128((const __m128i*)x[i].scales);
2529        const __m128i scales_16_0 = _mm_cvtepi8_epi16(scales);
2530        const __m128i scales_16_1 = _mm_cvtepi8_epi16(_mm_bsrli_si128(scales, 8));
2531        const __m128i q8sclsub_0 = _mm_slli_epi32(_mm_madd_epi16(q8sums_0, scales_16_0), 5);
2532        const __m128i q8sclsub_1 = _mm_slli_epi32(_mm_madd_epi16(q8sums_1, scales_16_1), 5);
2533
2534        __m128i sumi_0 = _mm_setzero_si128();
2535        __m128i sumi_1 = _mm_setzero_si128();
2536
2537        int is = 0;
2538
2539        for (int j = 0; j < QK_K/128; ++j) {
2540
2541            const __m128i q4bitsH_0 = _mm_loadu_si128((const __m128i*)qh); qh += 16;
2542            const __m128i q4bitsH_1 = _mm_loadu_si128((const __m128i*)qh); qh += 16;
2543
2544            const __m128i q4h_0 = _mm_slli_epi16(_mm_and_si128(q4bitsH_0, m3), 4);
2545            const __m128i q4h_1 = _mm_slli_epi16(_mm_and_si128(q4bitsH_1, m3), 4);
2546            const __m128i q4h_2 = _mm_slli_epi16(_mm_and_si128(q4bitsH_0, _mm_set1_epi8(12)), 2);
2547            const __m128i q4h_3 = _mm_slli_epi16(_mm_and_si128(q4bitsH_1, _mm_set1_epi8(12)), 2);
2548            const __m128i q4h_4 = _mm_and_si128(q4bitsH_0, _mm_set1_epi8(48));
2549            const __m128i q4h_5 = _mm_and_si128(q4bitsH_1, _mm_set1_epi8(48));
2550            const __m128i q4h_6 = _mm_srli_epi16(_mm_and_si128(q4bitsH_0, _mm_set1_epi8(-64)), 2);
2551            const __m128i q4h_7 = _mm_srli_epi16(_mm_and_si128(q4bitsH_1, _mm_set1_epi8(-64)), 2);
2552
2553            const __m128i q4bits1_0 = _mm_loadu_si128((const __m128i*)q4); q4 += 16;
2554            const __m128i q4bits1_1 = _mm_loadu_si128((const __m128i*)q4); q4 += 16;
2555            const __m128i q4bits2_0 = _mm_loadu_si128((const __m128i*)q4); q4 += 16;
2556            const __m128i q4bits2_1 = _mm_loadu_si128((const __m128i*)q4); q4 += 16;
2557
2558            const __m128i q4_0 = _mm_or_si128(_mm_and_si128(q4bits1_0, m15), q4h_0);
2559            const __m128i q4_1 = _mm_or_si128(_mm_and_si128(q4bits1_1, m15), q4h_1);
2560            const __m128i q4_2 = _mm_or_si128(_mm_and_si128(q4bits2_0, m15), q4h_2);
2561            const __m128i q4_3 = _mm_or_si128(_mm_and_si128(q4bits2_1, m15), q4h_3);
2562            const __m128i q4_4 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits1_0, 4), m15), q4h_4);
2563            const __m128i q4_5 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits1_1, 4), m15), q4h_5);
2564            const __m128i q4_6 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits2_0, 4), m15), q4h_6);
2565            const __m128i q4_7 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits2_1, 4), m15), q4h_7);
2566
2567            const __m128i q8_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2568            const __m128i q8_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2569            const __m128i q8_2 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2570            const __m128i q8_3 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2571            const __m128i q8_4 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2572            const __m128i q8_5 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2573            const __m128i q8_6 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2574            const __m128i q8_7 = _mm_loadu_si128((const __m128i*)q8); q8 += 16;
2575
2576            __m128i p16_0 = _mm_maddubs_epi16(q4_0, q8_0);
2577            __m128i p16_1 = _mm_maddubs_epi16(q4_1, q8_1);
2578            __m128i p16_2 = _mm_maddubs_epi16(q4_2, q8_2);
2579            __m128i p16_3 = _mm_maddubs_epi16(q4_3, q8_3);
2580            __m128i p16_4 = _mm_maddubs_epi16(q4_4, q8_4);
2581            __m128i p16_5 = _mm_maddubs_epi16(q4_5, q8_5);
2582            __m128i p16_6 = _mm_maddubs_epi16(q4_6, q8_6);
2583            __m128i p16_7 = _mm_maddubs_epi16(q4_7, q8_7);
2584
2585            const __m128i scale_0 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 0));
2586            const __m128i scale_1 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 1));
2587            const __m128i scale_2 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 2));
2588            const __m128i scale_3 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 3));
2589            is += 4;
2590
2591            p16_0 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_0), p16_0);
2592            p16_1 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_bsrli_si128(scale_0, 8)), p16_1);
2593            p16_2 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_1), p16_2);
2594            p16_3 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_bsrli_si128(scale_1, 8)), p16_3);
2595            p16_4 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_2), p16_4);
2596            p16_5 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_bsrli_si128(scale_2, 8)), p16_5);
2597            p16_6 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_3), p16_6);
2598            p16_7 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_bsrli_si128(scale_3, 8)), p16_7);
2599
2600            sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_0, p16_2));
2601            sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_1, p16_3));
2602            sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_4, p16_6));
2603            sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_5, p16_7));
2604
2605        }
2606
2607        sumi_0 = _mm_sub_epi32(sumi_0, q8sclsub_0);
2608        sumi_1 = _mm_sub_epi32(sumi_1, q8sclsub_1);
2609        const __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0);
2610        acc = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(sumi)), acc);
2611    }
2612
2613    *s = hsum_float_8(acc);
2614
2615#else
2616    UNUSED(x);
2617    UNUSED(y);
2618    UNUSED(nb);
2619    ggml_vec_dot_q6_K_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
2620#endif
2621}
2622
2623#if defined (__AVX__) || defined (__AVX2__)
2624static const int8_t keven_signs_q2xs[1024] = {
2625     1,  1,  1,  1,  1,  1,  1,  1, -1,  1,  1,  1,  1,  1,  1, -1,  1, -1,  1,  1,  1,  1,  1, -1, -1, -1,  1,  1,  1,  1,  1,  1,
2626     1,  1, -1,  1,  1,  1,  1, -1, -1,  1, -1,  1,  1,  1,  1,  1,  1, -1, -1,  1,  1,  1,  1,  1, -1, -1, -1,  1,  1,  1,  1, -1,
2627     1,  1,  1, -1,  1,  1,  1, -1, -1,  1,  1, -1,  1,  1,  1,  1,  1, -1,  1, -1,  1,  1,  1,  1, -1, -1,  1, -1,  1,  1,  1, -1,
2628     1,  1, -1, -1,  1,  1,  1,  1, -1,  1, -1, -1,  1,  1,  1, -1,  1, -1, -1, -1,  1,  1,  1, -1, -1, -1, -1, -1,  1,  1,  1,  1,
2629     1,  1,  1,  1, -1,  1,  1, -1, -1,  1,  1,  1, -1,  1,  1,  1,  1, -1,  1,  1, -1,  1,  1,  1, -1, -1,  1,  1, -1,  1,  1, -1,
2630     1,  1, -1,  1, -1,  1,  1,  1, -1,  1, -1,  1, -1,  1,  1, -1,  1, -1, -1,  1, -1,  1,  1, -1, -1, -1, -1,  1, -1,  1,  1,  1,
2631     1,  1,  1, -1, -1,  1,  1,  1, -1,  1,  1, -1, -1,  1,  1, -1,  1, -1,  1, -1, -1,  1,  1, -1, -1, -1,  1, -1, -1,  1,  1,  1,
2632     1,  1, -1, -1, -1,  1,  1, -1, -1,  1, -1, -1, -1,  1,  1,  1,  1, -1, -1, -1, -1,  1,  1,  1, -1, -1, -1, -1, -1,  1,  1, -1,
2633     1,  1,  1,  1,  1, -1,  1, -1, -1,  1,  1,  1,  1, -1,  1,  1,  1, -1,  1,  1,  1, -1,  1,  1, -1, -1,  1,  1,  1, -1,  1, -1,
2634     1,  1, -1,  1,  1, -1,  1,  1, -1,  1, -1,  1,  1, -1,  1, -1,  1, -1, -1,  1,  1, -1,  1, -1, -1, -1, -1,  1,  1, -1,  1,  1,
2635     1,  1,  1, -1,  1, -1,  1,  1, -1,  1,  1, -1,  1, -1,  1, -1,  1, -1,  1, -1,  1, -1,  1, -1, -1, -1,  1, -1,  1, -1,  1,  1,
2636     1,  1, -1, -1,  1, -1,  1, -1, -1,  1, -1, -1,  1, -1,  1,  1,  1, -1, -1, -1,  1, -1,  1,  1, -1, -1, -1, -1,  1, -1,  1, -1,
2637     1,  1,  1,  1, -1, -1,  1,  1, -1,  1,  1,  1, -1, -1,  1, -1,  1, -1,  1,  1, -1, -1,  1, -1, -1, -1,  1,  1, -1, -1,  1,  1,
2638     1,  1, -1,  1, -1, -1,  1, -1, -1,  1, -1,  1, -1, -1,  1,  1,  1, -1, -1,  1, -1, -1,  1,  1, -1, -1, -1,  1, -1, -1,  1, -1,
2639     1,  1,  1, -1, -1, -1,  1, -1, -1,  1,  1, -1, -1, -1,  1,  1,  1, -1,  1, -1, -1, -1,  1,  1, -1, -1,  1, -1, -1, -1,  1, -1,
2640     1,  1, -1, -1, -1, -1,  1,  1, -1,  1, -1, -1, -1, -1,  1, -1,  1, -1, -1, -1, -1, -1,  1, -1, -1, -1, -1, -1, -1, -1,  1,  1,
2641     1,  1,  1,  1,  1,  1, -1, -1, -1,  1,  1,  1,  1,  1, -1,  1,  1, -1,  1,  1,  1,  1, -1,  1, -1, -1,  1,  1,  1,  1, -1, -1,
2642     1,  1, -1,  1,  1,  1, -1,  1, -1,  1, -1,  1,  1,  1, -1, -1,  1, -1, -1,  1,  1,  1, -1, -1, -1, -1, -1,  1,  1,  1, -1,  1,
2643     1,  1,  1, -1,  1,  1, -1,  1, -1,  1,  1, -1,  1,  1, -1, -1,  1, -1,  1, -1,  1,  1, -1, -1, -1, -1,  1, -1,  1,  1, -1,  1,
2644     1,  1, -1, -1,  1,  1, -1, -1, -1,  1, -1, -1,  1,  1, -1,  1,  1, -1, -1, -1,  1,  1, -1,  1, -1, -1, -1, -1,  1,  1, -1, -1,
2645     1,  1,  1,  1, -1,  1, -1,  1, -1,  1,  1,  1, -1,  1, -1, -1,  1, -1,  1,  1, -1,  1, -1, -1, -1, -1,  1,  1, -1,  1, -1,  1,
2646     1,  1, -1,  1, -1,  1, -1, -1, -1,  1, -1,  1, -1,  1, -1,  1,  1, -1, -1,  1, -1,  1, -1,  1, -1, -1, -1,  1, -1,  1, -1, -1,
2647     1,  1,  1, -1, -1,  1, -1, -1, -1,  1,  1, -1, -1,  1, -1,  1,  1, -1,  1, -1, -1,  1, -1,  1, -1, -1,  1, -1, -1,  1, -1, -1,
2648     1,  1, -1, -1, -1,  1, -1,  1, -1,  1, -1, -1, -1,  1, -1, -1,  1, -1, -1, -1, -1,  1, -1, -1, -1, -1, -1, -1, -1,  1, -1,  1,
2649     1,  1,  1,  1,  1, -1, -1,  1, -1,  1,  1,  1,  1, -1, -1, -1,  1, -1,  1,  1,  1, -1, -1, -1, -1, -1,  1,  1,  1, -1, -1,  1,
2650     1,  1, -1,  1,  1, -1, -1, -1, -1,  1, -1,  1,  1, -1, -1,  1,  1, -1, -1,  1,  1, -1, -1,  1, -1, -1, -1,  1,  1, -1, -1, -1,
2651     1,  1,  1, -1,  1, -1, -1, -1, -1,  1,  1, -1,  1, -1, -1,  1,  1, -1,  1, -1,  1, -1, -1,  1, -1, -1,  1, -1,  1, -1, -1, -1,
2652     1,  1, -1, -1,  1, -1, -1,  1, -1,  1, -1, -1,  1, -1, -1, -1,  1, -1, -1, -1,  1, -1, -1, -1, -1, -1, -1, -1,  1, -1, -1,  1,
2653     1,  1,  1,  1, -1, -1, -1, -1, -1,  1,  1,  1, -1, -1, -1,  1,  1, -1,  1,  1, -1, -1, -1,  1, -1, -1,  1,  1, -1, -1, -1, -1,
2654     1,  1, -1,  1, -1, -1, -1,  1, -1,  1, -1,  1, -1, -1, -1, -1,  1, -1, -1,  1, -1, -1, -1, -1, -1, -1, -1,  1, -1, -1, -1,  1,
2655     1,  1,  1, -1, -1, -1, -1,  1, -1,  1,  1, -1, -1, -1, -1, -1,  1, -1,  1, -1, -1, -1, -1, -1, -1, -1,  1, -1, -1, -1, -1,  1,
2656     1,  1, -1, -1, -1, -1, -1, -1, -1,  1, -1, -1, -1, -1, -1,  1,  1, -1, -1, -1, -1, -1, -1,  1, -1, -1, -1, -1, -1, -1, -1, -1,
2657};
2658#endif
2659
2660void ggml_vec_dot_iq2_xxs_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
2661    assert(n % QK_K == 0);
2662    assert(nrc == 1);
2663    UNUSED(nrc);
2664    UNUSED(bx);
2665    UNUSED(by);
2666    UNUSED(bs);
2667
2668    const block_iq2_xxs * GGML_RESTRICT x = vx;
2669    const block_q8_K    * GGML_RESTRICT y = vy;
2670
2671    const int nb = n / QK_K;
2672
2673#if defined(__AVX2__)
2674
2675    const uint64_t * signs64 = (const uint64_t *)keven_signs_q2xs;
2676
2677    uint32_t aux32[4];
2678    const uint8_t * aux8 = (const uint8_t *)aux32;
2679
2680    __m256 accumf = _mm256_setzero_ps();
2681    for (int i = 0; i < nb; ++i) {
2682        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
2683        const uint16_t * GGML_RESTRICT q2 = x[i].qs;
2684        const int8_t   * GGML_RESTRICT q8 = y[i].qs;
2685        __m256i sumi1 = _mm256_setzero_si256();
2686        __m256i sumi2 = _mm256_setzero_si256();
2687        for (int ib32 = 0; ib32 < QK_K/32; ib32 += 2) {
2688            const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
2689            const __m256i q8_2 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
2690            memcpy(aux32, q2, 4*sizeof(uint32_t)); q2 += 8;
2691            const __m256i q2_1 = _mm256_set_epi64x(iq2xxs_grid[aux8[ 3]], iq2xxs_grid[aux8[ 2]], iq2xxs_grid[aux8[1]], iq2xxs_grid[aux8[0]]);
2692            const __m256i q2_2 = _mm256_set_epi64x(iq2xxs_grid[aux8[11]], iq2xxs_grid[aux8[10]], iq2xxs_grid[aux8[9]], iq2xxs_grid[aux8[8]]);
2693            const __m256i s2_1 = _mm256_set_epi64x(signs64[(aux32[1] >> 21) & 127], signs64[(aux32[1] >> 14) & 127],
2694                                                   signs64[(aux32[1] >>  7) & 127], signs64[(aux32[1] >>  0) & 127]);
2695            const __m256i s2_2 = _mm256_set_epi64x(signs64[(aux32[3] >> 21) & 127], signs64[(aux32[3] >> 14) & 127],
2696                                                   signs64[(aux32[3] >>  7) & 127], signs64[(aux32[3] >>  0) & 127]);
2697            const __m256i q8s_1 = _mm256_sign_epi8(q8_1, s2_1);
2698            const __m256i q8s_2 = _mm256_sign_epi8(q8_2, s2_2);
2699            const __m256i dot1  = _mm256_maddubs_epi16(q2_1, q8s_1);
2700            const __m256i dot2  = _mm256_maddubs_epi16(q2_2, q8s_2);
2701            const uint16_t ls1 = aux32[1] >> 28;
2702            const uint16_t ls2 = aux32[3] >> 28;
2703            const __m256i p1 = _mm256_madd_epi16(dot1, _mm256_set1_epi16(2*ls1+1));
2704            const __m256i p2 = _mm256_madd_epi16(dot2, _mm256_set1_epi16(2*ls2+1));
2705            sumi1 = _mm256_add_epi32(sumi1, p1);
2706            sumi2 = _mm256_add_epi32(sumi2, p2);
2707        }
2708
2709        accumf = _mm256_fmadd_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(_mm256_add_epi32(sumi1, sumi2)), accumf);
2710
2711    }
2712
2713    *s = 0.125f * hsum_float_8(accumf);
2714
2715#elif defined(__AVX__)
2716    const uint64_t * signs64 = (const uint64_t *)keven_signs_q2xs;
2717
2718    uint32_t aux32[4];
2719    const uint8_t * aux8 = (const uint8_t *)aux32;
2720
2721    __m256 accumf = _mm256_setzero_ps();
2722    for (int i = 0; i < nb; ++i) {
2723        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
2724        const uint16_t * GGML_RESTRICT q2 = x[i].qs;
2725        const int8_t   * GGML_RESTRICT q8 = y[i].qs;
2726        __m128i sumi1_0 = _mm_setzero_si128();
2727        __m128i sumi1_1 = _mm_setzero_si128();
2728        __m128i sumi2_0 = _mm_setzero_si128();
2729        __m128i sumi2_1 = _mm_setzero_si128();
2730        for (int ib32 = 0; ib32 < QK_K/32; ib32 += 2) {
2731            const __m128i q8_1_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
2732            const __m128i q8_1_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
2733            const __m128i q8_2_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
2734            const __m128i q8_2_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
2735            memcpy(aux32, q2, 4*sizeof(uint32_t)); q2 += 8;
2736            const __m128i q2_1_0 = _mm_set_epi64x(iq2xxs_grid[aux8[1]], iq2xxs_grid[aux8[0]]);
2737            const __m128i q2_1_1 = _mm_set_epi64x(iq2xxs_grid[aux8[3]], iq2xxs_grid[aux8[2]]);
2738            const __m128i q2_2_0 = _mm_set_epi64x(iq2xxs_grid[aux8[9]], iq2xxs_grid[aux8[8]]);
2739            const __m128i q2_2_1 = _mm_set_epi64x(iq2xxs_grid[aux8[11]], iq2xxs_grid[aux8[10]]);
2740            const __m128i s2_1_0 = _mm_set_epi64x(signs64[(aux32[1] >>  7) & 127], signs64[(aux32[1] >>  0) & 127]);
2741            const __m128i s2_1_1 = _mm_set_epi64x(signs64[(aux32[1] >> 21) & 127], signs64[(aux32[1] >> 14) & 127]);
2742            const __m128i s2_2_0 = _mm_set_epi64x(signs64[(aux32[3] >>  7) & 127], signs64[(aux32[3] >>  0) & 127]);
2743            const __m128i s2_2_1 = _mm_set_epi64x(signs64[(aux32[3] >> 21) & 127], signs64[(aux32[3] >> 14) & 127]);
2744            const __m128i q8s_1_0 = _mm_sign_epi8(q8_1_0, s2_1_0);
2745            const __m128i q8s_1_1 = _mm_sign_epi8(q8_1_1, s2_1_1);
2746            const __m128i q8s_2_0 = _mm_sign_epi8(q8_2_0, s2_2_0);
2747            const __m128i q8s_2_1 = _mm_sign_epi8(q8_2_1, s2_2_1);
2748            const __m128i dot1_0  = _mm_maddubs_epi16(q2_1_0, q8s_1_0);
2749            const __m128i dot1_1  = _mm_maddubs_epi16(q2_1_1, q8s_1_1);
2750            const __m128i dot2_0  = _mm_maddubs_epi16(q2_2_0, q8s_2_0);
2751            const __m128i dot2_1  = _mm_maddubs_epi16(q2_2_1, q8s_2_1);
2752            const uint16_t ls1 = aux32[1] >> 28;
2753            const uint16_t ls2 = aux32[3] >> 28;
2754            const __m128i p1_0 = _mm_madd_epi16(dot1_0, _mm_set1_epi16(2*ls1+1));
2755            const __m128i p1_1 = _mm_madd_epi16(dot1_1, _mm_set1_epi16(2*ls1+1));
2756            const __m128i p2_0 = _mm_madd_epi16(dot2_0, _mm_set1_epi16(2*ls2+1));
2757            const __m128i p2_1 = _mm_madd_epi16(dot2_1, _mm_set1_epi16(2*ls2+1));
2758            sumi1_0 = _mm_add_epi32(sumi1_0, p1_0);
2759            sumi1_1 = _mm_add_epi32(sumi1_1, p1_1);
2760            sumi2_0 = _mm_add_epi32(sumi2_0, p2_0);
2761            sumi2_1 = _mm_add_epi32(sumi2_1, p2_1);
2762        }
2763
2764        accumf = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(MM256_SET_M128I(_mm_add_epi32(sumi1_1, sumi2_1), _mm_add_epi32(sumi1_0, sumi2_0)))), accumf);
2765
2766    }
2767
2768    *s = 0.125f * hsum_float_8(accumf);
2769
2770#else
2771    UNUSED(x);
2772    UNUSED(y);
2773    UNUSED(nb);
2774    ggml_vec_dot_iq2_xxs_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
2775#endif
2776}
2777
2778void ggml_vec_dot_iq2_xs_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
2779    assert(n % QK_K == 0);
2780    assert(nrc == 1);
2781    UNUSED(nrc);
2782    UNUSED(bx);
2783    UNUSED(by);
2784    UNUSED(bs);
2785
2786    const block_iq2_xs * GGML_RESTRICT x = vx;
2787    const block_q8_K   * GGML_RESTRICT y = vy;
2788
2789    const int nb = n / QK_K;
2790
2791#if defined(__AVX2__)
2792
2793    const __m256i mone = _mm256_set1_epi8(1);
2794    static const char block_sign_shuffle_mask_1[32] = {
2795        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
2796        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
2797    };
2798    static const char block_sign_shuffle_mask_2[32] = {
2799        0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
2800        0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
2801    };
2802    static const uint8_t bit_selector_mask_bytes[32] = {
2803        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
2804        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
2805    };
2806
2807    const __m256i bit_selector_mask = _mm256_loadu_si256((const __m256i*)bit_selector_mask_bytes);
2808    const __m256i block_sign_shuffle_1 = _mm256_loadu_si256((const __m256i*)block_sign_shuffle_mask_1);
2809    const __m256i block_sign_shuffle_2 = _mm256_loadu_si256((const __m256i*)block_sign_shuffle_mask_2);
2810
2811    static const uint8_t k_bit_helper[32] = {
2812        0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00,
2813        0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00,
2814    };
2815    const __m256i bit_helper = _mm256_loadu_si256((const __m256i*)k_bit_helper);
2816    const __m256i m511 = _mm256_set1_epi16(511);
2817    const __m128i m4 = _mm_set1_epi8(0xf);
2818    const __m128i m1 = _mm_set1_epi8(1);
2819
2820    uint64_t aux64;
2821
2822    // somewhat hacky, but gives a significant boost in performance
2823    __m256i aux_gindex;
2824    const uint16_t * gindex = (const uint16_t *)&aux_gindex;
2825
2826    __m256 accumf = _mm256_setzero_ps();
2827    for (int i = 0; i < nb; ++i) {
2828        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
2829        const uint16_t * GGML_RESTRICT q2 = x[i].qs;
2830        const int8_t   * GGML_RESTRICT q8 = y[i].qs;
2831
2832        memcpy(&aux64, x[i].scales, 8);
2833        __m128i stmp = _mm_set1_epi64x(aux64);
2834        stmp = _mm_unpacklo_epi8(_mm_and_si128(stmp, m4), _mm_and_si128(_mm_srli_epi16(stmp, 4), m4));
2835        const __m128i scales = _mm_add_epi8(_mm_slli_epi16(stmp, 1), m1);
2836
2837        __m256i sumi1 = _mm256_setzero_si256();
2838        __m256i sumi2 = _mm256_setzero_si256();
2839        for (int ib32 = 0; ib32 < QK_K/32; ib32 += 4) {
2840
2841            const __m256i q2_data = _mm256_loadu_si256((const __m256i*)q2);  q2 += 16;
2842            aux_gindex = _mm256_and_si256(q2_data, m511);
2843
2844            const __m256i partial_sign_bits = _mm256_srli_epi16(q2_data, 9);
2845            const __m256i partial_sign_bits_upper = _mm256_srli_epi16(q2_data, 13);
2846            const __m256i partial_sign_bits_for_counting = _mm256_xor_si256(partial_sign_bits, partial_sign_bits_upper);
2847
2848            const __m256i odd_bits = _mm256_shuffle_epi8(bit_helper, partial_sign_bits_for_counting);
2849            const __m256i full_sign_bits = _mm256_or_si256(partial_sign_bits, odd_bits);
2850
2851            const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
2852            const __m256i q8_2 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
2853            const __m256i q8_3 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
2854            const __m256i q8_4 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
2855
2856            const __m256i q2_1 = _mm256_set_epi64x(iq2xs_grid[gindex[ 3]], iq2xs_grid[gindex[ 2]],
2857                                                   iq2xs_grid[gindex[ 1]], iq2xs_grid[gindex[ 0]]);
2858            const __m256i q2_2 = _mm256_set_epi64x(iq2xs_grid[gindex[ 7]], iq2xs_grid[gindex[ 6]],
2859                                                   iq2xs_grid[gindex[ 5]], iq2xs_grid[gindex[ 4]]);
2860            const __m256i q2_3 = _mm256_set_epi64x(iq2xs_grid[gindex[11]], iq2xs_grid[gindex[10]],
2861                                                   iq2xs_grid[gindex[ 9]], iq2xs_grid[gindex[ 8]]);
2862            const __m256i q2_4 = _mm256_set_epi64x(iq2xs_grid[gindex[15]], iq2xs_grid[gindex[14]],
2863                                                   iq2xs_grid[gindex[13]], iq2xs_grid[gindex[12]]);
2864
2865            const __m128i full_signs_l = _mm256_castsi256_si128(full_sign_bits);
2866            const __m128i full_signs_h = _mm256_extractf128_si256(full_sign_bits, 1);
2867            const __m256i full_signs_1 = MM256_SET_M128I(full_signs_l, full_signs_l);
2868            const __m256i full_signs_2 = MM256_SET_M128I(full_signs_h, full_signs_h);
2869
2870            __m256i signs;
2871            signs = _mm256_shuffle_epi8(full_signs_1, block_sign_shuffle_1);
2872            signs = _mm256_cmpeq_epi8(_mm256_and_si256(signs, bit_selector_mask), bit_selector_mask);
2873            const __m256i q8s_1 = _mm256_sign_epi8(q8_1, _mm256_or_si256(signs, mone));
2874
2875            signs = _mm256_shuffle_epi8(full_signs_1, block_sign_shuffle_2);
2876            signs = _mm256_cmpeq_epi8(_mm256_and_si256(signs, bit_selector_mask), bit_selector_mask);
2877            const __m256i q8s_2 = _mm256_sign_epi8(q8_2, _mm256_or_si256(signs, mone));
2878
2879            signs = _mm256_shuffle_epi8(full_signs_2, block_sign_shuffle_1);
2880            signs = _mm256_cmpeq_epi8(_mm256_and_si256(signs, bit_selector_mask), bit_selector_mask);
2881            const __m256i q8s_3 = _mm256_sign_epi8(q8_3, _mm256_or_si256(signs, mone));
2882
2883            signs = _mm256_shuffle_epi8(full_signs_2, block_sign_shuffle_2);
2884            signs = _mm256_cmpeq_epi8(_mm256_and_si256(signs, bit_selector_mask), bit_selector_mask);
2885            const __m256i q8s_4 = _mm256_sign_epi8(q8_4, _mm256_or_si256(signs, mone));
2886
2887            const __m256i dot1  = _mm256_maddubs_epi16(q2_1, q8s_1);
2888            const __m256i dot2  = _mm256_maddubs_epi16(q2_2, q8s_2);
2889            const __m256i dot3  = _mm256_maddubs_epi16(q2_3, q8s_3);
2890            const __m256i dot4  = _mm256_maddubs_epi16(q2_4, q8s_4);
2891
2892            const __m256i sc1 = _mm256_cvtepi8_epi16(_mm_shuffle_epi8(scales, get_scale_shuffle(ib32+0)));
2893            const __m256i sc2 = _mm256_cvtepi8_epi16(_mm_shuffle_epi8(scales, get_scale_shuffle(ib32+1)));
2894            const __m256i sc3 = _mm256_cvtepi8_epi16(_mm_shuffle_epi8(scales, get_scale_shuffle(ib32+2)));
2895            const __m256i sc4 = _mm256_cvtepi8_epi16(_mm_shuffle_epi8(scales, get_scale_shuffle(ib32+3)));
2896
2897            sumi1 = _mm256_add_epi32(sumi1, _mm256_madd_epi16(dot1, sc1));
2898            sumi2 = _mm256_add_epi32(sumi2, _mm256_madd_epi16(dot2, sc2));
2899            sumi1 = _mm256_add_epi32(sumi1, _mm256_madd_epi16(dot3, sc3));
2900            sumi2 = _mm256_add_epi32(sumi2, _mm256_madd_epi16(dot4, sc4));
2901        }
2902
2903        accumf = _mm256_fmadd_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(_mm256_add_epi32(sumi1, sumi2)), accumf);
2904
2905    }
2906
2907    *s = 0.125f * hsum_float_8(accumf);
2908
2909#elif defined(__AVX__)
2910    const __m128i mone = _mm_set1_epi8(1);
2911    static const char block_sign_shuffle_mask_1[32] = {
2912        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
2913        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
2914    };
2915    static const char block_sign_shuffle_mask_2[32] = {
2916        0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
2917        0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
2918    };
2919    static const uint8_t bit_selector_mask_bytes[32] = {
2920        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
2921        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
2922    };
2923
2924    const __m128i bit_selector_mask_0 = _mm_loadu_si128((const __m128i*)bit_selector_mask_bytes);
2925    const __m128i bit_selector_mask_1 = _mm_loadu_si128((const __m128i*)bit_selector_mask_bytes + 1);
2926    const __m128i block_sign_shuffle_1_0 = _mm_loadu_si128((const __m128i*)block_sign_shuffle_mask_1);
2927    const __m128i block_sign_shuffle_1_1 = _mm_loadu_si128((const __m128i*)block_sign_shuffle_mask_1 + 1);
2928    const __m128i block_sign_shuffle_2_0 = _mm_loadu_si128((const __m128i*)block_sign_shuffle_mask_2);
2929    const __m128i block_sign_shuffle_2_1 = _mm_loadu_si128((const __m128i*)block_sign_shuffle_mask_2 + 1);
2930
2931    static const uint8_t k_bit_helper[32] = {
2932        0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00,
2933        0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00,
2934    };
2935    const __m128i bit_helper_0 = _mm_loadu_si128((const __m128i*)k_bit_helper);
2936    const __m128i bit_helper_1 = _mm_loadu_si128((const __m128i*)k_bit_helper + 1);
2937    const __m128i m511 = _mm_set1_epi16(511);
2938    const __m128i m4 = _mm_set1_epi8(0xf);
2939    const __m128i m1 = _mm_set1_epi8(1);
2940
2941    uint64_t aux64;
2942
2943    // somewhat hacky, but gives a significant boost in performance
2944    __m256i aux_gindex;
2945    const uint16_t * gindex = (const uint16_t *)&aux_gindex;
2946
2947    __m256 accumf = _mm256_setzero_ps();
2948    for (int i = 0; i < nb; ++i) {
2949        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
2950        const uint16_t * GGML_RESTRICT q2 = x[i].qs;
2951        const int8_t   * GGML_RESTRICT q8 = y[i].qs;
2952
2953        memcpy(&aux64, x[i].scales, 8);
2954        __m128i stmp = _mm_set1_epi64x(aux64);
2955        stmp = _mm_unpacklo_epi8(_mm_and_si128(stmp, m4), _mm_and_si128(_mm_srli_epi16(stmp, 4), m4));
2956        const __m128i scales = _mm_add_epi8(_mm_slli_epi16(stmp, 1), m1);
2957
2958        __m128i sumi1_0 = _mm_setzero_si128();
2959        __m128i sumi1_1 = _mm_setzero_si128();
2960        __m128i sumi2_0 = _mm_setzero_si128();
2961        __m128i sumi2_1 = _mm_setzero_si128();
2962        for (int ib32 = 0; ib32 < QK_K/32; ib32 += 4) {
2963
2964            const __m128i q2_data_0 = _mm_loadu_si128((const __m128i*)q2);
2965            const __m128i q2_data_1 = _mm_loadu_si128((const __m128i*)q2 + 1);  q2 += 16;
2966            aux_gindex = MM256_SET_M128I(_mm_and_si128(q2_data_1, m511), _mm_and_si128(q2_data_0, m511));
2967
2968            const __m128i partial_sign_bits_0 = _mm_srli_epi16(q2_data_0, 9);
2969            const __m128i partial_sign_bits_1 = _mm_srli_epi16(q2_data_1, 9);
2970            const __m128i partial_sign_bits_upper_0 = _mm_srli_epi16(q2_data_0, 13);
2971            const __m128i partial_sign_bits_upper_1 = _mm_srli_epi16(q2_data_1, 13);
2972            const __m128i partial_sign_bits_for_counting_0 = _mm_xor_si128(partial_sign_bits_0, partial_sign_bits_upper_0);
2973            const __m128i partial_sign_bits_for_counting_1 = _mm_xor_si128(partial_sign_bits_1, partial_sign_bits_upper_1);
2974
2975            const __m128i odd_bits_0 = _mm_shuffle_epi8(bit_helper_0, partial_sign_bits_for_counting_0);
2976            const __m128i odd_bits_1 = _mm_shuffle_epi8(bit_helper_1, partial_sign_bits_for_counting_1);
2977            const __m128i full_sign_bits_0 = _mm_or_si128(partial_sign_bits_0, odd_bits_0);
2978            const __m128i full_sign_bits_1 = _mm_or_si128(partial_sign_bits_1, odd_bits_1);
2979
2980            const __m128i q8_1_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
2981            const __m128i q8_1_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
2982            const __m128i q8_2_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
2983            const __m128i q8_2_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
2984            const __m128i q8_3_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
2985            const __m128i q8_3_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
2986            const __m128i q8_4_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
2987            const __m128i q8_4_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
2988
2989            const __m128i q2_1_0 = _mm_set_epi64x(iq2xs_grid[gindex[1]], iq2xs_grid[gindex[0]]);
2990            const __m128i q2_1_1 = _mm_set_epi64x(iq2xs_grid[gindex[3]], iq2xs_grid[gindex[2]]);
2991            const __m128i q2_2_0 = _mm_set_epi64x(iq2xs_grid[gindex[5]], iq2xs_grid[gindex[4]]);
2992            const __m128i q2_2_1 = _mm_set_epi64x(iq2xs_grid[gindex[7]], iq2xs_grid[gindex[6]]);
2993            const __m128i q2_3_0 = _mm_set_epi64x(iq2xs_grid[gindex[9]], iq2xs_grid[gindex[8]]);
2994            const __m128i q2_3_1 = _mm_set_epi64x(iq2xs_grid[gindex[11]], iq2xs_grid[gindex[10]]);
2995            const __m128i q2_4_0 = _mm_set_epi64x(iq2xs_grid[gindex[13]], iq2xs_grid[gindex[12]]);
2996            const __m128i q2_4_1 = _mm_set_epi64x(iq2xs_grid[gindex[15]], iq2xs_grid[gindex[14]]);
2997
2998            // AVX2 full_signs_1 is full_sign_bits_0 here
2999            // AVX2 full_signs_2 is full_sign_bits_1 here
3000            __m128i signs_0, signs_1;
3001            signs_0 = _mm_shuffle_epi8(full_sign_bits_0, block_sign_shuffle_1_0);
3002            signs_1 = _mm_shuffle_epi8(full_sign_bits_0, block_sign_shuffle_1_1);
3003            signs_0 = _mm_cmpeq_epi8(_mm_and_si128(signs_0, bit_selector_mask_0), bit_selector_mask_0);
3004            signs_1 = _mm_cmpeq_epi8(_mm_and_si128(signs_1, bit_selector_mask_1), bit_selector_mask_1);
3005            const __m128i q8s_1_0 = _mm_sign_epi8(q8_1_0, _mm_or_si128(signs_0, mone));
3006            const __m128i q8s_1_1 = _mm_sign_epi8(q8_1_1, _mm_or_si128(signs_1, mone));
3007
3008            signs_0 = _mm_shuffle_epi8(full_sign_bits_0, block_sign_shuffle_2_0);
3009            signs_1 = _mm_shuffle_epi8(full_sign_bits_0, block_sign_shuffle_2_1);
3010            signs_0 = _mm_cmpeq_epi8(_mm_and_si128(signs_0, bit_selector_mask_0), bit_selector_mask_0);
3011            signs_1 = _mm_cmpeq_epi8(_mm_and_si128(signs_1, bit_selector_mask_1), bit_selector_mask_1);
3012            const __m128i q8s_2_0 = _mm_sign_epi8(q8_2_0, _mm_or_si128(signs_0, mone));
3013            const __m128i q8s_2_1 = _mm_sign_epi8(q8_2_1, _mm_or_si128(signs_1, mone));
3014
3015            signs_0 = _mm_shuffle_epi8(full_sign_bits_1, block_sign_shuffle_1_0);
3016            signs_1 = _mm_shuffle_epi8(full_sign_bits_1, block_sign_shuffle_1_1);
3017            signs_0 = _mm_cmpeq_epi8(_mm_and_si128(signs_0, bit_selector_mask_0), bit_selector_mask_0);
3018            signs_1 = _mm_cmpeq_epi8(_mm_and_si128(signs_1, bit_selector_mask_1), bit_selector_mask_1);
3019            const __m128i q8s_3_0 = _mm_sign_epi8(q8_3_0, _mm_or_si128(signs_0, mone));
3020            const __m128i q8s_3_1 = _mm_sign_epi8(q8_3_1, _mm_or_si128(signs_1, mone));
3021
3022            signs_0 = _mm_shuffle_epi8(full_sign_bits_1, block_sign_shuffle_2_0);
3023            signs_1 = _mm_shuffle_epi8(full_sign_bits_1, block_sign_shuffle_2_1);
3024            signs_0 = _mm_cmpeq_epi8(_mm_and_si128(signs_0, bit_selector_mask_0), bit_selector_mask_0);
3025            signs_1 = _mm_cmpeq_epi8(_mm_and_si128(signs_1, bit_selector_mask_1), bit_selector_mask_1);
3026            const __m128i q8s_4_0 = _mm_sign_epi8(q8_4_0, _mm_or_si128(signs_0, mone));
3027            const __m128i q8s_4_1 = _mm_sign_epi8(q8_4_1, _mm_or_si128(signs_1, mone));
3028
3029            const __m128i dot1_0  = _mm_maddubs_epi16(q2_1_0, q8s_1_0);
3030            const __m128i dot1_1  = _mm_maddubs_epi16(q2_1_1, q8s_1_1);
3031            const __m128i dot2_0  = _mm_maddubs_epi16(q2_2_0, q8s_2_0);
3032            const __m128i dot2_1  = _mm_maddubs_epi16(q2_2_1, q8s_2_1);
3033            const __m128i dot3_0  = _mm_maddubs_epi16(q2_3_0, q8s_3_0);
3034            const __m128i dot3_1  = _mm_maddubs_epi16(q2_3_1, q8s_3_1);
3035            const __m128i dot4_0  = _mm_maddubs_epi16(q2_4_0, q8s_4_0);
3036            const __m128i dot4_1  = _mm_maddubs_epi16(q2_4_1, q8s_4_1);
3037
3038            __m128i sc_tmp = _mm_shuffle_epi8(scales, get_scale_shuffle(ib32+0));
3039            const __m128i sc1_0 = _mm_cvtepi8_epi16(sc_tmp);
3040            const __m128i sc1_1 = _mm_cvtepi8_epi16(_mm_srli_si128(sc_tmp, 8));
3041            sc_tmp = _mm_shuffle_epi8(scales, get_scale_shuffle(ib32+1));
3042            const __m128i sc2_0 = _mm_cvtepi8_epi16(sc_tmp);
3043            const __m128i sc2_1 = _mm_cvtepi8_epi16(_mm_srli_si128(sc_tmp, 8));
3044            sc_tmp = _mm_shuffle_epi8(scales, get_scale_shuffle(ib32+2));
3045            const __m128i sc3_0 = _mm_cvtepi8_epi16(sc_tmp);
3046            const __m128i sc3_1 = _mm_cvtepi8_epi16(_mm_srli_si128(sc_tmp, 8));
3047            sc_tmp = _mm_shuffle_epi8(scales, get_scale_shuffle(ib32+3));
3048            const __m128i sc4_0 = _mm_cvtepi8_epi16(sc_tmp);
3049            const __m128i sc4_1 = _mm_cvtepi8_epi16(_mm_srli_si128(sc_tmp, 8));
3050
3051            sumi1_0 = _mm_add_epi32(sumi1_0, _mm_madd_epi16(dot1_0, sc1_0));
3052            sumi1_1 = _mm_add_epi32(sumi1_1, _mm_madd_epi16(dot1_1, sc1_1));
3053            sumi2_0 = _mm_add_epi32(sumi2_0, _mm_madd_epi16(dot2_0, sc2_0));
3054            sumi2_1 = _mm_add_epi32(sumi2_1, _mm_madd_epi16(dot2_1, sc2_1));
3055            sumi1_0 = _mm_add_epi32(sumi1_0, _mm_madd_epi16(dot3_0, sc3_0));
3056            sumi1_1 = _mm_add_epi32(sumi1_1, _mm_madd_epi16(dot3_1, sc3_1));
3057            sumi2_0 = _mm_add_epi32(sumi2_0, _mm_madd_epi16(dot4_0, sc4_0));
3058            sumi2_1 = _mm_add_epi32(sumi2_1, _mm_madd_epi16(dot4_1, sc4_1));
3059        }
3060
3061        accumf = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(MM256_SET_M128I(_mm_add_epi32(sumi1_1, sumi2_1), _mm_add_epi32(sumi1_0, sumi2_0)))), accumf);
3062
3063    }
3064
3065    *s = 0.125f * hsum_float_8(accumf);
3066
3067#else
3068    UNUSED(x);
3069    UNUSED(y);
3070    UNUSED(nb);
3071    ggml_vec_dot_iq2_xs_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
3072#endif
3073}
3074
3075void ggml_vec_dot_iq2_s_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
3076    assert(n % QK_K == 0);
3077    assert(nrc == 1);
3078    UNUSED(nrc);
3079    UNUSED(bx);
3080    UNUSED(by);
3081    UNUSED(bs);
3082
3083    const block_iq2_s * GGML_RESTRICT x = vx;
3084    const block_q8_K  * GGML_RESTRICT y = vy;
3085
3086    const int nb = n / QK_K;
3087
3088#if defined(__AVX2__)
3089
3090   static const uint8_t k_mask1[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
3091                                       0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
3092   };
3093
3094    static const uint8_t k_mask2[32] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
3095                                        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
3096    };
3097
3098    const __m128i m4 = _mm_set1_epi8(0xf);
3099    const __m128i m1 = _mm_set1_epi8(1);
3100
3101    const __m256i mask1 = _mm256_loadu_si256((const __m256i*)k_mask1);
3102    const __m256i mask2 = _mm256_loadu_si256((const __m256i*)k_mask2);
3103
3104    uint64_t aux64;
3105
3106    __m256 accumf = _mm256_setzero_ps();
3107    for (int i = 0; i < nb; ++i) {
3108        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
3109        const uint8_t * GGML_RESTRICT qs = x[i].qs;
3110        const uint8_t * GGML_RESTRICT qh = x[i].qh;
3111        const uint16_t * GGML_RESTRICT signs = (const uint16_t *)(x[i].qs + QK_K/8);
3112        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
3113
3114        memcpy(&aux64, x[i].scales, 8);
3115        const __m128i scales8 = _mm_add_epi8(_mm_slli_epi16(_mm_and_si128(_mm_set_epi64x(aux64 >> 4, aux64), m4), 1), m1);
3116        const __m256i scales16 = _mm256_cvtepi8_epi16(scales8); // 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15
3117
3118        __m256i sumi1 = _mm256_setzero_si256();
3119        __m256i sumi2 = _mm256_setzero_si256();
3120        for (int ib32 = 0; ib32 < QK_K/32; ib32 += 2) {
3121            const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
3122            const __m256i q8_2 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
3123            const __m256i q2_1 = _mm256_set_epi64x(iq2s_grid[qs[3] | ((qh[ib32+0] << 2) & 0x300)],
3124                                                   iq2s_grid[qs[2] | ((qh[ib32+0] << 4) & 0x300)],
3125                                                   iq2s_grid[qs[1] | ((qh[ib32+0] << 6) & 0x300)],
3126                                                   iq2s_grid[qs[0] | ((qh[ib32+0] << 8) & 0x300)]);
3127            const __m256i q2_2 = _mm256_set_epi64x(iq2s_grid[qs[7] | ((qh[ib32+1] << 2) & 0x300)],
3128                                                   iq2s_grid[qs[6] | ((qh[ib32+1] << 4) & 0x300)],
3129                                                   iq2s_grid[qs[5] | ((qh[ib32+1] << 6) & 0x300)],
3130                                                   iq2s_grid[qs[4] | ((qh[ib32+1] << 8) & 0x300)]);
3131            qs += 8;
3132
3133            __m256i aux256 = _mm256_set1_epi32(signs[0] | ((uint32_t) signs[1] << 16));
3134            aux256 = _mm256_and_si256(_mm256_shuffle_epi8(aux256,mask1), mask2);
3135            const __m256i s2_1 = _mm256_cmpeq_epi8(aux256, mask2);
3136            const __m256i q8s_1 = _mm256_sub_epi8(_mm256_xor_si256(s2_1, q8_1), s2_1);
3137
3138            aux256 = _mm256_set1_epi32(signs[2] | ((uint32_t) signs[3] << 16));
3139            aux256 = _mm256_and_si256(_mm256_shuffle_epi8(aux256,mask1), mask2);
3140            const __m256i s2_2 = _mm256_cmpeq_epi8(aux256, mask2);
3141            const __m256i q8s_2 = _mm256_sub_epi8(_mm256_xor_si256(s2_2, q8_2), s2_2);
3142
3143            signs += 4;
3144
3145            const __m256i dot1  = _mm256_maddubs_epi16(q2_1, q8s_1); // blocks 2*ib32+0, 2*ib32+1
3146            const __m256i dot2  = _mm256_maddubs_epi16(q2_2, q8s_2); // blocks 2*ib32+2, 2*ib32+3
3147
3148            const __m256i p1 = _mm256_madd_epi16(dot1, _mm256_shuffle_epi8(scales16, get_scale_shuffle_k4(ib32+0)));
3149            const __m256i p2 = _mm256_madd_epi16(dot2, _mm256_shuffle_epi8(scales16, get_scale_shuffle_k4(ib32+1)));
3150            sumi1 = _mm256_add_epi32(sumi1, p1);
3151            sumi2 = _mm256_add_epi32(sumi2, p2);
3152        }
3153
3154        accumf = _mm256_fmadd_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(_mm256_add_epi32(sumi1, sumi2)), accumf);
3155
3156    }
3157
3158    *s = 0.125f * hsum_float_8(accumf);
3159
3160#elif defined(__AVX__)
3161   static const uint8_t k_mask1[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
3162                                       0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
3163   };
3164
3165    static const uint8_t k_mask2[32] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
3166                                        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
3167    };
3168
3169    const __m128i m4 = _mm_set1_epi8(0xf);
3170    const __m128i m1 = _mm_set1_epi8(1);
3171
3172    const __m128i mask1_0 = _mm_loadu_si128((const __m128i*)k_mask1);
3173    const __m128i mask1_1 = _mm_loadu_si128((const __m128i*)k_mask1 + 1);
3174    const __m128i mask2_0 = _mm_loadu_si128((const __m128i*)k_mask2);
3175    const __m128i mask2_1 = _mm_loadu_si128((const __m128i*)k_mask2 + 1);
3176
3177    uint64_t aux64;
3178
3179    __m256 accumf = _mm256_setzero_ps();
3180    for (int i = 0; i < nb; ++i) {
3181        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
3182        const uint8_t * GGML_RESTRICT qs = x[i].qs;
3183        const uint8_t * GGML_RESTRICT qh = x[i].qh;
3184        const uint16_t * GGML_RESTRICT signs = (const uint16_t *)(x[i].qs + QK_K/8);
3185        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
3186
3187        memcpy(&aux64, x[i].scales, 8);
3188        const __m128i scales8 = _mm_add_epi8(_mm_slli_epi16(_mm_and_si128(_mm_set_epi64x(aux64 >> 4, aux64), m4), 1), m1);
3189        const __m128i scales16_0 = _mm_cvtepi8_epi16(scales8);
3190        const __m128i scales16_1 = _mm_cvtepi8_epi16(_mm_srli_si128(scales8, 8));
3191
3192        __m128i sumi1_0 = _mm_setzero_si128();
3193        __m128i sumi1_1 = _mm_setzero_si128();
3194        __m128i sumi2_0 = _mm_setzero_si128();
3195        __m128i sumi2_1 = _mm_setzero_si128();
3196        for (int ib32 = 0; ib32 < QK_K/32; ib32 += 2) {
3197            const __m128i q8_1_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3198            const __m128i q8_1_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3199            const __m128i q8_2_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3200            const __m128i q8_2_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3201            const __m128i q2_1_0 = _mm_set_epi64x(iq2s_grid[qs[1] | ((qh[ib32+0] << 6) & 0x300)],
3202                                                  iq2s_grid[qs[0] | ((qh[ib32+0] << 8) & 0x300)]);
3203            const __m128i q2_1_1 = _mm_set_epi64x(iq2s_grid[qs[3] | ((qh[ib32+0] << 2) & 0x300)],
3204                                                  iq2s_grid[qs[2] | ((qh[ib32+0] << 4) & 0x300)]);
3205            const __m128i q2_2_0 = _mm_set_epi64x(iq2s_grid[qs[5] | ((qh[ib32+1] << 6) & 0x300)],
3206                                                  iq2s_grid[qs[4] | ((qh[ib32+1] << 8) & 0x300)]);
3207            const __m128i q2_2_1 = _mm_set_epi64x(iq2s_grid[qs[7] | ((qh[ib32+1] << 2) & 0x300)],
3208                                                  iq2s_grid[qs[6] | ((qh[ib32+1] << 4) & 0x300)]);
3209            qs += 8;
3210
3211            __m128i aux128_0 = _mm_set1_epi32(signs[0] | ((uint32_t) signs[1] << 16));
3212            __m128i aux128_1 = aux128_0;
3213            aux128_0 = _mm_and_si128(_mm_shuffle_epi8(aux128_0,mask1_0), mask2_0);
3214            aux128_1 = _mm_and_si128(_mm_shuffle_epi8(aux128_1,mask1_1), mask2_1);
3215            const __m128i s2_1_0 = _mm_cmpeq_epi8(aux128_0, mask2_0);
3216            const __m128i s2_1_1 = _mm_cmpeq_epi8(aux128_1, mask2_1);
3217            const __m128i q8s_1_0 = _mm_sub_epi8(_mm_xor_si128(s2_1_0, q8_1_0), s2_1_0);
3218            const __m128i q8s_1_1 = _mm_sub_epi8(_mm_xor_si128(s2_1_1, q8_1_1), s2_1_1);
3219
3220            aux128_0 = _mm_set1_epi32(signs[2] | ((uint32_t) signs[3] << 16));
3221            aux128_1 = aux128_0;
3222            aux128_0 = _mm_and_si128(_mm_shuffle_epi8(aux128_0,mask1_0), mask2_0);
3223            aux128_1 = _mm_and_si128(_mm_shuffle_epi8(aux128_1,mask1_1), mask2_1);
3224            const __m128i s2_2_0 = _mm_cmpeq_epi8(aux128_0, mask2_0);
3225            const __m128i s2_2_1 = _mm_cmpeq_epi8(aux128_1, mask2_1);
3226            const __m128i q8s_2_0 = _mm_sub_epi8(_mm_xor_si128(s2_2_0, q8_2_0), s2_2_0);
3227            const __m128i q8s_2_1 = _mm_sub_epi8(_mm_xor_si128(s2_2_1, q8_2_1), s2_2_1);
3228
3229            signs += 4;
3230
3231            const __m128i dot1_0  = _mm_maddubs_epi16(q2_1_0, q8s_1_0);
3232            const __m128i dot1_1  = _mm_maddubs_epi16(q2_1_1, q8s_1_1);
3233            const __m128i dot2_0  = _mm_maddubs_epi16(q2_2_0, q8s_2_0);
3234            const __m128i dot2_1  = _mm_maddubs_epi16(q2_2_1, q8s_2_1);
3235
3236            const __m128i p1_0 = _mm_madd_epi16(dot1_0, _mm_shuffle_epi8(scales16_0, _mm256_extractf128_si256(get_scale_shuffle_k4(ib32+0), 0)));
3237            const __m128i p1_1 = _mm_madd_epi16(dot1_1, _mm_shuffle_epi8(scales16_1, _mm256_extractf128_si256(get_scale_shuffle_k4(ib32+0), 1)));
3238            const __m128i p2_0 = _mm_madd_epi16(dot2_0, _mm_shuffle_epi8(scales16_0, _mm256_extractf128_si256(get_scale_shuffle_k4(ib32+1), 0)));
3239            const __m128i p2_1 = _mm_madd_epi16(dot2_1, _mm_shuffle_epi8(scales16_1, _mm256_extractf128_si256(get_scale_shuffle_k4(ib32+1), 1)));
3240            sumi1_0 = _mm_add_epi32(sumi1_0, p1_0);
3241            sumi1_1 = _mm_add_epi32(sumi1_1, p1_1);
3242            sumi2_0 = _mm_add_epi32(sumi2_0, p2_0);
3243            sumi2_1 = _mm_add_epi32(sumi2_1, p2_1);
3244        }
3245
3246        accumf = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(MM256_SET_M128I(_mm_add_epi32(sumi1_1, sumi2_1), _mm_add_epi32(sumi1_0, sumi2_0)))), accumf);
3247
3248    }
3249
3250    *s = 0.125f * hsum_float_8(accumf);
3251
3252#else
3253    UNUSED(x);
3254    UNUSED(y);
3255    UNUSED(nb);
3256    ggml_vec_dot_iq2_s_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
3257#endif
3258}
3259
3260void ggml_vec_dot_iq3_xxs_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
3261    assert(n % QK_K == 0);
3262    assert(nrc == 1);
3263    UNUSED(nrc);
3264    UNUSED(bx);
3265    UNUSED(by);
3266    UNUSED(bs);
3267
3268    const block_iq3_xxs * GGML_RESTRICT x = vx;
3269    const block_q8_K    * GGML_RESTRICT y = vy;
3270
3271    const int nb = n / QK_K;
3272
3273#if defined(__AVX2__)
3274
3275    const uint64_t * signs64 = (const uint64_t *)keven_signs_q2xs;
3276
3277    uint32_t aux32[2];
3278
3279    __m256 accumf = _mm256_setzero_ps();
3280    for (int i = 0; i < nb; ++i) {
3281        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
3282        const uint8_t * GGML_RESTRICT q3 = x[i].qs;
3283        const uint8_t * GGML_RESTRICT gas = x[i].qs + QK_K/4;
3284        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
3285        __m256i sumi1 = _mm256_setzero_si256();
3286        __m256i sumi2 = _mm256_setzero_si256();
3287        for (int ib32 = 0; ib32 < QK_K/32; ib32 += 2) {
3288            const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
3289            const __m256i q8_2 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
3290            const __m256i q2_1 = _mm256_set_epi32(iq3xxs_grid[q3[7]], iq3xxs_grid[q3[6]], iq3xxs_grid[q3[5]], iq3xxs_grid[q3[4]],
3291                                                  iq3xxs_grid[q3[3]], iq3xxs_grid[q3[2]], iq3xxs_grid[q3[1]], iq3xxs_grid[q3[0]]);
3292            q3 += 8;
3293            const __m256i q2_2 = _mm256_set_epi32(iq3xxs_grid[q3[7]], iq3xxs_grid[q3[6]], iq3xxs_grid[q3[5]], iq3xxs_grid[q3[4]],
3294                                                  iq3xxs_grid[q3[3]], iq3xxs_grid[q3[2]], iq3xxs_grid[q3[1]], iq3xxs_grid[q3[0]]);
3295            q3 += 8;
3296            memcpy(aux32, gas, 8); gas += 8;
3297            const __m256i s2_1 = _mm256_set_epi64x(signs64[(aux32[0] >> 21) & 127], signs64[(aux32[0] >> 14) & 127],
3298                                                   signs64[(aux32[0] >>  7) & 127], signs64[(aux32[0] >>  0) & 127]);
3299            const __m256i s2_2 = _mm256_set_epi64x(signs64[(aux32[1] >> 21) & 127], signs64[(aux32[1] >> 14) & 127],
3300                                                   signs64[(aux32[1] >>  7) & 127], signs64[(aux32[1] >>  0) & 127]);
3301            const __m256i q8s_1 = _mm256_sign_epi8(q8_1, s2_1);
3302            const __m256i q8s_2 = _mm256_sign_epi8(q8_2, s2_2);
3303            const __m256i dot1  = _mm256_maddubs_epi16(q2_1, q8s_1);
3304            const __m256i dot2  = _mm256_maddubs_epi16(q2_2, q8s_2);
3305            const uint16_t ls1 = aux32[0] >> 28;
3306            const uint16_t ls2 = aux32[1] >> 28;
3307            const __m256i p1 = _mm256_madd_epi16(dot1, _mm256_set1_epi16(2*ls1+1));
3308            const __m256i p2 = _mm256_madd_epi16(dot2, _mm256_set1_epi16(2*ls2+1));
3309            sumi1 = _mm256_add_epi32(sumi1, p1);
3310            sumi2 = _mm256_add_epi32(sumi2, p2);
3311        }
3312
3313        accumf = _mm256_fmadd_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(_mm256_add_epi32(sumi1, sumi2)), accumf);
3314
3315    }
3316
3317    *s = 0.25f * hsum_float_8(accumf);
3318
3319#elif defined(__AVX__)
3320    const uint64_t * signs64 = (const uint64_t *)keven_signs_q2xs;
3321
3322    uint32_t aux32[2];
3323
3324    __m256 accumf = _mm256_setzero_ps();
3325    for (int i = 0; i < nb; ++i) {
3326        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
3327        const uint8_t * GGML_RESTRICT q3 = x[i].qs;
3328        const uint8_t * GGML_RESTRICT gas = x[i].qs + QK_K/4;
3329        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
3330        __m128i sumi1_0 = _mm_setzero_si128();
3331        __m128i sumi1_1 = _mm_setzero_si128();
3332        __m128i sumi2_0 = _mm_setzero_si128();
3333        __m128i sumi2_1 = _mm_setzero_si128();
3334        for (int ib32 = 0; ib32 < QK_K/32; ib32 += 2) {
3335            const __m128i q8_1_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3336            const __m128i q8_1_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3337            const __m128i q8_2_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3338            const __m128i q8_2_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3339            const __m128i q2_1_0 = _mm_set_epi32(iq3xxs_grid[q3[3]], iq3xxs_grid[q3[2]], iq3xxs_grid[q3[1]], iq3xxs_grid[q3[0]]);
3340            const __m128i q2_1_1 = _mm_set_epi32(iq3xxs_grid[q3[7]], iq3xxs_grid[q3[6]], iq3xxs_grid[q3[5]], iq3xxs_grid[q3[4]]);
3341            q3 += 8;
3342            const __m128i q2_2_0 = _mm_set_epi32(iq3xxs_grid[q3[3]], iq3xxs_grid[q3[2]], iq3xxs_grid[q3[1]], iq3xxs_grid[q3[0]]);
3343            const __m128i q2_2_1 = _mm_set_epi32(iq3xxs_grid[q3[7]], iq3xxs_grid[q3[6]], iq3xxs_grid[q3[5]], iq3xxs_grid[q3[4]]);
3344            q3 += 8;
3345            memcpy(aux32, gas, 8); gas += 8;
3346            const __m128i s2_1_0 = _mm_set_epi64x(signs64[(aux32[0] >>  7) & 127], signs64[(aux32[0] >>  0) & 127]);
3347            const __m128i s2_1_1 = _mm_set_epi64x(signs64[(aux32[0] >> 21) & 127], signs64[(aux32[0] >> 14) & 127]);
3348            const __m128i s2_2_0 = _mm_set_epi64x(signs64[(aux32[1] >>  7) & 127], signs64[(aux32[1] >>  0) & 127]);
3349            const __m128i s2_2_1 = _mm_set_epi64x(signs64[(aux32[1] >> 21) & 127], signs64[(aux32[1] >> 14) & 127]);
3350            const __m128i q8s_1_0 = _mm_sign_epi8(q8_1_0, s2_1_0);
3351            const __m128i q8s_1_1 = _mm_sign_epi8(q8_1_1, s2_1_1);
3352            const __m128i q8s_2_0 = _mm_sign_epi8(q8_2_0, s2_2_0);
3353            const __m128i q8s_2_1 = _mm_sign_epi8(q8_2_1, s2_2_1);
3354            const __m128i dot1_0  = _mm_maddubs_epi16(q2_1_0, q8s_1_0);
3355            const __m128i dot1_1  = _mm_maddubs_epi16(q2_1_1, q8s_1_1);
3356            const __m128i dot2_0  = _mm_maddubs_epi16(q2_2_0, q8s_2_0);
3357            const __m128i dot2_1  = _mm_maddubs_epi16(q2_2_1, q8s_2_1);
3358            const uint16_t ls1 = aux32[0] >> 28;
3359            const uint16_t ls2 = aux32[1] >> 28;
3360            const __m128i p1_0 = _mm_madd_epi16(dot1_0, _mm_set1_epi16(2*ls1+1));
3361            const __m128i p1_1 = _mm_madd_epi16(dot1_1, _mm_set1_epi16(2*ls1+1));
3362            const __m128i p2_0 = _mm_madd_epi16(dot2_0, _mm_set1_epi16(2*ls2+1));
3363            const __m128i p2_1 = _mm_madd_epi16(dot2_1, _mm_set1_epi16(2*ls2+1));
3364            sumi1_0 = _mm_add_epi32(sumi1_0, p1_0);
3365            sumi1_1 = _mm_add_epi32(sumi1_1, p1_1);
3366            sumi2_0 = _mm_add_epi32(sumi2_0, p2_0);
3367            sumi2_1 = _mm_add_epi32(sumi2_1, p2_1);
3368        }
3369
3370        accumf = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(MM256_SET_M128I(_mm_add_epi32(sumi1_1, sumi2_1), _mm_add_epi32(sumi1_0, sumi2_0)))), accumf);
3371
3372    }
3373
3374    *s = 0.25f * hsum_float_8(accumf);
3375
3376#else
3377    UNUSED(x);
3378    UNUSED(y);
3379    UNUSED(nb);
3380    ggml_vec_dot_iq3_xxs_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
3381#endif
3382}
3383
3384void ggml_vec_dot_iq3_s_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
3385    assert(n % QK_K == 0);
3386    assert(nrc == 1);
3387    UNUSED(nrc);
3388    UNUSED(bx);
3389    UNUSED(by);
3390    UNUSED(bs);
3391
3392    const block_iq3_s * GGML_RESTRICT x = vx;
3393    const block_q8_K  * GGML_RESTRICT y = vy;
3394
3395    const int nb = n / QK_K;
3396
3397#if defined(__AVX2__)
3398
3399   static const uint8_t k_mask1[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
3400                                       0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
3401   };
3402
3403    static const uint8_t k_mask2[32] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
3404                                        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
3405    };
3406
3407    const __m256i mask1 = _mm256_loadu_si256((const __m256i*)k_mask1);
3408    const __m256i mask2 = _mm256_loadu_si256((const __m256i*)k_mask2);
3409
3410    const __m256i idx_shift = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8);
3411    const __m256i idx_mask  = _mm256_set1_epi32(256);
3412
3413    typedef union {
3414        __m256i  vec[2];
3415        uint32_t index[16];
3416    } index_t;
3417
3418    index_t idx;
3419
3420    __m256 accumf = _mm256_setzero_ps();
3421    for (int i = 0; i < nb; ++i) {
3422        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
3423        const uint8_t * GGML_RESTRICT qs = x[i].qs;
3424        const uint8_t * GGML_RESTRICT qh = x[i].qh;
3425        const uint16_t * GGML_RESTRICT signs = (const uint16_t *)x[i].signs;
3426        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
3427        __m256i sumi1 = _mm256_setzero_si256();
3428        __m256i sumi2 = _mm256_setzero_si256();
3429        for (int ib32 = 0; ib32 < QK_K/32; ib32 += 2) {
3430            const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
3431            const __m256i q8_2 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
3432            const __m256i idx_l = _mm256_cvtepu8_epi16(_mm_loadu_si128((const __m128i *)qs)); qs += 16;
3433            idx.vec[0] = _mm256_set1_epi32(qh[ib32+0]);
3434            idx.vec[1] = _mm256_set1_epi32(qh[ib32+1]);
3435            idx.vec[0] = _mm256_and_si256(_mm256_sllv_epi32(idx.vec[0], idx_shift), idx_mask);
3436            idx.vec[1] = _mm256_and_si256(_mm256_sllv_epi32(idx.vec[1], idx_shift), idx_mask);
3437            idx.vec[0] = _mm256_or_si256(idx.vec[0], _mm256_cvtepi16_epi32(_mm256_castsi256_si128(idx_l)));
3438            idx.vec[1] = _mm256_or_si256(idx.vec[1], _mm256_cvtepi16_epi32(_mm256_extractf128_si256(idx_l, 1)));
3439
3440            // At leat on my CPU (Ryzen 7950X), using _mm256_i32gather_epi32 is slower than _mm256_set_epi32. Strange.
3441            //const __m256i q2_1 = _mm256_i32gather_epi32((const int *)iq3s_grid, idx.vec[0], 4);
3442            //const __m256i q2_2 = _mm256_i32gather_epi32((const int *)iq3s_grid, idx.vec[1], 4);
3443            const __m256i q2_1 = _mm256_set_epi32(
3444                    iq3s_grid[idx.index[7]], iq3s_grid[idx.index[6]], iq3s_grid[idx.index[5]], iq3s_grid[idx.index[4]],
3445                    iq3s_grid[idx.index[3]], iq3s_grid[idx.index[2]], iq3s_grid[idx.index[1]], iq3s_grid[idx.index[0]]
3446            );
3447            const __m256i q2_2 = _mm256_set_epi32(
3448                    iq3s_grid[idx.index[15]], iq3s_grid[idx.index[14]], iq3s_grid[idx.index[13]], iq3s_grid[idx.index[12]],
3449                    iq3s_grid[idx.index[11]], iq3s_grid[idx.index[10]], iq3s_grid[idx.index[ 9]], iq3s_grid[idx.index[ 8]]
3450            );
3451
3452            __m256i aux256 = _mm256_set1_epi32(signs[0] | (signs[1] << 16));
3453            aux256 = _mm256_and_si256(_mm256_shuffle_epi8(aux256,mask1), mask2);
3454            const __m256i s2_1 = _mm256_cmpeq_epi8(aux256, mask2);
3455            const __m256i q8s_1 = _mm256_sub_epi8(_mm256_xor_si256(s2_1, q8_1), s2_1);
3456
3457            aux256 = _mm256_set1_epi32(signs[2] | (signs[3] << 16));
3458            aux256 = _mm256_and_si256(_mm256_shuffle_epi8(aux256,mask1), mask2);
3459            const __m256i s2_2 = _mm256_cmpeq_epi8(aux256, mask2);
3460            const __m256i q8s_2 = _mm256_sub_epi8(_mm256_xor_si256(s2_2, q8_2), s2_2);
3461
3462            signs += 4;
3463
3464            const __m256i dot1  = _mm256_maddubs_epi16(q2_1, q8s_1);
3465            const __m256i dot2  = _mm256_maddubs_epi16(q2_2, q8s_2);
3466            const uint16_t ls1 = x[i].scales[ib32/2] & 0xf;
3467            const uint16_t ls2 = x[i].scales[ib32/2] >>  4;
3468            const __m256i p1 = _mm256_madd_epi16(dot1, _mm256_set1_epi16(2*ls1+1));
3469            const __m256i p2 = _mm256_madd_epi16(dot2, _mm256_set1_epi16(2*ls2+1));
3470            sumi1 = _mm256_add_epi32(sumi1, p1);
3471            sumi2 = _mm256_add_epi32(sumi2, p2);
3472        }
3473
3474        accumf = _mm256_fmadd_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(_mm256_add_epi32(sumi1, sumi2)), accumf);
3475
3476    }
3477
3478    *s = hsum_float_8(accumf);
3479
3480#elif defined(__AVX__)
3481   static const uint8_t k_mask1[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
3482                                       0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
3483   };
3484
3485    static const uint8_t k_mask2[32] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
3486                                        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
3487    };
3488
3489    const __m128i mask1_0 = _mm_loadu_si128((const __m128i*)k_mask1);
3490    const __m128i mask1_1 = _mm_loadu_si128((const __m128i*)k_mask1 + 1);
3491    const __m128i mask2_0 = _mm_loadu_si128((const __m128i*)k_mask2);
3492    const __m128i mask2_1 = _mm_loadu_si128((const __m128i*)k_mask2 + 1);
3493
3494    const __m128i idx_mul_0 = _mm_set_epi32(32, 64, 128, 256);
3495    const __m128i idx_mul_1 = _mm_set_epi32(2, 4, 8, 16);
3496    const __m128i idx_mask  = _mm_set1_epi32(256);
3497
3498    typedef union {
3499        __m128i  vec[4];
3500        uint32_t index[16];
3501    } index_t;
3502
3503    index_t idx;
3504
3505    __m256 accumf = _mm256_setzero_ps();
3506    for (int i = 0; i < nb; ++i) {
3507        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
3508        const uint8_t * GGML_RESTRICT qs = x[i].qs;
3509        const uint8_t * GGML_RESTRICT qh = x[i].qh;
3510        const uint16_t * GGML_RESTRICT signs = (const uint16_t *)x[i].signs;
3511        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
3512        __m128i sumi1_0 = _mm_setzero_si128();
3513        __m128i sumi1_1 = _mm_setzero_si128();
3514        __m128i sumi2_0 = _mm_setzero_si128();
3515        __m128i sumi2_1 = _mm_setzero_si128();
3516        for (int ib32 = 0; ib32 < QK_K/32; ib32 += 2) {
3517            const __m128i q8_1_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3518            const __m128i q8_1_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3519            const __m128i q8_2_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3520            const __m128i q8_2_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3521            const __m128i qs_tmp = _mm_loadu_si128((const __m128i *)qs);
3522            const __m128i idx_l_0 = _mm_cvtepu8_epi16(qs_tmp);
3523            const __m128i idx_l_1 = _mm_cvtepu8_epi16(_mm_srli_si128(qs_tmp, 8)); qs += 16;
3524            idx.vec[0] = _mm_set1_epi32(qh[ib32+0]);
3525            idx.vec[1] = idx.vec[0];
3526            idx.vec[2] = _mm_set1_epi32(qh[ib32+1]);
3527            idx.vec[3] = idx.vec[2];
3528
3529            idx.vec[0] = _mm_and_si128(_mm_mullo_epi32(idx.vec[0], idx_mul_0), idx_mask);
3530            idx.vec[1] = _mm_and_si128(_mm_mullo_epi32(idx.vec[1], idx_mul_1), idx_mask);
3531            idx.vec[2] = _mm_and_si128(_mm_mullo_epi32(idx.vec[2], idx_mul_0), idx_mask);
3532            idx.vec[3] = _mm_and_si128(_mm_mullo_epi32(idx.vec[3], idx_mul_1), idx_mask);
3533
3534            idx.vec[0] = _mm_or_si128(idx.vec[0], _mm_cvtepi16_epi32(idx_l_0));
3535            idx.vec[1] = _mm_or_si128(idx.vec[1], _mm_cvtepi16_epi32(_mm_srli_si128(idx_l_0, 8)));
3536            idx.vec[2] = _mm_or_si128(idx.vec[2], _mm_cvtepi16_epi32(idx_l_1));
3537            idx.vec[3] = _mm_or_si128(idx.vec[3], _mm_cvtepi16_epi32(_mm_srli_si128(idx_l_1, 8)));
3538
3539            const __m128i q2_1_0 = _mm_set_epi32(iq3s_grid[idx.index[3]], iq3s_grid[idx.index[2]], iq3s_grid[idx.index[1]], iq3s_grid[idx.index[0]]);
3540            const __m128i q2_1_1 = _mm_set_epi32(iq3s_grid[idx.index[7]], iq3s_grid[idx.index[6]], iq3s_grid[idx.index[5]], iq3s_grid[idx.index[4]]);
3541            const __m128i q2_2_0 = _mm_set_epi32(iq3s_grid[idx.index[11]], iq3s_grid[idx.index[10]], iq3s_grid[idx.index[9]], iq3s_grid[idx.index[8]]);
3542            const __m128i q2_2_1 = _mm_set_epi32(iq3s_grid[idx.index[15]], iq3s_grid[idx.index[14]], iq3s_grid[idx.index[13]], iq3s_grid[idx.index[12]]);
3543
3544            __m128i aux128_0 = _mm_set1_epi32(signs[0] | (signs[1] << 16));
3545            __m128i aux128_1 = aux128_0;
3546            aux128_0 = _mm_and_si128(_mm_shuffle_epi8(aux128_0,mask1_0), mask2_0);
3547            aux128_1 = _mm_and_si128(_mm_shuffle_epi8(aux128_1,mask1_1), mask2_1);
3548            const __m128i s2_1_0 = _mm_cmpeq_epi8(aux128_0, mask2_0);
3549            const __m128i s2_1_1 = _mm_cmpeq_epi8(aux128_1, mask2_1);
3550            const __m128i q8s_1_0 = _mm_sub_epi8(_mm_xor_si128(s2_1_0, q8_1_0), s2_1_0);
3551            const __m128i q8s_1_1 = _mm_sub_epi8(_mm_xor_si128(s2_1_1, q8_1_1), s2_1_1);
3552
3553            aux128_0 = _mm_set1_epi32(signs[2] | (signs[3] << 16));
3554            aux128_1 = aux128_0;
3555            aux128_0 = _mm_and_si128(_mm_shuffle_epi8(aux128_0,mask1_0), mask2_0);
3556            aux128_1 = _mm_and_si128(_mm_shuffle_epi8(aux128_1,mask1_1), mask2_1);
3557            const __m128i s2_2_0 = _mm_cmpeq_epi8(aux128_0, mask2_0);
3558            const __m128i s2_2_1 = _mm_cmpeq_epi8(aux128_1, mask2_1);
3559            const __m128i q8s_2_0 = _mm_sub_epi8(_mm_xor_si128(s2_2_0, q8_2_0), s2_2_0);
3560            const __m128i q8s_2_1 = _mm_sub_epi8(_mm_xor_si128(s2_2_1, q8_2_1), s2_2_1);
3561
3562            signs += 4;
3563
3564            const __m128i dot1_0  = _mm_maddubs_epi16(q2_1_0, q8s_1_0);
3565            const __m128i dot1_1  = _mm_maddubs_epi16(q2_1_1, q8s_1_1);
3566            const __m128i dot2_0  = _mm_maddubs_epi16(q2_2_0, q8s_2_0);
3567            const __m128i dot2_1  = _mm_maddubs_epi16(q2_2_1, q8s_2_1);
3568            const uint16_t ls1 = x[i].scales[ib32/2] & 0xf;
3569            const uint16_t ls2 = x[i].scales[ib32/2] >>  4;
3570            const __m128i p1_0 = _mm_madd_epi16(dot1_0, _mm_set1_epi16(2*ls1+1));
3571            const __m128i p1_1 = _mm_madd_epi16(dot1_1, _mm_set1_epi16(2*ls1+1));
3572            const __m128i p2_0 = _mm_madd_epi16(dot2_0, _mm_set1_epi16(2*ls2+1));
3573            const __m128i p2_1 = _mm_madd_epi16(dot2_1, _mm_set1_epi16(2*ls2+1));
3574            sumi1_0 = _mm_add_epi32(sumi1_0, p1_0);
3575            sumi1_1 = _mm_add_epi32(sumi1_1, p1_1);
3576            sumi2_0 = _mm_add_epi32(sumi2_0, p2_0);
3577            sumi2_1 = _mm_add_epi32(sumi2_1, p2_1);
3578        }
3579
3580        accumf = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(MM256_SET_M128I(_mm_add_epi32(sumi1_1, sumi2_1), _mm_add_epi32(sumi1_0, sumi2_0)))), accumf);
3581
3582    }
3583
3584    *s = hsum_float_8(accumf);
3585
3586#else
3587    UNUSED(x);
3588    UNUSED(y);
3589    UNUSED(nb);
3590    ggml_vec_dot_iq3_s_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
3591#endif
3592}
3593
3594void ggml_vec_dot_iq1_s_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
3595    assert(n % QK_K == 0);
3596    assert(nrc == 1);
3597    UNUSED(nrc);
3598    UNUSED(bx);
3599    UNUSED(by);
3600    UNUSED(bs);
3601
3602    const block_iq1_s * GGML_RESTRICT x = vx;
3603    const block_q8_K  * GGML_RESTRICT y = vy;
3604
3605    const int nb = n / QK_K;
3606
3607#if defined __AVX2__
3608
3609    __m256 accum = _mm256_setzero_ps();
3610    float accum1 = 0;
3611    for (int i = 0; i < nb; ++i) {
3612
3613        const int8_t   * q8 = y[i].qs;
3614        const uint8_t  * qs = x[i].qs;
3615        const uint16_t * qh = x[i].qh;
3616
3617        __m256i sumi = _mm256_setzero_si256();
3618        int sumi1 = 0;
3619        for (int ib = 0; ib < QK_K/32; ib += 2) {
3620#ifdef __BMI2__
3621            const uint64_t packed_idx1 = _pdep_u64(*(const uint32_t *)qs, 0x00ff00ff00ff00ffULL) | _pdep_u64(qh[ib], 0x700070007000700ULL);
3622            const uint64_t packed_idx2 = _pdep_u64(*(const uint32_t *)(qs + 4), 0x00ff00ff00ff00ffULL) | _pdep_u64(qh[ib + 1], 0x700070007000700ULL);
3623            const uint16_t *idx1 = (const uint16_t *)(&packed_idx1);
3624            const uint16_t *idx2 = (const uint16_t *)(&packed_idx2);
3625            const __m256i q1b_1 = _mm256_set_epi64x(iq1s_grid[idx1[3]], iq1s_grid[idx1[2]], iq1s_grid[idx1[1]], iq1s_grid[idx1[0]]);
3626            const __m256i q1b_2 = _mm256_set_epi64x(iq1s_grid[idx2[3]], iq1s_grid[idx2[2]], iq1s_grid[idx2[1]], iq1s_grid[idx2[0]]);
3627#else
3628            const __m256i q1b_1 = _mm256_set_epi64x(iq1s_grid[qs[3] | ((qh[ib+0] >> 1) & 0x700)], iq1s_grid[qs[2] | ((qh[ib+0] << 2) & 0x700)],
3629                                                    iq1s_grid[qs[1] | ((qh[ib+0] << 5) & 0x700)], iq1s_grid[qs[0] | ((qh[ib+0] << 8) & 0x700)]);
3630            const __m256i q1b_2 = _mm256_set_epi64x(iq1s_grid[qs[7] | ((qh[ib+1] >> 1) & 0x700)], iq1s_grid[qs[6] | ((qh[ib+1] << 2) & 0x700)],
3631                                                    iq1s_grid[qs[5] | ((qh[ib+1] << 5) & 0x700)], iq1s_grid[qs[4] | ((qh[ib+1] << 8) & 0x700)]);
3632#endif
3633            qs += 8;
3634            const __m256i q8b_1 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
3635            const __m256i q8b_2 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
3636
3637            const __m256i dot1 = mul_add_epi8(q1b_1, q8b_1);
3638            const __m256i dot2 = mul_add_epi8(q1b_2, q8b_2);
3639            const int16_t ls1 = 2*((qh[ib+0] >> 12) & 7) + 1;
3640            const int16_t ls2 = 2*((qh[ib+1] >> 12) & 7) + 1;
3641            const __m256i p1 = _mm256_madd_epi16(dot1, _mm256_set1_epi16(ls1));
3642            const __m256i p2 = _mm256_madd_epi16(dot2, _mm256_set1_epi16(ls2));
3643
3644            sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p1, p2));
3645            sumi1 += (y[i].bsums[2*ib+0] + y[i].bsums[2*ib+1]) * (qh[ib+0] & 0x8000 ? -1 : 1) * ls1
3646                   + (y[i].bsums[2*ib+2] + y[i].bsums[2*ib+3]) * (qh[ib+1] & 0x8000 ? -1 : 1) * ls2;
3647        }
3648
3649        const float d = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
3650        accum = _mm256_fmadd_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(sumi), accum);
3651        accum1 += d * sumi1;
3652
3653    }
3654
3655    *s = hsum_float_8(accum) + IQ1S_DELTA * accum1;
3656
3657#elif defined __AVX__
3658    __m256 accum = _mm256_setzero_ps();
3659    float accum1 = 0;
3660    for (int i = 0; i < nb; ++i) {
3661
3662        const int8_t   * q8 = y[i].qs;
3663        const uint8_t  * qs = x[i].qs;
3664        const uint16_t * qh = x[i].qh;
3665
3666        __m128i sumi1_0 = _mm_setzero_si128();
3667        __m128i sumi1_1 = _mm_setzero_si128();
3668        int sumi1 = 0;
3669        for (int ib = 0; ib < QK_K/32; ib += 2) {
3670            const __m128i q1b_1_0 = _mm_set_epi64x(iq1s_grid[qs[1] | ((qh[ib+0] << 5) & 0x700)], iq1s_grid[qs[0] | ((qh[ib+0] << 8) & 0x700)]);
3671            const __m128i q1b_1_1 = _mm_set_epi64x(iq1s_grid[qs[3] | ((qh[ib+0] >> 1) & 0x700)], iq1s_grid[qs[2] | ((qh[ib+0] << 2) & 0x700)]);
3672            const __m128i q1b_2_0 = _mm_set_epi64x(iq1s_grid[qs[5] | ((qh[ib+1] << 5) & 0x700)], iq1s_grid[qs[4] | ((qh[ib+1] << 8) & 0x700)]);
3673            const __m128i q1b_2_1 = _mm_set_epi64x(iq1s_grid[qs[7] | ((qh[ib+1] >> 1) & 0x700)], iq1s_grid[qs[6] | ((qh[ib+1] << 2) & 0x700)]);
3674            qs += 8;
3675            const __m128i q8b_1_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3676            const __m128i q8b_1_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3677            const __m128i q8b_2_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3678            const __m128i q8b_2_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3679
3680            const __m128i dot1_0 = mul_add_epi8_sse(q1b_1_0, q8b_1_0);
3681            const __m128i dot1_1 = mul_add_epi8_sse(q1b_1_1, q8b_1_1);
3682            const __m128i dot2_0 = mul_add_epi8_sse(q1b_2_0, q8b_2_0);
3683            const __m128i dot2_1 = mul_add_epi8_sse(q1b_2_1, q8b_2_1);
3684            const int16_t ls1 = 2*((qh[ib+0] >> 12) & 7) + 1;
3685            const int16_t ls2 = 2*((qh[ib+1] >> 12) & 7) + 1;
3686            const __m128i p1_0 = _mm_madd_epi16(dot1_0, _mm_set1_epi16(ls1));
3687            const __m128i p1_1 = _mm_madd_epi16(dot1_1, _mm_set1_epi16(ls1));
3688            const __m128i p2_0 = _mm_madd_epi16(dot2_0, _mm_set1_epi16(ls2));
3689            const __m128i p2_1 = _mm_madd_epi16(dot2_1, _mm_set1_epi16(ls2));
3690
3691            sumi1_0 = _mm_add_epi32(sumi1_0, _mm_add_epi32(p1_0, p2_0));
3692            sumi1_1 = _mm_add_epi32(sumi1_1, _mm_add_epi32(p1_1, p2_1));
3693            sumi1 += (y[i].bsums[2*ib+0] + y[i].bsums[2*ib+1]) * (qh[ib+0] & 0x8000 ? -1 : 1) * ls1
3694                   + (y[i].bsums[2*ib+2] + y[i].bsums[2*ib+3]) * (qh[ib+1] & 0x8000 ? -1 : 1) * ls2;
3695        }
3696
3697        const float d = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
3698        accum = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(MM256_SET_M128I(sumi1_1, sumi1_0))), accum);
3699        accum1 += d * sumi1;
3700
3701    }
3702
3703    *s = hsum_float_8(accum) + IQ1S_DELTA * accum1;
3704
3705#else
3706    UNUSED(x);
3707    UNUSED(y);
3708    UNUSED(nb);
3709    ggml_vec_dot_iq1_s_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
3710#endif
3711}
3712
3713void ggml_vec_dot_iq1_m_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
3714    assert(n % QK_K == 0);
3715    assert(nrc == 1);
3716    UNUSED(nrc);
3717    UNUSED(bx);
3718    UNUSED(by);
3719    UNUSED(bs);
3720
3721    const block_iq1_m * GGML_RESTRICT x = vx;
3722    const block_q8_K  * GGML_RESTRICT y = vy;
3723
3724    const int nb = n / QK_K;
3725
3726    iq1m_scale_t scale;
3727
3728#if defined __AVX2__
3729
3730    const __m256i mask = _mm256_set1_epi16(0x7);
3731    const __m256i mone = _mm256_set1_epi16(1);
3732    const __m256i mone8 = _mm256_set1_epi8(1);
3733    const __m256i mtwo8 = _mm256_set1_epi8(2);
3734    // VPSHUFB cannot cross 128-bit lanes so odd shifts go to upper half.
3735    const __m256i scales_shift = _mm256_set_epi64x(9, 3, 6, 0);
3736
3737    __m256 accum1 = _mm256_setzero_ps();
3738    __m256 accum2 = _mm256_setzero_ps();
3739    for (int i = 0; i < nb; ++i) {
3740
3741        const int8_t   * q8 = y[i].qs;
3742        const uint8_t  * qs = x[i].qs;
3743        const uint8_t  * qh = x[i].qh;
3744        const uint16_t * sc = (const uint16_t *)x[i].scales;
3745
3746        scale.u16 = (sc[0] >> 12) | ((sc[1] >> 8) & 0x00f0) | ((sc[2] >> 4) & 0x0f00) | (sc[3] & 0xf000);
3747        // Extract 3-bit scales (16 values)
3748        __m256i scales = _mm256_set1_epi64x(*(const uint64_t*)sc);
3749        scales = _mm256_srlv_epi64(scales, scales_shift);
3750        scales = _mm256_add_epi16(_mm256_slli_epi16(_mm256_and_si256(scales, mask), 1), mone);
3751
3752        // Indices to repeat each scale 8 times.
3753        __m256i scales_idx1 = _mm256_set1_epi16(0x0100);
3754        __m256i scales_idx2 = _mm256_add_epi8(scales_idx1, _mm256_set1_epi8(8));
3755
3756        __m256i sumi1 = _mm256_setzero_si256();
3757        __m256i sumi2 = _mm256_setzero_si256();
3758        for (int ib = 0; ib < QK_K/32; ib += 2) {
3759#ifdef __BMI2__
3760            const uint64_t packed_idx1 = _pdep_u64(*(const uint32_t *)qs, 0x00ff00ff00ff00ffULL)
3761                                       | _pdep_u64(*(const uint16_t*)(qh) & 0x7777, 0xf000f000f000f00ULL);
3762            const uint64_t packed_idx2 = _pdep_u64(*(const uint32_t *)(qs + 4), 0x00ff00ff00ff00ffULL)
3763                                       | _pdep_u64(*(const uint16_t*)(qh + 2) & 0x7777, 0xf000f000f000f00ULL);
3764            const uint16_t *idx1 = (const uint16_t *)(&packed_idx1);
3765            const uint16_t *idx2 = (const uint16_t *)(&packed_idx2);
3766            const __m256i q1b_1 = _mm256_set_epi64x(iq1s_grid[idx1[3]], iq1s_grid[idx1[2]], iq1s_grid[idx1[1]], iq1s_grid[idx1[0]]);
3767            const __m256i q1b_2 = _mm256_set_epi64x(iq1s_grid[idx2[3]], iq1s_grid[idx2[2]], iq1s_grid[idx2[1]], iq1s_grid[idx2[0]]);
3768
3769            // Convert signs to bytes 0x81 (negative) or 0x01 (positive)
3770            const uint64_t delta_sign = _pdep_u64(*(const uint32_t*)(qh) & 0x88888888, 0xf0f0f0f0f0f0f0f0ULL);
3771            const __m256i delta1 = _mm256_or_si256(mone8, _mm256_cvtepi8_epi64(_mm_set1_epi32(delta_sign)));
3772            const __m256i delta2 = _mm256_or_si256(mone8, _mm256_cvtepi8_epi64(_mm_set1_epi32(delta_sign >> 32)));
3773#else
3774            const __m256i q1b_1 = _mm256_set_epi64x(
3775                    iq1s_grid[qs[3] | (((uint16_t)qh[1] << 4) & 0x700)], iq1s_grid[qs[2] | (((uint16_t)qh[1] << 8) & 0x700)],
3776                    iq1s_grid[qs[1] | (((uint16_t)qh[0] << 4) & 0x700)], iq1s_grid[qs[0] | (((uint16_t)qh[0] << 8) & 0x700)]
3777            );
3778            const __m256i q1b_2 = _mm256_set_epi64x(
3779                    iq1s_grid[qs[7] | (((uint16_t)qh[3] << 4) & 0x700)], iq1s_grid[qs[6] | (((uint16_t)qh[3] << 8) & 0x700)],
3780                    iq1s_grid[qs[5] | (((uint16_t)qh[2] << 4) & 0x700)], iq1s_grid[qs[4] | (((uint16_t)qh[2] << 8) & 0x700)]
3781            );
3782
3783            const __m256i delta1 = _mm256_set_epi64x(qh[1] & 0x80 ? 0xffffffffffffffff : 0x0101010101010101,
3784                                                     qh[1] & 0x08 ? 0xffffffffffffffff : 0x0101010101010101,
3785                                                     qh[0] & 0x80 ? 0xffffffffffffffff : 0x0101010101010101,
3786                                                     qh[0] & 0x08 ? 0xffffffffffffffff : 0x0101010101010101);
3787            const __m256i delta2 = _mm256_set_epi64x(qh[3] & 0x80 ? 0xffffffffffffffff : 0x0101010101010101,
3788                                                     qh[3] & 0x08 ? 0xffffffffffffffff : 0x0101010101010101,
3789                                                     qh[2] & 0x80 ? 0xffffffffffffffff : 0x0101010101010101,
3790                                                     qh[2] & 0x08 ? 0xffffffffffffffff : 0x0101010101010101);
3791#endif
3792            const __m256i q8b_1 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
3793            const __m256i q8b_2 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32;
3794
3795            const __m256i dot1 = mul_add_epi8(q1b_1, q8b_1);
3796            const __m256i dot2 = mul_add_epi8(q1b_2, q8b_2);
3797            const __m256i dot3 = _mm256_maddubs_epi16(mone8, _mm256_sign_epi8(q8b_1, delta1));
3798            const __m256i dot4 = _mm256_maddubs_epi16(mone8, _mm256_sign_epi8(q8b_2, delta2));
3799
3800            __m256i scale1 = _mm256_shuffle_epi8(scales, scales_idx1);
3801            __m256i scale2 = _mm256_shuffle_epi8(scales, scales_idx2);
3802
3803            scales_idx1 = _mm256_add_epi8(scales_idx1, mtwo8);
3804            scales_idx2 = _mm256_add_epi8(scales_idx2, mtwo8);
3805
3806            const __m256i p1 = _mm256_madd_epi16(dot1, scale1);
3807            const __m256i p2 = _mm256_madd_epi16(dot2, scale2);
3808            const __m256i p3 = _mm256_madd_epi16(dot3, scale1);
3809            const __m256i p4 = _mm256_madd_epi16(dot4, scale2);
3810
3811            sumi1 = _mm256_add_epi32(sumi1, _mm256_add_epi32(p1, p2));
3812            sumi2 = _mm256_add_epi32(sumi2, _mm256_add_epi32(p3, p4));
3813
3814            qs += 8; qh += 4;
3815        }
3816
3817        const __m256 d = _mm256_set1_ps(y[i].d * GGML_CPU_FP16_TO_FP32(scale.f16));
3818
3819        accum1 = _mm256_fmadd_ps(d, _mm256_cvtepi32_ps(sumi1), accum1);
3820        accum2 = _mm256_fmadd_ps(d, _mm256_cvtepi32_ps(sumi2), accum2);
3821    }
3822
3823    *s = hsum_float_8(accum1) + IQ1M_DELTA * hsum_float_8(accum2);
3824
3825#elif defined __AVX__
3826    const __m128i mask = _mm_set1_epi16(0x7);
3827    const __m128i mone = _mm_set1_epi16(1);
3828
3829    __m256 accum1 = _mm256_setzero_ps();
3830    __m256 accum2 = _mm256_setzero_ps();
3831    for (int i = 0; i < nb; ++i) {
3832
3833        const int8_t   * q8 = y[i].qs;
3834        const uint8_t  * qs = x[i].qs;
3835        const uint8_t  * qh = x[i].qh;
3836        const uint16_t * sc = (const uint16_t *)x[i].scales;
3837
3838        scale.u16 = (sc[0] >> 12) | ((sc[1] >> 8) & 0x00f0) | ((sc[2] >> 4) & 0x0f00) | (sc[3] & 0xf000);
3839
3840        __m128i sumi1_0 = _mm_setzero_si128();
3841        __m128i sumi1_1 = _mm_setzero_si128();
3842        __m128i sumi2_0 = _mm_setzero_si128();
3843        __m128i sumi2_1 = _mm_setzero_si128();
3844        for (int ib = 0; ib < QK_K/32; ib += 2) {
3845            const __m128i q1b_1_0 = _mm_set_epi64x(
3846                    iq1s_grid[qs[1] | (((uint16_t)qh[0] << 4) & 0x700)], iq1s_grid[qs[0] | (((uint16_t)qh[0] << 8) & 0x700)]);
3847            const __m128i q1b_1_1 = _mm_set_epi64x(
3848                    iq1s_grid[qs[3] | (((uint16_t)qh[1] << 4) & 0x700)], iq1s_grid[qs[2] | (((uint16_t)qh[1] << 8) & 0x700)]);
3849            const __m128i q1b_2_0 = _mm_set_epi64x(
3850                    iq1s_grid[qs[5] | (((uint16_t)qh[2] << 4) & 0x700)], iq1s_grid[qs[4] | (((uint16_t)qh[2] << 8) & 0x700)]);
3851            const __m128i q1b_2_1 = _mm_set_epi64x(
3852                    iq1s_grid[qs[7] | (((uint16_t)qh[3] << 4) & 0x700)], iq1s_grid[qs[6] | (((uint16_t)qh[3] << 8) & 0x700)]);
3853            const __m128i q8b_1_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3854            const __m128i q8b_1_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3855            const __m128i q8b_2_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3856            const __m128i q8b_2_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
3857
3858            const __m128i dot1_0 = mul_add_epi8_sse(q1b_1_0, q8b_1_0);
3859            const __m128i dot1_1 = mul_add_epi8_sse(q1b_1_1, q8b_1_1);
3860            const __m128i dot2_0 = mul_add_epi8_sse(q1b_2_0, q8b_2_0);
3861            const __m128i dot2_1 = mul_add_epi8_sse(q1b_2_1, q8b_2_1);
3862
3863            const __m128i delta1_0 = _mm_set_epi64x(qh[0] & 0x80 ? 0xffffffffffffffff : 0x0101010101010101,
3864                                                     qh[0] & 0x08 ? 0xffffffffffffffff : 0x0101010101010101);
3865            const __m128i delta1_1 = _mm_set_epi64x(qh[1] & 0x80 ? 0xffffffffffffffff : 0x0101010101010101,
3866                                                     qh[1] & 0x08 ? 0xffffffffffffffff : 0x0101010101010101);
3867            const __m128i delta2_0 = _mm_set_epi64x(qh[2] & 0x80 ? 0xffffffffffffffff : 0x0101010101010101,
3868                                                     qh[2] & 0x08 ? 0xffffffffffffffff : 0x0101010101010101);
3869            const __m128i delta2_1 = _mm_set_epi64x(qh[3] & 0x80 ? 0xffffffffffffffff : 0x0101010101010101,
3870                                                     qh[3] & 0x08 ? 0xffffffffffffffff : 0x0101010101010101);
3871
3872            const __m128i dot3_0 = mul_add_epi8_sse(delta1_0, q8b_1_0);
3873            const __m128i dot3_1 = mul_add_epi8_sse(delta1_1, q8b_1_1);
3874            const __m128i dot4_0 = mul_add_epi8_sse(delta2_0, q8b_2_0);
3875            const __m128i dot4_1 = mul_add_epi8_sse(delta2_1, q8b_2_1);
3876
3877            __m128i scale1_0 = _mm_set1_epi16(sc[ib/2] >> 0);
3878            __m128i scale1_1 = _mm_set1_epi16(sc[ib/2] >> 3);
3879            __m128i scale2_0 = _mm_set1_epi16(sc[ib/2] >> 6);
3880            __m128i scale2_1 = _mm_set1_epi16(sc[ib/2] >> 9);
3881
3882            scale1_0 = _mm_add_epi16(_mm_slli_epi16(_mm_and_si128(scale1_0, mask), 1), mone);
3883            scale1_1 = _mm_add_epi16(_mm_slli_epi16(_mm_and_si128(scale1_1, mask), 1), mone);
3884            scale2_0 = _mm_add_epi16(_mm_slli_epi16(_mm_and_si128(scale2_0, mask), 1), mone);
3885            scale2_1 = _mm_add_epi16(_mm_slli_epi16(_mm_and_si128(scale2_1, mask), 1), mone);
3886            const __m128i p1_0 = _mm_madd_epi16(dot1_0, scale1_0);
3887            const __m128i p1_1 = _mm_madd_epi16(dot1_1, scale1_1);
3888            const __m128i p2_0 = _mm_madd_epi16(dot2_0, scale2_0);
3889            const __m128i p2_1 = _mm_madd_epi16(dot2_1, scale2_1);
3890            const __m128i p3_0 = _mm_madd_epi16(dot3_0, scale1_0);
3891            const __m128i p3_1 = _mm_madd_epi16(dot3_1, scale1_1);
3892            const __m128i p4_0 = _mm_madd_epi16(dot4_0, scale2_0);
3893            const __m128i p4_1 = _mm_madd_epi16(dot4_1, scale2_1);
3894
3895            sumi1_0 = _mm_add_epi32(sumi1_0, _mm_add_epi32(p1_0, p2_0));
3896            sumi1_1 = _mm_add_epi32(sumi1_1, _mm_add_epi32(p1_1, p2_1));
3897            sumi2_0 = _mm_add_epi32(sumi2_0, _mm_add_epi32(p3_0, p4_0));
3898            sumi2_1 = _mm_add_epi32(sumi2_1, _mm_add_epi32(p3_1, p4_1));
3899
3900            qs += 8; qh += 4;
3901        }
3902
3903        const __m256 d = _mm256_set1_ps(y[i].d * GGML_CPU_FP16_TO_FP32(scale.f16));
3904
3905        accum1 = _mm256_add_ps(_mm256_mul_ps(d, _mm256_cvtepi32_ps(MM256_SET_M128I(sumi1_1, sumi1_0))), accum1);
3906        accum2 = _mm256_add_ps(_mm256_mul_ps(d, _mm256_cvtepi32_ps(MM256_SET_M128I(sumi2_1, sumi2_0))), accum2);
3907    }
3908
3909    *s = hsum_float_8(accum1) + IQ1M_DELTA * hsum_float_8(accum2);
3910
3911#else
3912    UNUSED(x);
3913    UNUSED(y);
3914    UNUSED(nb);
3915    UNUSED(scale);
3916    ggml_vec_dot_iq1_m_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
3917#endif
3918}
3919
3920void ggml_vec_dot_iq4_nl_q8_0(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
3921    assert(nrc == 1);
3922    UNUSED(nrc);
3923    UNUSED(bx);
3924    UNUSED(by);
3925    UNUSED(bs);
3926    assert(n % QK4_NL == 0);
3927    static_assert(QK4_NL == QK8_0, "QK4_NL and QK8_0 must be the same");
3928
3929    const block_iq4_nl * GGML_RESTRICT x = vx;
3930    const block_q8_0   * GGML_RESTRICT y = vy;
3931
3932    const int nb = n / QK4_NL;
3933
3934    int ib = 0;
3935    float sumf = 0;
3936
3937#if defined __AVX2__
3938
3939    const __m128i values128 = _mm_loadu_si128((const __m128i*)kvalues_iq4nl);
3940    const __m128i m4b  = _mm_set1_epi8(0x0f);
3941    const __m256i mone = _mm256_set1_epi16(1);
3942
3943    __m256 accum1 = _mm256_setzero_ps();
3944    __m256 accum2 = _mm256_setzero_ps();
3945    for (; ib + 1 < nb; ib += 2) {
3946        const __m128i q4bits_1 = _mm_loadu_si128((const __m128i*)x[ib + 0].qs);
3947        const __m128i q4bits_2 = _mm_loadu_si128((const __m128i*)x[ib + 1].qs);
3948        const __m256i q8b_1 = _mm256_loadu_si256((const __m256i *)y[ib + 0].qs);
3949        const __m256i q8b_2 = _mm256_loadu_si256((const __m256i *)y[ib + 1].qs);
3950        const __m256i q4b_1 = MM256_SET_M128I(_mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_1, 4), m4b)),
3951                                              _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_1, m4b)));
3952        const __m256i q4b_2 = MM256_SET_M128I(_mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_2, 4), m4b)),
3953                                              _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_2, m4b)));
3954        const __m256i p16_1 = mul_add_epi8(q4b_1, q8b_1);
3955        const __m256i p16_2 = mul_add_epi8(q4b_2, q8b_2);
3956        const __m256i p_1 = _mm256_madd_epi16(p16_1, mone);
3957        const __m256i p_2 = _mm256_madd_epi16(p16_2, mone);
3958        accum1 = _mm256_fmadd_ps(_mm256_set1_ps(GGML_CPU_FP16_TO_FP32(y[ib + 0].d)*GGML_CPU_FP16_TO_FP32(x[ib + 0].d)),
3959                _mm256_cvtepi32_ps(p_1), accum1);
3960        accum2 = _mm256_fmadd_ps(_mm256_set1_ps(GGML_CPU_FP16_TO_FP32(y[ib + 1].d)*GGML_CPU_FP16_TO_FP32(x[ib + 1].d)),
3961                _mm256_cvtepi32_ps(p_2), accum2);
3962    }
3963
3964    sumf = hsum_float_8(_mm256_add_ps(accum1, accum2));
3965
3966#elif defined __AVX__
3967    const __m128i values128 = _mm_loadu_si128((const __m128i*)kvalues_iq4nl);
3968    const __m128i m4b  = _mm_set1_epi8(0x0f);
3969
3970    __m256 accum = _mm256_setzero_ps();
3971    for (; ib + 1 < nb; ib += 2) {
3972        const __m128i q4bits_1 = _mm_loadu_si128((const __m128i *)x[ib + 0].qs);
3973        const __m128i q4bits_2 = _mm_loadu_si128((const __m128i *)x[ib + 1].qs);
3974        const __m128i q8b_1_0 = _mm_loadu_si128((const __m128i *)y[ib + 0].qs);
3975        const __m128i q8b_1_1 = _mm_loadu_si128((const __m128i *)y[ib + 0].qs + 1);
3976        const __m128i q8b_2_0 = _mm_loadu_si128((const __m128i *)y[ib + 1].qs);
3977        const __m128i q8b_2_1 = _mm_loadu_si128((const __m128i *)y[ib + 1].qs + 1);
3978
3979        const __m128i q4b_1_0 = _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_1, m4b));
3980        const __m128i q4b_1_1 = _mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_1, 4), m4b));
3981        const __m128i q4b_2_0 = _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_2, m4b));
3982        const __m128i q4b_2_1 = _mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_2, 4), m4b));
3983
3984        const __m256 p = mul_sum_i8_quad_float(q4b_1_0, q4b_1_1, q4b_2_0, q4b_2_1, q8b_1_0, q8b_1_1, q8b_2_0, q8b_2_1);
3985        const __m256 deltas = quad_fp16_delta_float(x[ib].d, y[ib].d, x[ib + 1].d, y[ib + 1].d);
3986        accum = _mm256_add_ps(_mm256_mul_ps(deltas, p), accum);
3987    }
3988
3989    sumf = hsum_float_8(accum);
3990
3991#endif
3992    for (; ib < nb; ++ib) {
3993        const float d = GGML_CPU_FP16_TO_FP32(y[ib].d)*GGML_CPU_FP16_TO_FP32(x[ib].d);
3994        int sumi1 = 0, sumi2 = 0;
3995        for (int j = 0; j < QK4_NL/2; ++j) {
3996            sumi1 += y[ib].qs[j+       0] * kvalues_iq4nl[x[ib].qs[j] & 0xf];
3997            sumi2 += y[ib].qs[j+QK4_NL/2] * kvalues_iq4nl[x[ib].qs[j] >>  4];
3998        }
3999        sumf += d * (sumi1 + sumi2);
4000    }
4001    *s = sumf;
4002}
4003
4004void ggml_vec_dot_iq4_xs_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
4005    assert(nrc == 1);
4006    UNUSED(nrc);
4007    UNUSED(bx);
4008    UNUSED(by);
4009    UNUSED(bs);
4010    assert(n % QK_K == 0);
4011
4012    const block_iq4_xs * GGML_RESTRICT x = vx;
4013    const block_q8_K   * GGML_RESTRICT y = vy;
4014
4015    const int nb = n / QK_K;
4016
4017#if defined __AVX2__
4018
4019    const __m128i values128 = _mm_loadu_si128((const __m128i*)kvalues_iq4nl);
4020    const __m128i m4b  = _mm_set1_epi8(0x0f);
4021
4022    __m256 accum = _mm256_setzero_ps();
4023    for (int ibl = 0; ibl < nb; ++ibl) {
4024        const uint8_t * qs = x[ibl].qs;
4025        const int8_t  * q8 = y[ibl].qs;
4026        uint16_t sh = x[ibl].scales_h;
4027        __m256i sumi1 = _mm256_setzero_si256();
4028        __m256i sumi2 = _mm256_setzero_si256();
4029        for (int ib = 0; ib < QK_K/32; ib += 2) {
4030            const __m128i q4bits_1 = _mm_loadu_si128((const __m128i*)qs);  qs += 16;
4031            const __m128i q4bits_2 = _mm_loadu_si128((const __m128i*)qs);  qs += 16;
4032            const __m256i q8b_1 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
4033            const __m256i q8b_2 = _mm256_loadu_si256((const __m256i *)q8); q8 += 32;
4034            const __m256i q4b_1 = MM256_SET_M128I(_mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_1, 4), m4b)),
4035                                                  _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_1, m4b)));
4036            const __m256i q4b_2 = MM256_SET_M128I(_mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_2, 4), m4b)),
4037                                                  _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_2, m4b)));
4038            const __m256i p16_1 = mul_add_epi8(q4b_1, q8b_1);
4039            const __m256i p16_2 = mul_add_epi8(q4b_2, q8b_2);
4040            const int16_t ls1 = ((x[ibl].scales_l[ib/2] & 0xf) | ((sh << 4) & 0x30)) - 32;
4041            const int16_t ls2 = ((x[ibl].scales_l[ib/2] >>  4) | ((sh << 2) & 0x30)) - 32;
4042            sh >>= 4;
4043            const __m256i p_1 = _mm256_madd_epi16(p16_1, _mm256_set1_epi16(ls1));
4044            const __m256i p_2 = _mm256_madd_epi16(p16_2, _mm256_set1_epi16(ls2));
4045            sumi1 = _mm256_add_epi32(p_1, sumi1);
4046            sumi2 = _mm256_add_epi32(p_2, sumi2);
4047        }
4048        accum = _mm256_fmadd_ps(_mm256_set1_ps(GGML_CPU_FP16_TO_FP32(x[ibl].d)*y[ibl].d),
4049                _mm256_cvtepi32_ps(_mm256_add_epi32(sumi1, sumi2)), accum);
4050    }
4051
4052    *s = hsum_float_8(accum);
4053
4054#elif defined __AVX__
4055    const __m128i values128 = _mm_loadu_si128((const __m128i*)kvalues_iq4nl);
4056    const __m128i m4b  = _mm_set1_epi8(0x0f);
4057
4058    __m256 accum = _mm256_setzero_ps();
4059    for (int ibl = 0; ibl < nb; ++ibl) {
4060        const uint8_t * qs = x[ibl].qs;
4061        const int8_t  * q8 = y[ibl].qs;
4062        uint16_t sh = x[ibl].scales_h;
4063        __m128i sumi1_0 = _mm_setzero_si128();
4064        __m128i sumi1_1 = _mm_setzero_si128();
4065        __m128i sumi2_0 = _mm_setzero_si128();
4066        __m128i sumi2_1 = _mm_setzero_si128();
4067        for (int ib = 0; ib < QK_K/32; ib += 2) {
4068            const __m128i q4bits_1 = _mm_loadu_si128((const __m128i *)qs); qs += 16;
4069            const __m128i q4bits_2 = _mm_loadu_si128((const __m128i *)qs); qs += 16;
4070            const __m128i q8b_1_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
4071            const __m128i q8b_1_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
4072            const __m128i q8b_2_0 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
4073            const __m128i q8b_2_1 = _mm_loadu_si128((const __m128i *)q8); q8 += 16;
4074            const __m128i q4b_1_0 = _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_1, m4b));
4075            const __m128i q4b_1_1 = _mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_1, 4), m4b));
4076            const __m128i q4b_2_0 = _mm_shuffle_epi8(values128, _mm_and_si128(q4bits_2, m4b));
4077            const __m128i q4b_2_1 = _mm_shuffle_epi8(values128, _mm_and_si128(_mm_srli_epi16(q4bits_2, 4), m4b));
4078            const __m128i p16_1_0 = mul_add_epi8_sse(q4b_1_0, q8b_1_0);
4079            const __m128i p16_1_1 = mul_add_epi8_sse(q4b_1_1, q8b_1_1);
4080            const __m128i p16_2_0 = mul_add_epi8_sse(q4b_2_0, q8b_2_0);
4081            const __m128i p16_2_1 = mul_add_epi8_sse(q4b_2_1, q8b_2_1);
4082            const int16_t ls1 = ((x[ibl].scales_l[ib/2] & 0xf) | ((sh << 4) & 0x30)) - 32;
4083            const int16_t ls2 = ((x[ibl].scales_l[ib/2] >>  4) | ((sh << 2) & 0x30)) - 32;
4084            sh >>= 4;
4085            const __m128i p_1_0 = _mm_madd_epi16(p16_1_0, _mm_set1_epi16(ls1));
4086            const __m128i p_1_1 = _mm_madd_epi16(p16_1_1, _mm_set1_epi16(ls1));
4087            const __m128i p_2_0 = _mm_madd_epi16(p16_2_0, _mm_set1_epi16(ls2));
4088            const __m128i p_2_1 = _mm_madd_epi16(p16_2_1, _mm_set1_epi16(ls2));
4089            sumi1_0 = _mm_add_epi32(p_1_0, sumi1_0);
4090            sumi1_1 = _mm_add_epi32(p_1_1, sumi1_1);
4091            sumi2_0 = _mm_add_epi32(p_2_0, sumi2_0);
4092            sumi2_1 = _mm_add_epi32(p_2_1, sumi2_1);
4093        }
4094        __m128i sumi12_0 = _mm_add_epi32(sumi1_0, sumi2_0);
4095        __m128i sumi12_1 = _mm_add_epi32(sumi1_1, sumi2_1);
4096        accum = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(GGML_CPU_FP16_TO_FP32(x[ibl].d)*y[ibl].d),
4097                _mm256_cvtepi32_ps(MM256_SET_M128I(sumi12_1, sumi12_0))), accum);
4098    }
4099
4100    *s = hsum_float_8(accum);
4101
4102#else
4103    UNUSED(x);
4104    UNUSED(y);
4105    UNUSED(nb);
4106    ggml_vec_dot_iq4_xs_q8_K_generic(n, s, bs, vx, bx, vy, by, nrc);
4107#endif
4108}