char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
6dbc1174b
char/aliceai-t5-moe
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 32const __m128i ax = _mm_sign_epi8 (x ,x ); 33// Sign the values of the y vectors 34const __m128i sy = _mm_sign_epi8 (y ,x ); 35// Perform multiplication and create 16-bit values 36const __m128i dot = _mm_maddubs_epi16 (ax ,sy ); 37const __m128i ones = _mm_set1_epi16 (1 ); 38return _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 ); 45res = _mm_add_ps (res ,_mm256_castps256_ps128 (x )); 46res = _mm_add_ps (res ,_mm_movehl_ps (res ,res )); 47res = _mm_add_ss (res ,_mm_movehdup_ps (res )); 48return _mm_cvtss_f32 (res ); 49} 50 51// horizontally add 8 int32_t 52static inline int hsum_i32_8 (const __m256i a ) { 53const __m128i sum128 = _mm_add_epi32 (_mm256_castsi256_si128 (a ),_mm256_extractf128_si256 (a ,1 )); 54const __m128i hi64 = _mm_unpackhi_epi64 (sum128 ,sum128 ); 55const __m128i sum64 = _mm_add_epi32 (hi64 ,sum128 ); 56const __m128i hi32 = _mm_shuffle_epi32 (sum64 ,_MM_SHUFFLE (2 ,3 ,0 ,1 )); 57return _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 ) { 62const __m128i hi64 = _mm_unpackhi_epi64 (a ,a ); 63const __m128i sum64 = _mm_add_epi32 (hi64 ,a ); 64const __m128i hi32 = _mm_shuffle_epi32 (sum64 ,_MM_SHUFFLE (2 ,3 ,0 ,1 )); 65return _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 ) { 70const __m256i ax = _mm256_sign_epi8 (x ,x ); 71const __m256i sy = _mm256_sign_epi8 (y ,x ); 72return _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 ) { 77uint32_t x32 ; 78memcpy (& x32 ,x ,sizeof (uint32_t )); 79const __m256i shuf_mask = _mm256_set_epi64x ( 800x0303030303030303 ,0x0202020202020202 , 810x0101010101010101 ,0x0000000000000000 ); 82__m256i bytes = _mm256_shuffle_epi8 (_mm256_set1_epi32 (x32 ),shuf_mask ); 83const __m256i bit_mask = _mm256_set1_epi64x (0x7fbfdfeff7fbfdfe ); 84bytes = _mm256_or_si256 (bytes ,bit_mask ); 85return _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{ 92const __m128i tmp = _mm_loadu_si128 ((const __m128i * )rsi ); 93const __m256i bytes = MM256_SET_M128I (_mm_srli_epi16 (tmp ,4 ),tmp ); 94const __m256i lowMask = _mm256_set1_epi8 (0xF ); 95return _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 ) { 100const __m256i ones = _mm256_set1_epi16 (1 ); 101const __m256i summed_pairs = _mm256_madd_epi16 (ones ,x ); 102return _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__ ) 107const __m256i zero = _mm256_setzero_si256 (); 108const __m256i summed_pairs = _mm256_dpbusd_epi32 (zero ,ax ,sy ); 109return _mm256_cvtepi32_ps (summed_pairs ); 110#elif defined(__AVXVNNI__ ) 111const __m256i zero = _mm256_setzero_si256 (); 112const __m256i summed_pairs = _mm256_dpbusd_avx_epi32 (zero ,ax ,sy ); 113return _mm256_cvtepi32_ps (summed_pairs ); 114#else 115// Perform multiplication and create 16-bit values 116const __m256i dot = _mm256_maddubs_epi16 (ax ,sy ); 117return 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__ 124const __m256i zero = _mm256_setzero_si256 (); 125const __m256i summed_pairs = _mm256_dpbssd_epi32 (zero ,x ,y ); 126return _mm256_cvtepi32_ps (summed_pairs ); 127#else 128// Get absolute values of x vectors 129const __m256i ax = _mm256_sign_epi8 (x ,x ); 130// Sign the values of the y vectors 131const __m256i sy = _mm256_sign_epi8 (y ,x ); 132return 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__ 140const __m256i bytes_srli_4 = _mm256_srli_epi16 (bytes ,4 );// 0000_0000_abcd_0000 141bytes = _mm256_or_si256 (bytes ,bytes_srli_4 );// 0000_abcd_abcd_efgh 142return _mm256_cvtepi16_epi8 (bytes );// abcd_efgh 143#else 144const __m256i lowByte = _mm256_set1_epi16 (0xFF ); 145__m256i high = _mm256_andnot_si256 (lowByte ,bytes ); 146__m256i low = _mm256_and_si256 (lowByte ,bytes ); 147high = _mm256_srli_epi16 (high ,4 ); 148bytes = _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 ); 153return _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 160const __m128i lowByte = _mm_set1_epi16 (0xFF ); 161__m128i high = _mm_andnot_si128 (lowByte ,bytes1 ); 162__m128i low = _mm_and_si128 (lowByte ,bytes1 ); 163high = _mm_srli_epi16 (high ,4 ); 164bytes1 = _mm_or_si128 (low ,high ); 165high = _mm_andnot_si128 (lowByte ,bytes2 ); 166low = _mm_and_si128 (lowByte ,bytes2 ); 167high = _mm_srli_epi16 (high ,4 ); 168bytes2 = _mm_or_si128 (low ,high ); 169 170return _mm_packus_epi16 (bytes1 ,bytes2 ); 171} 172 173static inline __m128i mul_add_epi8_sse (const __m128i x ,const __m128i y ) { 174const __m128i ax = _mm_sign_epi8 (x ,x ); 175const __m128i sy = _mm_sign_epi8 (y ,x ); 176return _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 ) { 181uint32_t x32 ; 182memcpy (& x32 ,x ,sizeof (uint32_t )); 183const __m128i shuf_maskl = _mm_set_epi64x (0x0101010101010101 ,0x0000000000000000 ); 184const __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 ); 187const __m128i bit_mask = _mm_set1_epi64x (0x7fbfdfeff7fbfdfe ); 188bytesl = _mm_or_si128 (bytesl ,bit_mask ); 189bytesh = _mm_or_si128 (bytesh ,bit_mask ); 190bytesl = _mm_cmpeq_epi8 (bytesl ,_mm_set1_epi64x (-1 )); 191bytesh = _mm_cmpeq_epi8 (bytesh ,_mm_set1_epi64x (-1 )); 192return 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 ); 202const __m128i lowMask = _mm_set1_epi8 (0xF ); 203tmpl = _mm_and_si128 (lowMask ,tmpl ); 204tmph = _mm_and_si128 (lowMask ,tmph ); 205return 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 ) { 210const __m128i ones = _mm_set1_epi16 (1 ); 211const __m128i summed_pairsl = _mm_madd_epi16 (ones ,xl ); 212const __m128i summed_pairsh = _mm_madd_epi16 (ones ,xh ); 213const __m256i summed_pairs = MM256_SET_M128I (summed_pairsh ,summed_pairsl ); 214return _mm256_cvtepi32_ps (summed_pairs ); 215} 216 217static inline __m256 mul_sum_us8_pairs_float (const __m256i ax ,const __m256i sy ) { 218const __m128i axl = _mm256_castsi256_si128 (ax ); 219const __m128i axh = _mm256_extractf128_si256 (ax ,1 ); 220const __m128i syl = _mm256_castsi256_si128 (sy ); 221const __m128i syh = _mm256_extractf128_si256 (sy ,1 ); 222// Perform multiplication and create 16-bit values 223const __m128i dotl = _mm_maddubs_epi16 (axl ,syl ); 224const __m128i doth = _mm_maddubs_epi16 (axh ,syh ); 225return 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 ) { 230const __m128i xl = _mm256_castsi256_si128 (x ); 231const __m128i xh = _mm256_extractf128_si256 (x ,1 ); 232const __m128i yl = _mm256_castsi256_si128 (y ); 233const __m128i yh = _mm256_extractf128_si256 (y ,1 ); 234// Get absolute values of x vectors 235const __m128i axl = _mm_sign_epi8 (xl ,xl ); 236const __m128i axh = _mm_sign_epi8 (xh ,xh ); 237// Sign the values of the y vectors 238const __m128i syl = _mm_sign_epi8 (yl ,xl ); 239const __m128i syh = _mm_sign_epi8 (yh ,xh ); 240// Perform multiplication and create 16-bit values 241const __m128i dotl = _mm_maddubs_epi16 (axl ,syl ); 242const __m128i doth = _mm_maddubs_epi16 (axh ,syh ); 243return 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 , 248const __m128i y_1_0 ,const __m128i y_1_1 ,const __m128i y_2_0 ,const __m128i y_2_1 ) { 249const __m128i mone = _mm_set1_epi16 (1 ); 250 251const __m128i p16_1_0 = mul_add_epi8_sse (x_1_0 ,y_1_0 ); 252const __m128i p16_1_1 = mul_add_epi8_sse (x_1_1 ,y_1_1 ); 253const __m128i p16_2_0 = mul_add_epi8_sse (x_2_0 ,y_2_0 ); 254const __m128i p16_2_1 = mul_add_epi8_sse (x_2_1 ,y_2_1 ); 255const __m128i p_1_0 = _mm_madd_epi16 (p16_1_0 ,mone ); 256const __m128i p_1_1 = _mm_madd_epi16 (p16_1_1 ,mone ); 257const __m128i p_2_0 = _mm_madd_epi16 (p16_2_0 ,mone ); 258const __m128i p_2_1 = _mm_madd_epi16 (p16_2_1 ,mone ); 259const __m128i p_1 = _mm_add_epi32 (p_1_0 ,p_1_1 ); 260const __m128i p_2 = _mm_add_epi32 (p_2_0 ,p_2_1 ); 261return _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 267return _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 ) { 272return _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 ) { 278uint16_t x16 ; 279memcpy (& x16 ,x ,sizeof (uint16_t )); 280 281const __m128i shuf_mask = _mm_set_epi64x (0x0101010101010101 ,0x0000000000000000 ); 282__m128i bytes = _mm_shuffle_epi8 (_mm_set1_epi16 ((short )x16 ),shuf_mask ); 283const __m128i bit_mask = _mm_set_epi64x (0x7fbfdfeff7fbfdfe ,0x7fbfdfeff7fbfdfe ); 284bytes = _mm_or_si128 (bytes ,bit_mask ); 285 286return _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 ); 294res = _mm_hadd_ps (res ,res ); 295res = _mm_hadd_ps (res ,res ); 296 297return _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 ) { 303assert (QK8_0 == 32 ); 304assert (k %QK8_0 == 0 ); 305const int nb = k /QK8_0 ; 306 307block_q8_0 * GGML_RESTRICT y = vy ; 308 309#if defined(__AVX2__ )|| defined(__AVX__ ) 310for (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 ); 316x += 32 ; 317 318// Compute max(abs(e)) for the block 319const __m256 signBit = _mm256_set1_ps (-0.0f ); 320__m256 maxAbs = _mm256_andnot_ps (signBit ,v0 ); 321maxAbs = _mm256_max_ps (maxAbs ,_mm256_andnot_ps (signBit ,v1 ) ); 322maxAbs = _mm256_max_ps (maxAbs ,_mm256_andnot_ps (signBit ,v2 ) ); 323maxAbs = _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 ) ); 326max4 = _mm_max_ps (max4 ,_mm_movehl_ps (max4 ,max4 ) ); 327max4 = _mm_max_ss (max4 ,_mm_movehdup_ps (max4 ) ); 328const float maxScalar = _mm_cvtss_f32 (max4 ); 329 330// Quantize these floats 331const float d = maxScalar /127.f ; 332y [i ].d = GGML_CPU_FP32_TO_FP16 (d ); 333const float id = (maxScalar != 0.0f ) ?127.f /maxScalar :0.0f ; 334const __m256 mul = _mm256_set1_ps (id ); 335 336// Apply the multiplier 337v0 = _mm256_mul_ps (v0 ,mul ); 338v1 = _mm256_mul_ps (v1 ,mul ); 339v2 = _mm256_mul_ps (v2 ,mul ); 340v3 = _mm256_mul_ps (v3 ,mul ); 341 342// Round to nearest integer 343v0 = _mm256_round_ps (v0 ,_MM_ROUND_NEAREST ); 344v1 = _mm256_round_ps (v1 ,_MM_ROUND_NEAREST ); 345v2 = _mm256_round_ps (v2 ,_MM_ROUND_NEAREST ); 346v3 = _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 356i0 = _mm256_packs_epi32 (i0 ,i1 );// 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15 357i2 = _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 359i0 = _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 364const __m256i perm = _mm256_setr_epi32 (0 ,4 ,1 ,5 ,2 ,6 ,3 ,7 ); 365i0 = _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 381ni0 = _mm_packs_epi32 (ni0 ,ni1 ); 382ni2 = _mm_packs_epi32 (ni2 ,ni3 ); 383ni4 = _mm_packs_epi32 (ni4 ,ni5 ); 384ni6 = _mm_packs_epi32 (ni6 ,ni7 ); 385// Convert int16 to int8 386ni0 = _mm_packs_epi16 (ni0 ,ni2 ); 387ni4 = _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 394GGML_UNUSED (nb ); 395// scalar 396quantize_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 ) { 401assert (k %QK8_1 == 0 ); 402const int nb = k /QK8_1 ; 403 404block_q8_1 * GGML_RESTRICT y = vy ; 405#if defined(__AVX2__ )|| defined(__AVX__ ) 406for (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 ); 412x += 32 ; 413 414// Compute max(abs(e)) for the block 415const __m256 signBit = _mm256_set1_ps (-0.0f ); 416__m256 maxAbs = _mm256_andnot_ps (signBit ,v0 ); 417maxAbs = _mm256_max_ps (maxAbs ,_mm256_andnot_ps (signBit ,v1 ) ); 418maxAbs = _mm256_max_ps (maxAbs ,_mm256_andnot_ps (signBit ,v2 ) ); 419maxAbs = _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 ) ); 422max4 = _mm_max_ps (max4 ,_mm_movehl_ps (max4 ,max4 ) ); 423max4 = _mm_max_ss (max4 ,_mm_movehdup_ps (max4 ) ); 424const float max_scalar = _mm_cvtss_f32 (max4 ); 425 426// Quantize these floats 427const float d = max_scalar /127.f ; 428y [i ].d = GGML_CPU_FP32_TO_FP16 (d ); 429const float id = (max_scalar != 0.0f ) ?127.f /max_scalar :0.0f ; 430const __m256 mul = _mm256_set1_ps (id ); 431 432// Apply the multiplier 433v0 = _mm256_mul_ps (v0 ,mul ); 434v1 = _mm256_mul_ps (v1 ,mul ); 435v2 = _mm256_mul_ps (v2 ,mul ); 436v3 = _mm256_mul_ps (v3 ,mul ); 437 438// Round to nearest integer 439v0 = _mm256_round_ps (v0 ,_MM_ROUND_NEAREST ); 440v1 = _mm256_round_ps (v1 ,_MM_ROUND_NEAREST ); 441v2 = _mm256_round_ps (v2 ,_MM_ROUND_NEAREST ); 442v3 = _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 452y [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 455i0 = _mm256_packs_epi32 (i0 ,i1 );// 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15 456i2 = _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 458i0 = _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 463const __m256i perm = _mm256_setr_epi32 (0 ,4 ,1 ,5 ,2 ,6 ,3 ,7 ); 464i0 = _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 480const __m128i s0 = _mm_add_epi32 (_mm_add_epi32 (ni0 ,ni1 ),_mm_add_epi32 (ni2 ,ni3 )); 481const __m128i s1 = _mm_add_epi32 (_mm_add_epi32 (ni4 ,ni5 ),_mm_add_epi32 (ni6 ,ni7 )); 482y [i ].s = GGML_CPU_FP32_TO_FP16 (d * hsum_i32_4 (_mm_add_epi32 (s0 ,s1 ))); 483 484// Convert int32 to int16 485ni0 = _mm_packs_epi32 (ni0 ,ni1 ); 486ni2 = _mm_packs_epi32 (ni2 ,ni3 ); 487ni4 = _mm_packs_epi32 (ni4 ,ni5 ); 488ni6 = _mm_packs_epi32 (ni6 ,ni7 ); 489// Convert int16 to int8 490ni0 = _mm_packs_epi16 (ni0 ,ni2 ); 491ni4 = _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 498GGML_UNUSED (nb ); 499// scalar 500quantize_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 ) { 506quantize_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 ) { 519static const uint8_t k_shuffle [128 ]= { 5200 ,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 , 5214 ,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 , 5228 ,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 , 52312 ,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 }; 525return _mm256_loadu_si256 ((const __m256i * )k_shuffle + i ); 526} 527static inline __m256i get_scale_shuffle_k4 (int i ) { 528static const uint8_t k_shuffle [256 ]= { 5290 ,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 , 5302 ,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 , 5314 ,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 , 5326 ,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 , 5338 ,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 , 53410 ,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 , 53512 ,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 , 53614 ,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 }; 538return _mm256_loadu_si256 ((const __m256i * )k_shuffle + i ); 539} 540static inline __m128i get_scale_shuffle (int i ) { 541static const uint8_t k_shuffle [128 ]= { 5420 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , 5432 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 , 5444 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 , 5456 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 , 5468 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 , 54710 ,10 ,10 ,10 ,10 ,10 ,10 ,10 ,11 ,11 ,11 ,11 ,11 ,11 ,11 ,11 , 54812 ,12 ,12 ,12 ,12 ,12 ,12 ,12 ,13 ,13 ,13 ,13 ,13 ,13 ,13 ,13 , 54914 ,14 ,14 ,14 ,14 ,14 ,14 ,14 ,15 ,15 ,15 ,15 ,15 ,15 ,15 ,15 550 }; 551return _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 ) { 556const int qk = QK1_0 ; 557const int nb = n /qk ; 558 559assert (n %qk == 0 ); 560assert (nrc == 1 ); 561UNUSED (nrc ); 562UNUSED (bx ); 563UNUSED (by ); 564UNUSED (bs ); 565 566const block_q1_0 * GGML_RESTRICT x = vx ; 567const block_q8_0 * GGML_RESTRICT y = vy ; 568 569#if defined(__AVX2__ ) 570const __m256i ones_8 = _mm256_set1_epi8 (1 ); 571const __m256i ones_16 = _mm256_set1_epi16 (1 ); 572const __m256i byte_shuf = _mm256_setr_epi8 ( 5730 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , 5742 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ); 575const __m256i bit_masks = _mm256_setr_epi8 ( 5761 ,2 ,4 ,8 ,16 ,32 ,64 , (char )-128 ,1 ,2 ,4 ,8 ,16 ,32 ,64 , (char )-128 , 5771 ,2 ,4 ,8 ,16 ,32 ,64 , (char )-128 ,1 ,2 ,4 ,8 ,16 ,32 ,64 , (char )-128 ); 578const __m256i zero = _mm256_setzero_si256 (); 579__m256 acc = _mm256_setzero_ps (); 580 581for (int ib = 0 ;ib < nb ;++ ib ) { 582const float d0 = GGML_CPU_FP16_TO_FP32 (x [ib ].d ); 583const uint32_t * GGML_RESTRICT qs32 = (const uint32_t * )x [ib ].qs ; 584const block_q8_0 * GGML_RESTRICT y_ptr = & y [ib * 4 ]; 585 586__m256 acc_block ; 587 { 588const __m256i qy = _mm256_loadu_si256 ((const __m256i * )y_ptr [0 ].qs ); 589const __m256i sm = _mm256_cmpeq_epi8 ( 590_mm256_and_si256 (_mm256_shuffle_epi8 (_mm256_set1_epi32 ((int )qs32 [0 ]),byte_shuf ),bit_masks ),zero ); 591const __m256i sy = _mm256_sub_epi8 (_mm256_xor_si256 (qy ,sm ),sm ); 592const __m256i s32 = _mm256_madd_epi16 (_mm256_maddubs_epi16 (ones_8 ,sy ),ones_16 ); 593acc_block = _mm256_mul_ps (_mm256_set1_ps (GGML_CPU_FP16_TO_FP32 (y_ptr [0 ].d )),_mm256_cvtepi32_ps (s32 )); 594 } 595for (int K = 1 ;K < 4 ;++ K ) { 596const __m256i qy = _mm256_loadu_si256 ((const __m256i * )y_ptr [K ].qs ); 597const __m256i sm = _mm256_cmpeq_epi8 ( 598_mm256_and_si256 (_mm256_shuffle_epi8 (_mm256_set1_epi32 ((int )qs32 [K ]),byte_shuf ),bit_masks ),zero ); 599const __m256i sy = _mm256_sub_epi8 (_mm256_xor_si256 (qy ,sm ),sm ); 600const __m256i s32 = _mm256_madd_epi16 (_mm256_maddubs_epi16 (ones_8 ,sy ),ones_16 ); 601acc_block = _mm256_fmadd_ps (_mm256_set1_ps (GGML_CPU_FP16_TO_FP32 (y_ptr [K ].d )),_mm256_cvtepi32_ps (s32 ),acc_block ); 602 } 603acc = _mm256_fmadd_ps (_mm256_set1_ps (d0 ),acc_block ,acc ); 604 } 605 606* s = hsum_float_8 (acc ); 607#elif defined(__AVX__ ) 608const __m128i ones_8 = _mm_set1_epi8 (1 ); 609const __m128i ones_16 = _mm_set1_epi16 (1 ); 610const __m128i zero = _mm_setzero_si128 (); 611__m256 acc = _mm256_setzero_ps (); 612 613for (int ib = 0 ;ib < nb ;++ ib ) { 614const float d0 = GGML_CPU_FP16_TO_FP32 (x [ib ].d ); 615const block_q8_0 * GGML_RESTRICT y_ptr = & y [ib * 4 ]; 616__m256 acc_block ; 617 { 618const __m256i bit_mask = bytes_from_bits_32 (& x [ib ].qs [0 ]); 619const __m128i bit_mask_0 = _mm256_castsi256_si128 (bit_mask ); 620const __m128i bit_mask_1 = _mm256_extractf128_si256 (bit_mask ,1 ); 621const __m128i qy_0 = _mm_loadu_si128 ((const __m128i * )& y_ptr [0 ].qs [0 ]); 622const __m128i qy_1 = _mm_loadu_si128 ((const __m128i * )& y_ptr [0 ].qs [16 ]); 623const __m128i sign_mask_0 = _mm_cmpeq_epi8 (bit_mask_0 ,zero ); 624const __m128i sign_mask_1 = _mm_cmpeq_epi8 (bit_mask_1 ,zero ); 625const __m128i sy_0 = _mm_sub_epi8 (_mm_xor_si128 (qy_0 ,sign_mask_0 ),sign_mask_0 ); 626const __m128i sy_1 = _mm_sub_epi8 (_mm_xor_si128 (qy_1 ,sign_mask_1 ),sign_mask_1 ); 627const __m128i sum16_0 = _mm_maddubs_epi16 (ones_8 ,sy_0 ); 628const __m128i sum16_1 = _mm_maddubs_epi16 (ones_8 ,sy_1 ); 629const __m128i sum32_0 = _mm_madd_epi16 (sum16_0 ,ones_16 ); 630const __m128i sum32_1 = _mm_madd_epi16 (sum16_1 ,ones_16 ); 631const __m256 q = _mm256_cvtepi32_ps (MM256_SET_M128I (sum32_1 ,sum32_0 )); 632acc_block = _mm256_mul_ps (_mm256_set1_ps (GGML_CPU_FP16_TO_FP32 (y_ptr [0 ].d )),q ); 633 } 634for (int K = 1 ;K < 4 ;++ K ) { 635const __m256i bit_mask = bytes_from_bits_32 (& x [ib ].qs [(K )* 4 ]); 636const __m128i bit_mask_0 = _mm256_castsi256_si128 (bit_mask ); 637const __m128i bit_mask_1 = _mm256_extractf128_si256 (bit_mask ,1 ); 638const __m128i qy_0 = _mm_loadu_si128 ((const __m128i * )& y_ptr [(K )].qs [0 ]); 639const __m128i qy_1 = _mm_loadu_si128 ((const __m128i * )& y_ptr [(K )].qs [16 ]); 640const __m128i sign_mask_0 = _mm_cmpeq_epi8 (bit_mask_0 ,zero ); 641const __m128i sign_mask_1 = _mm_cmpeq_epi8 (bit_mask_1 ,zero ); 642const __m128i sy_0 = _mm_sub_epi8 (_mm_xor_si128 (qy_0 ,sign_mask_0 ),sign_mask_0 ); 643const __m128i sy_1 = _mm_sub_epi8 (_mm_xor_si128 (qy_1 ,sign_mask_1 ),sign_mask_1 ); 644const __m128i sum16_0 = _mm_maddubs_epi16 (ones_8 ,sy_0 ); 645const __m128i sum16_1 = _mm_maddubs_epi16 (ones_8 ,sy_1 ); 646const __m128i sum32_0 = _mm_madd_epi16 (sum16_0 ,ones_16 ); 647const __m128i sum32_1 = _mm_madd_epi16 (sum16_1 ,ones_16 ); 648const __m256 q = _mm256_cvtepi32_ps (MM256_SET_M128I (sum32_1 ,sum32_0 )); 649acc_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 653acc = _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__ ) 658const __m128i ones_8 = _mm_set1_epi8 (1 ); 659const __m128i ones_16 = _mm_set1_epi16 (1 ); 660const __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 666for (int ib = 0 ;ib < nb ;++ ib ) { 667const __m128 d0 = _mm_set1_ps (GGML_CPU_FP16_TO_FP32 (x [ib ].d )); 668const 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 } 685Q1_SSSE3_BLOCK (0 ,0 ,acc_0 ) 686Q1_SSSE3_BLOCK (4 ,1 ,acc_1 ) 687Q1_SSSE3_BLOCK (8 ,2 ,acc_2 ) 688Q1_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 694UNUSED (nb ); 695UNUSED (x ); 696UNUSED (y ); 697ggml_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 ) { 702const int qk = QK8_0 ; 703const int nb = n /qk ; 704 705assert (n %qk == 0 ); 706assert (nrc == 1 ); 707UNUSED (nrc ); 708UNUSED (bx ); 709UNUSED (by ); 710UNUSED (bs ); 711 712const block_q4_0 * GGML_RESTRICT x = vx ; 713const block_q8_0 * GGML_RESTRICT y = vy ; 714 715int ib = 0 ; 716float sumf = 0 ; 717 718#if defined(__AVX2__ ) 719// Initialize accumulator with zeros 720__m256 acc = _mm256_setzero_ps (); 721 722// Main loop 723for (;ib < nb ;++ ib ) { 724/* Compute combined scale for the block */ 725const __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. 730const __m256i off = _mm256_set1_epi8 (8 ); 731qx = _mm256_sub_epi8 (qx ,off ); 732 733__m256i qy = _mm256_loadu_si256 ((const __m256i * )y [ib ].qs ); 734 735const __m256 q = mul_sum_i8_pairs_float (qx ,qy ); 736 737/* Multiply q with scale and accumulate */ 738acc = _mm256_fmadd_ps (d ,q ,acc ); 739 } 740 741sumf = hsum_float_8 (acc ); 742#elif defined(__AVX__ ) 743__m256 accum = _mm256_setzero_ps (); 744for (;ib + 1 < nb ;ib += 2 ) { 745const __m128i q4bits_1 = _mm_loadu_si128 ((const __m128i * )x [ib + 0 ].qs ); 746const __m128i q4bits_2 = _mm_loadu_si128 ((const __m128i * )x [ib + 1 ].qs ); 747const __m128i q8b_1_0 = _mm_loadu_si128 ((const __m128i * )y [ib + 0 ].qs ); 748const __m128i q8b_1_1 = _mm_loadu_si128 ((const __m128i * )y [ib + 0 ].qs + 1 ); 749const __m128i q8b_2_0 = _mm_loadu_si128 ((const __m128i * )y [ib + 1 ].qs ); 750const __m128i q8b_2_1 = _mm_loadu_si128 ((const __m128i * )y [ib + 1 ].qs + 1 ); 751 752const __m128i q4b_1_0 = _mm_sub_epi8 (_mm_and_si128 (_mm_set1_epi8 (15 ),q4bits_1 ),_mm_set1_epi8 (8 )); 753const __m128i q4b_1_1 = _mm_sub_epi8 (_mm_and_si128 (_mm_set1_epi8 (15 ),_mm_srli_epi16 (q4bits_1 ,4 )),_mm_set1_epi8 (8 )); 754const __m128i q4b_2_0 = _mm_sub_epi8 (_mm_and_si128 (_mm_set1_epi8 (15 ),q4bits_2 ),_mm_set1_epi8 (8 )); 755const __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 757const __m128i p16_1_0 = mul_add_epi8_sse (q4b_1_0 ,q8b_1_0 ); 758const __m128i p16_1_1 = mul_add_epi8_sse (q4b_1_1 ,q8b_1_1 ); 759const __m128i p16_2_0 = mul_add_epi8_sse (q4b_2_0 ,q8b_2_0 ); 760const __m128i p16_2_1 = mul_add_epi8_sse (q4b_2_1 ,q8b_2_1 ); 761const __m128i p_1 = _mm_add_epi16 (p16_1_0 ,p16_1_1 ); 762const __m128i p_2 = _mm_add_epi16 (p16_2_0 ,p16_2_1 ); 763const __m256 p = sum_i16_pairs_float (p_2 ,p_1 ); 764 765const __m256 deltas = quad_fp16_delta_float (x [ib ].d ,y [ib ].d ,x [ib + 1 ].d ,y [ib + 1 ].d ); 766accum = _mm256_add_ps (_mm256_mul_ps (deltas ,p ),accum ); 767 } 768 769sumf = hsum_float_8 (accum ); 770#elif defined(__SSSE3__ ) 771// set constants 772const __m128i lowMask = _mm_set1_epi8 (0xF ); 773const __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 781for (;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 786const __m128 d_0_1 = _mm_set1_ps (GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ) ); 787 788const __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 ); 792bx_0 = _mm_sub_epi8 (bx_0 ,off ); 793const __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 )); 797bx_1 = _mm_sub_epi8 (bx_1 ,off ); 798const __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 804const __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 806const __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 ); 810bx_2 = _mm_sub_epi8 (bx_2 ,off ); 811const __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 )); 815bx_3 = _mm_sub_epi8 (bx_3 ,off ); 816const __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 831acc_0 = _mm_add_ps (p0_d ,acc_0 ); 832acc_1 = _mm_add_ps (p1_d ,acc_1 ); 833acc_2 = _mm_add_ps (p2_d ,acc_2 ); 834acc_3 = _mm_add_ps (p3_d ,acc_3 ); 835 } 836 837sumf = hsum_float_4x4 (acc_0 ,acc_1 ,acc_2 ,acc_3 ); 838 839#endif 840for (;ib < nb ;++ ib ) { 841int sumi0 = 0 ; 842int sumi1 = 0 ; 843 844for (int j = 0 ;j < qk /2 ;++ j ) { 845const int v0 = (x [ib ].qs [j ]& 0x0F )- 8 ; 846const int v1 = (x [ib ].qs [j ] >>4 )- 8 ; 847 848sumi0 += (v0 * y [ib ].qs [j ]); 849sumi1 += (v1 * y [ib ].qs [j + qk /2 ]); 850 } 851 852int sumi = sumi0 + sumi1 ; 853sumf += 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 ) { 860const int qk = QK8_1 ; 861const int nb = n /qk ; 862 863assert (n %qk == 0 ); 864assert (nrc == 1 ); 865UNUSED (nrc ); 866UNUSED (bx ); 867UNUSED (by ); 868UNUSED (bs ); 869 870const block_q4_1 * GGML_RESTRICT x = vx ; 871const block_q8_1 * GGML_RESTRICT y = vy ; 872 873int ib = 0 ; 874 875#if defined(__AVX2__ )|| defined(__AVX__ ) 876// Initialize accumulator with zeros 877__m256 acc = _mm256_setzero_ps (); 878 879float summs = 0 ; 880 881// Main loop 882for (;ib < nb ;++ ib ) { 883const float d0 = GGML_CPU_FP16_TO_FP32 (x [ib ].d ); 884const float d1 = GGML_CPU_FP16_TO_FP32 (y [ib ].d ); 885 886summs += GGML_CPU_FP16_TO_FP32 (x [ib ].m )* GGML_CPU_FP16_TO_FP32 (y [ib ].s ); 887 888const __m256 d0v = _mm256_set1_ps (d0 ); 889const __m256 d1v = _mm256_set1_ps (d1 ); 890 891// Compute combined scales 892const __m256 d0d1 = _mm256_mul_ps (d0v ,d1v ); 893 894// Load 16 bytes, and unpack 4 bit fields into bytes, making 32 bytes 895const __m256i qx = bytes_from_nibbles_32 (x [ib ].qs ); 896const __m256i qy = _mm256_loadu_si256 ( (const __m256i * )y [ib ].qs ); 897 898const __m256 xy = mul_sum_us8_pairs_float (qx ,qy ); 899 900// Accumulate d0*d1*x*y 901#if defined(__AVX2__ ) 902acc = _mm256_fmadd_ps (d0d1 ,xy ,acc ); 903#else 904acc = _mm256_add_ps (_mm256_mul_ps (d0d1 ,xy ),acc ); 905#endif 906 } 907 908* s = hsum_float_8 (acc )+ summs ; 909#else 910UNUSED (nb ); 911UNUSED (x ); 912UNUSED (y ); 913UNUSED (ib ); 914ggml_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 ) { 919assert (nrc == 1 ); 920UNUSED (nrc ); 921UNUSED (bx ); 922UNUSED (by ); 923UNUSED (bs ); 924assert (n %QK_MXFP4 == 0 ); 925static_assert (QK_MXFP4 == QK8_0 ,"QK_MXFP4 and QK8_0 must be the same" ); 926 927const block_mxfp4 * GGML_RESTRICT x = vx ; 928const block_q8_0 * GGML_RESTRICT y = vy ; 929 930const int nb = n /QK_MXFP4 ; 931 932int ib = 0 ; 933float sumf = 0 ; 934 935#if defined__AVX2__ 936 937const __m128i values128 = _mm_loadu_si128 ((const __m128i * )kvalues_fp4 ); 938const __m128i m4b = _mm_set1_epi8 (0x0f ); 939const __m256i mone = _mm256_set1_epi16 (1 ); 940 941__m256 accum1 = _mm256_setzero_ps (); 942__m256 accum2 = _mm256_setzero_ps (); 943 944for (;ib + 1 < nb ;ib += 2 ) { 945const __m128i q4bits_1 = _mm_loadu_si128 ((const __m128i * )x [ib + 0 ].qs ); 946const __m128i q4bits_2 = _mm_loadu_si128 ((const __m128i * )x [ib + 1 ].qs ); 947const __m256i q8b_1 = _mm256_loadu_si256 ((const __m256i * )y [ib + 0 ].qs ); 948const __m256i q8b_2 = _mm256_loadu_si256 ((const __m256i * )y [ib + 1 ].qs ); 949const __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 ))); 951const __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 ))); 953const __m256i p16_1 = mul_add_epi8 (q4b_1 ,q8b_1 ); 954const __m256i p16_2 = mul_add_epi8 (q4b_2 ,q8b_2 ); 955const __m256i p_1 = _mm256_madd_epi16 (p16_1 ,mone ); 956const __m256i p_2 = _mm256_madd_epi16 (p16_2 ,mone ); 957const __m256 scale0 = _mm256_set1_ps (GGML_CPU_FP16_TO_FP32 (y [ib + 0 ].d )* GGML_CPU_E8M0_TO_FP32_HALF (x [ib + 0 ].e )); 958const __m256 scale1 = _mm256_set1_ps (GGML_CPU_FP16_TO_FP32 (y [ib + 1 ].d )* GGML_CPU_E8M0_TO_FP32_HALF (x [ib + 1 ].e )); 959accum1 = _mm256_fmadd_ps (scale0 ,_mm256_cvtepi32_ps (p_1 ),accum1 ); 960accum2 = _mm256_fmadd_ps (scale1 ,_mm256_cvtepi32_ps (p_2 ),accum2 ); 961 } 962 963sumf = hsum_float_8 (_mm256_add_ps (accum1 ,accum2 )); 964 965#elif defined__AVX__ 966const __m128i values128 = _mm_loadu_si128 ((const __m128i * )kvalues_fp4 ); 967const __m128i m4b = _mm_set1_epi8 (0x0f ); 968 969__m256 accum = _mm256_setzero_ps (); 970for (;ib + 1 < nb ;ib += 2 ) { 971const __m128i q4bits_1 = _mm_loadu_si128 ((const __m128i * )x [ib + 0 ].qs ); 972const __m128i q4bits_2 = _mm_loadu_si128 ((const __m128i * )x [ib + 1 ].qs ); 973const __m128i q8b_1_0 = _mm_loadu_si128 ((const __m128i * )y [ib + 0 ].qs ); 974const __m128i q8b_1_1 = _mm_loadu_si128 ((const __m128i * )y [ib + 0 ].qs + 1 ); 975const __m128i q8b_2_0 = _mm_loadu_si128 ((const __m128i * )y [ib + 1 ].qs ); 976const __m128i q8b_2_1 = _mm_loadu_si128 ((const __m128i * )y [ib + 1 ].qs + 1 ); 977 978const __m128i q4b_1_0 = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (q4bits_1 ,m4b )); 979const __m128i q4b_1_1 = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (_mm_srli_epi16 (q4bits_1 ,4 ),m4b )); 980const __m128i q4b_2_0 = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (q4bits_2 ,m4b )); 981const __m128i q4b_2_1 = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (_mm_srli_epi16 (q4bits_2 ,4 ),m4b )); 982 983const __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 ); 984const __m256 deltas = quad_mx_delta_float (x [ib ].e ,y [ib ].d ,x [ib + 1 ].e ,y [ib + 1 ].d ); 985accum = _mm256_add_ps (_mm256_mul_ps (deltas ,p ),accum ); 986 } 987 988sumf = hsum_float_8 (accum ); 989 990#endif 991for (;ib < nb ;++ ib ) { 992const float d = GGML_CPU_FP16_TO_FP32 (y [ib ].d )* GGML_CPU_E8M0_TO_FP32_HALF (x [ib ].e ); 993int sumi1 = 0 ; 994int sumi2 = 0 ; 995for (int j = 0 ;j < QK_MXFP4 /2 ;++ j ) { 996sumi1 += y [ib ].qs [j + 0 ]* kvalues_fp4 [x [ib ].qs [j ]& 0xf ]; 997sumi2 += y [ib ].qs [j + QK_MXFP4 /2 ]* kvalues_fp4 [x [ib ].qs [j ] >>4 ]; 998 } 999sumf += 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 ) { 1005assert (nrc == 1 ); 1006UNUSED (nrc ); 1007UNUSED (bx ); 1008UNUSED (by ); 1009UNUSED (bs ); 1010assert (n %QK_NVFP4 == 0 ); 1011 1012const block_nvfp4 * GGML_RESTRICT x = vx ; 1013const block_q8_0 * GGML_RESTRICT y = vy ; 1014 1015const int nb = n /QK_NVFP4 ; 1016int ib = 0 ; 1017float sumf = 0 ; 1018 1019#if defined(__AVX2__ ) 1020 1021const __m128i values128 = _mm_loadu_si128 ((const __m128i * )kvalues_fp4 ); 1022const __m128i m4b = _mm_set1_epi8 (0x0f ); 1023const __m256i mone = _mm256_set1_epi16 (1 ); 1024 1025__m256 accum = _mm256_setzero_ps (); 1026for (;ib < nb ;ib ++ ){ 1027 1028const __m128i q4bits_01 = _mm_loadu_si128 ((const __m128i * )(x [ib ].qs + 0 )); 1029const __m128i q4bits_23 = _mm_loadu_si128 ((const __m128i * )(x [ib ].qs + 16 )); 1030 1031const __m256i q8_01 = _mm256_loadu_si256 ((const __m256i * )y [2 * ib + 0 ].qs ); 1032const __m256i q8_23 = _mm256_loadu_si256 ((const __m256i * )y [2 * ib + 1 ].qs ); 1033 1034const __m128i q4_01_lo = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (q4bits_01 ,m4b )); 1035const __m128i q4_01_hi = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (_mm_srli_epi16 (q4bits_01 ,4 ),m4b )); 1036const __m128i q4_23_lo = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (q4bits_23 ,m4b )); 1037const __m128i q4_23_hi = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (_mm_srli_epi16 (q4bits_23 ,4 ),m4b )); 1038 1039//reordering 1040const __m256i q4_01 = MM256_SET_M128I (_mm_unpackhi_epi64 (q4_01_lo ,q4_01_hi ),_mm_unpacklo_epi64 (q4_01_lo ,q4_01_hi )); 1041const __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 1043const __m256i p01 = mul_add_epi8 (q4_01 ,q8_01 ); 1044const __m256i p_1 = _mm256_madd_epi16 (p01 ,mone ); 1045 1046const __m256i p23 = mul_add_epi8 (q4_23 ,q8_23 ); 1047const __m256i p_2 = _mm256_madd_epi16 (p23 ,mone ); 1048 1049const float dy0 = GGML_CPU_FP16_TO_FP32 (y [2 * ib ].d ); 1050const float dy1 = GGML_CPU_FP16_TO_FP32 (y [2 * ib + 1 ].d ); 1051 1052const float s0 = GGML_CPU_UE4M3_TO_FP32 (x [ib ].d [0 ])* dy0 ; 1053const float s1 = GGML_CPU_UE4M3_TO_FP32 (x [ib ].d [1 ])* dy0 ; 1054const float s2 = GGML_CPU_UE4M3_TO_FP32 (x [ib ].d [2 ])* dy1 ; 1055const float s3 = GGML_CPU_UE4M3_TO_FP32 (x [ib ].d [3 ])* dy1 ; 1056 1057const __m256 scales01 = _mm256_set_m128 (_mm_set1_ps (s1 ),_mm_set1_ps (s0 )); 1058const __m256 scales23 = _mm256_set_m128 (_mm_set1_ps (s3 ),_mm_set1_ps (s2 )); 1059 1060accum = _mm256_fmadd_ps (scales01 ,_mm256_cvtepi32_ps (p_1 ),accum ); 1061accum = _mm256_fmadd_ps (scales23 ,_mm256_cvtepi32_ps (p_2 ),accum ); 1062 } 1063sumf = hsum_float_8 (accum ); 1064 1065#elif defined(__AVX__ ) 1066 1067const __m128i values128 = _mm_loadu_si128 ((const __m128i * )kvalues_fp4 ); 1068const __m128i m4b = _mm_set1_epi8 (0x0f ); 1069 1070__m256 accum = _mm256_setzero_ps (); 1071for (;ib < nb ;ib ++ ){ 1072 1073const __m128i q4bits_01 = _mm_loadu_si128 ((const __m128i * )(x [ib ].qs + 0 )); 1074const __m128i q4bits_23 = _mm_loadu_si128 ((const __m128i * )(x [ib ].qs + 16 )); 1075 1076const __m128i q8_0 = _mm_loadu_si128 ((const __m128i * )(y [2 * ib + 0 ].qs + 0 )); 1077const __m128i q8_1 = _mm_loadu_si128 ((const __m128i * )(y [2 * ib + 0 ].qs + 16 )); 1078const __m128i q8_2 = _mm_loadu_si128 ((const __m128i * )(y [2 * ib + 1 ].qs + 0 )); 1079const __m128i q8_3 = _mm_loadu_si128 ((const __m128i * )(y [2 * ib + 1 ].qs + 16 )); 1080 1081const __m128i q4_01_lo = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (q4bits_01 ,m4b )); 1082const __m128i q4_01_hi = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (_mm_srli_epi16 (q4bits_01 ,4 ),m4b )); 1083const __m128i q4_23_lo = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (q4bits_23 ,m4b )); 1084const __m128i q4_23_hi = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (_mm_srli_epi16 (q4bits_23 ,4 ),m4b )); 1085 1086const __m128i q4_0 = _mm_unpacklo_epi64 (q4_01_lo ,q4_01_hi ); 1087const __m128i q4_1 = _mm_unpackhi_epi64 (q4_01_lo ,q4_01_hi ); 1088const __m128i q4_2 = _mm_unpacklo_epi64 (q4_23_lo ,q4_23_hi ); 1089const __m128i q4_3 = _mm_unpackhi_epi64 (q4_23_lo ,q4_23_hi ); 1090 1091const __m128i p0_i32 = mul_sum_i8_pairs (q4_0 ,q8_0 ); 1092const __m128i p1_i32 = mul_sum_i8_pairs (q4_1 ,q8_1 ); 1093const __m128i p2_i32 = mul_sum_i8_pairs (q4_2 ,q8_2 ); 1094const __m128i p3_i32 = mul_sum_i8_pairs (q4_3 ,q8_3 ); 1095 1096const __m128 p0 = _mm_cvtepi32_ps (p0_i32 ); 1097const __m128 p1 = _mm_cvtepi32_ps (p1_i32 ); 1098const __m128 p2 = _mm_cvtepi32_ps (p2_i32 ); 1099const __m128 p3 = _mm_cvtepi32_ps (p3_i32 ); 1100 1101const __m256 p01 = _mm256_set_m128 (p1 ,p0 ); 1102const __m256 p23 = _mm256_set_m128 (p3 ,p2 ); 1103 1104const float dy0 = GGML_CPU_FP16_TO_FP32 (y [2 * ib ].d ); 1105const float dy1 = GGML_CPU_FP16_TO_FP32 (y [2 * ib + 1 ].d ); 1106 1107const float s0 = GGML_CPU_UE4M3_TO_FP32 (x [ib ].d [0 ])* dy0 ; 1108const float s1 = GGML_CPU_UE4M3_TO_FP32 (x [ib ].d [1 ])* dy0 ; 1109const float s2 = GGML_CPU_UE4M3_TO_FP32 (x [ib ].d [2 ])* dy1 ; 1110const float s3 = GGML_CPU_UE4M3_TO_FP32 (x [ib ].d [3 ])* dy1 ; 1111 1112const __m256 scales01 = _mm256_set_m128 (_mm_set1_ps (s1 ),_mm_set1_ps (s0 )); 1113const __m256 scales23 = _mm256_set_m128 (_mm_set1_ps (s3 ),_mm_set1_ps (s2 )); 1114 1115accum = _mm256_add_ps (accum ,_mm256_mul_ps (p01 ,scales01 )); 1116accum = _mm256_add_ps (accum ,_mm256_mul_ps (p23 ,scales23 )); 1117 } 1118sumf = hsum_float_8 (accum ); 1119 1120#endif 1121 1122for (;ib < nb ;++ ib ) { 1123for (int s_idx = 0 ;s_idx < 4 ;++ s_idx ) { 1124const float d = GGML_CPU_UE4M3_TO_FP32 (x [ib ].d [s_idx ]); 1125const int q8_block = s_idx /2 ; 1126const int q8_off = (s_idx %2 )* QK_NVFP4_SUB ; 1127const float dy = GGML_CPU_FP16_TO_FP32 (y [2 * ib + q8_block ].d ); 1128 1129int sumi_lo = 0 ,sumi_hi = 0 ; 1130for (int j = 0 ;j < QK_NVFP4_SUB /2 ;++ j ) { 1131const uint8_t qv = x [ib ].qs [s_idx * (QK_NVFP4_SUB /2 )+ j ]; 1132sumi_lo += y [2 * ib + q8_block ].qs [q8_off + j + 0 ]* kvalues_fp4 [qv & 0xf ]; 1133sumi_hi += y [2 * ib + q8_block ].qs [q8_off + j + QK_NVFP4_SUB /2 ]* kvalues_fp4 [qv >>4 ]; 1134 } 1135 1136sumf += 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 ) { 1143const int qk = QK8_0 ; 1144const int nb = n /qk ; 1145 1146int ib = 0 ; 1147 1148assert (n %qk == 0 ); 1149assert (qk == QK5_0 ); 1150assert (nrc == 1 ); 1151UNUSED (nrc ); 1152UNUSED (bx ); 1153UNUSED (by ); 1154UNUSED (bs ); 1155 1156const block_q5_0 * GGML_RESTRICT x = vx ; 1157const 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 1164for (;ib < nb ;++ ib ) { 1165/* Compute combined scale for the block */ 1166const __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 ); 1170bxhi = _mm256_andnot_si256 (bxhi ,_mm256_set1_epi8 ((char )0xF0 )); 1171qx = _mm256_or_si256 (qx ,bxhi ); 1172 1173__m256i qy = _mm256_loadu_si256 ((const __m256i * )y [ib ].qs ); 1174 1175const __m256 q = mul_sum_i8_pairs_float (qx ,qy ); 1176 1177/* Multiply q with scale and accumulate */ 1178acc = _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 1188for (;ib < nb ;++ ib ) { 1189/* Compute combined scale for the block */ 1190const __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 ); 1193const __m256i bxhi = bytes_from_bits_32 (x [ib ].qh ); 1194__m128i bxhil = _mm256_castsi256_si128 (bxhi ); 1195__m128i bxhih = _mm256_extractf128_si256 (bxhi ,1 ); 1196bxhil = _mm_andnot_si128 (bxhil ,mask ); 1197bxhih = _mm_andnot_si128 (bxhih ,mask ); 1198__m128i bxl = _mm256_castsi256_si128 (bx_0 ); 1199__m128i bxh = _mm256_extractf128_si256 (bx_0 ,1 ); 1200bxl = _mm_or_si128 (bxl ,bxhil ); 1201bxh = _mm_or_si128 (bxh ,bxhih ); 1202bx_0 = MM256_SET_M128I (bxh ,bxl ); 1203 1204const __m256i by_0 = _mm256_loadu_si256 ((const __m256i * )y [ib ].qs ); 1205 1206const __m256 q = mul_sum_i8_pairs_float (bx_0 ,by_0 ); 1207 1208/* Multiply q with scale and accumulate */ 1209acc = _mm256_add_ps (_mm256_mul_ps (d ,q ),acc ); 1210 } 1211 1212* s = hsum_float_8 (acc ); 1213#else 1214UNUSED (nb ); 1215UNUSED (ib ); 1216UNUSED (x ); 1217UNUSED (y ); 1218ggml_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 ) { 1223const int qk = QK8_1 ; 1224const int nb = n /qk ; 1225 1226int ib = 0 ; 1227 1228assert (n %qk == 0 ); 1229assert (qk == QK5_1 ); 1230assert (nrc == 1 ); 1231UNUSED (nrc ); 1232UNUSED (bx ); 1233UNUSED (by ); 1234UNUSED (bs ); 1235 1236const block_q5_1 * GGML_RESTRICT x = vx ; 1237const block_q8_1 * GGML_RESTRICT y = vy ; 1238 1239#if defined(__AVX2__ ) 1240// Initialize accumulator with zeros 1241__m256 acc = _mm256_setzero_ps (); 1242 1243float summs = 0.0f ; 1244 1245// Main loop 1246for (;ib < nb ;++ ib ) { 1247const __m256 dx = _mm256_set1_ps (GGML_CPU_FP16_TO_FP32 (x [ib ].d )); 1248 1249summs += 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 ); 1253bxhi = _mm256_and_si256 (bxhi ,_mm256_set1_epi8 (0x10 )); 1254qx = _mm256_or_si256 (qx ,bxhi ); 1255 1256const __m256 dy = _mm256_set1_ps (GGML_CPU_FP16_TO_FP32 (y [ib ].d )); 1257const __m256i qy = _mm256_loadu_si256 ((const __m256i * )y [ib ].qs ); 1258 1259const __m256 q = mul_sum_us8_pairs_float (qx ,qy ); 1260 1261acc = _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 1270float summs = 0.0f ; 1271 1272// Main loop 1273for (;ib < nb ;++ ib ) { 1274const __m256 dx = _mm256_set1_ps (GGML_CPU_FP16_TO_FP32 (x [ib ].d )); 1275 1276summs += 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 ); 1279const __m256i bxhi = bytes_from_bits_32 (x [ib ].qh ); 1280__m128i bxhil = _mm256_castsi256_si128 (bxhi ); 1281__m128i bxhih = _mm256_extractf128_si256 (bxhi ,1 ); 1282bxhil = _mm_and_si128 (bxhil ,mask ); 1283bxhih = _mm_and_si128 (bxhih ,mask ); 1284__m128i bxl = _mm256_castsi256_si128 (bx_0 ); 1285__m128i bxh = _mm256_extractf128_si256 (bx_0 ,1 ); 1286bxl = _mm_or_si128 (bxl ,bxhil ); 1287bxh = _mm_or_si128 (bxh ,bxhih ); 1288bx_0 = MM256_SET_M128I (bxh ,bxl ); 1289 1290const __m256 dy = _mm256_set1_ps (GGML_CPU_FP16_TO_FP32 (y [ib ].d )); 1291const __m256i by_0 = _mm256_loadu_si256 ((const __m256i * )y [ib ].qs ); 1292 1293const __m256 q = mul_sum_us8_pairs_float (bx_0 ,by_0 ); 1294 1295acc = _mm256_add_ps (_mm256_mul_ps (q ,_mm256_mul_ps (dx ,dy )),acc ); 1296 } 1297 1298* s = hsum_float_8 (acc )+ summs ; 1299#else 1300UNUSED (nb ); 1301UNUSED (ib ); 1302UNUSED (x ); 1303UNUSED (y ); 1304ggml_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 ) { 1309const int qk = QK8_0 ; 1310const int nb = n /qk ; 1311 1312assert (n %qk == 0 ); 1313assert (nrc == 1 ); 1314UNUSED (nrc ); 1315UNUSED (bx ); 1316UNUSED (by ); 1317UNUSED (bs ); 1318 1319const block_q8_0 * GGML_RESTRICT x = vx ; 1320const block_q8_0 * GGML_RESTRICT y = vy ; 1321 1322int ib = 0 ; 1323float sumf = 0 ; 1324 1325#if defined(__AVX2__ ) 1326// Initialize accumulator with zeros 1327__m256 acc = _mm256_setzero_ps (); 1328 1329// Main loop 1330for (;ib < nb ;++ ib ) { 1331// Compute combined scale for the block 1332const __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 1336const __m256 q = mul_sum_i8_pairs_float (qx ,qy ); 1337 1338// Multiply q with scale and accumulate 1339acc = _mm256_fmadd_ps (d ,q ,acc ); 1340 } 1341 1342sumf = hsum_float_8 (acc ); 1343#elif defined(__AVX__ ) 1344__m256 accum = _mm256_setzero_ps (); 1345 1346for (;ib + 1 < nb ;ib += 2 ) { 1347const __m128i qx_1_0 = _mm_loadu_si128 ((const __m128i * )x [ib ].qs ); 1348const __m128i qx_1_1 = _mm_loadu_si128 ((const __m128i * )x [ib ].qs + 1 ); 1349const __m128i qx_2_0 = _mm_loadu_si128 ((const __m128i * )x [ib + 1 ].qs ); 1350const __m128i qx_2_1 = _mm_loadu_si128 ((const __m128i * )x [ib + 1 ].qs + 1 ); 1351const __m128i qy_1_0 = _mm_loadu_si128 ((const __m128i * )y [ib ].qs ); 1352const __m128i qy_1_1 = _mm_loadu_si128 ((const __m128i * )y [ib ].qs + 1 ); 1353const __m128i qy_2_0 = _mm_loadu_si128 ((const __m128i * )y [ib + 1 ].qs ); 1354const __m128i qy_2_1 = _mm_loadu_si128 ((const __m128i * )y [ib + 1 ].qs + 1 ); 1355 1356const __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 ); 1357const __m256 deltas = quad_fp16_delta_float (x [ib ].d ,y [ib ].d ,x [ib + 1 ].d ,y [ib + 1 ].d ); 1358accum = _mm256_add_ps (_mm256_mul_ps (deltas ,p ),accum ); 1359 } 1360 1361sumf = hsum_float_8 (accum ); 1362#endif 1363for (;ib < nb ;++ ib ) { 1364int sumi = 0 ; 1365 1366for (int j = 0 ;j < qk ;j ++ ) { 1367sumi += x [ib ].qs [j ]* y [ib ].qs [j ]; 1368 } 1369 1370sumf += 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 ) { 1377assert (nrc == 1 ); 1378UNUSED (nrc ); 1379UNUSED (bx ); 1380UNUSED (by ); 1381UNUSED (bs ); 1382 1383const block_tq1_0 * GGML_RESTRICT x = vx ; 1384const block_q8_K * GGML_RESTRICT y = vy ; 1385 1386const int nb = n /QK_K ; 1387 1388#if defined(__AVX2__ ) 1389__m256 sumf = _mm256_setzero_ps (); 1390 1391for (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 1409qx0 = _mm256_subs_epu8 (qx0 ,_mm256_set1_epi8 (1 )); 1410qx1 = _mm256_subs_epu8 (qx1 ,_mm256_set1_epi8 (1 )); 1411qx2 = _mm256_subs_epu8 (qx2 ,_mm256_set1_epi8 (1 )); 1412qx3 = _mm256_subs_epu8 (qx3 ,_mm256_set1_epi8 (1 )); 1413qx4 = _mm256_subs_epu8 (qx4 ,_mm256_set1_epi8 (1 )); 1414// Multiply by 3 and get the top 2 bits 1415qx0 = _mm256_avg_epu8 (qx0 ,_mm256_avg_epu8 (qx0 ,_mm256_setzero_si256 ())); 1416qx1 = _mm256_avg_epu8 (qx1 ,_mm256_avg_epu8 (qx1 ,_mm256_setzero_si256 ())); 1417qx2 = _mm256_avg_epu8 (qx2 ,_mm256_avg_epu8 (qx2 ,_mm256_setzero_si256 ())); 1418qx3 = _mm256_avg_epu8 (qx3 ,_mm256_avg_epu8 (qx3 ,_mm256_setzero_si256 ())); 1419qx4 = _mm256_avg_epu8 (qx4 ,_mm256_avg_epu8 (qx4 ,_mm256_setzero_si256 ())); 1420qx0 = _mm256_and_si256 (_mm256_srli_epi16 (qx0 ,6 ),_mm256_set1_epi8 (3 )); 1421qx1 = _mm256_and_si256 (_mm256_srli_epi16 (qx1 ,6 ),_mm256_set1_epi8 (3 )); 1422qx2 = _mm256_and_si256 (_mm256_srli_epi16 (qx2 ,6 ),_mm256_set1_epi8 (3 )); 1423qx3 = _mm256_and_si256 (_mm256_srli_epi16 (qx3 ,6 ),_mm256_set1_epi8 (3 )); 1424qx4 = _mm256_and_si256 (_mm256_srli_epi16 (qx4 ,6 ),_mm256_set1_epi8 (3 )); 1425 1426const __m256i qy0 = _mm256_loadu_si256 ((const __m256i * ) (y [i ].qs + 0 )); 1427const __m256i qy1 = _mm256_loadu_si256 ((const __m256i * ) (y [i ].qs + 32 )); 1428const __m256i qy2 = _mm256_loadu_si256 ((const __m256i * ) (y [i ].qs + 64 )); 1429const __m256i qy3 = _mm256_loadu_si256 ((const __m256i * ) (y [i ].qs + 96 )); 1430const __m256i qy4 = _mm256_loadu_si256 ((const __m256i * ) (y [i ].qs + 128 )); 1431 1432qx0 = _mm256_maddubs_epi16 (qx0 ,qy0 ); 1433qx1 = _mm256_maddubs_epi16 (qx1 ,qy1 ); 1434qx2 = _mm256_maddubs_epi16 (qx2 ,qy2 ); 1435qx3 = _mm256_maddubs_epi16 (qx3 ,qy3 ); 1436qx4 = _mm256_maddubs_epi16 (qx4 ,qy4 ); 1437 1438sumi0 = _mm256_add_epi16 (sumi0 ,_mm256_add_epi16 (qx0 ,qx1 )); 1439sumi1 = _mm256_add_epi16 (sumi1 ,_mm256_add_epi16 (qx2 ,qx3 )); 1440sumi2 = _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 )); 1446uint32_t qh ; 1447memcpy (& 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. 1457qx5_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 )); 1458qx5_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 1464qx01 = _mm256_subs_epu8 (qx01 ,_mm256_set1_epi8 (1 )); 1465qx23 = _mm256_subs_epu8 (qx23 ,_mm256_set1_epi8 (1 )); 1466qx45 = _mm256_subs_epu8 (qx45 ,_mm256_set1_epi8 (1 )); 1467// Multiply by 3 and get the top 2 bits 1468qx01 = _mm256_avg_epu8 (qx01 ,_mm256_avg_epu8 (qx01 ,_mm256_setzero_si256 ())); 1469qx23 = _mm256_avg_epu8 (qx23 ,_mm256_avg_epu8 (qx23 ,_mm256_setzero_si256 ())); 1470qx45 = _mm256_avg_epu8 (qx45 ,_mm256_avg_epu8 (qx45 ,_mm256_setzero_si256 ())); 1471qx01 = _mm256_and_si256 (_mm256_srli_epi16 (qx01 ,6 ),_mm256_set1_epi8 (3 )); 1472qx23 = _mm256_and_si256 (_mm256_srli_epi16 (qx23 ,6 ),_mm256_set1_epi8 (3 )); 1473qx45 = _mm256_and_si256 (_mm256_srli_epi16 (qx45 ,6 ),_mm256_set1_epi8 (3 )); 1474 1475const __m256i qy01 = _mm256_loadu_si256 ((const __m256i * ) (y [i ].qs + 160 )); 1476const __m256i qy23 = _mm256_loadu_si256 ((const __m256i * ) (y [i ].qs + 192 )); 1477const __m256i qy45 = _mm256_loadu_si256 ((const __m256i * ) (y [i ].qs + 224 )); 1478 1479qx01 = _mm256_maddubs_epi16 (qx01 ,qy01 ); 1480qx23 = _mm256_maddubs_epi16 (qx23 ,qy23 ); 1481qx45 = _mm256_maddubs_epi16 (qx45 ,qy45 ); 1482 1483sumi0 = _mm256_add_epi16 (sumi0 ,qx01 ); 1484sumi1 = _mm256_add_epi16 (sumi1 ,qx23 ); 1485sumi2 = _mm256_add_epi16 (sumi2 ,qx45 ); 1486 } 1487 1488const __m256i ysum = _mm256_loadu_si256 ((const __m256i * )y [i ].bsums ); 1489const __m256 d = _mm256_set1_ps (y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d )); 1490 1491sumi0 = _mm256_sub_epi16 (sumi0 ,ysum ); 1492sumi0 = _mm256_add_epi16 (sumi0 ,_mm256_add_epi16 (sumi1 ,sumi2 )); 1493sumi0 = _mm256_madd_epi16 (sumi0 ,_mm256_set1_epi16 (1 )); 1494 1495sumf = _mm256_add_ps (_mm256_mul_ps (_mm256_cvtepi32_ps (sumi0 ),d ),sumf ); 1496 } 1497 1498* s = hsum_float_8 (sumf ); 1499 1500#else 1501UNUSED (x ); 1502UNUSED (y ); 1503UNUSED (nb ); 1504ggml_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 ) { 1509assert (nrc == 1 ); 1510UNUSED (nrc ); 1511UNUSED (bx ); 1512UNUSED (by ); 1513UNUSED (bs ); 1514 1515const block_tq2_0 * GGML_RESTRICT x = vx ; 1516const block_q8_K * GGML_RESTRICT y = vy ; 1517 1518const int nb = n /QK_K ; 1519 1520#if defined(__AVX2__ ) 1521__m256 sumf = _mm256_setzero_ps (); 1522 1523for (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 1528for (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) 1535qx0 = _mm256_and_si256 (qx0 ,_mm256_set1_epi8 (3 )); 1536qx1 = _mm256_and_si256 (qx1 ,_mm256_set1_epi8 (3 )); 1537qx2 = _mm256_and_si256 (qx2 ,_mm256_set1_epi8 (3 )); 1538qx3 = _mm256_and_si256 (qx3 ,_mm256_set1_epi8 (3 )); 1539 1540const __m256i qy0 = _mm256_loadu_si256 ((const __m256i * ) (y [i ].qs + j * 4 + 0 )); 1541const __m256i qy1 = _mm256_loadu_si256 ((const __m256i * ) (y [i ].qs + j * 4 + 32 )); 1542const __m256i qy2 = _mm256_loadu_si256 ((const __m256i * ) (y [i ].qs + j * 4 + 64 )); 1543const __m256i qy3 = _mm256_loadu_si256 ((const __m256i * ) (y [i ].qs + j * 4 + 96 )); 1544 1545qx0 = _mm256_maddubs_epi16 (qx0 ,qy0 ); 1546qx1 = _mm256_maddubs_epi16 (qx1 ,qy1 ); 1547qx2 = _mm256_maddubs_epi16 (qx2 ,qy2 ); 1548qx3 = _mm256_maddubs_epi16 (qx3 ,qy3 ); 1549 1550sumi0 = _mm256_add_epi16 (sumi0 ,_mm256_add_epi16 (qx0 ,qx1 )); 1551sumi1 = _mm256_add_epi16 (sumi1 ,_mm256_add_epi16 (qx2 ,qx3 )); 1552 } 1553 1554const __m256i ysum = _mm256_loadu_si256 ((const __m256i * )y [i ].bsums ); 1555const __m256 d = _mm256_set1_ps (y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d )); 1556 1557sumi0 = _mm256_add_epi16 (sumi0 ,sumi1 ); 1558sumi0 = _mm256_sub_epi16 (sumi0 ,ysum ); 1559sumi0 = _mm256_madd_epi16 (sumi0 ,_mm256_set1_epi16 (1 )); 1560 1561sumf = _mm256_add_ps (_mm256_mul_ps (_mm256_cvtepi32_ps (sumi0 ),d ),sumf ); 1562 } 1563 1564* s = hsum_float_8 (sumf ); 1565 1566#else 1567UNUSED (x ); 1568UNUSED (y ); 1569UNUSED (nb ); 1570ggml_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 ) { 1575assert (nrc == 1 ); 1576UNUSED (nrc ); 1577UNUSED (bx ); 1578UNUSED (by ); 1579UNUSED (bs ); 1580 1581const block_q2_K * GGML_RESTRICT x = vx ; 1582const block_q8_K * GGML_RESTRICT y = vy ; 1583 1584const int nb = n /QK_K ; 1585 1586#if defined__AVX2__ 1587 1588const __m256i m3 = _mm256_set1_epi8 (3 ); 1589const __m128i m4 = _mm_set1_epi8 (0xF ); 1590 1591__m256 acc = _mm256_setzero_ps (); 1592 1593for (int i = 0 ;i < nb ;++ i ) { 1594 1595const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1596const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 1597 1598const uint8_t * GGML_RESTRICT q2 = x [i ].qs ; 1599const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1600 1601const __m128i mins_and_scales = _mm_loadu_si128 ((const __m128i * )x [i ].scales ); 1602const __m128i scales8 = _mm_and_si128 (mins_and_scales ,m4 ); 1603const __m128i mins8 = _mm_and_si128 (_mm_srli_epi16 (mins_and_scales ,4 ),m4 ); 1604const __m256i mins = _mm256_cvtepi8_epi16 (mins8 ); 1605const __m256i prod = _mm256_madd_epi16 (mins ,_mm256_loadu_si256 ((const __m256i * )y [i ].bsums )); 1606 1607acc = _mm256_fmadd_ps (_mm256_broadcast_ss (& dmin ),_mm256_cvtepi32_ps (prod ),acc ); 1608 1609const __m256i all_scales = _mm256_cvtepi8_epi16 (scales8 ); 1610const __m128i l_scales = _mm256_extracti128_si256 (all_scales ,0 ); 1611const __m128i h_scales = _mm256_extracti128_si256 (all_scales ,1 ); 1612const __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 1616for (int j = 0 ;j < QK_K /128 ;++ j ) { 1617 1618const __m256i q2bits = _mm256_loadu_si256 ((const __m256i * )q2 );q2 += 32 ; 1619 1620const __m256i q8_0 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 1621const __m256i q8_1 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 1622const __m256i q8_2 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 1623const __m256i q8_3 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 1624 1625const __m256i q2_0 = _mm256_and_si256 (q2bits ,m3 ); 1626const __m256i q2_1 = _mm256_and_si256 (_mm256_srli_epi16 (q2bits ,2 ),m3 ); 1627const __m256i q2_2 = _mm256_and_si256 (_mm256_srli_epi16 (q2bits ,4 ),m3 ); 1628const __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 1635p0 = _mm256_madd_epi16 (_mm256_shuffle_epi8 (scales [j ],get_scale_shuffle_q3k (0 )),p0 ); 1636p1 = _mm256_madd_epi16 (_mm256_shuffle_epi8 (scales [j ],get_scale_shuffle_q3k (1 )),p1 ); 1637p2 = _mm256_madd_epi16 (_mm256_shuffle_epi8 (scales [j ],get_scale_shuffle_q3k (2 )),p2 ); 1638p3 = _mm256_madd_epi16 (_mm256_shuffle_epi8 (scales [j ],get_scale_shuffle_q3k (3 )),p3 ); 1639 1640p0 = _mm256_add_epi32 (p0 ,p1 ); 1641p2 = _mm256_add_epi32 (p2 ,p3 ); 1642 1643sumi = _mm256_add_epi32 (sumi ,_mm256_add_epi32 (p0 ,p2 )); 1644 } 1645 1646acc = _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 1654const __m128i m3 = _mm_set1_epi8 (0x3 ); 1655const __m128i m4 = _mm_set1_epi8 (0xF ); 1656const __m128i m2 = _mm_set1_epi8 (0x2 ); 1657 1658__m256 acc = _mm256_setzero_ps (); 1659 1660for (int i = 0 ;i < nb ;++ i ) { 1661 1662const float dall = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1663const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 1664 1665const uint8_t * GGML_RESTRICT q2 = x [i ].qs ; 1666const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1667 1668// load mins and scales from block_q2_K.scales[QK_K/16] 1669const __m128i mins_and_scales = _mm_loadu_si128 ((const __m128i * )x [i ].scales ); 1670const __m128i scales16 = _mm_and_si128 (mins_and_scales ,m4 ); 1671const __m128i mins16 = _mm_and_si128 (_mm_srli_epi16 (mins_and_scales ,4 ),m4 ); 1672const __m128i mins_0 = _mm_cvtepi8_epi16 (mins16 ); 1673const __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 1676const __m128i summs_0 = _mm_madd_epi16 (mins_0 ,_mm_loadu_si128 ((const __m128i * )& y [i ].bsums [0 ])); 1677const __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 1680acc = _mm256_add_ps (_mm256_mul_ps (_mm256_broadcast_ss (& dmin ),_mm256_cvtepi32_ps (MM256_SET_M128I (summs_1 ,summs_0 ))),acc ); 1681 1682const __m128i scales_0 = _mm_cvtepi8_epi16 (scales16 ); 1683const __m128i scales_1 = _mm_cvtepi8_epi16 (_mm_unpackhi_epi64 (scales16 ,scales16 )); 1684const __m128i scales [2 ]= {scales_0 ,scales_1 }; 1685 1686__m128i sumi_0 = _mm_setzero_si128 (); 1687__m128i sumi_1 = _mm_setzero_si128 (); 1688 1689for (int j = 0 ;j < QK_K /128 ;++ j ) { 1690 1691// load Q8 quants int8*16*8 from block_q8_K.qs[QK_K] 1692const __m128i q8_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1693const __m128i q8_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1694const __m128i q8_2 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1695const __m128i q8_3 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1696const __m128i q8_4 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1697const __m128i q8_5 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1698const __m128i q8_6 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1699const __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 ; 1703const __m128i q2_0 = _mm_and_si128 (q2bits ,m3 ); 1704const __m128i q2_2 = _mm_and_si128 (_mm_srli_epi16 (q2bits ,2 ),m3 ); 1705const __m128i q2_4 = _mm_and_si128 (_mm_srli_epi16 (q2bits ,4 ),m3 ); 1706const __m128i q2_6 = _mm_and_si128 (_mm_srli_epi16 (q2bits ,6 ),m3 ); 1707q2bits = _mm_loadu_si128 ((const __m128i * )q2 );q2 += 16 ; 1708const __m128i q2_1 = _mm_and_si128 (q2bits ,m3 ); 1709const __m128i q2_3 = _mm_and_si128 (_mm_srli_epi16 (q2bits ,2 ),m3 ); 1710const __m128i q2_5 = _mm_and_si128 (_mm_srli_epi16 (q2bits ,4 ),m3 ); 1711const __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 ); 1725p0 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p0 ); 1726shuffle = _mm_add_epi16 (shuffle ,m2 ); 1727p1 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p1 ); 1728shuffle = _mm_add_epi16 (shuffle ,m2 ); 1729p2 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p2 ); 1730shuffle = _mm_add_epi16 (shuffle ,m2 ); 1731p3 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p3 ); 1732shuffle = _mm_add_epi16 (shuffle ,m2 ); 1733p4 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p4 ); 1734shuffle = _mm_add_epi16 (shuffle ,m2 ); 1735p5 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p5 ); 1736shuffle = _mm_add_epi16 (shuffle ,m2 ); 1737p6 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p6 ); 1738shuffle = _mm_add_epi16 (shuffle ,m2 ); 1739p7 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p7 ); 1740 1741p0 = _mm_add_epi32 (p0 ,p1 ); 1742p2 = _mm_add_epi32 (p2 ,p3 ); 1743p4 = _mm_add_epi32 (p4 ,p5 ); 1744p6 = _mm_add_epi32 (p6 ,p7 ); 1745 1746// isum in 32bits*4*2 1747sumi_0 = _mm_add_epi32 (sumi_0 ,_mm_add_epi32 (p0 ,p2 )); 1748sumi_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 ); 1753acc = _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 1759UNUSED (x ); 1760UNUSED (y ); 1761UNUSED (nb ); 1762ggml_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 ) { 1767assert (n %QK_K == 0 ); 1768assert (nrc == 1 ); 1769UNUSED (nrc ); 1770UNUSED (bx ); 1771UNUSED (by ); 1772UNUSED (bs ); 1773 1774const uint32_t kmask1 = 0x03030303 ; 1775const uint32_t kmask2 = 0x0f0f0f0f ; 1776 1777const block_q3_K * GGML_RESTRICT x = vx ; 1778const block_q8_K * GGML_RESTRICT y = vy ; 1779 1780const int nb = n /QK_K ; 1781 1782#if defined__AVX2__ 1783 1784const __m256i m3 = _mm256_set1_epi8 (3 ); 1785const __m256i mone = _mm256_set1_epi8 (1 ); 1786const __m128i m32 = _mm_set1_epi8 (32 ); 1787 1788__m256 acc = _mm256_setzero_ps (); 1789 1790uint32_t aux [3 ]; 1791 1792for (int i = 0 ;i < nb ;++ i ) { 1793 1794const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1795 1796const uint8_t * GGML_RESTRICT q3 = x [i ].qs ; 1797const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1798 1799// Set up scales 1800memcpy (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 )); 1806scales128 = _mm_sub_epi8 (scales128 ,m32 ); 1807const __m256i all_scales = _mm256_cvtepi8_epi16 (scales128 ); 1808const __m128i l_scales = _mm256_extracti128_si256 (all_scales ,0 ); 1809const __m128i h_scales = _mm256_extracti128_si256 (all_scales ,1 ); 1810const __m256i scales [2 ]= {MM256_SET_M128I (l_scales ,l_scales ),MM256_SET_M128I (h_scales ,h_scales )}; 1811 1812// high bit 1813const __m256i hbits = _mm256_loadu_si256 ((const __m256i * )x [i ].hmask ); 1814 1815// integer accumulator 1816__m256i sumi = _mm256_setzero_si256 (); 1817 1818int bit = 0 ; 1819int is = 0 ; 1820 1821for (int j = 0 ;j < QK_K /128 ;++ j ) { 1822// load low 2 bits 1823const __m256i q3bits = _mm256_loadu_si256 ((const __m256i * )q3 );q3 += 32 ; 1824 1825// prepare low and high bits 1826const __m256i q3l_0 = _mm256_and_si256 (q3bits ,m3 ); 1827const __m256i q3h_0 = _mm256_slli_epi16 (_mm256_srli_epi16 (_mm256_andnot_si256 (hbits ,_mm256_slli_epi16 (mone ,bit )),bit ),2 ); 1828++ bit ; 1829 1830const __m256i q3l_1 = _mm256_and_si256 (_mm256_srli_epi16 (q3bits ,2 ),m3 ); 1831const __m256i q3h_1 = _mm256_slli_epi16 (_mm256_srli_epi16 (_mm256_andnot_si256 (hbits ,_mm256_slli_epi16 (mone ,bit )),bit ),2 ); 1832++ bit ; 1833 1834const __m256i q3l_2 = _mm256_and_si256 (_mm256_srli_epi16 (q3bits ,4 ),m3 ); 1835const __m256i q3h_2 = _mm256_slli_epi16 (_mm256_srli_epi16 (_mm256_andnot_si256 (hbits ,_mm256_slli_epi16 (mone ,bit )),bit ),2 ); 1836++ bit ; 1837 1838const __m256i q3l_3 = _mm256_and_si256 (_mm256_srli_epi16 (q3bits ,6 ),m3 ); 1839const __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 1843const __m256i q8_0 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 1844const __m256i q8_1 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 1845const __m256i q8_2 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 1846const __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 1861p16_0 = _mm256_sub_epi16 (p16_0 ,q8s_0 ); 1862p16_1 = _mm256_sub_epi16 (p16_1 ,q8s_1 ); 1863p16_2 = _mm256_sub_epi16 (p16_2 ,q8s_2 ); 1864p16_3 = _mm256_sub_epi16 (p16_3 ,q8s_3 ); 1865 1866// multiply with scales 1867p16_0 = _mm256_madd_epi16 (_mm256_shuffle_epi8 (scales [j ],get_scale_shuffle_q3k (is + 0 )),p16_0 ); 1868p16_1 = _mm256_madd_epi16 (_mm256_shuffle_epi8 (scales [j ],get_scale_shuffle_q3k (is + 1 )),p16_1 ); 1869p16_2 = _mm256_madd_epi16 (_mm256_shuffle_epi8 (scales [j ],get_scale_shuffle_q3k (is + 2 )),p16_2 ); 1870p16_3 = _mm256_madd_epi16 (_mm256_shuffle_epi8 (scales [j ],get_scale_shuffle_q3k (is + 3 )),p16_3 ); 1871 1872// accumulate 1873p16_0 = _mm256_add_epi32 (p16_0 ,p16_1 ); 1874p16_2 = _mm256_add_epi32 (p16_2 ,p16_3 ); 1875sumi = _mm256_add_epi32 (sumi ,_mm256_add_epi32 (p16_0 ,p16_2 )); 1876 1877 } 1878 1879// multiply with block scale and accumulate 1880acc = _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 1888const __m128i m3 = _mm_set1_epi8 (3 ); 1889const __m128i mone = _mm_set1_epi8 (1 ); 1890const __m128i m32 = _mm_set1_epi8 (32 ); 1891const __m128i m2 = _mm_set1_epi8 (2 ); 1892 1893__m256 acc = _mm256_setzero_ps (); 1894 1895const uint32_t * aux ; 1896 1897for (int i = 0 ;i < nb ;++ i ) { 1898 1899const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1900 1901const uint8_t * GGML_RESTRICT q3 = x [i ].qs ; 1902const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1903 1904// Set up scales 1905aux = (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 )); 1911scales128 = _mm_sub_epi8 (scales128 ,m32 ); 1912const __m128i scales_0 = _mm_cvtepi8_epi16 (scales128 ); 1913const __m128i scales_1 = _mm_cvtepi8_epi16 (_mm_unpackhi_epi64 (scales128 ,scales128 )); 1914const __m128i scales [2 ]= {scales_0 ,scales_1 }; 1915 1916// high bit *128*2 from block_q3_K.hmask[QK_K/8] 1917const __m128i hbits_0 = _mm_loadu_si128 ((const __m128i * )& x [i ].hmask [0 ]); 1918const __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 1924for (int j = 0 ;j < QK_K /128 ;++ j ) { 1925// load low 2 bits *64*2 from block_q3_K.qs[QK_K/4] 1926const __m128i q3bits_0 = _mm_loadu_si128 ((const __m128i * )q3 );q3 += 16 ; 1927const __m128i q3bits_1 = _mm_loadu_si128 ((const __m128i * )q3 );q3 += 16 ; 1928 1929// prepare low and high bits 1930const int bit = j <<2 ; 1931 1932const __m128i q3l_0 = _mm_and_si128 (q3bits_0 ,m3 ); 1933const __m128i q3l_1 = _mm_and_si128 (q3bits_1 ,m3 ); 1934const __m128i q3h_0 = _mm_slli_epi16 (_mm_srli_epi16 (_mm_andnot_si128 (hbits_0 ,_mm_slli_epi16 (mone ,bit )),bit ),2 ); 1935const __m128i q3h_1 = _mm_slli_epi16 (_mm_srli_epi16 (_mm_andnot_si128 (hbits_1 ,_mm_slli_epi16 (mone ,bit )),bit ),2 ); 1936 1937const __m128i q3l_2 = _mm_and_si128 (_mm_srli_epi16 (q3bits_0 ,2 ),m3 ); 1938const __m128i q3l_3 = _mm_and_si128 (_mm_srli_epi16 (q3bits_1 ,2 ),m3 ); 1939const __m128i q3h_2 = _mm_slli_epi16 (_mm_srli_epi16 (_mm_andnot_si128 (hbits_0 ,_mm_slli_epi16 (mone ,bit + 1 )),bit + 1 ),2 ); 1940const __m128i q3h_3 = _mm_slli_epi16 (_mm_srli_epi16 (_mm_andnot_si128 (hbits_1 ,_mm_slli_epi16 (mone ,bit + 1 )),bit + 1 ),2 ); 1941 1942const __m128i q3l_4 = _mm_and_si128 (_mm_srli_epi16 (q3bits_0 ,4 ),m3 ); 1943const __m128i q3l_5 = _mm_and_si128 (_mm_srli_epi16 (q3bits_1 ,4 ),m3 ); 1944const __m128i q3h_4 = _mm_slli_epi16 (_mm_srli_epi16 (_mm_andnot_si128 (hbits_0 ,_mm_slli_epi16 (mone ,bit + 2 )),bit + 2 ),2 ); 1945const __m128i q3h_5 = _mm_slli_epi16 (_mm_srli_epi16 (_mm_andnot_si128 (hbits_1 ,_mm_slli_epi16 (mone ,bit + 2 )),bit + 2 ),2 ); 1946 1947const __m128i q3l_6 = _mm_and_si128 (_mm_srli_epi16 (q3bits_0 ,6 ),m3 ); 1948const __m128i q3l_7 = _mm_and_si128 (_mm_srli_epi16 (q3bits_1 ,6 ),m3 ); 1949const __m128i q3h_6 = _mm_slli_epi16 (_mm_srli_epi16 (_mm_andnot_si128 (hbits_0 ,_mm_slli_epi16 (mone ,bit + 3 )),bit + 3 ),2 ); 1950const __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] 1953const __m128i q8_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1954const __m128i q8_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1955const __m128i q8_2 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1956const __m128i q8_3 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1957const __m128i q8_4 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1958const __m128i q8_5 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1959const __m128i q8_6 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 1960const __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 1983p16_0 = _mm_sub_epi16 (p16_0 ,q8s_0 ); 1984p16_1 = _mm_sub_epi16 (p16_1 ,q8s_1 ); 1985p16_2 = _mm_sub_epi16 (p16_2 ,q8s_2 ); 1986p16_3 = _mm_sub_epi16 (p16_3 ,q8s_3 ); 1987p16_4 = _mm_sub_epi16 (p16_4 ,q8s_4 ); 1988p16_5 = _mm_sub_epi16 (p16_5 ,q8s_5 ); 1989p16_6 = _mm_sub_epi16 (p16_6 ,q8s_6 ); 1990p16_7 = _mm_sub_epi16 (p16_7 ,q8s_7 ); 1991 1992// multiply with scales 1993__m128i shuffle = _mm_set1_epi16 (0x0100 ); 1994p16_0 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p16_0 ); 1995shuffle = _mm_add_epi16 (shuffle ,m2 ); 1996p16_1 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p16_1 ); 1997shuffle = _mm_add_epi16 (shuffle ,m2 ); 1998p16_2 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p16_2 ); 1999shuffle = _mm_add_epi16 (shuffle ,m2 ); 2000p16_3 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p16_3 ); 2001shuffle = _mm_add_epi16 (shuffle ,m2 ); 2002p16_4 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p16_4 ); 2003shuffle = _mm_add_epi16 (shuffle ,m2 ); 2004p16_5 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p16_5 ); 2005shuffle = _mm_add_epi16 (shuffle ,m2 ); 2006p16_6 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p16_6 ); 2007shuffle = _mm_add_epi16 (shuffle ,m2 ); 2008p16_7 = _mm_madd_epi16 (_mm_shuffle_epi8 (scales [j ],shuffle ),p16_7 ); 2009 2010// accumulate 2011p16_0 = _mm_add_epi32 (p16_0 ,p16_1 ); 2012p16_2 = _mm_add_epi32 (p16_2 ,p16_3 ); 2013p16_4 = _mm_add_epi32 (p16_4 ,p16_5 ); 2014p16_6 = _mm_add_epi32 (p16_6 ,p16_7 ); 2015sumi_0 = _mm_add_epi32 (sumi_0 ,_mm_add_epi32 (p16_0 ,p16_2 )); 2016sumi_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 ); 2022acc = _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 2029UNUSED (kmask1 ); 2030UNUSED (kmask2 ); 2031UNUSED (x ); 2032UNUSED (y ); 2033UNUSED (nb ); 2034ggml_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 ) { 2039assert (n %QK_K == 0 ); 2040assert (nrc == 1 ); 2041UNUSED (nrc ); 2042UNUSED (bx ); 2043UNUSED (by ); 2044UNUSED (bs ); 2045 2046const block_q4_K * GGML_RESTRICT x = vx ; 2047const block_q8_K * GGML_RESTRICT y = vy ; 2048 2049const int nb = n /QK_K ; 2050 2051static const uint32_t kmask1 = 0x3f3f3f3f ; 2052static const uint32_t kmask2 = 0x0f0f0f0f ; 2053static const uint32_t kmask3 = 0x03030303 ; 2054 2055uint32_t utmp [4 ]; 2056 2057#if defined__AVX2__ 2058 2059const __m256i m4 = _mm256_set1_epi8 (0xF ); 2060 2061__m256 acc = _mm256_setzero_ps (); 2062__m128 acc_m = _mm_setzero_ps (); 2063 2064for (int i = 0 ;i < nb ;++ i ) { 2065 2066const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 2067const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 2068 2069memcpy (utmp ,x [i ].scales ,12 ); 2070utmp [3 ]= ((utmp [2 ] >>4 )& kmask2 ) | (((utmp [1 ] >>6 )& kmask3 ) <<4 ); 2071const uint32_t uaux = utmp [1 ]& kmask1 ; 2072utmp [1 ]= (utmp [2 ]& kmask2 ) | (((utmp [0 ] >>6 )& kmask3 ) <<4 ); 2073utmp [2 ]= uaux ; 2074utmp [0 ] &=kmask1 ; 2075 2076const uint8_t * GGML_RESTRICT q4 = x [i ].qs ; 2077const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2078 2079const __m256i mins_and_scales = _mm256_cvtepu8_epi16 (_mm_set_epi32 (utmp [3 ],utmp [2 ],utmp [1 ],utmp [0 ])); 2080 2081const __m256i q8sums = _mm256_loadu_si256 ((const __m256i * )y [i ].bsums ); 2082const __m128i q8s = _mm_hadd_epi16 (_mm256_extracti128_si256 (q8sums ,0 ),_mm256_extracti128_si256 (q8sums ,1 )); 2083const __m128i prod = _mm_madd_epi16 (_mm256_extracti128_si256 (mins_and_scales ,1 ),q8s ); 2084acc_m = _mm_fmadd_ps (_mm_set1_ps (dmin ),_mm_cvtepi32_ps (prod ),acc_m ); 2085 2086const __m128i sc128 = _mm256_extracti128_si256 (mins_and_scales ,0 ); 2087const __m256i scales = MM256_SET_M128I (sc128 ,sc128 ); 2088 2089__m256i sumi = _mm256_setzero_si256 (); 2090 2091for (int j = 0 ;j < QK_K /64 ;++ j ) { 2092 2093const __m256i scale_l = _mm256_shuffle_epi8 (scales ,get_scale_shuffle_k4 (2 * j + 0 )); 2094const __m256i scale_h = _mm256_shuffle_epi8 (scales ,get_scale_shuffle_k4 (2 * j + 1 )); 2095 2096const __m256i q4bits = _mm256_loadu_si256 ((const __m256i * )q4 );q4 += 32 ; 2097const __m256i q4l = _mm256_and_si256 (q4bits ,m4 ); 2098const __m256i q4h = _mm256_and_si256 (_mm256_srli_epi16 (q4bits ,4 ),m4 ); 2099 2100const __m256i q8l = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 2101__m256i p16l = _mm256_maddubs_epi16 (q4l ,q8l ); 2102p16l = _mm256_madd_epi16 (scale_l ,p16l ); 2103 2104const __m256i q8h = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 2105__m256i p16h = _mm256_maddubs_epi16 (q4h ,q8h ); 2106p16h = _mm256_madd_epi16 (scale_h ,p16h ); 2107const __m256i sumj = _mm256_add_epi32 (p16l ,p16h ); 2108 2109sumi = _mm256_add_epi32 (sumi ,sumj ); 2110 } 2111 2112__m256 vd = _mm256_set1_ps (d ); 2113acc = _mm256_fmadd_ps (vd ,_mm256_cvtepi32_ps (sumi ),acc ); 2114 2115 } 2116 2117acc_m = _mm_add_ps (acc_m ,_mm_movehl_ps (acc_m ,acc_m )); 2118acc_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 2124const __m128i m4 = _mm_set1_epi8 (0xF ); 2125const __m128i m2 = _mm_set1_epi8 (0x2 ); 2126 2127__m256 acc = _mm256_setzero_ps (); 2128__m128 acc_m = _mm_setzero_ps (); 2129 2130for (int i = 0 ;i < nb ;++ i ) { 2131 2132const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 2133const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 2134 2135const uint8_t * GGML_RESTRICT q4 = x [i ].qs ; 2136const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2137 2138memcpy (utmp ,x [i ].scales ,12 ); 2139utmp [3 ]= ((utmp [2 ] >>4 )& kmask2 ) | (((utmp [1 ] >>6 )& kmask3 ) <<4 ); 2140const uint32_t uaux = utmp [1 ]& kmask1 ; 2141utmp [1 ]= (utmp [2 ]& kmask2 ) | (((utmp [0 ] >>6 )& kmask3 ) <<4 ); 2142utmp [2 ]= uaux ; 2143utmp [0 ] &=kmask1 ; 2144 2145const __m128i utmps = _mm_set_epi32 (utmp [3 ],utmp [2 ],utmp [1 ],utmp [0 ]); 2146const __m128i scales = _mm_cvtepu8_epi16 (utmps ); 2147const __m128i mins = _mm_cvtepu8_epi16 (_mm_unpackhi_epi64 (utmps ,utmps )); 2148 2149const __m128i q8sums_0 = _mm_loadu_si128 ((const __m128i * )& y [i ].bsums [0 ]); 2150const __m128i q8sums_1 = _mm_loadu_si128 ((const __m128i * )& y [i ].bsums [8 ]); 2151const __m128i q8s = _mm_hadd_epi16 (q8sums_0 ,q8sums_1 ); 2152const __m128i prod = _mm_madd_epi16 (mins ,q8s ); 2153acc_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 ); 2159for (int j = 0 ;j < QK_K /64 ;++ j ) { 2160 2161const __m128i scale_l = _mm_shuffle_epi8 (scales ,shuffle ); 2162shuffle = _mm_add_epi16 (shuffle ,m2 ); 2163const __m128i scale_h = _mm_shuffle_epi8 (scales ,shuffle ); 2164shuffle = _mm_add_epi16 (shuffle ,m2 ); 2165 2166__m128i q4bits = _mm_loadu_si128 ((const __m128i * )q4 );q4 += 16 ; 2167const __m128i q4l_0 = _mm_and_si128 (q4bits ,m4 ); 2168const __m128i q4h_0 = _mm_and_si128 (_mm_srli_epi16 (q4bits ,4 ),m4 ); 2169q4bits = _mm_loadu_si128 ((const __m128i * )q4 );q4 += 16 ; 2170const __m128i q4l_1 = _mm_and_si128 (q4bits ,m4 ); 2171const __m128i q4h_1 = _mm_and_si128 (_mm_srli_epi16 (q4bits ,4 ),m4 ); 2172 2173const __m128i q8l_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2174__m128i p16l = _mm_maddubs_epi16 (q4l_0 ,q8l_0 ); 2175p16l = _mm_madd_epi16 (scale_l ,p16l ); 2176sumi_0 = _mm_add_epi32 (sumi_0 ,p16l ); 2177const __m128i q8l_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2178p16l = _mm_maddubs_epi16 (q4l_1 ,q8l_1 ); 2179p16l = _mm_madd_epi16 (scale_l ,p16l ); 2180sumi_1 = _mm_add_epi32 (sumi_1 ,p16l ); 2181 2182const __m128i q8h_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2183__m128i p16h = _mm_maddubs_epi16 (q4h_0 ,q8h_0 ); 2184p16h = _mm_madd_epi16 (scale_h ,p16h ); 2185sumi_0 = _mm_add_epi32 (sumi_0 ,p16h ); 2186const __m128i q8h_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2187p16h = _mm_maddubs_epi16 (q4h_1 ,q8h_1 ); 2188p16h = _mm_madd_epi16 (scale_h ,p16h ); 2189sumi_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 ); 2195acc = _mm256_add_ps (_mm256_mul_ps (vd ,_mm256_cvtepi32_ps (sumi )),acc ); 2196 2197 } 2198 2199acc_m = _mm_add_ps (acc_m ,_mm_movehl_ps (acc_m ,acc_m )); 2200acc_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 2205UNUSED (x ); 2206UNUSED (y ); 2207UNUSED (nb ); 2208UNUSED (kmask1 ); 2209UNUSED (kmask2 ); 2210UNUSED (kmask3 ); 2211UNUSED (utmp ); 2212ggml_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 ) { 2217assert (n %QK_K == 0 ); 2218assert (nrc == 1 ); 2219UNUSED (nrc ); 2220UNUSED (bx ); 2221UNUSED (by ); 2222UNUSED (bs ); 2223 2224const block_q5_K * GGML_RESTRICT x = vx ; 2225const block_q8_K * GGML_RESTRICT y = vy ; 2226 2227const int nb = n /QK_K ; 2228 2229static const uint32_t kmask1 = 0x3f3f3f3f ; 2230static const uint32_t kmask2 = 0x0f0f0f0f ; 2231static const uint32_t kmask3 = 0x03030303 ; 2232 2233uint32_t utmp [4 ]; 2234 2235#if defined__AVX2__ 2236 2237const __m256i m4 = _mm256_set1_epi8 (0xF ); 2238const __m128i mzero = _mm_setzero_si128 (); 2239const __m256i mone = _mm256_set1_epi8 (1 ); 2240 2241__m256 acc = _mm256_setzero_ps (); 2242 2243float summs = 0.f ; 2244 2245for (int i = 0 ;i < nb ;++ i ) { 2246const uint8_t * GGML_RESTRICT q5 = x [i ].qs ; 2247const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2248 2249const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 2250const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 2251 2252memcpy (utmp ,x [i ].scales ,12 ); 2253utmp [3 ]= ((utmp [2 ] >>4 )& kmask2 ) | (((utmp [1 ] >>6 )& kmask3 ) <<4 ); 2254const uint32_t uaux = utmp [1 ]& kmask1 ; 2255utmp [1 ]= (utmp [2 ]& kmask2 ) | (((utmp [0 ] >>6 )& kmask3 ) <<4 ); 2256utmp [2 ]= uaux ; 2257utmp [0 ] &=kmask1 ; 2258 2259const __m256i mins_and_scales = _mm256_cvtepu8_epi16 (_mm_set_epi32 (utmp [3 ],utmp [2 ],utmp [1 ],utmp [0 ])); 2260 2261const __m256i q8sums = _mm256_loadu_si256 ((const __m256i * )y [i ].bsums ); 2262const __m128i q8s = _mm_hadd_epi16 (_mm256_extracti128_si256 (q8sums ,0 ),_mm256_extracti128_si256 (q8sums ,1 )); 2263const __m128i prod = _mm_madd_epi16 (_mm256_extracti128_si256 (mins_and_scales ,1 ),q8s ); 2264const __m128i hsum = _mm_hadd_epi32 (_mm_hadd_epi32 (prod ,mzero ),mzero ); 2265summs += dmin * _mm_extract_epi32 (hsum ,0 ); 2266 2267const __m128i sc128 = _mm256_extracti128_si256 (mins_and_scales ,0 ); 2268const __m256i scales = MM256_SET_M128I (sc128 ,sc128 ); 2269 2270const __m256i hbits = _mm256_loadu_si256 ((const __m256i * )x [i ].qh ); 2271__m256i hmask = mone ; 2272 2273__m256i sumi = _mm256_setzero_si256 (); 2274 2275int bit = 0 ; 2276 2277for (int j = 0 ;j < QK_K /64 ;++ j ) { 2278 2279const __m256i scale_0 = _mm256_shuffle_epi8 (scales ,get_scale_shuffle_k4 (2 * j + 0 )); 2280const __m256i scale_1 = _mm256_shuffle_epi8 (scales ,get_scale_shuffle_k4 (2 * j + 1 )); 2281 2282const __m256i q5bits = _mm256_loadu_si256 ((const __m256i * )q5 );q5 += 32 ; 2283 2284const __m256i q5l_0 = _mm256_and_si256 (q5bits ,m4 ); 2285const __m256i q5h_0 = _mm256_slli_epi16 (_mm256_srli_epi16 (_mm256_and_si256 (hbits ,hmask ),bit ++ ),4 ); 2286const __m256i q5_0 = _mm256_add_epi8 (q5l_0 ,q5h_0 ); 2287hmask = _mm256_slli_epi16 (hmask ,1 ); 2288 2289const __m256i q5l_1 = _mm256_and_si256 (_mm256_srli_epi16 (q5bits ,4 ),m4 ); 2290const __m256i q5h_1 = _mm256_slli_epi16 (_mm256_srli_epi16 (_mm256_and_si256 (hbits ,hmask ),bit ++ ),4 ); 2291const __m256i q5_1 = _mm256_add_epi8 (q5l_1 ,q5h_1 ); 2292hmask = _mm256_slli_epi16 (hmask ,1 ); 2293 2294const __m256i q8_0 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 2295const __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 2300p16_0 = _mm256_madd_epi16 (scale_0 ,p16_0 ); 2301p16_1 = _mm256_madd_epi16 (scale_1 ,p16_1 ); 2302 2303sumi = _mm256_add_epi32 (sumi ,_mm256_add_epi32 (p16_0 ,p16_1 )); 2304 2305 } 2306 2307__m256 vd = _mm256_set1_ps (d ); 2308acc = _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 2316const __m128i m4 = _mm_set1_epi8 (0xF ); 2317const __m128i mzero = _mm_setzero_si128 (); 2318const __m128i mone = _mm_set1_epi8 (1 ); 2319const __m128i m2 = _mm_set1_epi8 (2 ); 2320 2321__m256 acc = _mm256_setzero_ps (); 2322 2323float summs = 0.f ; 2324 2325for (int i = 0 ;i < nb ;++ i ) { 2326 2327const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 2328const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 2329 2330const uint8_t * GGML_RESTRICT q5 = x [i ].qs ; 2331const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2332 2333memcpy (utmp ,x [i ].scales ,12 ); 2334utmp [3 ]= ((utmp [2 ] >>4 )& kmask2 ) | (((utmp [1 ] >>6 )& kmask3 ) <<4 ); 2335const uint32_t uaux = utmp [1 ]& kmask1 ; 2336utmp [1 ]= (utmp [2 ]& kmask2 ) | (((utmp [0 ] >>6 )& kmask3 ) <<4 ); 2337utmp [2 ]= uaux ; 2338utmp [0 ] &=kmask1 ; 2339 2340const __m128i utmps = _mm_set_epi32 (utmp [3 ],utmp [2 ],utmp [1 ],utmp [0 ]); 2341const __m128i scales = _mm_cvtepu8_epi16 (utmps ); 2342const __m128i mins = _mm_cvtepu8_epi16 (_mm_unpackhi_epi64 (utmps ,utmps )); 2343 2344const __m128i q8sums_0 = _mm_loadu_si128 ((const __m128i * )& y [i ].bsums [0 ]); 2345const __m128i q8sums_1 = _mm_loadu_si128 ((const __m128i * )& y [i ].bsums [8 ]); 2346const __m128i q8s = _mm_hadd_epi16 (q8sums_0 ,q8sums_1 ); 2347const __m128i prod = _mm_madd_epi16 (mins ,q8s ); 2348const __m128i hsum = _mm_hadd_epi32 (_mm_hadd_epi32 (prod ,mzero ),mzero ); 2349summs += dmin * _mm_extract_epi32 (hsum ,0 ); 2350 2351const __m128i hbits_0 = _mm_loadu_si128 ((const __m128i * )& x [i ].qh [0 ]); 2352const __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 2358int bit = 0 ; 2359 2360__m128i shuffle = _mm_set1_epi16 (0x0100 ); 2361for (int j = 0 ;j < QK_K /64 ;++ j ) { 2362 2363const __m128i scale_0 = _mm_shuffle_epi8 (scales ,shuffle ); 2364shuffle = _mm_add_epi16 (shuffle ,m2 ); 2365const __m128i scale_1 = _mm_shuffle_epi8 (scales ,shuffle ); 2366shuffle = _mm_add_epi16 (shuffle ,m2 ); 2367 2368const __m128i q5bits_0 = _mm_loadu_si128 ((const __m128i * )q5 );q5 += 16 ; 2369const __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 ); 2377hmask = _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 ); 2383p16_0 = _mm_madd_epi16 (scale_0 ,p16_0 ); 2384p16_1 = _mm_madd_epi16 (scale_0 ,p16_1 ); 2385 2386q5l_0 = _mm_and_si128 (_mm_srli_epi16 (q5bits_0 ,4 ),m4 ); 2387q5l_1 = _mm_and_si128 (_mm_srli_epi16 (q5bits_1 ,4 ),m4 ); 2388q5h_0 = _mm_slli_epi16 (_mm_srli_epi16 (_mm_and_si128 (hbits_0 ,hmask ),bit ),4 ); 2389q5h_1 = _mm_slli_epi16 (_mm_srli_epi16 (_mm_and_si128 (hbits_1 ,hmask ),bit ++ ),4 ); 2390q5_0 = _mm_add_epi8 (q5l_0 ,q5h_0 ); 2391q5_1 = _mm_add_epi8 (q5l_1 ,q5h_1 ); 2392hmask = _mm_slli_epi16 (hmask ,1 ); 2393 2394q8_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2395q8_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 ); 2398p16_2 = _mm_madd_epi16 (scale_1 ,p16_2 ); 2399p16_3 = _mm_madd_epi16 (scale_1 ,p16_3 ); 2400 2401sumi_0 = _mm_add_epi32 (sumi_0 ,_mm_add_epi32 (p16_0 ,p16_2 )); 2402sumi_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 ); 2408acc = _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 2415UNUSED (x ); 2416UNUSED (y ); 2417UNUSED (nb ); 2418UNUSED (kmask1 ); 2419UNUSED (kmask2 ); 2420UNUSED (kmask3 ); 2421UNUSED (utmp ); 2422ggml_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 ) { 2427assert (n %QK_K == 0 ); 2428assert (nrc == 1 ); 2429UNUSED (nrc ); 2430UNUSED (bx ); 2431UNUSED (by ); 2432UNUSED (bs ); 2433 2434const block_q6_K * GGML_RESTRICT x = vx ; 2435const block_q8_K * GGML_RESTRICT y = vy ; 2436 2437const int nb = n /QK_K ; 2438 2439#if defined__AVX2__ 2440 2441const __m256i m3 = _mm256_set1_epi8 (3 ); 2442const __m256i m15 = _mm256_set1_epi8 (15 ); 2443 2444__m256 acc = _mm256_setzero_ps (); 2445 2446for (int i = 0 ;i < nb ;++ i ) { 2447 2448const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 2449 2450const uint8_t * GGML_RESTRICT q4 = x [i ].ql ; 2451const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 2452const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2453 2454const __m256i q8sums = _mm256_loadu_si256 ((const __m256i * )y [i ].bsums ); 2455const __m128i scales = _mm_loadu_si128 ((const __m128i * )x [i ].scales ); 2456const __m256i scales_16 = _mm256_cvtepi8_epi16 (scales ); 2457const __m256i q8sclsub = _mm256_slli_epi32 (_mm256_madd_epi16 (q8sums ,scales_16 ),5 ); 2458 2459__m256i sumi = _mm256_setzero_si256 (); 2460 2461int is = 0 ; 2462 2463for (int j = 0 ;j < QK_K /128 ;++ j ) { 2464const __m256i q4bits1 = _mm256_loadu_si256 ((const __m256i * )q4 );q4 += 32 ; 2465const __m256i q4bits2 = _mm256_loadu_si256 ((const __m256i * )q4 );q4 += 32 ; 2466const __m256i q4bitsH = _mm256_loadu_si256 ((const __m256i * )qh );qh += 32 ; 2467 2468const __m256i q4h_0 = _mm256_slli_epi16 (_mm256_and_si256 (q4bitsH ,m3 ),4 ); 2469const __m256i q4h_1 = _mm256_slli_epi16 (_mm256_and_si256 (q4bitsH ,_mm256_set1_epi8 (12 )),2 ); 2470const __m256i q4h_2 = _mm256_and_si256 (q4bitsH ,_mm256_set1_epi8 (48 )); 2471const __m256i q4h_3 = _mm256_srli_epi16 (_mm256_and_si256 (q4bitsH ,_mm256_set1_epi8 (-64 )),2 ); 2472 2473const __m256i q4_0 = _mm256_or_si256 (_mm256_and_si256 (q4bits1 ,m15 ),q4h_0 ); 2474const __m256i q4_1 = _mm256_or_si256 (_mm256_and_si256 (q4bits2 ,m15 ),q4h_1 ); 2475const __m256i q4_2 = _mm256_or_si256 (_mm256_and_si256 (_mm256_srli_epi16 (q4bits1 ,4 ),m15 ),q4h_2 ); 2476const __m256i q4_3 = _mm256_or_si256 (_mm256_and_si256 (_mm256_srli_epi16 (q4bits2 ,4 ),m15 ),q4h_3 ); 2477 2478const __m256i q8_0 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 2479const __m256i q8_1 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 2480const __m256i q8_2 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 2481const __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 2488const __m128i scale_0 = _mm_shuffle_epi8 (scales ,get_scale_shuffle (is + 0 )); 2489const __m128i scale_1 = _mm_shuffle_epi8 (scales ,get_scale_shuffle (is + 1 )); 2490const __m128i scale_2 = _mm_shuffle_epi8 (scales ,get_scale_shuffle (is + 2 )); 2491const __m128i scale_3 = _mm_shuffle_epi8 (scales ,get_scale_shuffle (is + 3 )); 2492is += 4 ; 2493 2494p16_0 = _mm256_madd_epi16 (_mm256_cvtepi8_epi16 (scale_0 ),p16_0 ); 2495p16_1 = _mm256_madd_epi16 (_mm256_cvtepi8_epi16 (scale_1 ),p16_1 ); 2496p16_2 = _mm256_madd_epi16 (_mm256_cvtepi8_epi16 (scale_2 ),p16_2 ); 2497p16_3 = _mm256_madd_epi16 (_mm256_cvtepi8_epi16 (scale_3 ),p16_3 ); 2498 2499sumi = _mm256_add_epi32 (sumi ,_mm256_add_epi32 (p16_0 ,p16_1 )); 2500sumi = _mm256_add_epi32 (sumi ,_mm256_add_epi32 (p16_2 ,p16_3 )); 2501 2502 } 2503 2504sumi = _mm256_sub_epi32 (sumi ,q8sclsub ); 2505acc = _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 2512const __m128i m3 = _mm_set1_epi8 (3 ); 2513const __m128i m15 = _mm_set1_epi8 (15 ); 2514 2515__m256 acc = _mm256_setzero_ps (); 2516 2517for (int i = 0 ;i < nb ;++ i ) { 2518 2519const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 2520 2521const uint8_t * GGML_RESTRICT q4 = x [i ].ql ; 2522const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 2523const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2524 2525// handle the q6_k -32 offset separately using bsums 2526const __m128i q8sums_0 = _mm_loadu_si128 ((const __m128i * )y [i ].bsums ); 2527const __m128i q8sums_1 = _mm_loadu_si128 ((const __m128i * )y [i ].bsums + 1 ); 2528const __m128i scales = _mm_loadu_si128 ((const __m128i * )x [i ].scales ); 2529const __m128i scales_16_0 = _mm_cvtepi8_epi16 (scales ); 2530const __m128i scales_16_1 = _mm_cvtepi8_epi16 (_mm_bsrli_si128 (scales ,8 )); 2531const __m128i q8sclsub_0 = _mm_slli_epi32 (_mm_madd_epi16 (q8sums_0 ,scales_16_0 ),5 ); 2532const __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 2537int is = 0 ; 2538 2539for (int j = 0 ;j < QK_K /128 ;++ j ) { 2540 2541const __m128i q4bitsH_0 = _mm_loadu_si128 ((const __m128i * )qh );qh += 16 ; 2542const __m128i q4bitsH_1 = _mm_loadu_si128 ((const __m128i * )qh );qh += 16 ; 2543 2544const __m128i q4h_0 = _mm_slli_epi16 (_mm_and_si128 (q4bitsH_0 ,m3 ),4 ); 2545const __m128i q4h_1 = _mm_slli_epi16 (_mm_and_si128 (q4bitsH_1 ,m3 ),4 ); 2546const __m128i q4h_2 = _mm_slli_epi16 (_mm_and_si128 (q4bitsH_0 ,_mm_set1_epi8 (12 )),2 ); 2547const __m128i q4h_3 = _mm_slli_epi16 (_mm_and_si128 (q4bitsH_1 ,_mm_set1_epi8 (12 )),2 ); 2548const __m128i q4h_4 = _mm_and_si128 (q4bitsH_0 ,_mm_set1_epi8 (48 )); 2549const __m128i q4h_5 = _mm_and_si128 (q4bitsH_1 ,_mm_set1_epi8 (48 )); 2550const __m128i q4h_6 = _mm_srli_epi16 (_mm_and_si128 (q4bitsH_0 ,_mm_set1_epi8 (-64 )),2 ); 2551const __m128i q4h_7 = _mm_srli_epi16 (_mm_and_si128 (q4bitsH_1 ,_mm_set1_epi8 (-64 )),2 ); 2552 2553const __m128i q4bits1_0 = _mm_loadu_si128 ((const __m128i * )q4 );q4 += 16 ; 2554const __m128i q4bits1_1 = _mm_loadu_si128 ((const __m128i * )q4 );q4 += 16 ; 2555const __m128i q4bits2_0 = _mm_loadu_si128 ((const __m128i * )q4 );q4 += 16 ; 2556const __m128i q4bits2_1 = _mm_loadu_si128 ((const __m128i * )q4 );q4 += 16 ; 2557 2558const __m128i q4_0 = _mm_or_si128 (_mm_and_si128 (q4bits1_0 ,m15 ),q4h_0 ); 2559const __m128i q4_1 = _mm_or_si128 (_mm_and_si128 (q4bits1_1 ,m15 ),q4h_1 ); 2560const __m128i q4_2 = _mm_or_si128 (_mm_and_si128 (q4bits2_0 ,m15 ),q4h_2 ); 2561const __m128i q4_3 = _mm_or_si128 (_mm_and_si128 (q4bits2_1 ,m15 ),q4h_3 ); 2562const __m128i q4_4 = _mm_or_si128 (_mm_and_si128 (_mm_srli_epi16 (q4bits1_0 ,4 ),m15 ),q4h_4 ); 2563const __m128i q4_5 = _mm_or_si128 (_mm_and_si128 (_mm_srli_epi16 (q4bits1_1 ,4 ),m15 ),q4h_5 ); 2564const __m128i q4_6 = _mm_or_si128 (_mm_and_si128 (_mm_srli_epi16 (q4bits2_0 ,4 ),m15 ),q4h_6 ); 2565const __m128i q4_7 = _mm_or_si128 (_mm_and_si128 (_mm_srli_epi16 (q4bits2_1 ,4 ),m15 ),q4h_7 ); 2566 2567const __m128i q8_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2568const __m128i q8_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2569const __m128i q8_2 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2570const __m128i q8_3 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2571const __m128i q8_4 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2572const __m128i q8_5 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2573const __m128i q8_6 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2574const __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 2585const __m128i scale_0 = _mm_shuffle_epi8 (scales ,get_scale_shuffle (is + 0 )); 2586const __m128i scale_1 = _mm_shuffle_epi8 (scales ,get_scale_shuffle (is + 1 )); 2587const __m128i scale_2 = _mm_shuffle_epi8 (scales ,get_scale_shuffle (is + 2 )); 2588const __m128i scale_3 = _mm_shuffle_epi8 (scales ,get_scale_shuffle (is + 3 )); 2589is += 4 ; 2590 2591p16_0 = _mm_madd_epi16 (_mm_cvtepi8_epi16 (scale_0 ),p16_0 ); 2592p16_1 = _mm_madd_epi16 (_mm_cvtepi8_epi16 (_mm_bsrli_si128 (scale_0 ,8 )),p16_1 ); 2593p16_2 = _mm_madd_epi16 (_mm_cvtepi8_epi16 (scale_1 ),p16_2 ); 2594p16_3 = _mm_madd_epi16 (_mm_cvtepi8_epi16 (_mm_bsrli_si128 (scale_1 ,8 )),p16_3 ); 2595p16_4 = _mm_madd_epi16 (_mm_cvtepi8_epi16 (scale_2 ),p16_4 ); 2596p16_5 = _mm_madd_epi16 (_mm_cvtepi8_epi16 (_mm_bsrli_si128 (scale_2 ,8 )),p16_5 ); 2597p16_6 = _mm_madd_epi16 (_mm_cvtepi8_epi16 (scale_3 ),p16_6 ); 2598p16_7 = _mm_madd_epi16 (_mm_cvtepi8_epi16 (_mm_bsrli_si128 (scale_3 ,8 )),p16_7 ); 2599 2600sumi_0 = _mm_add_epi32 (sumi_0 ,_mm_add_epi32 (p16_0 ,p16_2 )); 2601sumi_1 = _mm_add_epi32 (sumi_1 ,_mm_add_epi32 (p16_1 ,p16_3 )); 2602sumi_0 = _mm_add_epi32 (sumi_0 ,_mm_add_epi32 (p16_4 ,p16_6 )); 2603sumi_1 = _mm_add_epi32 (sumi_1 ,_mm_add_epi32 (p16_5 ,p16_7 )); 2604 2605 } 2606 2607sumi_0 = _mm_sub_epi32 (sumi_0 ,q8sclsub_0 ); 2608sumi_1 = _mm_sub_epi32 (sumi_1 ,q8sclsub_1 ); 2609const __m256i sumi = MM256_SET_M128I (sumi_1 ,sumi_0 ); 2610acc = _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 2616UNUSED (x ); 2617UNUSED (y ); 2618UNUSED (nb ); 2619ggml_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 ]= { 26251 ,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 , 26261 ,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 , 26271 ,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 , 26281 ,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 , 26291 ,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 , 26301 ,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 , 26311 ,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 , 26321 ,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 , 26331 ,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 , 26341 ,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 , 26351 ,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 , 26361 ,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 , 26371 ,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 , 26381 ,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 , 26391 ,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 , 26401 ,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 , 26411 ,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 , 26421 ,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 , 26431 ,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 , 26441 ,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 , 26451 ,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 , 26461 ,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 , 26471 ,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 , 26481 ,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 , 26491 ,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 , 26501 ,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 , 26511 ,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 , 26521 ,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 , 26531 ,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 , 26541 ,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 , 26551 ,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 , 26561 ,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 ) { 2661assert (n %QK_K == 0 ); 2662assert (nrc == 1 ); 2663UNUSED (nrc ); 2664UNUSED (bx ); 2665UNUSED (by ); 2666UNUSED (bs ); 2667 2668const block_iq2_xxs * GGML_RESTRICT x = vx ; 2669const block_q8_K * GGML_RESTRICT y = vy ; 2670 2671const int nb = n /QK_K ; 2672 2673#if defined(__AVX2__ ) 2674 2675const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 2676 2677uint32_t aux32 [4 ]; 2678const uint8_t * aux8 = (const uint8_t * )aux32 ; 2679 2680__m256 accumf = _mm256_setzero_ps (); 2681for (int i = 0 ;i < nb ;++ i ) { 2682const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 2683const uint16_t * GGML_RESTRICT q2 = x [i ].qs ; 2684const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2685__m256i sumi1 = _mm256_setzero_si256 (); 2686__m256i sumi2 = _mm256_setzero_si256 (); 2687for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 2688const __m256i q8_1 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 2689const __m256i q8_2 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 2690memcpy (aux32 ,q2 ,4 * sizeof (uint32_t ));q2 += 8 ; 2691const __m256i q2_1 = _mm256_set_epi64x (iq2xxs_grid [aux8 [3 ]],iq2xxs_grid [aux8 [2 ]],iq2xxs_grid [aux8 [1 ]],iq2xxs_grid [aux8 [0 ]]); 2692const __m256i q2_2 = _mm256_set_epi64x (iq2xxs_grid [aux8 [11 ]],iq2xxs_grid [aux8 [10 ]],iq2xxs_grid [aux8 [9 ]],iq2xxs_grid [aux8 [8 ]]); 2693const __m256i s2_1 = _mm256_set_epi64x (signs64 [(aux32 [1 ] >>21 )& 127 ],signs64 [(aux32 [1 ] >>14 )& 127 ], 2694signs64 [(aux32 [1 ] >>7 )& 127 ],signs64 [(aux32 [1 ] >>0 )& 127 ]); 2695const __m256i s2_2 = _mm256_set_epi64x (signs64 [(aux32 [3 ] >>21 )& 127 ],signs64 [(aux32 [3 ] >>14 )& 127 ], 2696signs64 [(aux32 [3 ] >>7 )& 127 ],signs64 [(aux32 [3 ] >>0 )& 127 ]); 2697const __m256i q8s_1 = _mm256_sign_epi8 (q8_1 ,s2_1 ); 2698const __m256i q8s_2 = _mm256_sign_epi8 (q8_2 ,s2_2 ); 2699const __m256i dot1 = _mm256_maddubs_epi16 (q2_1 ,q8s_1 ); 2700const __m256i dot2 = _mm256_maddubs_epi16 (q2_2 ,q8s_2 ); 2701const uint16_t ls1 = aux32 [1 ] >>28 ; 2702const uint16_t ls2 = aux32 [3 ] >>28 ; 2703const __m256i p1 = _mm256_madd_epi16 (dot1 ,_mm256_set1_epi16 (2 * ls1 + 1 )); 2704const __m256i p2 = _mm256_madd_epi16 (dot2 ,_mm256_set1_epi16 (2 * ls2 + 1 )); 2705sumi1 = _mm256_add_epi32 (sumi1 ,p1 ); 2706sumi2 = _mm256_add_epi32 (sumi2 ,p2 ); 2707 } 2708 2709accumf = _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__ ) 2716const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 2717 2718uint32_t aux32 [4 ]; 2719const uint8_t * aux8 = (const uint8_t * )aux32 ; 2720 2721__m256 accumf = _mm256_setzero_ps (); 2722for (int i = 0 ;i < nb ;++ i ) { 2723const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 2724const uint16_t * GGML_RESTRICT q2 = x [i ].qs ; 2725const 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 (); 2730for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 2731const __m128i q8_1_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2732const __m128i q8_1_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2733const __m128i q8_2_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2734const __m128i q8_2_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2735memcpy (aux32 ,q2 ,4 * sizeof (uint32_t ));q2 += 8 ; 2736const __m128i q2_1_0 = _mm_set_epi64x (iq2xxs_grid [aux8 [1 ]],iq2xxs_grid [aux8 [0 ]]); 2737const __m128i q2_1_1 = _mm_set_epi64x (iq2xxs_grid [aux8 [3 ]],iq2xxs_grid [aux8 [2 ]]); 2738const __m128i q2_2_0 = _mm_set_epi64x (iq2xxs_grid [aux8 [9 ]],iq2xxs_grid [aux8 [8 ]]); 2739const __m128i q2_2_1 = _mm_set_epi64x (iq2xxs_grid [aux8 [11 ]],iq2xxs_grid [aux8 [10 ]]); 2740const __m128i s2_1_0 = _mm_set_epi64x (signs64 [(aux32 [1 ] >>7 )& 127 ],signs64 [(aux32 [1 ] >>0 )& 127 ]); 2741const __m128i s2_1_1 = _mm_set_epi64x (signs64 [(aux32 [1 ] >>21 )& 127 ],signs64 [(aux32 [1 ] >>14 )& 127 ]); 2742const __m128i s2_2_0 = _mm_set_epi64x (signs64 [(aux32 [3 ] >>7 )& 127 ],signs64 [(aux32 [3 ] >>0 )& 127 ]); 2743const __m128i s2_2_1 = _mm_set_epi64x (signs64 [(aux32 [3 ] >>21 )& 127 ],signs64 [(aux32 [3 ] >>14 )& 127 ]); 2744const __m128i q8s_1_0 = _mm_sign_epi8 (q8_1_0 ,s2_1_0 ); 2745const __m128i q8s_1_1 = _mm_sign_epi8 (q8_1_1 ,s2_1_1 ); 2746const __m128i q8s_2_0 = _mm_sign_epi8 (q8_2_0 ,s2_2_0 ); 2747const __m128i q8s_2_1 = _mm_sign_epi8 (q8_2_1 ,s2_2_1 ); 2748const __m128i dot1_0 = _mm_maddubs_epi16 (q2_1_0 ,q8s_1_0 ); 2749const __m128i dot1_1 = _mm_maddubs_epi16 (q2_1_1 ,q8s_1_1 ); 2750const __m128i dot2_0 = _mm_maddubs_epi16 (q2_2_0 ,q8s_2_0 ); 2751const __m128i dot2_1 = _mm_maddubs_epi16 (q2_2_1 ,q8s_2_1 ); 2752const uint16_t ls1 = aux32 [1 ] >>28 ; 2753const uint16_t ls2 = aux32 [3 ] >>28 ; 2754const __m128i p1_0 = _mm_madd_epi16 (dot1_0 ,_mm_set1_epi16 (2 * ls1 + 1 )); 2755const __m128i p1_1 = _mm_madd_epi16 (dot1_1 ,_mm_set1_epi16 (2 * ls1 + 1 )); 2756const __m128i p2_0 = _mm_madd_epi16 (dot2_0 ,_mm_set1_epi16 (2 * ls2 + 1 )); 2757const __m128i p2_1 = _mm_madd_epi16 (dot2_1 ,_mm_set1_epi16 (2 * ls2 + 1 )); 2758sumi1_0 = _mm_add_epi32 (sumi1_0 ,p1_0 ); 2759sumi1_1 = _mm_add_epi32 (sumi1_1 ,p1_1 ); 2760sumi2_0 = _mm_add_epi32 (sumi2_0 ,p2_0 ); 2761sumi2_1 = _mm_add_epi32 (sumi2_1 ,p2_1 ); 2762 } 2763 2764accumf = _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 2771UNUSED (x ); 2772UNUSED (y ); 2773UNUSED (nb ); 2774ggml_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 ) { 2779assert (n %QK_K == 0 ); 2780assert (nrc == 1 ); 2781UNUSED (nrc ); 2782UNUSED (bx ); 2783UNUSED (by ); 2784UNUSED (bs ); 2785 2786const block_iq2_xs * GGML_RESTRICT x = vx ; 2787const block_q8_K * GGML_RESTRICT y = vy ; 2788 2789const int nb = n /QK_K ; 2790 2791#if defined(__AVX2__ ) 2792 2793const __m256i mone = _mm256_set1_epi8 (1 ); 2794static const char block_sign_shuffle_mask_1 [32 ]= { 27950x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 , 27960x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x06 ,0x06 ,0x06 ,0x06 ,0x06 ,0x06 ,0x06 ,0x06 , 2797 }; 2798static const char block_sign_shuffle_mask_2 [32 ]= { 27990x08 ,0x08 ,0x08 ,0x08 ,0x08 ,0x08 ,0x08 ,0x08 ,0x0a ,0x0a ,0x0a ,0x0a ,0x0a ,0x0a ,0x0a ,0x0a , 28000x0c ,0x0c ,0x0c ,0x0c ,0x0c ,0x0c ,0x0c ,0x0c ,0x0e ,0x0e ,0x0e ,0x0e ,0x0e ,0x0e ,0x0e ,0x0e , 2801 }; 2802static const uint8_t bit_selector_mask_bytes [32 ]= { 28030x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 28040x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 2805 }; 2806 2807const __m256i bit_selector_mask = _mm256_loadu_si256 ((const __m256i * )bit_selector_mask_bytes ); 2808const __m256i block_sign_shuffle_1 = _mm256_loadu_si256 ((const __m256i * )block_sign_shuffle_mask_1 ); 2809const __m256i block_sign_shuffle_2 = _mm256_loadu_si256 ((const __m256i * )block_sign_shuffle_mask_2 ); 2810 2811static const uint8_t k_bit_helper [32 ]= { 28120x00 ,0x80 ,0x80 ,0x00 ,0x80 ,0x00 ,0x00 ,0x80 ,0x80 ,0x00 ,0x00 ,0x80 ,0x00 ,0x80 ,0x80 ,0x00 , 28130x00 ,0x80 ,0x80 ,0x00 ,0x80 ,0x00 ,0x00 ,0x80 ,0x80 ,0x00 ,0x00 ,0x80 ,0x00 ,0x80 ,0x80 ,0x00 , 2814 }; 2815const __m256i bit_helper = _mm256_loadu_si256 ((const __m256i * )k_bit_helper ); 2816const __m256i m511 = _mm256_set1_epi16 (511 ); 2817const __m128i m4 = _mm_set1_epi8 (0xf ); 2818const __m128i m1 = _mm_set1_epi8 (1 ); 2819 2820uint64_t aux64 ; 2821 2822// somewhat hacky, but gives a significant boost in performance 2823__m256i aux_gindex ; 2824const uint16_t * gindex = (const uint16_t * )& aux_gindex ; 2825 2826__m256 accumf = _mm256_setzero_ps (); 2827for (int i = 0 ;i < nb ;++ i ) { 2828const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 2829const uint16_t * GGML_RESTRICT q2 = x [i ].qs ; 2830const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2831 2832memcpy (& aux64 ,x [i ].scales ,8 ); 2833__m128i stmp = _mm_set1_epi64x (aux64 ); 2834stmp = _mm_unpacklo_epi8 (_mm_and_si128 (stmp ,m4 ),_mm_and_si128 (_mm_srli_epi16 (stmp ,4 ),m4 )); 2835const __m128i scales = _mm_add_epi8 (_mm_slli_epi16 (stmp ,1 ),m1 ); 2836 2837__m256i sumi1 = _mm256_setzero_si256 (); 2838__m256i sumi2 = _mm256_setzero_si256 (); 2839for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 4 ) { 2840 2841const __m256i q2_data = _mm256_loadu_si256 ((const __m256i * )q2 );q2 += 16 ; 2842aux_gindex = _mm256_and_si256 (q2_data ,m511 ); 2843 2844const __m256i partial_sign_bits = _mm256_srli_epi16 (q2_data ,9 ); 2845const __m256i partial_sign_bits_upper = _mm256_srli_epi16 (q2_data ,13 ); 2846const __m256i partial_sign_bits_for_counting = _mm256_xor_si256 (partial_sign_bits ,partial_sign_bits_upper ); 2847 2848const __m256i odd_bits = _mm256_shuffle_epi8 (bit_helper ,partial_sign_bits_for_counting ); 2849const __m256i full_sign_bits = _mm256_or_si256 (partial_sign_bits ,odd_bits ); 2850 2851const __m256i q8_1 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 2852const __m256i q8_2 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 2853const __m256i q8_3 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 2854const __m256i q8_4 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 2855 2856const __m256i q2_1 = _mm256_set_epi64x (iq2xs_grid [gindex [3 ]],iq2xs_grid [gindex [2 ]], 2857iq2xs_grid [gindex [1 ]],iq2xs_grid [gindex [0 ]]); 2858const __m256i q2_2 = _mm256_set_epi64x (iq2xs_grid [gindex [7 ]],iq2xs_grid [gindex [6 ]], 2859iq2xs_grid [gindex [5 ]],iq2xs_grid [gindex [4 ]]); 2860const __m256i q2_3 = _mm256_set_epi64x (iq2xs_grid [gindex [11 ]],iq2xs_grid [gindex [10 ]], 2861iq2xs_grid [gindex [9 ]],iq2xs_grid [gindex [8 ]]); 2862const __m256i q2_4 = _mm256_set_epi64x (iq2xs_grid [gindex [15 ]],iq2xs_grid [gindex [14 ]], 2863iq2xs_grid [gindex [13 ]],iq2xs_grid [gindex [12 ]]); 2864 2865const __m128i full_signs_l = _mm256_castsi256_si128 (full_sign_bits ); 2866const __m128i full_signs_h = _mm256_extractf128_si256 (full_sign_bits ,1 ); 2867const __m256i full_signs_1 = MM256_SET_M128I (full_signs_l ,full_signs_l ); 2868const __m256i full_signs_2 = MM256_SET_M128I (full_signs_h ,full_signs_h ); 2869 2870__m256i signs ; 2871signs = _mm256_shuffle_epi8 (full_signs_1 ,block_sign_shuffle_1 ); 2872signs = _mm256_cmpeq_epi8 (_mm256_and_si256 (signs ,bit_selector_mask ),bit_selector_mask ); 2873const __m256i q8s_1 = _mm256_sign_epi8 (q8_1 ,_mm256_or_si256 (signs ,mone )); 2874 2875signs = _mm256_shuffle_epi8 (full_signs_1 ,block_sign_shuffle_2 ); 2876signs = _mm256_cmpeq_epi8 (_mm256_and_si256 (signs ,bit_selector_mask ),bit_selector_mask ); 2877const __m256i q8s_2 = _mm256_sign_epi8 (q8_2 ,_mm256_or_si256 (signs ,mone )); 2878 2879signs = _mm256_shuffle_epi8 (full_signs_2 ,block_sign_shuffle_1 ); 2880signs = _mm256_cmpeq_epi8 (_mm256_and_si256 (signs ,bit_selector_mask ),bit_selector_mask ); 2881const __m256i q8s_3 = _mm256_sign_epi8 (q8_3 ,_mm256_or_si256 (signs ,mone )); 2882 2883signs = _mm256_shuffle_epi8 (full_signs_2 ,block_sign_shuffle_2 ); 2884signs = _mm256_cmpeq_epi8 (_mm256_and_si256 (signs ,bit_selector_mask ),bit_selector_mask ); 2885const __m256i q8s_4 = _mm256_sign_epi8 (q8_4 ,_mm256_or_si256 (signs ,mone )); 2886 2887const __m256i dot1 = _mm256_maddubs_epi16 (q2_1 ,q8s_1 ); 2888const __m256i dot2 = _mm256_maddubs_epi16 (q2_2 ,q8s_2 ); 2889const __m256i dot3 = _mm256_maddubs_epi16 (q2_3 ,q8s_3 ); 2890const __m256i dot4 = _mm256_maddubs_epi16 (q2_4 ,q8s_4 ); 2891 2892const __m256i sc1 = _mm256_cvtepi8_epi16 (_mm_shuffle_epi8 (scales ,get_scale_shuffle (ib32 + 0 ))); 2893const __m256i sc2 = _mm256_cvtepi8_epi16 (_mm_shuffle_epi8 (scales ,get_scale_shuffle (ib32 + 1 ))); 2894const __m256i sc3 = _mm256_cvtepi8_epi16 (_mm_shuffle_epi8 (scales ,get_scale_shuffle (ib32 + 2 ))); 2895const __m256i sc4 = _mm256_cvtepi8_epi16 (_mm_shuffle_epi8 (scales ,get_scale_shuffle (ib32 + 3 ))); 2896 2897sumi1 = _mm256_add_epi32 (sumi1 ,_mm256_madd_epi16 (dot1 ,sc1 )); 2898sumi2 = _mm256_add_epi32 (sumi2 ,_mm256_madd_epi16 (dot2 ,sc2 )); 2899sumi1 = _mm256_add_epi32 (sumi1 ,_mm256_madd_epi16 (dot3 ,sc3 )); 2900sumi2 = _mm256_add_epi32 (sumi2 ,_mm256_madd_epi16 (dot4 ,sc4 )); 2901 } 2902 2903accumf = _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__ ) 2910const __m128i mone = _mm_set1_epi8 (1 ); 2911static const char block_sign_shuffle_mask_1 [32 ]= { 29120x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 , 29130x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x06 ,0x06 ,0x06 ,0x06 ,0x06 ,0x06 ,0x06 ,0x06 , 2914 }; 2915static const char block_sign_shuffle_mask_2 [32 ]= { 29160x08 ,0x08 ,0x08 ,0x08 ,0x08 ,0x08 ,0x08 ,0x08 ,0x0a ,0x0a ,0x0a ,0x0a ,0x0a ,0x0a ,0x0a ,0x0a , 29170x0c ,0x0c ,0x0c ,0x0c ,0x0c ,0x0c ,0x0c ,0x0c ,0x0e ,0x0e ,0x0e ,0x0e ,0x0e ,0x0e ,0x0e ,0x0e , 2918 }; 2919static const uint8_t bit_selector_mask_bytes [32 ]= { 29200x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 29210x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 2922 }; 2923 2924const __m128i bit_selector_mask_0 = _mm_loadu_si128 ((const __m128i * )bit_selector_mask_bytes ); 2925const __m128i bit_selector_mask_1 = _mm_loadu_si128 ((const __m128i * )bit_selector_mask_bytes + 1 ); 2926const __m128i block_sign_shuffle_1_0 = _mm_loadu_si128 ((const __m128i * )block_sign_shuffle_mask_1 ); 2927const __m128i block_sign_shuffle_1_1 = _mm_loadu_si128 ((const __m128i * )block_sign_shuffle_mask_1 + 1 ); 2928const __m128i block_sign_shuffle_2_0 = _mm_loadu_si128 ((const __m128i * )block_sign_shuffle_mask_2 ); 2929const __m128i block_sign_shuffle_2_1 = _mm_loadu_si128 ((const __m128i * )block_sign_shuffle_mask_2 + 1 ); 2930 2931static const uint8_t k_bit_helper [32 ]= { 29320x00 ,0x80 ,0x80 ,0x00 ,0x80 ,0x00 ,0x00 ,0x80 ,0x80 ,0x00 ,0x00 ,0x80 ,0x00 ,0x80 ,0x80 ,0x00 , 29330x00 ,0x80 ,0x80 ,0x00 ,0x80 ,0x00 ,0x00 ,0x80 ,0x80 ,0x00 ,0x00 ,0x80 ,0x00 ,0x80 ,0x80 ,0x00 , 2934 }; 2935const __m128i bit_helper_0 = _mm_loadu_si128 ((const __m128i * )k_bit_helper ); 2936const __m128i bit_helper_1 = _mm_loadu_si128 ((const __m128i * )k_bit_helper + 1 ); 2937const __m128i m511 = _mm_set1_epi16 (511 ); 2938const __m128i m4 = _mm_set1_epi8 (0xf ); 2939const __m128i m1 = _mm_set1_epi8 (1 ); 2940 2941uint64_t aux64 ; 2942 2943// somewhat hacky, but gives a significant boost in performance 2944__m256i aux_gindex ; 2945const uint16_t * gindex = (const uint16_t * )& aux_gindex ; 2946 2947__m256 accumf = _mm256_setzero_ps (); 2948for (int i = 0 ;i < nb ;++ i ) { 2949const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 2950const uint16_t * GGML_RESTRICT q2 = x [i ].qs ; 2951const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2952 2953memcpy (& aux64 ,x [i ].scales ,8 ); 2954__m128i stmp = _mm_set1_epi64x (aux64 ); 2955stmp = _mm_unpacklo_epi8 (_mm_and_si128 (stmp ,m4 ),_mm_and_si128 (_mm_srli_epi16 (stmp ,4 ),m4 )); 2956const __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 (); 2962for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 4 ) { 2963 2964const __m128i q2_data_0 = _mm_loadu_si128 ((const __m128i * )q2 ); 2965const __m128i q2_data_1 = _mm_loadu_si128 ((const __m128i * )q2 + 1 );q2 += 16 ; 2966aux_gindex = MM256_SET_M128I (_mm_and_si128 (q2_data_1 ,m511 ),_mm_and_si128 (q2_data_0 ,m511 )); 2967 2968const __m128i partial_sign_bits_0 = _mm_srli_epi16 (q2_data_0 ,9 ); 2969const __m128i partial_sign_bits_1 = _mm_srli_epi16 (q2_data_1 ,9 ); 2970const __m128i partial_sign_bits_upper_0 = _mm_srli_epi16 (q2_data_0 ,13 ); 2971const __m128i partial_sign_bits_upper_1 = _mm_srli_epi16 (q2_data_1 ,13 ); 2972const __m128i partial_sign_bits_for_counting_0 = _mm_xor_si128 (partial_sign_bits_0 ,partial_sign_bits_upper_0 ); 2973const __m128i partial_sign_bits_for_counting_1 = _mm_xor_si128 (partial_sign_bits_1 ,partial_sign_bits_upper_1 ); 2974 2975const __m128i odd_bits_0 = _mm_shuffle_epi8 (bit_helper_0 ,partial_sign_bits_for_counting_0 ); 2976const __m128i odd_bits_1 = _mm_shuffle_epi8 (bit_helper_1 ,partial_sign_bits_for_counting_1 ); 2977const __m128i full_sign_bits_0 = _mm_or_si128 (partial_sign_bits_0 ,odd_bits_0 ); 2978const __m128i full_sign_bits_1 = _mm_or_si128 (partial_sign_bits_1 ,odd_bits_1 ); 2979 2980const __m128i q8_1_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2981const __m128i q8_1_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2982const __m128i q8_2_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2983const __m128i q8_2_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2984const __m128i q8_3_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2985const __m128i q8_3_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2986const __m128i q8_4_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2987const __m128i q8_4_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 2988 2989const __m128i q2_1_0 = _mm_set_epi64x (iq2xs_grid [gindex [1 ]],iq2xs_grid [gindex [0 ]]); 2990const __m128i q2_1_1 = _mm_set_epi64x (iq2xs_grid [gindex [3 ]],iq2xs_grid [gindex [2 ]]); 2991const __m128i q2_2_0 = _mm_set_epi64x (iq2xs_grid [gindex [5 ]],iq2xs_grid [gindex [4 ]]); 2992const __m128i q2_2_1 = _mm_set_epi64x (iq2xs_grid [gindex [7 ]],iq2xs_grid [gindex [6 ]]); 2993const __m128i q2_3_0 = _mm_set_epi64x (iq2xs_grid [gindex [9 ]],iq2xs_grid [gindex [8 ]]); 2994const __m128i q2_3_1 = _mm_set_epi64x (iq2xs_grid [gindex [11 ]],iq2xs_grid [gindex [10 ]]); 2995const __m128i q2_4_0 = _mm_set_epi64x (iq2xs_grid [gindex [13 ]],iq2xs_grid [gindex [12 ]]); 2996const __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 ; 3001signs_0 = _mm_shuffle_epi8 (full_sign_bits_0 ,block_sign_shuffle_1_0 ); 3002signs_1 = _mm_shuffle_epi8 (full_sign_bits_0 ,block_sign_shuffle_1_1 ); 3003signs_0 = _mm_cmpeq_epi8 (_mm_and_si128 (signs_0 ,bit_selector_mask_0 ),bit_selector_mask_0 ); 3004signs_1 = _mm_cmpeq_epi8 (_mm_and_si128 (signs_1 ,bit_selector_mask_1 ),bit_selector_mask_1 ); 3005const __m128i q8s_1_0 = _mm_sign_epi8 (q8_1_0 ,_mm_or_si128 (signs_0 ,mone )); 3006const __m128i q8s_1_1 = _mm_sign_epi8 (q8_1_1 ,_mm_or_si128 (signs_1 ,mone )); 3007 3008signs_0 = _mm_shuffle_epi8 (full_sign_bits_0 ,block_sign_shuffle_2_0 ); 3009signs_1 = _mm_shuffle_epi8 (full_sign_bits_0 ,block_sign_shuffle_2_1 ); 3010signs_0 = _mm_cmpeq_epi8 (_mm_and_si128 (signs_0 ,bit_selector_mask_0 ),bit_selector_mask_0 ); 3011signs_1 = _mm_cmpeq_epi8 (_mm_and_si128 (signs_1 ,bit_selector_mask_1 ),bit_selector_mask_1 ); 3012const __m128i q8s_2_0 = _mm_sign_epi8 (q8_2_0 ,_mm_or_si128 (signs_0 ,mone )); 3013const __m128i q8s_2_1 = _mm_sign_epi8 (q8_2_1 ,_mm_or_si128 (signs_1 ,mone )); 3014 3015signs_0 = _mm_shuffle_epi8 (full_sign_bits_1 ,block_sign_shuffle_1_0 ); 3016signs_1 = _mm_shuffle_epi8 (full_sign_bits_1 ,block_sign_shuffle_1_1 ); 3017signs_0 = _mm_cmpeq_epi8 (_mm_and_si128 (signs_0 ,bit_selector_mask_0 ),bit_selector_mask_0 ); 3018signs_1 = _mm_cmpeq_epi8 (_mm_and_si128 (signs_1 ,bit_selector_mask_1 ),bit_selector_mask_1 ); 3019const __m128i q8s_3_0 = _mm_sign_epi8 (q8_3_0 ,_mm_or_si128 (signs_0 ,mone )); 3020const __m128i q8s_3_1 = _mm_sign_epi8 (q8_3_1 ,_mm_or_si128 (signs_1 ,mone )); 3021 3022signs_0 = _mm_shuffle_epi8 (full_sign_bits_1 ,block_sign_shuffle_2_0 ); 3023signs_1 = _mm_shuffle_epi8 (full_sign_bits_1 ,block_sign_shuffle_2_1 ); 3024signs_0 = _mm_cmpeq_epi8 (_mm_and_si128 (signs_0 ,bit_selector_mask_0 ),bit_selector_mask_0 ); 3025signs_1 = _mm_cmpeq_epi8 (_mm_and_si128 (signs_1 ,bit_selector_mask_1 ),bit_selector_mask_1 ); 3026const __m128i q8s_4_0 = _mm_sign_epi8 (q8_4_0 ,_mm_or_si128 (signs_0 ,mone )); 3027const __m128i q8s_4_1 = _mm_sign_epi8 (q8_4_1 ,_mm_or_si128 (signs_1 ,mone )); 3028 3029const __m128i dot1_0 = _mm_maddubs_epi16 (q2_1_0 ,q8s_1_0 ); 3030const __m128i dot1_1 = _mm_maddubs_epi16 (q2_1_1 ,q8s_1_1 ); 3031const __m128i dot2_0 = _mm_maddubs_epi16 (q2_2_0 ,q8s_2_0 ); 3032const __m128i dot2_1 = _mm_maddubs_epi16 (q2_2_1 ,q8s_2_1 ); 3033const __m128i dot3_0 = _mm_maddubs_epi16 (q2_3_0 ,q8s_3_0 ); 3034const __m128i dot3_1 = _mm_maddubs_epi16 (q2_3_1 ,q8s_3_1 ); 3035const __m128i dot4_0 = _mm_maddubs_epi16 (q2_4_0 ,q8s_4_0 ); 3036const __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 )); 3039const __m128i sc1_0 = _mm_cvtepi8_epi16 (sc_tmp ); 3040const __m128i sc1_1 = _mm_cvtepi8_epi16 (_mm_srli_si128 (sc_tmp ,8 )); 3041sc_tmp = _mm_shuffle_epi8 (scales ,get_scale_shuffle (ib32 + 1 )); 3042const __m128i sc2_0 = _mm_cvtepi8_epi16 (sc_tmp ); 3043const __m128i sc2_1 = _mm_cvtepi8_epi16 (_mm_srli_si128 (sc_tmp ,8 )); 3044sc_tmp = _mm_shuffle_epi8 (scales ,get_scale_shuffle (ib32 + 2 )); 3045const __m128i sc3_0 = _mm_cvtepi8_epi16 (sc_tmp ); 3046const __m128i sc3_1 = _mm_cvtepi8_epi16 (_mm_srli_si128 (sc_tmp ,8 )); 3047sc_tmp = _mm_shuffle_epi8 (scales ,get_scale_shuffle (ib32 + 3 )); 3048const __m128i sc4_0 = _mm_cvtepi8_epi16 (sc_tmp ); 3049const __m128i sc4_1 = _mm_cvtepi8_epi16 (_mm_srli_si128 (sc_tmp ,8 )); 3050 3051sumi1_0 = _mm_add_epi32 (sumi1_0 ,_mm_madd_epi16 (dot1_0 ,sc1_0 )); 3052sumi1_1 = _mm_add_epi32 (sumi1_1 ,_mm_madd_epi16 (dot1_1 ,sc1_1 )); 3053sumi2_0 = _mm_add_epi32 (sumi2_0 ,_mm_madd_epi16 (dot2_0 ,sc2_0 )); 3054sumi2_1 = _mm_add_epi32 (sumi2_1 ,_mm_madd_epi16 (dot2_1 ,sc2_1 )); 3055sumi1_0 = _mm_add_epi32 (sumi1_0 ,_mm_madd_epi16 (dot3_0 ,sc3_0 )); 3056sumi1_1 = _mm_add_epi32 (sumi1_1 ,_mm_madd_epi16 (dot3_1 ,sc3_1 )); 3057sumi2_0 = _mm_add_epi32 (sumi2_0 ,_mm_madd_epi16 (dot4_0 ,sc4_0 )); 3058sumi2_1 = _mm_add_epi32 (sumi2_1 ,_mm_madd_epi16 (dot4_1 ,sc4_1 )); 3059 } 3060 3061accumf = _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 3068UNUSED (x ); 3069UNUSED (y ); 3070UNUSED (nb ); 3071ggml_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 ) { 3076assert (n %QK_K == 0 ); 3077assert (nrc == 1 ); 3078UNUSED (nrc ); 3079UNUSED (bx ); 3080UNUSED (by ); 3081UNUSED (bs ); 3082 3083const block_iq2_s * GGML_RESTRICT x = vx ; 3084const block_q8_K * GGML_RESTRICT y = vy ; 3085 3086const int nb = n /QK_K ; 3087 3088#if defined(__AVX2__ ) 3089 3090static const uint8_t k_mask1 [32 ]= {0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 , 30910x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 3092 }; 3093 3094static const uint8_t k_mask2 [32 ]= {0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 30950x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 3096 }; 3097 3098const __m128i m4 = _mm_set1_epi8 (0xf ); 3099const __m128i m1 = _mm_set1_epi8 (1 ); 3100 3101const __m256i mask1 = _mm256_loadu_si256 ((const __m256i * )k_mask1 ); 3102const __m256i mask2 = _mm256_loadu_si256 ((const __m256i * )k_mask2 ); 3103 3104uint64_t aux64 ; 3105 3106__m256 accumf = _mm256_setzero_ps (); 3107for (int i = 0 ;i < nb ;++ i ) { 3108const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3109const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 3110const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 3111const uint16_t * GGML_RESTRICT signs = (const uint16_t * )(x [i ].qs + QK_K /8 ); 3112const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3113 3114memcpy (& aux64 ,x [i ].scales ,8 ); 3115const __m128i scales8 = _mm_add_epi8 (_mm_slli_epi16 (_mm_and_si128 (_mm_set_epi64x (aux64 >>4 ,aux64 ),m4 ),1 ),m1 ); 3116const __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 (); 3120for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 3121const __m256i q8_1 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 3122const __m256i q8_2 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 3123const __m256i q2_1 = _mm256_set_epi64x (iq2s_grid [qs [3 ] | ((qh [ib32 + 0 ] <<2 )& 0x300 )], 3124iq2s_grid [qs [2 ] | ((qh [ib32 + 0 ] <<4 )& 0x300 )], 3125iq2s_grid [qs [1 ] | ((qh [ib32 + 0 ] <<6 )& 0x300 )], 3126iq2s_grid [qs [0 ] | ((qh [ib32 + 0 ] <<8 )& 0x300 )]); 3127const __m256i q2_2 = _mm256_set_epi64x (iq2s_grid [qs [7 ] | ((qh [ib32 + 1 ] <<2 )& 0x300 )], 3128iq2s_grid [qs [6 ] | ((qh [ib32 + 1 ] <<4 )& 0x300 )], 3129iq2s_grid [qs [5 ] | ((qh [ib32 + 1 ] <<6 )& 0x300 )], 3130iq2s_grid [qs [4 ] | ((qh [ib32 + 1 ] <<8 )& 0x300 )]); 3131qs += 8 ; 3132 3133__m256i aux256 = _mm256_set1_epi32 (signs [0 ] | ((uint32_t )signs [1 ] <<16 )); 3134aux256 = _mm256_and_si256 (_mm256_shuffle_epi8 (aux256 ,mask1 ),mask2 ); 3135const __m256i s2_1 = _mm256_cmpeq_epi8 (aux256 ,mask2 ); 3136const __m256i q8s_1 = _mm256_sub_epi8 (_mm256_xor_si256 (s2_1 ,q8_1 ),s2_1 ); 3137 3138aux256 = _mm256_set1_epi32 (signs [2 ] | ((uint32_t )signs [3 ] <<16 )); 3139aux256 = _mm256_and_si256 (_mm256_shuffle_epi8 (aux256 ,mask1 ),mask2 ); 3140const __m256i s2_2 = _mm256_cmpeq_epi8 (aux256 ,mask2 ); 3141const __m256i q8s_2 = _mm256_sub_epi8 (_mm256_xor_si256 (s2_2 ,q8_2 ),s2_2 ); 3142 3143signs += 4 ; 3144 3145const __m256i dot1 = _mm256_maddubs_epi16 (q2_1 ,q8s_1 );// blocks 2*ib32+0, 2*ib32+1 3146const __m256i dot2 = _mm256_maddubs_epi16 (q2_2 ,q8s_2 );// blocks 2*ib32+2, 2*ib32+3 3147 3148const __m256i p1 = _mm256_madd_epi16 (dot1 ,_mm256_shuffle_epi8 (scales16 ,get_scale_shuffle_k4 (ib32 + 0 ))); 3149const __m256i p2 = _mm256_madd_epi16 (dot2 ,_mm256_shuffle_epi8 (scales16 ,get_scale_shuffle_k4 (ib32 + 1 ))); 3150sumi1 = _mm256_add_epi32 (sumi1 ,p1 ); 3151sumi2 = _mm256_add_epi32 (sumi2 ,p2 ); 3152 } 3153 3154accumf = _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__ ) 3161static const uint8_t k_mask1 [32 ]= {0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 , 31620x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 3163 }; 3164 3165static const uint8_t k_mask2 [32 ]= {0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 31660x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 3167 }; 3168 3169const __m128i m4 = _mm_set1_epi8 (0xf ); 3170const __m128i m1 = _mm_set1_epi8 (1 ); 3171 3172const __m128i mask1_0 = _mm_loadu_si128 ((const __m128i * )k_mask1 ); 3173const __m128i mask1_1 = _mm_loadu_si128 ((const __m128i * )k_mask1 + 1 ); 3174const __m128i mask2_0 = _mm_loadu_si128 ((const __m128i * )k_mask2 ); 3175const __m128i mask2_1 = _mm_loadu_si128 ((const __m128i * )k_mask2 + 1 ); 3176 3177uint64_t aux64 ; 3178 3179__m256 accumf = _mm256_setzero_ps (); 3180for (int i = 0 ;i < nb ;++ i ) { 3181const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3182const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 3183const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 3184const uint16_t * GGML_RESTRICT signs = (const uint16_t * )(x [i ].qs + QK_K /8 ); 3185const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3186 3187memcpy (& aux64 ,x [i ].scales ,8 ); 3188const __m128i scales8 = _mm_add_epi8 (_mm_slli_epi16 (_mm_and_si128 (_mm_set_epi64x (aux64 >>4 ,aux64 ),m4 ),1 ),m1 ); 3189const __m128i scales16_0 = _mm_cvtepi8_epi16 (scales8 ); 3190const __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 (); 3196for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 3197const __m128i q8_1_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3198const __m128i q8_1_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3199const __m128i q8_2_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3200const __m128i q8_2_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3201const __m128i q2_1_0 = _mm_set_epi64x (iq2s_grid [qs [1 ] | ((qh [ib32 + 0 ] <<6 )& 0x300 )], 3202iq2s_grid [qs [0 ] | ((qh [ib32 + 0 ] <<8 )& 0x300 )]); 3203const __m128i q2_1_1 = _mm_set_epi64x (iq2s_grid [qs [3 ] | ((qh [ib32 + 0 ] <<2 )& 0x300 )], 3204iq2s_grid [qs [2 ] | ((qh [ib32 + 0 ] <<4 )& 0x300 )]); 3205const __m128i q2_2_0 = _mm_set_epi64x (iq2s_grid [qs [5 ] | ((qh [ib32 + 1 ] <<6 )& 0x300 )], 3206iq2s_grid [qs [4 ] | ((qh [ib32 + 1 ] <<8 )& 0x300 )]); 3207const __m128i q2_2_1 = _mm_set_epi64x (iq2s_grid [qs [7 ] | ((qh [ib32 + 1 ] <<2 )& 0x300 )], 3208iq2s_grid [qs [6 ] | ((qh [ib32 + 1 ] <<4 )& 0x300 )]); 3209qs += 8 ; 3210 3211__m128i aux128_0 = _mm_set1_epi32 (signs [0 ] | ((uint32_t )signs [1 ] <<16 )); 3212__m128i aux128_1 = aux128_0 ; 3213aux128_0 = _mm_and_si128 (_mm_shuffle_epi8 (aux128_0 ,mask1_0 ),mask2_0 ); 3214aux128_1 = _mm_and_si128 (_mm_shuffle_epi8 (aux128_1 ,mask1_1 ),mask2_1 ); 3215const __m128i s2_1_0 = _mm_cmpeq_epi8 (aux128_0 ,mask2_0 ); 3216const __m128i s2_1_1 = _mm_cmpeq_epi8 (aux128_1 ,mask2_1 ); 3217const __m128i q8s_1_0 = _mm_sub_epi8 (_mm_xor_si128 (s2_1_0 ,q8_1_0 ),s2_1_0 ); 3218const __m128i q8s_1_1 = _mm_sub_epi8 (_mm_xor_si128 (s2_1_1 ,q8_1_1 ),s2_1_1 ); 3219 3220aux128_0 = _mm_set1_epi32 (signs [2 ] | ((uint32_t )signs [3 ] <<16 )); 3221aux128_1 = aux128_0 ; 3222aux128_0 = _mm_and_si128 (_mm_shuffle_epi8 (aux128_0 ,mask1_0 ),mask2_0 ); 3223aux128_1 = _mm_and_si128 (_mm_shuffle_epi8 (aux128_1 ,mask1_1 ),mask2_1 ); 3224const __m128i s2_2_0 = _mm_cmpeq_epi8 (aux128_0 ,mask2_0 ); 3225const __m128i s2_2_1 = _mm_cmpeq_epi8 (aux128_1 ,mask2_1 ); 3226const __m128i q8s_2_0 = _mm_sub_epi8 (_mm_xor_si128 (s2_2_0 ,q8_2_0 ),s2_2_0 ); 3227const __m128i q8s_2_1 = _mm_sub_epi8 (_mm_xor_si128 (s2_2_1 ,q8_2_1 ),s2_2_1 ); 3228 3229signs += 4 ; 3230 3231const __m128i dot1_0 = _mm_maddubs_epi16 (q2_1_0 ,q8s_1_0 ); 3232const __m128i dot1_1 = _mm_maddubs_epi16 (q2_1_1 ,q8s_1_1 ); 3233const __m128i dot2_0 = _mm_maddubs_epi16 (q2_2_0 ,q8s_2_0 ); 3234const __m128i dot2_1 = _mm_maddubs_epi16 (q2_2_1 ,q8s_2_1 ); 3235 3236const __m128i p1_0 = _mm_madd_epi16 (dot1_0 ,_mm_shuffle_epi8 (scales16_0 ,_mm256_extractf128_si256 (get_scale_shuffle_k4 (ib32 + 0 ),0 ))); 3237const __m128i p1_1 = _mm_madd_epi16 (dot1_1 ,_mm_shuffle_epi8 (scales16_1 ,_mm256_extractf128_si256 (get_scale_shuffle_k4 (ib32 + 0 ),1 ))); 3238const __m128i p2_0 = _mm_madd_epi16 (dot2_0 ,_mm_shuffle_epi8 (scales16_0 ,_mm256_extractf128_si256 (get_scale_shuffle_k4 (ib32 + 1 ),0 ))); 3239const __m128i p2_1 = _mm_madd_epi16 (dot2_1 ,_mm_shuffle_epi8 (scales16_1 ,_mm256_extractf128_si256 (get_scale_shuffle_k4 (ib32 + 1 ),1 ))); 3240sumi1_0 = _mm_add_epi32 (sumi1_0 ,p1_0 ); 3241sumi1_1 = _mm_add_epi32 (sumi1_1 ,p1_1 ); 3242sumi2_0 = _mm_add_epi32 (sumi2_0 ,p2_0 ); 3243sumi2_1 = _mm_add_epi32 (sumi2_1 ,p2_1 ); 3244 } 3245 3246accumf = _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 3253UNUSED (x ); 3254UNUSED (y ); 3255UNUSED (nb ); 3256ggml_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 ) { 3261assert (n %QK_K == 0 ); 3262assert (nrc == 1 ); 3263UNUSED (nrc ); 3264UNUSED (bx ); 3265UNUSED (by ); 3266UNUSED (bs ); 3267 3268const block_iq3_xxs * GGML_RESTRICT x = vx ; 3269const block_q8_K * GGML_RESTRICT y = vy ; 3270 3271const int nb = n /QK_K ; 3272 3273#if defined(__AVX2__ ) 3274 3275const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 3276 3277uint32_t aux32 [2 ]; 3278 3279__m256 accumf = _mm256_setzero_ps (); 3280for (int i = 0 ;i < nb ;++ i ) { 3281const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3282const uint8_t * GGML_RESTRICT q3 = x [i ].qs ; 3283const uint8_t * GGML_RESTRICT gas = x [i ].qs + QK_K /4 ; 3284const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3285__m256i sumi1 = _mm256_setzero_si256 (); 3286__m256i sumi2 = _mm256_setzero_si256 (); 3287for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 3288const __m256i q8_1 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 3289const __m256i q8_2 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 3290const __m256i q2_1 = _mm256_set_epi32 (iq3xxs_grid [q3 [7 ]],iq3xxs_grid [q3 [6 ]],iq3xxs_grid [q3 [5 ]],iq3xxs_grid [q3 [4 ]], 3291iq3xxs_grid [q3 [3 ]],iq3xxs_grid [q3 [2 ]],iq3xxs_grid [q3 [1 ]],iq3xxs_grid [q3 [0 ]]); 3292q3 += 8 ; 3293const __m256i q2_2 = _mm256_set_epi32 (iq3xxs_grid [q3 [7 ]],iq3xxs_grid [q3 [6 ]],iq3xxs_grid [q3 [5 ]],iq3xxs_grid [q3 [4 ]], 3294iq3xxs_grid [q3 [3 ]],iq3xxs_grid [q3 [2 ]],iq3xxs_grid [q3 [1 ]],iq3xxs_grid [q3 [0 ]]); 3295q3 += 8 ; 3296memcpy (aux32 ,gas ,8 );gas += 8 ; 3297const __m256i s2_1 = _mm256_set_epi64x (signs64 [(aux32 [0 ] >>21 )& 127 ],signs64 [(aux32 [0 ] >>14 )& 127 ], 3298signs64 [(aux32 [0 ] >>7 )& 127 ],signs64 [(aux32 [0 ] >>0 )& 127 ]); 3299const __m256i s2_2 = _mm256_set_epi64x (signs64 [(aux32 [1 ] >>21 )& 127 ],signs64 [(aux32 [1 ] >>14 )& 127 ], 3300signs64 [(aux32 [1 ] >>7 )& 127 ],signs64 [(aux32 [1 ] >>0 )& 127 ]); 3301const __m256i q8s_1 = _mm256_sign_epi8 (q8_1 ,s2_1 ); 3302const __m256i q8s_2 = _mm256_sign_epi8 (q8_2 ,s2_2 ); 3303const __m256i dot1 = _mm256_maddubs_epi16 (q2_1 ,q8s_1 ); 3304const __m256i dot2 = _mm256_maddubs_epi16 (q2_2 ,q8s_2 ); 3305const uint16_t ls1 = aux32 [0 ] >>28 ; 3306const uint16_t ls2 = aux32 [1 ] >>28 ; 3307const __m256i p1 = _mm256_madd_epi16 (dot1 ,_mm256_set1_epi16 (2 * ls1 + 1 )); 3308const __m256i p2 = _mm256_madd_epi16 (dot2 ,_mm256_set1_epi16 (2 * ls2 + 1 )); 3309sumi1 = _mm256_add_epi32 (sumi1 ,p1 ); 3310sumi2 = _mm256_add_epi32 (sumi2 ,p2 ); 3311 } 3312 3313accumf = _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__ ) 3320const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 3321 3322uint32_t aux32 [2 ]; 3323 3324__m256 accumf = _mm256_setzero_ps (); 3325for (int i = 0 ;i < nb ;++ i ) { 3326const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3327const uint8_t * GGML_RESTRICT q3 = x [i ].qs ; 3328const uint8_t * GGML_RESTRICT gas = x [i ].qs + QK_K /4 ; 3329const 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 (); 3334for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 3335const __m128i q8_1_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3336const __m128i q8_1_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3337const __m128i q8_2_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3338const __m128i q8_2_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3339const __m128i q2_1_0 = _mm_set_epi32 (iq3xxs_grid [q3 [3 ]],iq3xxs_grid [q3 [2 ]],iq3xxs_grid [q3 [1 ]],iq3xxs_grid [q3 [0 ]]); 3340const __m128i q2_1_1 = _mm_set_epi32 (iq3xxs_grid [q3 [7 ]],iq3xxs_grid [q3 [6 ]],iq3xxs_grid [q3 [5 ]],iq3xxs_grid [q3 [4 ]]); 3341q3 += 8 ; 3342const __m128i q2_2_0 = _mm_set_epi32 (iq3xxs_grid [q3 [3 ]],iq3xxs_grid [q3 [2 ]],iq3xxs_grid [q3 [1 ]],iq3xxs_grid [q3 [0 ]]); 3343const __m128i q2_2_1 = _mm_set_epi32 (iq3xxs_grid [q3 [7 ]],iq3xxs_grid [q3 [6 ]],iq3xxs_grid [q3 [5 ]],iq3xxs_grid [q3 [4 ]]); 3344q3 += 8 ; 3345memcpy (aux32 ,gas ,8 );gas += 8 ; 3346const __m128i s2_1_0 = _mm_set_epi64x (signs64 [(aux32 [0 ] >>7 )& 127 ],signs64 [(aux32 [0 ] >>0 )& 127 ]); 3347const __m128i s2_1_1 = _mm_set_epi64x (signs64 [(aux32 [0 ] >>21 )& 127 ],signs64 [(aux32 [0 ] >>14 )& 127 ]); 3348const __m128i s2_2_0 = _mm_set_epi64x (signs64 [(aux32 [1 ] >>7 )& 127 ],signs64 [(aux32 [1 ] >>0 )& 127 ]); 3349const __m128i s2_2_1 = _mm_set_epi64x (signs64 [(aux32 [1 ] >>21 )& 127 ],signs64 [(aux32 [1 ] >>14 )& 127 ]); 3350const __m128i q8s_1_0 = _mm_sign_epi8 (q8_1_0 ,s2_1_0 ); 3351const __m128i q8s_1_1 = _mm_sign_epi8 (q8_1_1 ,s2_1_1 ); 3352const __m128i q8s_2_0 = _mm_sign_epi8 (q8_2_0 ,s2_2_0 ); 3353const __m128i q8s_2_1 = _mm_sign_epi8 (q8_2_1 ,s2_2_1 ); 3354const __m128i dot1_0 = _mm_maddubs_epi16 (q2_1_0 ,q8s_1_0 ); 3355const __m128i dot1_1 = _mm_maddubs_epi16 (q2_1_1 ,q8s_1_1 ); 3356const __m128i dot2_0 = _mm_maddubs_epi16 (q2_2_0 ,q8s_2_0 ); 3357const __m128i dot2_1 = _mm_maddubs_epi16 (q2_2_1 ,q8s_2_1 ); 3358const uint16_t ls1 = aux32 [0 ] >>28 ; 3359const uint16_t ls2 = aux32 [1 ] >>28 ; 3360const __m128i p1_0 = _mm_madd_epi16 (dot1_0 ,_mm_set1_epi16 (2 * ls1 + 1 )); 3361const __m128i p1_1 = _mm_madd_epi16 (dot1_1 ,_mm_set1_epi16 (2 * ls1 + 1 )); 3362const __m128i p2_0 = _mm_madd_epi16 (dot2_0 ,_mm_set1_epi16 (2 * ls2 + 1 )); 3363const __m128i p2_1 = _mm_madd_epi16 (dot2_1 ,_mm_set1_epi16 (2 * ls2 + 1 )); 3364sumi1_0 = _mm_add_epi32 (sumi1_0 ,p1_0 ); 3365sumi1_1 = _mm_add_epi32 (sumi1_1 ,p1_1 ); 3366sumi2_0 = _mm_add_epi32 (sumi2_0 ,p2_0 ); 3367sumi2_1 = _mm_add_epi32 (sumi2_1 ,p2_1 ); 3368 } 3369 3370accumf = _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 3377UNUSED (x ); 3378UNUSED (y ); 3379UNUSED (nb ); 3380ggml_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 ) { 3385assert (n %QK_K == 0 ); 3386assert (nrc == 1 ); 3387UNUSED (nrc ); 3388UNUSED (bx ); 3389UNUSED (by ); 3390UNUSED (bs ); 3391 3392const block_iq3_s * GGML_RESTRICT x = vx ; 3393const block_q8_K * GGML_RESTRICT y = vy ; 3394 3395const int nb = n /QK_K ; 3396 3397#if defined(__AVX2__ ) 3398 3399static const uint8_t k_mask1 [32 ]= {0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 , 34000x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 3401 }; 3402 3403static const uint8_t k_mask2 [32 ]= {0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 34040x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 3405 }; 3406 3407const __m256i mask1 = _mm256_loadu_si256 ((const __m256i * )k_mask1 ); 3408const __m256i mask2 = _mm256_loadu_si256 ((const __m256i * )k_mask2 ); 3409 3410const __m256i idx_shift = _mm256_set_epi32 (1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ); 3411const __m256i idx_mask = _mm256_set1_epi32 (256 ); 3412 3413typedef union { 3414__m256i vec [2 ]; 3415uint32_t index [16 ]; 3416 }index_t ; 3417 3418index_t idx ; 3419 3420__m256 accumf = _mm256_setzero_ps (); 3421for (int i = 0 ;i < nb ;++ i ) { 3422const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3423const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 3424const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 3425const uint16_t * GGML_RESTRICT signs = (const uint16_t * )x [i ].signs ; 3426const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3427__m256i sumi1 = _mm256_setzero_si256 (); 3428__m256i sumi2 = _mm256_setzero_si256 (); 3429for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 3430const __m256i q8_1 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 3431const __m256i q8_2 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 3432const __m256i idx_l = _mm256_cvtepu8_epi16 (_mm_loadu_si128 ((const __m128i * )qs ));qs += 16 ; 3433idx .vec [0 ]= _mm256_set1_epi32 (qh [ib32 + 0 ]); 3434idx .vec [1 ]= _mm256_set1_epi32 (qh [ib32 + 1 ]); 3435idx .vec [0 ]= _mm256_and_si256 (_mm256_sllv_epi32 (idx .vec [0 ],idx_shift ),idx_mask ); 3436idx .vec [1 ]= _mm256_and_si256 (_mm256_sllv_epi32 (idx .vec [1 ],idx_shift ),idx_mask ); 3437idx .vec [0 ]= _mm256_or_si256 (idx .vec [0 ],_mm256_cvtepi16_epi32 (_mm256_castsi256_si128 (idx_l ))); 3438idx .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); 3443const __m256i q2_1 = _mm256_set_epi32 ( 3444iq3s_grid [idx .index [7 ]],iq3s_grid [idx .index [6 ]],iq3s_grid [idx .index [5 ]],iq3s_grid [idx .index [4 ]], 3445iq3s_grid [idx .index [3 ]],iq3s_grid [idx .index [2 ]],iq3s_grid [idx .index [1 ]],iq3s_grid [idx .index [0 ]] 3446 ); 3447const __m256i q2_2 = _mm256_set_epi32 ( 3448iq3s_grid [idx .index [15 ]],iq3s_grid [idx .index [14 ]],iq3s_grid [idx .index [13 ]],iq3s_grid [idx .index [12 ]], 3449iq3s_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 )); 3453aux256 = _mm256_and_si256 (_mm256_shuffle_epi8 (aux256 ,mask1 ),mask2 ); 3454const __m256i s2_1 = _mm256_cmpeq_epi8 (aux256 ,mask2 ); 3455const __m256i q8s_1 = _mm256_sub_epi8 (_mm256_xor_si256 (s2_1 ,q8_1 ),s2_1 ); 3456 3457aux256 = _mm256_set1_epi32 (signs [2 ] | (signs [3 ] <<16 )); 3458aux256 = _mm256_and_si256 (_mm256_shuffle_epi8 (aux256 ,mask1 ),mask2 ); 3459const __m256i s2_2 = _mm256_cmpeq_epi8 (aux256 ,mask2 ); 3460const __m256i q8s_2 = _mm256_sub_epi8 (_mm256_xor_si256 (s2_2 ,q8_2 ),s2_2 ); 3461 3462signs += 4 ; 3463 3464const __m256i dot1 = _mm256_maddubs_epi16 (q2_1 ,q8s_1 ); 3465const __m256i dot2 = _mm256_maddubs_epi16 (q2_2 ,q8s_2 ); 3466const uint16_t ls1 = x [i ].scales [ib32 /2 ]& 0xf ; 3467const uint16_t ls2 = x [i ].scales [ib32 /2 ] >>4 ; 3468const __m256i p1 = _mm256_madd_epi16 (dot1 ,_mm256_set1_epi16 (2 * ls1 + 1 )); 3469const __m256i p2 = _mm256_madd_epi16 (dot2 ,_mm256_set1_epi16 (2 * ls2 + 1 )); 3470sumi1 = _mm256_add_epi32 (sumi1 ,p1 ); 3471sumi2 = _mm256_add_epi32 (sumi2 ,p2 ); 3472 } 3473 3474accumf = _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__ ) 3481static const uint8_t k_mask1 [32 ]= {0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 , 34820x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 3483 }; 3484 3485static const uint8_t k_mask2 [32 ]= {0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 34860x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 3487 }; 3488 3489const __m128i mask1_0 = _mm_loadu_si128 ((const __m128i * )k_mask1 ); 3490const __m128i mask1_1 = _mm_loadu_si128 ((const __m128i * )k_mask1 + 1 ); 3491const __m128i mask2_0 = _mm_loadu_si128 ((const __m128i * )k_mask2 ); 3492const __m128i mask2_1 = _mm_loadu_si128 ((const __m128i * )k_mask2 + 1 ); 3493 3494const __m128i idx_mul_0 = _mm_set_epi32 (32 ,64 ,128 ,256 ); 3495const __m128i idx_mul_1 = _mm_set_epi32 (2 ,4 ,8 ,16 ); 3496const __m128i idx_mask = _mm_set1_epi32 (256 ); 3497 3498typedef union { 3499__m128i vec [4 ]; 3500uint32_t index [16 ]; 3501 }index_t ; 3502 3503index_t idx ; 3504 3505__m256 accumf = _mm256_setzero_ps (); 3506for (int i = 0 ;i < nb ;++ i ) { 3507const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3508const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 3509const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 3510const uint16_t * GGML_RESTRICT signs = (const uint16_t * )x [i ].signs ; 3511const 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 (); 3516for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 3517const __m128i q8_1_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3518const __m128i q8_1_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3519const __m128i q8_2_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3520const __m128i q8_2_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3521const __m128i qs_tmp = _mm_loadu_si128 ((const __m128i * )qs ); 3522const __m128i idx_l_0 = _mm_cvtepu8_epi16 (qs_tmp ); 3523const __m128i idx_l_1 = _mm_cvtepu8_epi16 (_mm_srli_si128 (qs_tmp ,8 ));qs += 16 ; 3524idx .vec [0 ]= _mm_set1_epi32 (qh [ib32 + 0 ]); 3525idx .vec [1 ]= idx .vec [0 ]; 3526idx .vec [2 ]= _mm_set1_epi32 (qh [ib32 + 1 ]); 3527idx .vec [3 ]= idx .vec [2 ]; 3528 3529idx .vec [0 ]= _mm_and_si128 (_mm_mullo_epi32 (idx .vec [0 ],idx_mul_0 ),idx_mask ); 3530idx .vec [1 ]= _mm_and_si128 (_mm_mullo_epi32 (idx .vec [1 ],idx_mul_1 ),idx_mask ); 3531idx .vec [2 ]= _mm_and_si128 (_mm_mullo_epi32 (idx .vec [2 ],idx_mul_0 ),idx_mask ); 3532idx .vec [3 ]= _mm_and_si128 (_mm_mullo_epi32 (idx .vec [3 ],idx_mul_1 ),idx_mask ); 3533 3534idx .vec [0 ]= _mm_or_si128 (idx .vec [0 ],_mm_cvtepi16_epi32 (idx_l_0 )); 3535idx .vec [1 ]= _mm_or_si128 (idx .vec [1 ],_mm_cvtepi16_epi32 (_mm_srli_si128 (idx_l_0 ,8 ))); 3536idx .vec [2 ]= _mm_or_si128 (idx .vec [2 ],_mm_cvtepi16_epi32 (idx_l_1 )); 3537idx .vec [3 ]= _mm_or_si128 (idx .vec [3 ],_mm_cvtepi16_epi32 (_mm_srli_si128 (idx_l_1 ,8 ))); 3538 3539const __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 ]]); 3540const __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 ]]); 3541const __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 ]]); 3542const __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 ; 3546aux128_0 = _mm_and_si128 (_mm_shuffle_epi8 (aux128_0 ,mask1_0 ),mask2_0 ); 3547aux128_1 = _mm_and_si128 (_mm_shuffle_epi8 (aux128_1 ,mask1_1 ),mask2_1 ); 3548const __m128i s2_1_0 = _mm_cmpeq_epi8 (aux128_0 ,mask2_0 ); 3549const __m128i s2_1_1 = _mm_cmpeq_epi8 (aux128_1 ,mask2_1 ); 3550const __m128i q8s_1_0 = _mm_sub_epi8 (_mm_xor_si128 (s2_1_0 ,q8_1_0 ),s2_1_0 ); 3551const __m128i q8s_1_1 = _mm_sub_epi8 (_mm_xor_si128 (s2_1_1 ,q8_1_1 ),s2_1_1 ); 3552 3553aux128_0 = _mm_set1_epi32 (signs [2 ] | (signs [3 ] <<16 )); 3554aux128_1 = aux128_0 ; 3555aux128_0 = _mm_and_si128 (_mm_shuffle_epi8 (aux128_0 ,mask1_0 ),mask2_0 ); 3556aux128_1 = _mm_and_si128 (_mm_shuffle_epi8 (aux128_1 ,mask1_1 ),mask2_1 ); 3557const __m128i s2_2_0 = _mm_cmpeq_epi8 (aux128_0 ,mask2_0 ); 3558const __m128i s2_2_1 = _mm_cmpeq_epi8 (aux128_1 ,mask2_1 ); 3559const __m128i q8s_2_0 = _mm_sub_epi8 (_mm_xor_si128 (s2_2_0 ,q8_2_0 ),s2_2_0 ); 3560const __m128i q8s_2_1 = _mm_sub_epi8 (_mm_xor_si128 (s2_2_1 ,q8_2_1 ),s2_2_1 ); 3561 3562signs += 4 ; 3563 3564const __m128i dot1_0 = _mm_maddubs_epi16 (q2_1_0 ,q8s_1_0 ); 3565const __m128i dot1_1 = _mm_maddubs_epi16 (q2_1_1 ,q8s_1_1 ); 3566const __m128i dot2_0 = _mm_maddubs_epi16 (q2_2_0 ,q8s_2_0 ); 3567const __m128i dot2_1 = _mm_maddubs_epi16 (q2_2_1 ,q8s_2_1 ); 3568const uint16_t ls1 = x [i ].scales [ib32 /2 ]& 0xf ; 3569const uint16_t ls2 = x [i ].scales [ib32 /2 ] >>4 ; 3570const __m128i p1_0 = _mm_madd_epi16 (dot1_0 ,_mm_set1_epi16 (2 * ls1 + 1 )); 3571const __m128i p1_1 = _mm_madd_epi16 (dot1_1 ,_mm_set1_epi16 (2 * ls1 + 1 )); 3572const __m128i p2_0 = _mm_madd_epi16 (dot2_0 ,_mm_set1_epi16 (2 * ls2 + 1 )); 3573const __m128i p2_1 = _mm_madd_epi16 (dot2_1 ,_mm_set1_epi16 (2 * ls2 + 1 )); 3574sumi1_0 = _mm_add_epi32 (sumi1_0 ,p1_0 ); 3575sumi1_1 = _mm_add_epi32 (sumi1_1 ,p1_1 ); 3576sumi2_0 = _mm_add_epi32 (sumi2_0 ,p2_0 ); 3577sumi2_1 = _mm_add_epi32 (sumi2_1 ,p2_1 ); 3578 } 3579 3580accumf = _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 3587UNUSED (x ); 3588UNUSED (y ); 3589UNUSED (nb ); 3590ggml_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 ) { 3595assert (n %QK_K == 0 ); 3596assert (nrc == 1 ); 3597UNUSED (nrc ); 3598UNUSED (bx ); 3599UNUSED (by ); 3600UNUSED (bs ); 3601 3602const block_iq1_s * GGML_RESTRICT x = vx ; 3603const block_q8_K * GGML_RESTRICT y = vy ; 3604 3605const int nb = n /QK_K ; 3606 3607#if defined__AVX2__ 3608 3609__m256 accum = _mm256_setzero_ps (); 3610float accum1 = 0 ; 3611for (int i = 0 ;i < nb ;++ i ) { 3612 3613const int8_t * q8 = y [i ].qs ; 3614const uint8_t * qs = x [i ].qs ; 3615const uint16_t * qh = x [i ].qh ; 3616 3617__m256i sumi = _mm256_setzero_si256 (); 3618int sumi1 = 0 ; 3619for (int ib = 0 ;ib < QK_K /32 ;ib += 2 ) { 3620#ifdef __BMI2__ 3621const uint64_t packed_idx1 = _pdep_u64 (* (const uint32_t * )qs ,0x00ff00ff00ff00ffULL ) |_pdep_u64 (qh [ib ],0x700070007000700ULL ); 3622const uint64_t packed_idx2 = _pdep_u64 (* (const uint32_t * )(qs + 4 ),0x00ff00ff00ff00ffULL ) |_pdep_u64 (qh [ib + 1 ],0x700070007000700ULL ); 3623const uint16_t * idx1 = (const uint16_t * )(& packed_idx1 ); 3624const uint16_t * idx2 = (const uint16_t * )(& packed_idx2 ); 3625const __m256i q1b_1 = _mm256_set_epi64x (iq1s_grid [idx1 [3 ]],iq1s_grid [idx1 [2 ]],iq1s_grid [idx1 [1 ]],iq1s_grid [idx1 [0 ]]); 3626const __m256i q1b_2 = _mm256_set_epi64x (iq1s_grid [idx2 [3 ]],iq1s_grid [idx2 [2 ]],iq1s_grid [idx2 [1 ]],iq1s_grid [idx2 [0 ]]); 3627#else 3628const __m256i q1b_1 = _mm256_set_epi64x (iq1s_grid [qs [3 ] | ((qh [ib + 0 ] >>1 )& 0x700 )],iq1s_grid [qs [2 ] | ((qh [ib + 0 ] <<2 )& 0x700 )], 3629iq1s_grid [qs [1 ] | ((qh [ib + 0 ] <<5 )& 0x700 )],iq1s_grid [qs [0 ] | ((qh [ib + 0 ] <<8 )& 0x700 )]); 3630const __m256i q1b_2 = _mm256_set_epi64x (iq1s_grid [qs [7 ] | ((qh [ib + 1 ] >>1 )& 0x700 )],iq1s_grid [qs [6 ] | ((qh [ib + 1 ] <<2 )& 0x700 )], 3631iq1s_grid [qs [5 ] | ((qh [ib + 1 ] <<5 )& 0x700 )],iq1s_grid [qs [4 ] | ((qh [ib + 1 ] <<8 )& 0x700 )]); 3632#endif 3633qs += 8 ; 3634const __m256i q8b_1 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 3635const __m256i q8b_2 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 3636 3637const __m256i dot1 = mul_add_epi8 (q1b_1 ,q8b_1 ); 3638const __m256i dot2 = mul_add_epi8 (q1b_2 ,q8b_2 ); 3639const int16_t ls1 = 2 * ((qh [ib + 0 ] >>12 )& 7 )+ 1 ; 3640const int16_t ls2 = 2 * ((qh [ib + 1 ] >>12 )& 7 )+ 1 ; 3641const __m256i p1 = _mm256_madd_epi16 (dot1 ,_mm256_set1_epi16 (ls1 )); 3642const __m256i p2 = _mm256_madd_epi16 (dot2 ,_mm256_set1_epi16 (ls2 )); 3643 3644sumi = _mm256_add_epi32 (sumi ,_mm256_add_epi32 (p1 ,p2 )); 3645sumi1 += (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 3649const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 3650accum = _mm256_fmadd_ps (_mm256_set1_ps (d ),_mm256_cvtepi32_ps (sumi ),accum ); 3651accum1 += 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 (); 3659float accum1 = 0 ; 3660for (int i = 0 ;i < nb ;++ i ) { 3661 3662const int8_t * q8 = y [i ].qs ; 3663const uint8_t * qs = x [i ].qs ; 3664const uint16_t * qh = x [i ].qh ; 3665 3666__m128i sumi1_0 = _mm_setzero_si128 (); 3667__m128i sumi1_1 = _mm_setzero_si128 (); 3668int sumi1 = 0 ; 3669for (int ib = 0 ;ib < QK_K /32 ;ib += 2 ) { 3670const __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 )]); 3671const __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 )]); 3672const __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 )]); 3673const __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 )]); 3674qs += 8 ; 3675const __m128i q8b_1_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3676const __m128i q8b_1_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3677const __m128i q8b_2_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3678const __m128i q8b_2_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3679 3680const __m128i dot1_0 = mul_add_epi8_sse (q1b_1_0 ,q8b_1_0 ); 3681const __m128i dot1_1 = mul_add_epi8_sse (q1b_1_1 ,q8b_1_1 ); 3682const __m128i dot2_0 = mul_add_epi8_sse (q1b_2_0 ,q8b_2_0 ); 3683const __m128i dot2_1 = mul_add_epi8_sse (q1b_2_1 ,q8b_2_1 ); 3684const int16_t ls1 = 2 * ((qh [ib + 0 ] >>12 )& 7 )+ 1 ; 3685const int16_t ls2 = 2 * ((qh [ib + 1 ] >>12 )& 7 )+ 1 ; 3686const __m128i p1_0 = _mm_madd_epi16 (dot1_0 ,_mm_set1_epi16 (ls1 )); 3687const __m128i p1_1 = _mm_madd_epi16 (dot1_1 ,_mm_set1_epi16 (ls1 )); 3688const __m128i p2_0 = _mm_madd_epi16 (dot2_0 ,_mm_set1_epi16 (ls2 )); 3689const __m128i p2_1 = _mm_madd_epi16 (dot2_1 ,_mm_set1_epi16 (ls2 )); 3690 3691sumi1_0 = _mm_add_epi32 (sumi1_0 ,_mm_add_epi32 (p1_0 ,p2_0 )); 3692sumi1_1 = _mm_add_epi32 (sumi1_1 ,_mm_add_epi32 (p1_1 ,p2_1 )); 3693sumi1 += (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 3697const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 3698accum = _mm256_add_ps (_mm256_mul_ps (_mm256_set1_ps (d ),_mm256_cvtepi32_ps (MM256_SET_M128I (sumi1_1 ,sumi1_0 ))),accum ); 3699accum1 += d * sumi1 ; 3700 3701 } 3702 3703* s = hsum_float_8 (accum )+ IQ1S_DELTA * accum1 ; 3704 3705#else 3706UNUSED (x ); 3707UNUSED (y ); 3708UNUSED (nb ); 3709ggml_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 ) { 3714assert (n %QK_K == 0 ); 3715assert (nrc == 1 ); 3716UNUSED (nrc ); 3717UNUSED (bx ); 3718UNUSED (by ); 3719UNUSED (bs ); 3720 3721const block_iq1_m * GGML_RESTRICT x = vx ; 3722const block_q8_K * GGML_RESTRICT y = vy ; 3723 3724const int nb = n /QK_K ; 3725 3726iq1m_scale_t scale ; 3727 3728#if defined__AVX2__ 3729 3730const __m256i mask = _mm256_set1_epi16 (0x7 ); 3731const __m256i mone = _mm256_set1_epi16 (1 ); 3732const __m256i mone8 = _mm256_set1_epi8 (1 ); 3733const __m256i mtwo8 = _mm256_set1_epi8 (2 ); 3734// VPSHUFB cannot cross 128-bit lanes so odd shifts go to upper half. 3735const __m256i scales_shift = _mm256_set_epi64x (9 ,3 ,6 ,0 ); 3736 3737__m256 accum1 = _mm256_setzero_ps (); 3738__m256 accum2 = _mm256_setzero_ps (); 3739for (int i = 0 ;i < nb ;++ i ) { 3740 3741const int8_t * q8 = y [i ].qs ; 3742const uint8_t * qs = x [i ].qs ; 3743const uint8_t * qh = x [i ].qh ; 3744const uint16_t * sc = (const uint16_t * )x [i ].scales ; 3745 3746scale .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 ); 3749scales = _mm256_srlv_epi64 (scales ,scales_shift ); 3750scales = _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 (); 3758for (int ib = 0 ;ib < QK_K /32 ;ib += 2 ) { 3759#ifdef __BMI2__ 3760const uint64_t packed_idx1 = _pdep_u64 (* (const uint32_t * )qs ,0x00ff00ff00ff00ffULL ) 3761 |_pdep_u64 (* (const uint16_t * )(qh )& 0x7777 ,0xf000f000f000f00ULL ); 3762const uint64_t packed_idx2 = _pdep_u64 (* (const uint32_t * )(qs + 4 ),0x00ff00ff00ff00ffULL ) 3763 |_pdep_u64 (* (const uint16_t * )(qh + 2 )& 0x7777 ,0xf000f000f000f00ULL ); 3764const uint16_t * idx1 = (const uint16_t * )(& packed_idx1 ); 3765const uint16_t * idx2 = (const uint16_t * )(& packed_idx2 ); 3766const __m256i q1b_1 = _mm256_set_epi64x (iq1s_grid [idx1 [3 ]],iq1s_grid [idx1 [2 ]],iq1s_grid [idx1 [1 ]],iq1s_grid [idx1 [0 ]]); 3767const __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) 3770const uint64_t delta_sign = _pdep_u64 (* (const uint32_t * )(qh )& 0x88888888 ,0xf0f0f0f0f0f0f0f0ULL ); 3771const __m256i delta1 = _mm256_or_si256 (mone8 ,_mm256_cvtepi8_epi64 (_mm_set1_epi32 (delta_sign ))); 3772const __m256i delta2 = _mm256_or_si256 (mone8 ,_mm256_cvtepi8_epi64 (_mm_set1_epi32 (delta_sign >>32 ))); 3773#else 3774const __m256i q1b_1 = _mm256_set_epi64x ( 3775iq1s_grid [qs [3 ] | (((uint16_t )qh [1 ] <<4 )& 0x700 )],iq1s_grid [qs [2 ] | (((uint16_t )qh [1 ] <<8 )& 0x700 )], 3776iq1s_grid [qs [1 ] | (((uint16_t )qh [0 ] <<4 )& 0x700 )],iq1s_grid [qs [0 ] | (((uint16_t )qh [0 ] <<8 )& 0x700 )] 3777 ); 3778const __m256i q1b_2 = _mm256_set_epi64x ( 3779iq1s_grid [qs [7 ] | (((uint16_t )qh [3 ] <<4 )& 0x700 )],iq1s_grid [qs [6 ] | (((uint16_t )qh [3 ] <<8 )& 0x700 )], 3780iq1s_grid [qs [5 ] | (((uint16_t )qh [2 ] <<4 )& 0x700 )],iq1s_grid [qs [4 ] | (((uint16_t )qh [2 ] <<8 )& 0x700 )] 3781 ); 3782 3783const __m256i delta1 = _mm256_set_epi64x (qh [1 ]& 0x80 ?0xffffffffffffffff :0x0101010101010101 , 3784qh [1 ]& 0x08 ?0xffffffffffffffff :0x0101010101010101 , 3785qh [0 ]& 0x80 ?0xffffffffffffffff :0x0101010101010101 , 3786qh [0 ]& 0x08 ?0xffffffffffffffff :0x0101010101010101 ); 3787const __m256i delta2 = _mm256_set_epi64x (qh [3 ]& 0x80 ?0xffffffffffffffff :0x0101010101010101 , 3788qh [3 ]& 0x08 ?0xffffffffffffffff :0x0101010101010101 , 3789qh [2 ]& 0x80 ?0xffffffffffffffff :0x0101010101010101 , 3790qh [2 ]& 0x08 ?0xffffffffffffffff :0x0101010101010101 ); 3791#endif 3792const __m256i q8b_1 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 3793const __m256i q8b_2 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 3794 3795const __m256i dot1 = mul_add_epi8 (q1b_1 ,q8b_1 ); 3796const __m256i dot2 = mul_add_epi8 (q1b_2 ,q8b_2 ); 3797const __m256i dot3 = _mm256_maddubs_epi16 (mone8 ,_mm256_sign_epi8 (q8b_1 ,delta1 )); 3798const __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 3803scales_idx1 = _mm256_add_epi8 (scales_idx1 ,mtwo8 ); 3804scales_idx2 = _mm256_add_epi8 (scales_idx2 ,mtwo8 ); 3805 3806const __m256i p1 = _mm256_madd_epi16 (dot1 ,scale1 ); 3807const __m256i p2 = _mm256_madd_epi16 (dot2 ,scale2 ); 3808const __m256i p3 = _mm256_madd_epi16 (dot3 ,scale1 ); 3809const __m256i p4 = _mm256_madd_epi16 (dot4 ,scale2 ); 3810 3811sumi1 = _mm256_add_epi32 (sumi1 ,_mm256_add_epi32 (p1 ,p2 )); 3812sumi2 = _mm256_add_epi32 (sumi2 ,_mm256_add_epi32 (p3 ,p4 )); 3813 3814qs += 8 ;qh += 4 ; 3815 } 3816 3817const __m256 d = _mm256_set1_ps (y [i ].d * GGML_CPU_FP16_TO_FP32 (scale .f16 )); 3818 3819accum1 = _mm256_fmadd_ps (d ,_mm256_cvtepi32_ps (sumi1 ),accum1 ); 3820accum2 = _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__ 3826const __m128i mask = _mm_set1_epi16 (0x7 ); 3827const __m128i mone = _mm_set1_epi16 (1 ); 3828 3829__m256 accum1 = _mm256_setzero_ps (); 3830__m256 accum2 = _mm256_setzero_ps (); 3831for (int i = 0 ;i < nb ;++ i ) { 3832 3833const int8_t * q8 = y [i ].qs ; 3834const uint8_t * qs = x [i ].qs ; 3835const uint8_t * qh = x [i ].qh ; 3836const uint16_t * sc = (const uint16_t * )x [i ].scales ; 3837 3838scale .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 (); 3844for (int ib = 0 ;ib < QK_K /32 ;ib += 2 ) { 3845const __m128i q1b_1_0 = _mm_set_epi64x ( 3846iq1s_grid [qs [1 ] | (((uint16_t )qh [0 ] <<4 )& 0x700 )],iq1s_grid [qs [0 ] | (((uint16_t )qh [0 ] <<8 )& 0x700 )]); 3847const __m128i q1b_1_1 = _mm_set_epi64x ( 3848iq1s_grid [qs [3 ] | (((uint16_t )qh [1 ] <<4 )& 0x700 )],iq1s_grid [qs [2 ] | (((uint16_t )qh [1 ] <<8 )& 0x700 )]); 3849const __m128i q1b_2_0 = _mm_set_epi64x ( 3850iq1s_grid [qs [5 ] | (((uint16_t )qh [2 ] <<4 )& 0x700 )],iq1s_grid [qs [4 ] | (((uint16_t )qh [2 ] <<8 )& 0x700 )]); 3851const __m128i q1b_2_1 = _mm_set_epi64x ( 3852iq1s_grid [qs [7 ] | (((uint16_t )qh [3 ] <<4 )& 0x700 )],iq1s_grid [qs [6 ] | (((uint16_t )qh [3 ] <<8 )& 0x700 )]); 3853const __m128i q8b_1_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3854const __m128i q8b_1_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3855const __m128i q8b_2_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3856const __m128i q8b_2_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 3857 3858const __m128i dot1_0 = mul_add_epi8_sse (q1b_1_0 ,q8b_1_0 ); 3859const __m128i dot1_1 = mul_add_epi8_sse (q1b_1_1 ,q8b_1_1 ); 3860const __m128i dot2_0 = mul_add_epi8_sse (q1b_2_0 ,q8b_2_0 ); 3861const __m128i dot2_1 = mul_add_epi8_sse (q1b_2_1 ,q8b_2_1 ); 3862 3863const __m128i delta1_0 = _mm_set_epi64x (qh [0 ]& 0x80 ?0xffffffffffffffff :0x0101010101010101 , 3864qh [0 ]& 0x08 ?0xffffffffffffffff :0x0101010101010101 ); 3865const __m128i delta1_1 = _mm_set_epi64x (qh [1 ]& 0x80 ?0xffffffffffffffff :0x0101010101010101 , 3866qh [1 ]& 0x08 ?0xffffffffffffffff :0x0101010101010101 ); 3867const __m128i delta2_0 = _mm_set_epi64x (qh [2 ]& 0x80 ?0xffffffffffffffff :0x0101010101010101 , 3868qh [2 ]& 0x08 ?0xffffffffffffffff :0x0101010101010101 ); 3869const __m128i delta2_1 = _mm_set_epi64x (qh [3 ]& 0x80 ?0xffffffffffffffff :0x0101010101010101 , 3870qh [3 ]& 0x08 ?0xffffffffffffffff :0x0101010101010101 ); 3871 3872const __m128i dot3_0 = mul_add_epi8_sse (delta1_0 ,q8b_1_0 ); 3873const __m128i dot3_1 = mul_add_epi8_sse (delta1_1 ,q8b_1_1 ); 3874const __m128i dot4_0 = mul_add_epi8_sse (delta2_0 ,q8b_2_0 ); 3875const __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 3882scale1_0 = _mm_add_epi16 (_mm_slli_epi16 (_mm_and_si128 (scale1_0 ,mask ),1 ),mone ); 3883scale1_1 = _mm_add_epi16 (_mm_slli_epi16 (_mm_and_si128 (scale1_1 ,mask ),1 ),mone ); 3884scale2_0 = _mm_add_epi16 (_mm_slli_epi16 (_mm_and_si128 (scale2_0 ,mask ),1 ),mone ); 3885scale2_1 = _mm_add_epi16 (_mm_slli_epi16 (_mm_and_si128 (scale2_1 ,mask ),1 ),mone ); 3886const __m128i p1_0 = _mm_madd_epi16 (dot1_0 ,scale1_0 ); 3887const __m128i p1_1 = _mm_madd_epi16 (dot1_1 ,scale1_1 ); 3888const __m128i p2_0 = _mm_madd_epi16 (dot2_0 ,scale2_0 ); 3889const __m128i p2_1 = _mm_madd_epi16 (dot2_1 ,scale2_1 ); 3890const __m128i p3_0 = _mm_madd_epi16 (dot3_0 ,scale1_0 ); 3891const __m128i p3_1 = _mm_madd_epi16 (dot3_1 ,scale1_1 ); 3892const __m128i p4_0 = _mm_madd_epi16 (dot4_0 ,scale2_0 ); 3893const __m128i p4_1 = _mm_madd_epi16 (dot4_1 ,scale2_1 ); 3894 3895sumi1_0 = _mm_add_epi32 (sumi1_0 ,_mm_add_epi32 (p1_0 ,p2_0 )); 3896sumi1_1 = _mm_add_epi32 (sumi1_1 ,_mm_add_epi32 (p1_1 ,p2_1 )); 3897sumi2_0 = _mm_add_epi32 (sumi2_0 ,_mm_add_epi32 (p3_0 ,p4_0 )); 3898sumi2_1 = _mm_add_epi32 (sumi2_1 ,_mm_add_epi32 (p3_1 ,p4_1 )); 3899 3900qs += 8 ;qh += 4 ; 3901 } 3902 3903const __m256 d = _mm256_set1_ps (y [i ].d * GGML_CPU_FP16_TO_FP32 (scale .f16 )); 3904 3905accum1 = _mm256_add_ps (_mm256_mul_ps (d ,_mm256_cvtepi32_ps (MM256_SET_M128I (sumi1_1 ,sumi1_0 ))),accum1 ); 3906accum2 = _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 3912UNUSED (x ); 3913UNUSED (y ); 3914UNUSED (nb ); 3915UNUSED (scale ); 3916ggml_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 ) { 3921assert (nrc == 1 ); 3922UNUSED (nrc ); 3923UNUSED (bx ); 3924UNUSED (by ); 3925UNUSED (bs ); 3926assert (n %QK4_NL == 0 ); 3927static_assert (QK4_NL == QK8_0 ,"QK4_NL and QK8_0 must be the same" ); 3928 3929const block_iq4_nl * GGML_RESTRICT x = vx ; 3930const block_q8_0 * GGML_RESTRICT y = vy ; 3931 3932const int nb = n /QK4_NL ; 3933 3934int ib = 0 ; 3935float sumf = 0 ; 3936 3937#if defined__AVX2__ 3938 3939const __m128i values128 = _mm_loadu_si128 ((const __m128i * )kvalues_iq4nl ); 3940const __m128i m4b = _mm_set1_epi8 (0x0f ); 3941const __m256i mone = _mm256_set1_epi16 (1 ); 3942 3943__m256 accum1 = _mm256_setzero_ps (); 3944__m256 accum2 = _mm256_setzero_ps (); 3945for (;ib + 1 < nb ;ib += 2 ) { 3946const __m128i q4bits_1 = _mm_loadu_si128 ((const __m128i * )x [ib + 0 ].qs ); 3947const __m128i q4bits_2 = _mm_loadu_si128 ((const __m128i * )x [ib + 1 ].qs ); 3948const __m256i q8b_1 = _mm256_loadu_si256 ((const __m256i * )y [ib + 0 ].qs ); 3949const __m256i q8b_2 = _mm256_loadu_si256 ((const __m256i * )y [ib + 1 ].qs ); 3950const __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 ))); 3952const __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 ))); 3954const __m256i p16_1 = mul_add_epi8 (q4b_1 ,q8b_1 ); 3955const __m256i p16_2 = mul_add_epi8 (q4b_2 ,q8b_2 ); 3956const __m256i p_1 = _mm256_madd_epi16 (p16_1 ,mone ); 3957const __m256i p_2 = _mm256_madd_epi16 (p16_2 ,mone ); 3958accum1 = _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 ); 3960accum2 = _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 3964sumf = hsum_float_8 (_mm256_add_ps (accum1 ,accum2 )); 3965 3966#elif defined__AVX__ 3967const __m128i values128 = _mm_loadu_si128 ((const __m128i * )kvalues_iq4nl ); 3968const __m128i m4b = _mm_set1_epi8 (0x0f ); 3969 3970__m256 accum = _mm256_setzero_ps (); 3971for (;ib + 1 < nb ;ib += 2 ) { 3972const __m128i q4bits_1 = _mm_loadu_si128 ((const __m128i * )x [ib + 0 ].qs ); 3973const __m128i q4bits_2 = _mm_loadu_si128 ((const __m128i * )x [ib + 1 ].qs ); 3974const __m128i q8b_1_0 = _mm_loadu_si128 ((const __m128i * )y [ib + 0 ].qs ); 3975const __m128i q8b_1_1 = _mm_loadu_si128 ((const __m128i * )y [ib + 0 ].qs + 1 ); 3976const __m128i q8b_2_0 = _mm_loadu_si128 ((const __m128i * )y [ib + 1 ].qs ); 3977const __m128i q8b_2_1 = _mm_loadu_si128 ((const __m128i * )y [ib + 1 ].qs + 1 ); 3978 3979const __m128i q4b_1_0 = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (q4bits_1 ,m4b )); 3980const __m128i q4b_1_1 = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (_mm_srli_epi16 (q4bits_1 ,4 ),m4b )); 3981const __m128i q4b_2_0 = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (q4bits_2 ,m4b )); 3982const __m128i q4b_2_1 = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (_mm_srli_epi16 (q4bits_2 ,4 ),m4b )); 3983 3984const __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 ); 3985const __m256 deltas = quad_fp16_delta_float (x [ib ].d ,y [ib ].d ,x [ib + 1 ].d ,y [ib + 1 ].d ); 3986accum = _mm256_add_ps (_mm256_mul_ps (deltas ,p ),accum ); 3987 } 3988 3989sumf = hsum_float_8 (accum ); 3990 3991#endif 3992for (;ib < nb ;++ ib ) { 3993const float d = GGML_CPU_FP16_TO_FP32 (y [ib ].d )* GGML_CPU_FP16_TO_FP32 (x [ib ].d ); 3994int sumi1 = 0 ,sumi2 = 0 ; 3995for (int j = 0 ;j < QK4_NL /2 ;++ j ) { 3996sumi1 += y [ib ].qs [j + 0 ]* kvalues_iq4nl [x [ib ].qs [j ]& 0xf ]; 3997sumi2 += y [ib ].qs [j + QK4_NL /2 ]* kvalues_iq4nl [x [ib ].qs [j ] >>4 ]; 3998 } 3999sumf += 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 ) { 4005assert (nrc == 1 ); 4006UNUSED (nrc ); 4007UNUSED (bx ); 4008UNUSED (by ); 4009UNUSED (bs ); 4010assert (n %QK_K == 0 ); 4011 4012const block_iq4_xs * GGML_RESTRICT x = vx ; 4013const block_q8_K * GGML_RESTRICT y = vy ; 4014 4015const int nb = n /QK_K ; 4016 4017#if defined__AVX2__ 4018 4019const __m128i values128 = _mm_loadu_si128 ((const __m128i * )kvalues_iq4nl ); 4020const __m128i m4b = _mm_set1_epi8 (0x0f ); 4021 4022__m256 accum = _mm256_setzero_ps (); 4023for (int ibl = 0 ;ibl < nb ;++ ibl ) { 4024const uint8_t * qs = x [ibl ].qs ; 4025const int8_t * q8 = y [ibl ].qs ; 4026uint16_t sh = x [ibl ].scales_h ; 4027__m256i sumi1 = _mm256_setzero_si256 (); 4028__m256i sumi2 = _mm256_setzero_si256 (); 4029for (int ib = 0 ;ib < QK_K /32 ;ib += 2 ) { 4030const __m128i q4bits_1 = _mm_loadu_si128 ((const __m128i * )qs );qs += 16 ; 4031const __m128i q4bits_2 = _mm_loadu_si128 ((const __m128i * )qs );qs += 16 ; 4032const __m256i q8b_1 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 4033const __m256i q8b_2 = _mm256_loadu_si256 ((const __m256i * )q8 );q8 += 32 ; 4034const __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 ))); 4036const __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 ))); 4038const __m256i p16_1 = mul_add_epi8 (q4b_1 ,q8b_1 ); 4039const __m256i p16_2 = mul_add_epi8 (q4b_2 ,q8b_2 ); 4040const int16_t ls1 = ((x [ibl ].scales_l [ib /2 ]& 0xf ) | ((sh <<4 )& 0x30 ))- 32 ; 4041const int16_t ls2 = ((x [ibl ].scales_l [ib /2 ] >>4 ) | ((sh <<2 )& 0x30 ))- 32 ; 4042sh >>=4 ; 4043const __m256i p_1 = _mm256_madd_epi16 (p16_1 ,_mm256_set1_epi16 (ls1 )); 4044const __m256i p_2 = _mm256_madd_epi16 (p16_2 ,_mm256_set1_epi16 (ls2 )); 4045sumi1 = _mm256_add_epi32 (p_1 ,sumi1 ); 4046sumi2 = _mm256_add_epi32 (p_2 ,sumi2 ); 4047 } 4048accum = _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__ 4055const __m128i values128 = _mm_loadu_si128 ((const __m128i * )kvalues_iq4nl ); 4056const __m128i m4b = _mm_set1_epi8 (0x0f ); 4057 4058__m256 accum = _mm256_setzero_ps (); 4059for (int ibl = 0 ;ibl < nb ;++ ibl ) { 4060const uint8_t * qs = x [ibl ].qs ; 4061const int8_t * q8 = y [ibl ].qs ; 4062uint16_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 (); 4067for (int ib = 0 ;ib < QK_K /32 ;ib += 2 ) { 4068const __m128i q4bits_1 = _mm_loadu_si128 ((const __m128i * )qs );qs += 16 ; 4069const __m128i q4bits_2 = _mm_loadu_si128 ((const __m128i * )qs );qs += 16 ; 4070const __m128i q8b_1_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 4071const __m128i q8b_1_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 4072const __m128i q8b_2_0 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 4073const __m128i q8b_2_1 = _mm_loadu_si128 ((const __m128i * )q8 );q8 += 16 ; 4074const __m128i q4b_1_0 = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (q4bits_1 ,m4b )); 4075const __m128i q4b_1_1 = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (_mm_srli_epi16 (q4bits_1 ,4 ),m4b )); 4076const __m128i q4b_2_0 = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (q4bits_2 ,m4b )); 4077const __m128i q4b_2_1 = _mm_shuffle_epi8 (values128 ,_mm_and_si128 (_mm_srli_epi16 (q4bits_2 ,4 ),m4b )); 4078const __m128i p16_1_0 = mul_add_epi8_sse (q4b_1_0 ,q8b_1_0 ); 4079const __m128i p16_1_1 = mul_add_epi8_sse (q4b_1_1 ,q8b_1_1 ); 4080const __m128i p16_2_0 = mul_add_epi8_sse (q4b_2_0 ,q8b_2_0 ); 4081const __m128i p16_2_1 = mul_add_epi8_sse (q4b_2_1 ,q8b_2_1 ); 4082const int16_t ls1 = ((x [ibl ].scales_l [ib /2 ]& 0xf ) | ((sh <<4 )& 0x30 ))- 32 ; 4083const int16_t ls2 = ((x [ibl ].scales_l [ib /2 ] >>4 ) | ((sh <<2 )& 0x30 ))- 32 ; 4084sh >>=4 ; 4085const __m128i p_1_0 = _mm_madd_epi16 (p16_1_0 ,_mm_set1_epi16 (ls1 )); 4086const __m128i p_1_1 = _mm_madd_epi16 (p16_1_1 ,_mm_set1_epi16 (ls1 )); 4087const __m128i p_2_0 = _mm_madd_epi16 (p16_2_0 ,_mm_set1_epi16 (ls2 )); 4088const __m128i p_2_1 = _mm_madd_epi16 (p16_2_1 ,_mm_set1_epi16 (ls2 )); 4089sumi1_0 = _mm_add_epi32 (p_1_0 ,sumi1_0 ); 4090sumi1_1 = _mm_add_epi32 (p_1_1 ,sumi1_1 ); 4091sumi2_0 = _mm_add_epi32 (p_2_0 ,sumi2_0 ); 4092sumi2_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 ); 4096accum = _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 4103UNUSED (x ); 4104UNUSED (y ); 4105UNUSED (nb ); 4106ggml_vec_dot_iq4_xs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4107#endif 4108}