char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
ac17f8ac1
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 <float.h> 15#include <stdlib.h> // for qsort 16#include <stdio.h> // for GGML_ASSERT 17 18#define GROUP_MAX_EPS 1e-15f 19#define GROUP_MAX_EPS_IQ3_XXS 1e-8f 20#define GROUP_MAX_EPS_IQ2_S 1e-8f 21#define GROUP_MAX_EPS_IQ1_M 1e-7f 22#define GROUP_MAX_EPS_IQ1_S 1e-12f 23 24#define UNUSED GGML_UNUSED 25 26#if defined(__ARM_NEON ) 27#define B1 (c ,s ,n ) 0x ## n ## c , 0x ## n ## s 28#define B2 (c ,s ,n ) B1(c,s,n ## c), B1(c,s,n ## s) 29#define B3 (c ,s ,n ) B2(c,s,n ## c), B2(c,s,n ## s) 30#define B4 (c ,s ,n ) B3(c,s,n ## c), B3(c,s,n ## s) 31#define B5 (c ,s ,n ) B4(c,s,n ## c), B4(c,s,n ## s) 32#define B6 (c ,s ,n ) B5(c,s,n ## c), B5(c,s,n ## s) 33#define B7 (c ,s ,n ) B6(c,s,n ## c), B6(c,s,n ## s) 34#define B8 (c ,s ) B7(c,s, c), B7(c,s, s) 35 36// precomputed tables for expanding 8bits to 8 bytes: 37static const uint64_t table_b2b_0 [1 <<8 ]= {B8 (00 ,10 ) };// ( b) << 4 38static const uint64_t table_b2b_1 [1 <<8 ]= {B8 (10 ,00 ) };// (!b) << 4 39#endif 40 41void quantize_row_q8_0 (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t k ) { 42assert (QK8_0 == 32 ); 43assert (k %QK8_0 == 0 ); 44const int nb = k /QK8_0 ; 45 46block_q8_0 * GGML_RESTRICT y = vy ; 47 48#if defined(__ARM_NEON ) 49for (int i = 0 ;i < nb ;i ++ ) { 50float32x4_t srcv [8 ]; 51float32x4_t asrcv [8 ]; 52float32x4_t amaxv [8 ]; 53 54for (int j = 0 ;j < 8 ;j ++ )srcv [j ]= vld1q_f32 (x + i * 32 + 4 * j ); 55for (int j = 0 ;j < 8 ;j ++ )asrcv [j ]= vabsq_f32 (srcv [j ]); 56 57for (int j = 0 ;j < 4 ;j ++ )amaxv [2 * j ]= vmaxq_f32 (asrcv [2 * j ],asrcv [2 * j + 1 ]); 58for (int j = 0 ;j < 2 ;j ++ )amaxv [4 * j ]= vmaxq_f32 (amaxv [4 * j ],amaxv [4 * j + 2 ]); 59for (int j = 0 ;j < 1 ;j ++ )amaxv [8 * j ]= vmaxq_f32 (amaxv [8 * j ],amaxv [8 * j + 4 ]); 60 61const float amax = vmaxvq_f32 (amaxv [0 ]); 62 63const float d = amax / ((1 <<7 )- 1 ); 64const float id = d ?1.0f /d :0.0f ; 65 66y [i ].d = GGML_CPU_FP32_TO_FP16 (d ); 67 68for (int j = 0 ;j < 8 ;j ++ ) { 69const float32x4_t v = vmulq_n_f32 (srcv [j ],id ); 70const int32x4_t vi = vcvtnq_s32_f32 (v ); 71 72y [i ].qs [4 * j + 0 ]= vgetq_lane_s32 (vi ,0 ); 73y [i ].qs [4 * j + 1 ]= vgetq_lane_s32 (vi ,1 ); 74y [i ].qs [4 * j + 2 ]= vgetq_lane_s32 (vi ,2 ); 75y [i ].qs [4 * j + 3 ]= vgetq_lane_s32 (vi ,3 ); 76 } 77 } 78#else 79GGML_UNUSED (nb ); 80// scalar 81quantize_row_q8_0_ref (x ,y ,k ); 82#endif 83} 84 85void quantize_row_q8_1 (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t k ) { 86assert (k %QK8_1 == 0 ); 87const int nb = k /QK8_1 ; 88 89block_q8_1 * GGML_RESTRICT y = vy ; 90#if defined(__ARM_NEON ) 91for (int i = 0 ;i < nb ;i ++ ) { 92float32x4_t srcv [8 ]; 93float32x4_t asrcv [8 ]; 94float32x4_t amaxv [8 ]; 95 96for (int j = 0 ;j < 8 ;j ++ )srcv [j ]= vld1q_f32 (x + i * 32 + 4 * j ); 97for (int j = 0 ;j < 8 ;j ++ )asrcv [j ]= vabsq_f32 (srcv [j ]); 98 99for (int j = 0 ;j < 4 ;j ++ )amaxv [2 * j ]= vmaxq_f32 (asrcv [2 * j ],asrcv [2 * j + 1 ]); 100for (int j = 0 ;j < 2 ;j ++ )amaxv [4 * j ]= vmaxq_f32 (amaxv [4 * j ],amaxv [4 * j + 2 ]); 101for (int j = 0 ;j < 1 ;j ++ )amaxv [8 * j ]= vmaxq_f32 (amaxv [8 * j ],amaxv [8 * j + 4 ]); 102 103const float amax = vmaxvq_f32 (amaxv [0 ]); 104 105const float d = amax / ((1 <<7 )- 1 ); 106const float id = d ?1.0f /d :0.0f ; 107 108y [i ].d = GGML_CPU_FP32_TO_FP16 (d ); 109 110int32x4_t accv = vdupq_n_s32 (0 ); 111 112for (int j = 0 ;j < 8 ;j ++ ) { 113const float32x4_t v = vmulq_n_f32 (srcv [j ],id ); 114const int32x4_t vi = vcvtnq_s32_f32 (v ); 115 116y [i ].qs [4 * j + 0 ]= vgetq_lane_s32 (vi ,0 ); 117y [i ].qs [4 * j + 1 ]= vgetq_lane_s32 (vi ,1 ); 118y [i ].qs [4 * j + 2 ]= vgetq_lane_s32 (vi ,2 ); 119y [i ].qs [4 * j + 3 ]= vgetq_lane_s32 (vi ,3 ); 120 121accv = vaddq_s32 (accv ,vi ); 122 } 123 124y [i ].s = GGML_CPU_FP32_TO_FP16 (d * vaddvq_s32 (accv )); 125 } 126#else 127GGML_UNUSED (nb ); 128// scalar 129quantize_row_q8_1_ref (x ,y ,k ); 130#endif 131} 132 133// placeholder implementation for Apple targets 134void quantize_row_q8_K (const float * GGML_RESTRICT x ,void * GGML_RESTRICT y ,int64_t k ) { 135quantize_row_q8_K_ref (x ,y ,k ); 136} 137 138//===================================== Dot products ================================= 139 140void 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 ) { 141const int qk = QK1_0 ;// 128 142const int nb = n /qk ; 143 144assert (n %qk == 0 ); 145assert (nrc == 1 ); 146UNUSED (nrc ); 147UNUSED (bx ); 148UNUSED (by ); 149UNUSED (bs ); 150 151const block_q1_0 * GGML_RESTRICT x = vx ; 152const block_q8_0 * GGML_RESTRICT y = vy ; 153 154#if defined(__ARM_NEON ) 155float32x4_t sumv = vdupq_n_f32 (0.0f ); 156 157for (int i = 0 ;i < nb ;i ++ ) { 158const float d0 = GGML_CPU_FP16_TO_FP32 (x [i ].d ); 159 160// Process 4 Q8_0 blocks (each has 32 elements) 161for (int k = 0 ;k < 4 ;k ++ ) { 162const block_q8_0 * GGML_RESTRICT yb = & y [i * 4 + k ]; 163const float d1 = GGML_CPU_FP16_TO_FP32 (yb -> d ); 164 165// Get the 4 bytes of bits for this Q8_0 block (32 bits = 4 bytes) 166// Bits are at offset k*4 bytes in x[i].qs 167const uint8_t * bits = & x [i ].qs [k * 4 ]; 168 169// Load 32 int8 values from y 170const int8x16_t y0 = vld1q_s8 (yb -> qs ); 171const int8x16_t y1 = vld1q_s8 (yb -> qs + 16 ); 172 173// Byte 0-1: bits for y0[0..15] 174const uint64_t expand0 = table_b2b_0 [bits [0 ]]; 175const uint64_t expand1 = table_b2b_0 [bits [1 ]]; 176// Byte 2-3: bits for y1[0..15] 177const uint64_t expand2 = table_b2b_0 [bits [2 ]]; 178const uint64_t expand3 = table_b2b_0 [bits [3 ]]; 179 180// Build the sign vectors by reinterpreting the table values 181uint8x8_t e0 = vcreate_u8 (expand0 ); 182uint8x8_t e1 = vcreate_u8 (expand1 ); 183uint8x8_t e2 = vcreate_u8 (expand2 ); 184uint8x8_t e3 = vcreate_u8 (expand3 ); 185 186// Shift right by 4 to get 0 or 1 187int8x8_t s0 = vreinterpret_s8_u8 (vshr_n_u8 (e0 ,4 )); 188int8x8_t s1 = vreinterpret_s8_u8 (vshr_n_u8 (e1 ,4 )); 189int8x8_t s2 = vreinterpret_s8_u8 (vshr_n_u8 (e2 ,4 )); 190int8x8_t s3 = vreinterpret_s8_u8 (vshr_n_u8 (e3 ,4 )); 191 192// Convert 0/1 to -1/+1: sign = 2*val - 1 193int8x8_t one = vdup_n_s8 (1 ); 194s0 = vsub_s8 (vadd_s8 (s0 ,s0 ),one );// 2*s0 - 1 195s1 = vsub_s8 (vadd_s8 (s1 ,s1 ),one ); 196s2 = vsub_s8 (vadd_s8 (s2 ,s2 ),one ); 197s3 = vsub_s8 (vadd_s8 (s3 ,s3 ),one ); 198 199// Combine into 16-element vectors 200int8x16_t signs0 = vcombine_s8 (s0 ,s1 ); 201int8x16_t signs1 = vcombine_s8 (s2 ,s3 ); 202 203// Multiply signs with y values and accumulate 204// dot(signs, y) where signs are +1/-1 205int32x4_t p0 = ggml_vdotq_s32 (vdupq_n_s32 (0 ),signs0 ,y0 ); 206int32x4_t p1 = ggml_vdotq_s32 (p0 ,signs1 ,y1 ); 207 208// Scale by d1 and accumulate 209sumv = vmlaq_n_f32 (sumv ,vcvtq_f32_s32 (p1 ),d0 * d1 ); 210 } 211 } 212 213* s = vaddvq_f32 (sumv ); 214#else 215UNUSED (nb ); 216UNUSED (x ); 217UNUSED (y ); 218ggml_vec_dot_q1_0_q8_0_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 219#endif 220} 221 222void ggml_vec_dot_q2_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 ) { 223const int qk = QK2_0 ; 224const int nb = n /qk ; 225 226assert (n %qk == 0 ); 227assert (nrc == 1 ); 228UNUSED (nrc ); 229UNUSED (bx ); 230UNUSED (by ); 231UNUSED (bs ); 232 233const block_q2_0 * GGML_RESTRICT x = vx ; 234const block_q8_0 * GGML_RESTRICT y = vy ; 235 236float sumf = 0.0f ; 237 238#if defined(__ARM_NEON ) 239// Replicate pattern: each byte repeated 4 times 240static const uint8_t tbl_idx_lo [16 ]= {0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,3 ,3 ,3 ,3 }; 241static const uint8_t tbl_idx_hi [16 ]= {4 ,4 ,4 ,4 ,5 ,5 ,5 ,5 ,6 ,6 ,6 ,6 ,7 ,7 ,7 ,7 }; 242// Right-shift amounts: 0,2,4,6 repeated for each group of 4 243static const int8_t shift_vals [16 ]= {0 ,-2 ,-4 ,-6 ,0 ,-2 ,-4 ,-6 ,0 ,-2 ,-4 ,-6 ,0 ,-2 ,-4 ,-6 }; 244 245const uint8x16_t idx_lo = vld1q_u8 (tbl_idx_lo ); 246const uint8x16_t idx_hi = vld1q_u8 (tbl_idx_hi ); 247const int8x16_t shifts = vld1q_s8 (shift_vals ); 248const uint8x16_t mask2 = vdupq_n_u8 (0x03 ); 249const int8x16_t one = vdupq_n_s8 (1 ); 250 251float32x4_t sumv = vdupq_n_f32 (0.0f ); 252 253for (int i = 0 ;i < nb ;i ++ ) { 254const float d0 = GGML_CPU_FP16_TO_FP32 (x [i ].d ); 255 256// group 64: one Q2_0 block (64 weights) maps to two Q8_0 blocks (2 * 32 = 64) 257for (int k = 0 ;k < 2 ;k ++ ) { 258const block_q8_0 * GGML_RESTRICT yb = & y [i * 2 + k ]; 259const float d1 = GGML_CPU_FP16_TO_FP32 (yb -> d ); 260 261// Load 8 bytes of packed 2-bit values 262const uint8x8_t raw = vld1_u8 (& x [i ].qs [k * 8 ]); 263const uint8x16_t raw16 = vcombine_u8 (raw ,raw ); 264 265// First 16 elements: replicate bytes 0-3, shift, mask, subtract 1 266uint8x16_t bytes0 = ggml_vqtbl1q_u8 (raw16 ,idx_lo ); 267int8x16_t qv0 = vsubq_s8 ( 268vreinterpretq_s8_u8 (vandq_u8 (vshlq_u8 (bytes0 ,shifts ),mask2 )), 269one ); 270 271// Second 16 elements: replicate bytes 4-7, shift, mask, subtract 1 272uint8x16_t bytes1 = ggml_vqtbl1q_u8 (raw16 ,idx_hi ); 273int8x16_t qv1 = vsubq_s8 ( 274vreinterpretq_s8_u8 (vandq_u8 (vshlq_u8 (bytes1 ,shifts ),mask2 )), 275one ); 276 277// Load Q8_0 values and dot product 278const int8x16_t y0 = vld1q_s8 (yb -> qs ); 279const int8x16_t y1 = vld1q_s8 (yb -> qs + 16 ); 280 281int32x4_t p0 = ggml_vdotq_s32 (vdupq_n_s32 (0 ),qv0 ,y0 ); 282int32x4_t p1 = ggml_vdotq_s32 (p0 ,qv1 ,y1 ); 283 284sumv = vmlaq_n_f32 (sumv ,vcvtq_f32_s32 (p1 ),d0 * d1 ); 285 } 286 } 287 288sumf = vaddvq_f32 (sumv ); 289#else 290ggml_vec_dot_q2_0_q8_0_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 291return ; 292#endif 293 294* s = sumf ; 295} 296 297void 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 ) { 298const int qk = QK8_0 ; 299const int nb = n /qk ; 300 301assert (n %qk == 0 ); 302#if defined(__ARM_FEATURE_MATMUL_INT8 ) 303assert ((nrc == 2 )|| (nrc == 1 )); 304#else 305assert (nrc == 1 ); 306#endif 307UNUSED (nrc ); 308UNUSED (bx ); 309UNUSED (by ); 310UNUSED (bs ); 311 312const block_q4_0 * GGML_RESTRICT x = vx ; 313const block_q8_0 * GGML_RESTRICT y = vy ; 314 315#if defined(__ARM_FEATURE_MATMUL_INT8 ) 316if (nrc == 2 ) { 317const block_q4_0 * GGML_RESTRICT vx0 = vx ; 318const block_q4_0 * GGML_RESTRICT vx1 = (const block_q4_0 * ) ((const uint8_t * )vx + bx ); 319const block_q8_0 * GGML_RESTRICT vy0 = vy ; 320const block_q8_0 * GGML_RESTRICT vy1 = (const block_q8_0 * ) ((const uint8_t * )vy + by ); 321 322float32x4_t sumv0 = vdupq_n_f32 (0.0f ); 323 324for (int i = 0 ;i < nb ;i ++ ) { 325const block_q4_0 * GGML_RESTRICT b_x0 = & vx0 [i ]; 326const block_q4_0 * GGML_RESTRICT b_x1 = & vx1 [i ]; 327const block_q8_0 * GGML_RESTRICT b_y0 = & vy0 [i ]; 328const block_q8_0 * GGML_RESTRICT b_y1 = & vy1 [i ]; 329 330const uint8x16_t m4b = vdupq_n_u8 (0x0F ); 331const int8x16_t s8b = vdupq_n_s8 (0x8 ); 332 333const uint8x16_t v0_0 = vld1q_u8 (b_x0 -> qs ); 334const uint8x16_t v0_1 = vld1q_u8 (b_x1 -> qs ); 335 336// 4-bit -> 8-bit 337const int8x16_t v0_0l = vreinterpretq_s8_u8 (vandq_u8 (v0_0 ,m4b )); 338const int8x16_t v0_0h = vreinterpretq_s8_u8 (vshrq_n_u8 (v0_0 ,4 )); 339const int8x16_t v0_1l = vreinterpretq_s8_u8 (vandq_u8 (v0_1 ,m4b )); 340const int8x16_t v0_1h = vreinterpretq_s8_u8 (vshrq_n_u8 (v0_1 ,4 )); 341 342// sub 8 343const int8x16_t x0_l = vsubq_s8 (v0_0l ,s8b ); 344const int8x16_t x0_h = vsubq_s8 (v0_0h ,s8b ); 345const int8x16_t x1_l = vsubq_s8 (v0_1l ,s8b ); 346const int8x16_t x1_h = vsubq_s8 (v0_1h ,s8b ); 347 348// load y 349const int8x16_t y0_l = vld1q_s8 (b_y0 -> qs ); 350const int8x16_t y0_h = vld1q_s8 (b_y0 -> qs + 16 ); 351const int8x16_t y1_l = vld1q_s8 (b_y1 -> qs ); 352const int8x16_t y1_h = vld1q_s8 (b_y1 -> qs + 16 ); 353 354float32_t _scale [4 ]= { 355GGML_CPU_FP16_TO_FP32 (b_x0 -> d )* GGML_CPU_FP16_TO_FP32 (b_y0 -> d ), 356GGML_CPU_FP16_TO_FP32 (b_x0 -> d )* GGML_CPU_FP16_TO_FP32 (b_y1 -> d ), 357GGML_CPU_FP16_TO_FP32 (b_x1 -> d )* GGML_CPU_FP16_TO_FP32 (b_y0 -> d ), 358GGML_CPU_FP16_TO_FP32 (b_x1 -> d )* GGML_CPU_FP16_TO_FP32 (b_y1 -> d ) 359 }; 360float32x4_t scale = vld1q_f32 (_scale ); 361 362int8x16_t l0 = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (x0_l ),vreinterpretq_s64_s8 (x1_l ))); 363int8x16_t l1 = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (x0_l ),vreinterpretq_s64_s8 (x1_l ))); 364 365int8x16_t l2 = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (x0_h ),vreinterpretq_s64_s8 (x1_h ))); 366int8x16_t l3 = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (x0_h ),vreinterpretq_s64_s8 (x1_h ))); 367 368int8x16_t r0 = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (y0_l ),vreinterpretq_s64_s8 (y1_l ))); 369int8x16_t r1 = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (y0_l ),vreinterpretq_s64_s8 (y1_l ))); 370 371int8x16_t r2 = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (y0_h ),vreinterpretq_s64_s8 (y1_h ))); 372int8x16_t r3 = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (y0_h ),vreinterpretq_s64_s8 (y1_h ))); 373 374sumv0 = vmlaq_f32 (sumv0 ,(vcvtq_f32_s32 (vmmlaq_s32 ((vmmlaq_s32 ((vmmlaq_s32 ((vmmlaq_s32 (vdupq_n_s32 (0 ),l0 ,r0 )), 375l1 ,r1 )),l2 ,r2 )),l3 ,r3 ))),scale ); 376 } 377 378float32x4_t sumv1 = vextq_f32 (sumv0 ,sumv0 ,2 ); 379float32x4_t sumv2 = vzip1q_f32 (sumv0 ,sumv1 ); 380 381vst1_f32 (s ,vget_low_f32 (sumv2 )); 382vst1_f32 (s + bs ,vget_high_f32 (sumv2 )); 383 384return ; 385 } 386#endif 387 388int ib = 0 ; 389float sumf = 0 ; 390 391#if defined(__ARM_FEATURE_SVE ) 392svfloat32_t sumv0 = svdup_n_f32 (0.0f ); 393svfloat32_t sumv1 = svdup_n_f32 (0.0f ); 394 395const int vector_length = ggml_cpu_get_sve_cnt ()* 8 ; 396 397// VLA Implementation using switch case 398switch (vector_length ) { 399case 128 : 400 { 401// predicate for activating higher lanes for 4 float32 elements 402const svbool_t ph4 = svptrue_pat_b32 (SV_VL4 ); 403 404for (;ib + 1 < nb ;ib += 2 ) { 405const block_q4_0 * GGML_RESTRICT x0 = & x [ib + 0 ]; 406const block_q4_0 * GGML_RESTRICT x1 = & x [ib + 1 ]; 407const block_q8_0 * GGML_RESTRICT y0 = & y [ib + 0 ]; 408const block_q8_0 * GGML_RESTRICT y1 = & y [ib + 1 ]; 409 410// load x 411const svuint8_t qx0r = svld1rq_u8 (svptrue_b8 (),x0 -> qs ); 412const svuint8_t qx1r = svld1rq_u8 (svptrue_b8 (),x1 -> qs ); 413 414// 4-bit -> 8-bit 415const svint8_t qx0l = svreinterpret_s8_u8 (svand_n_u8_m (svptrue_b8 (),qx0r ,0x0F )); 416const svint8_t qx0h = svreinterpret_s8_u8 (svlsr_n_u8_m (svptrue_b8 (),qx0r ,0x04 )); 417const svint8_t qx1l = svreinterpret_s8_u8 (svand_n_u8_m (svptrue_b8 (),qx1r ,0x0F )); 418const svint8_t qx1h = svreinterpret_s8_u8 (svlsr_n_u8_m (svptrue_b8 (),qx1r ,0x04 )); 419 420// sub 8 421const svint8_t qx0ls = svsub_n_s8_x (svptrue_b8 (),qx0h ,8 ); 422const svint8_t qx0hs = svsub_n_s8_x (svptrue_b8 (),qx0l ,8 ); 423const svint8_t qx1ls = svsub_n_s8_x (svptrue_b8 (),qx1h ,8 ); 424const svint8_t qx1hs = svsub_n_s8_x (svptrue_b8 (),qx1l ,8 ); 425 426// load y 427const svint8_t qy0h = svld1_s8 (svptrue_b8 (),y0 -> qs ); 428const svint8_t qy0l = svld1_s8 (svptrue_b8 (),y0 -> qs + 16 ); 429const svint8_t qy1h = svld1_s8 (svptrue_b8 (),y1 -> qs ); 430const svint8_t qy1l = svld1_s8 (svptrue_b8 (),y1 -> qs + 16 ); 431 432// dot product 433sumv0 = svmla_n_f32_x (ph4 ,sumv0 ,svcvt_f32_s32_x (ph4 ,svadd_x (ph4 , 434svdot_s32 (svdup_n_s32 (0 ),qx0ls ,qy0l ), 435svdot_s32 (svdup_n_s32 (0 ),qx0hs ,qy0h ))),GGML_CPU_FP16_TO_FP32 (x0 -> d )* GGML_CPU_FP16_TO_FP32 (y0 -> d )); 436sumv1 = svmla_n_f32_x (ph4 ,sumv1 ,svcvt_f32_s32_x (ph4 ,svadd_x (ph4 , 437svdot_s32 (svdup_n_s32 (0 ),qx1ls ,qy1l ), 438svdot_s32 (svdup_n_s32 (0 ),qx1hs ,qy1h ))),GGML_CPU_FP16_TO_FP32 (x1 -> d )* GGML_CPU_FP16_TO_FP32 (y1 -> d )); 439 } 440 441sumf = svaddv_f32 (svptrue_b32 (),svadd_f32_x (svptrue_b32 (),sumv0 ,sumv1 )); 442 }break ; 443case 256 : 444 { 445// predicate for activating higher lanes for 16 int8 elements 446const svbool_t ph16 = svptrue_pat_b8 (SV_VL16 ); 447// predicate for activating lower lanes for 16 int8 elements 448const svbool_t pl16 = svnot_b_z (svptrue_b8 (),ph16 ); 449 450for (;ib + 1 < nb ;ib += 2 ) { 451const block_q4_0 * GGML_RESTRICT x0 = & x [ib + 0 ]; 452const block_q4_0 * GGML_RESTRICT x1 = & x [ib + 1 ]; 453const block_q8_0 * GGML_RESTRICT y0 = & y [ib + 0 ]; 454const block_q8_0 * GGML_RESTRICT y1 = & y [ib + 1 ]; 455 456// load x 457const svuint8_t qx0r = svld1rq_u8 (svptrue_b8 (),x0 -> qs ); 458const svuint8_t qx1r = svld1rq_u8 (svptrue_b8 (),x1 -> qs ); 459 460// 4-bit -> 8-bit 461const svint8_t qx0 = svreinterpret_s8_u8 (svlsr_n_u8_m (pl16 ,svand_n_u8_m (ph16 ,qx0r ,0x0F ),0x04 )); 462const svint8_t qx1 = svreinterpret_s8_u8 (svlsr_n_u8_m (pl16 ,svand_n_u8_m (ph16 ,qx1r ,0x0F ),0x04 )); 463 464// sub 8 465const svint8_t qx0s = svsub_n_s8_x (svptrue_b8 (),qx0 ,8 ); 466const svint8_t qx1s = svsub_n_s8_x (svptrue_b8 (),qx1 ,8 ); 467 468// load y 469const svint8_t qy0 = svld1_s8 (svptrue_b8 (),y0 -> qs ); 470const svint8_t qy1 = svld1_s8 (svptrue_b8 (),y1 -> qs ); 471 472// dot product 473sumv0 = svmla_n_f32_x (svptrue_b32 (),sumv0 ,svcvt_f32_s32_x (svptrue_b32 (), 474svdot_s32 (svdup_n_s32 (0 ),qx0s ,qy0 )),GGML_CPU_FP16_TO_FP32 (x0 -> d )* GGML_CPU_FP16_TO_FP32 (y0 -> d )); 475sumv1 = svmla_n_f32_x (svptrue_b32 (),sumv1 ,svcvt_f32_s32_x (svptrue_b32 (), 476svdot_s32 (svdup_n_s32 (0 ),qx1s ,qy1 )),GGML_CPU_FP16_TO_FP32 (x1 -> d )* GGML_CPU_FP16_TO_FP32 (y1 -> d )); 477 } 478 479sumf = svaddv_f32 (svptrue_b32 (),svadd_f32_x (svptrue_b32 (),sumv0 ,sumv1 )); 480 }break ; 481case 512 : 482 { 483// predicate for activating higher lanes for 32 int8 elements 484const svbool_t ph32 = svptrue_pat_b8 (SV_VL32 ); 485 486// predicate for activating higher lanes for 16 int8 elements 487const svbool_t ph16 = svptrue_pat_b8 (SV_VL16 ); 488// predicate for activating lower lanes for 16 int8 elements from first 32 int8 activated lanes 489const svbool_t pl16 = svnot_b_z (ph32 ,ph16 ); 490 491for (;ib + 1 < nb ;ib += 2 ) { 492const block_q4_0 * GGML_RESTRICT x0 = & x [ib + 0 ]; 493const block_q4_0 * GGML_RESTRICT x1 = & x [ib + 1 ]; 494const block_q8_0 * GGML_RESTRICT y0 = & y [ib + 0 ]; 495const block_q8_0 * GGML_RESTRICT y1 = & y [ib + 1 ]; 496 497// load x 498const svuint8_t qx0r = svld1rq_u8 (ph32 ,x0 -> qs ); 499const svuint8_t qx1r = svld1rq_u8 (ph32 ,x1 -> qs ); 500 501// 4-bit -> 8-bit 502const svint8_t qx0 = svreinterpret_s8_u8 (svlsr_n_u8_m (pl16 ,svand_n_u8_m (ph16 ,qx0r ,0x0F ),0x04 )); 503const svint8_t qx1 = svreinterpret_s8_u8 (svlsr_n_u8_m (pl16 ,svand_n_u8_m (ph16 ,qx1r ,0x0F ),0x04 )); 504 505// sub 8 506const svint8_t qx0s = svsub_n_s8_x (ph32 ,qx0 ,8 ); 507const svint8_t qx1s = svsub_n_s8_x (ph32 ,qx1 ,8 ); 508 509// load y 510const svint8_t qy0 = svld1_s8 (ph32 ,y0 -> qs ); 511const svint8_t qy1 = svld1_s8 (ph32 ,y1 -> qs ); 512 513// dot product 514sumv0 = svmla_n_f32_x (ph32 ,sumv0 ,svcvt_f32_s32_x (ph32 , 515svdot_s32 (svdup_n_s32 (0 ),qx0s ,qy0 )),GGML_CPU_FP16_TO_FP32 (x0 -> d )* GGML_CPU_FP16_TO_FP32 (y0 -> d )); 516sumv1 = svmla_n_f32_x (ph32 ,sumv1 ,svcvt_f32_s32_x (ph32 , 517svdot_s32 (svdup_n_s32 (0 ),qx1s ,qy1 )),GGML_CPU_FP16_TO_FP32 (x1 -> d )* GGML_CPU_FP16_TO_FP32 (y1 -> d )); 518 } 519 520sumf = svaddv_f32 (ph32 ,svadd_f32_x (ph32 ,sumv0 ,sumv1 )); 521 }break ; 522default : 523assert (false&& "Unsupported vector length" ); 524break ; 525 } 526 527#elif defined(__ARM_NEON ) 528float32x4_t sumv0 = vdupq_n_f32 (0.0f ); 529float32x4_t sumv1 = vdupq_n_f32 (0.0f ); 530 531for (;ib + 1 < nb ;ib += 2 ) { 532const block_q4_0 * GGML_RESTRICT x0 = & x [ib + 0 ]; 533const block_q4_0 * GGML_RESTRICT x1 = & x [ib + 1 ]; 534const block_q8_0 * GGML_RESTRICT y0 = & y [ib + 0 ]; 535const block_q8_0 * GGML_RESTRICT y1 = & y [ib + 1 ]; 536 537const uint8x16_t m4b = vdupq_n_u8 (0x0F ); 538const int8x16_t s8b = vdupq_n_s8 (0x8 ); 539 540const uint8x16_t v0_0 = vld1q_u8 (x0 -> qs ); 541const uint8x16_t v0_1 = vld1q_u8 (x1 -> qs ); 542 543// 4-bit -> 8-bit 544const int8x16_t v0_0l = vreinterpretq_s8_u8 (vandq_u8 (v0_0 ,m4b )); 545const int8x16_t v0_0h = vreinterpretq_s8_u8 (vshrq_n_u8 (v0_0 ,4 )); 546const int8x16_t v0_1l = vreinterpretq_s8_u8 (vandq_u8 (v0_1 ,m4b )); 547const int8x16_t v0_1h = vreinterpretq_s8_u8 (vshrq_n_u8 (v0_1 ,4 )); 548 549// sub 8 550const int8x16_t v0_0ls = vsubq_s8 (v0_0l ,s8b ); 551const int8x16_t v0_0hs = vsubq_s8 (v0_0h ,s8b ); 552const int8x16_t v0_1ls = vsubq_s8 (v0_1l ,s8b ); 553const int8x16_t v0_1hs = vsubq_s8 (v0_1h ,s8b ); 554 555// load y 556const int8x16_t v1_0l = vld1q_s8 (y0 -> qs ); 557const int8x16_t v1_0h = vld1q_s8 (y0 -> qs + 16 ); 558const int8x16_t v1_1l = vld1q_s8 (y1 -> qs ); 559const int8x16_t v1_1h = vld1q_s8 (y1 -> qs + 16 ); 560 561// dot product into int32x4_t 562const int32x4_t p_0 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),v0_0ls ,v1_0l ),v0_0hs ,v1_0h ); 563const int32x4_t p_1 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),v0_1ls ,v1_1l ),v0_1hs ,v1_1h ); 564 565sumv0 = vmlaq_n_f32 (sumv0 ,vcvtq_f32_s32 (p_0 ),GGML_CPU_FP16_TO_FP32 (x0 -> d )* GGML_CPU_FP16_TO_FP32 (y0 -> d )); 566sumv1 = vmlaq_n_f32 (sumv1 ,vcvtq_f32_s32 (p_1 ),GGML_CPU_FP16_TO_FP32 (x1 -> d )* GGML_CPU_FP16_TO_FP32 (y1 -> d )); 567 } 568 569sumf = vaddvq_f32 (sumv0 )+ vaddvq_f32 (sumv1 ); 570#endif 571for (;ib < nb ;++ ib ) { 572int sumi0 = 0 ; 573int sumi1 = 0 ; 574 575for (int j = 0 ;j < qk /2 ;++ j ) { 576const int v0 = (x [ib ].qs [j ]& 0x0F )- 8 ; 577const int v1 = (x [ib ].qs [j ] >>4 )- 8 ; 578 579sumi0 += (v0 * y [ib ].qs [j ]); 580sumi1 += (v1 * y [ib ].qs [j + qk /2 ]); 581 } 582 583int sumi = sumi0 + sumi1 ; 584sumf += sumi * GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ); 585 } 586 587* s = sumf ; 588} 589 590void 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 ) { 591const int qk = QK8_1 ; 592const int nb = n /qk ; 593 594assert (n %qk == 0 ); 595#if defined(__ARM_FEATURE_MATMUL_INT8 ) 596assert ((nrc == 2 )|| (nrc == 1 )); 597#else 598assert (nrc == 1 ); 599#endif 600UNUSED (nrc ); 601UNUSED (bx ); 602UNUSED (by ); 603UNUSED (bs ); 604 605const block_q4_1 * GGML_RESTRICT x = vx ; 606const block_q8_1 * GGML_RESTRICT y = vy ; 607 608#if defined(__ARM_FEATURE_MATMUL_INT8 ) 609if (nrc == 2 ) { 610const block_q4_1 * GGML_RESTRICT vx0 = vx ; 611const block_q4_1 * GGML_RESTRICT vx1 = (const block_q4_1 * ) ((const uint8_t * )vx + bx ); 612const block_q8_1 * GGML_RESTRICT vy0 = vy ; 613const block_q8_1 * GGML_RESTRICT vy1 = (const block_q8_1 * ) ((const uint8_t * )vy + by ); 614 615float32x4_t sumv0 = vdupq_n_f32 (0.0f ); 616float32x4_t summs0 = vdupq_n_f32 (0.0f ); 617 618for (int i = 0 ;i < nb ;i ++ ) { 619const block_q4_1 * GGML_RESTRICT b_x0 = & vx0 [i ]; 620const block_q4_1 * GGML_RESTRICT b_x1 = & vx1 [i ]; 621const block_q8_1 * GGML_RESTRICT b_y0 = & vy0 [i ]; 622const block_q8_1 * GGML_RESTRICT b_y1 = & vy1 [i ]; 623 624float32_t summs_t [4 ]= { 625GGML_CPU_FP16_TO_FP32 (b_x0 -> m )* GGML_CPU_FP16_TO_FP32 (b_y0 -> s ), 626GGML_CPU_FP16_TO_FP32 (b_x1 -> m )* GGML_CPU_FP16_TO_FP32 (b_y0 -> s ), 627GGML_CPU_FP16_TO_FP32 (b_x0 -> m )* GGML_CPU_FP16_TO_FP32 (b_y1 -> s ), 628GGML_CPU_FP16_TO_FP32 (b_x1 -> m )* GGML_CPU_FP16_TO_FP32 (b_y1 -> s ) 629 }; 630summs0 = vaddq_f32 (summs0 ,vld1q_f32 (summs_t )); 631 632const uint8x16_t m4b = vdupq_n_u8 (0x0F ); 633 634const uint8x16_t v0_0 = vld1q_u8 (b_x0 -> qs ); 635const uint8x16_t v0_1 = vld1q_u8 (b_x1 -> qs ); 636 637// 4-bit -> 8-bit 638const int8x16_t x0_l = vreinterpretq_s8_u8 (vandq_u8 (v0_0 ,m4b )); 639const int8x16_t x0_h = vreinterpretq_s8_u8 (vshrq_n_u8 (v0_0 ,4 )); 640const int8x16_t x1_l = vreinterpretq_s8_u8 (vandq_u8 (v0_1 ,m4b )); 641const int8x16_t x1_h = vreinterpretq_s8_u8 (vshrq_n_u8 (v0_1 ,4 )); 642 643// load y 644const int8x16_t y0_l = vld1q_s8 (b_y0 -> qs ); 645const int8x16_t y0_h = vld1q_s8 (b_y0 -> qs + 16 ); 646const int8x16_t y1_l = vld1q_s8 (b_y1 -> qs ); 647const int8x16_t y1_h = vld1q_s8 (b_y1 -> qs + 16 ); 648 649// mmla into int32x4_t 650float32_t _scale [4 ]= { 651GGML_CPU_FP16_TO_FP32 (b_x0 -> d )* GGML_CPU_FP16_TO_FP32 (b_y0 -> d ), 652GGML_CPU_FP16_TO_FP32 (b_x0 -> d )* GGML_CPU_FP16_TO_FP32 (b_y1 -> d ), 653GGML_CPU_FP16_TO_FP32 (b_x1 -> d )* GGML_CPU_FP16_TO_FP32 (b_y0 -> d ), 654GGML_CPU_FP16_TO_FP32 (b_x1 -> d )* GGML_CPU_FP16_TO_FP32 (b_y1 -> d ) 655 }; 656float32x4_t scale = vld1q_f32 (_scale ); 657 658int8x16_t l0 = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (x0_l ),vreinterpretq_s64_s8 (x1_l ))); 659int8x16_t l1 = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (x0_l ),vreinterpretq_s64_s8 (x1_l ))); 660 661int8x16_t l2 = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (x0_h ),vreinterpretq_s64_s8 (x1_h ))); 662int8x16_t l3 = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (x0_h ),vreinterpretq_s64_s8 (x1_h ))); 663 664int8x16_t r0 = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (y0_l ),vreinterpretq_s64_s8 (y1_l ))); 665int8x16_t r1 = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (y0_l ),vreinterpretq_s64_s8 (y1_l ))); 666 667int8x16_t r2 = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (y0_h ),vreinterpretq_s64_s8 (y1_h ))); 668int8x16_t r3 = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (y0_h ),vreinterpretq_s64_s8 (y1_h ))); 669sumv0 = vmlaq_f32 (sumv0 ,(vcvtq_f32_s32 (vmmlaq_s32 ((vmmlaq_s32 ((vmmlaq_s32 ((vmmlaq_s32 (vdupq_n_s32 (0 ),l0 ,r0 )), 670l1 ,r1 )),l2 ,r2 )),l3 ,r3 ))),scale ); 671 } 672 673float32x4_t sumv1 = vextq_f32 (sumv0 ,sumv0 ,2 ); 674float32x4_t sumv2 = vzip1q_f32 (sumv0 ,sumv1 ); 675 676sumv2 = vaddq_f32 (sumv2 ,summs0 ); 677 678vst1_f32 (s ,vget_low_f32 (sumv2 )); 679vst1_f32 (s + bs ,vget_high_f32 (sumv2 )); 680 681return ; 682 } 683#endif 684 685int ib = 0 ; 686float sumf = 0 ; 687 688#if defined(__ARM_NEON ) 689float32x4_t sumv0 = vdupq_n_f32 (0.0f ); 690float32x4_t sumv1 = vdupq_n_f32 (0.0f ); 691 692float summs = 0 ; 693 694for (;ib + 1 < nb ;ib += 2 ) { 695const block_q4_1 * GGML_RESTRICT x0 = & x [ib + 0 ]; 696const block_q4_1 * GGML_RESTRICT x1 = & x [ib + 1 ]; 697const block_q8_1 * GGML_RESTRICT y0 = & y [ib + 0 ]; 698const block_q8_1 * GGML_RESTRICT y1 = & y [ib + 1 ]; 699 700summs += GGML_CPU_FP16_TO_FP32 (x0 -> m )* GGML_CPU_FP16_TO_FP32 (y0 -> s )+ GGML_CPU_FP16_TO_FP32 (x1 -> m )* GGML_CPU_FP16_TO_FP32 (y1 -> s ); 701 702const uint8x16_t m4b = vdupq_n_u8 (0x0F ); 703 704const uint8x16_t v0_0 = vld1q_u8 (x0 -> qs ); 705const uint8x16_t v0_1 = vld1q_u8 (x1 -> qs ); 706 707// 4-bit -> 8-bit 708const int8x16_t v0_0l = vreinterpretq_s8_u8 (vandq_u8 (v0_0 ,m4b )); 709const int8x16_t v0_0h = vreinterpretq_s8_u8 (vshrq_n_u8 (v0_0 ,4 )); 710const int8x16_t v0_1l = vreinterpretq_s8_u8 (vandq_u8 (v0_1 ,m4b )); 711const int8x16_t v0_1h = vreinterpretq_s8_u8 (vshrq_n_u8 (v0_1 ,4 )); 712 713// load y 714const int8x16_t v1_0l = vld1q_s8 (y0 -> qs ); 715const int8x16_t v1_0h = vld1q_s8 (y0 -> qs + 16 ); 716const int8x16_t v1_1l = vld1q_s8 (y1 -> qs ); 717const int8x16_t v1_1h = vld1q_s8 (y1 -> qs + 16 ); 718 719// dot product into int32x4_t 720const int32x4_t p_0 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),v0_0l ,v1_0l ),v0_0h ,v1_0h ); 721const int32x4_t p_1 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),v0_1l ,v1_1l ),v0_1h ,v1_1h ); 722 723sumv0 = vmlaq_n_f32 (sumv0 ,vcvtq_f32_s32 (p_0 ),GGML_CPU_FP16_TO_FP32 (x0 -> d )* GGML_CPU_FP16_TO_FP32 (y0 -> d )); 724sumv1 = vmlaq_n_f32 (sumv1 ,vcvtq_f32_s32 (p_1 ),GGML_CPU_FP16_TO_FP32 (x1 -> d )* GGML_CPU_FP16_TO_FP32 (y1 -> d )); 725 } 726 727sumf = vaddvq_f32 (sumv0 )+ vaddvq_f32 (sumv1 )+ summs ; 728 729#endif 730for (;ib < nb ;++ ib ) { 731int sumi0 = 0 ; 732int sumi1 = 0 ; 733 734for (int j = 0 ;j < qk /2 ;++ j ) { 735const int v0 = (x [ib ].qs [j ]& 0x0F ); 736const int v1 = (x [ib ].qs [j ] >>4 ); 737 738sumi0 += (v0 * y [ib ].qs [j ]); 739sumi1 += (v1 * y [ib ].qs [j + qk /2 ]); 740 } 741 742int sumi = sumi0 + sumi1 ; 743sumf += (GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ))* sumi + GGML_CPU_FP16_TO_FP32 (x [ib ].m )* GGML_CPU_FP16_TO_FP32 (y [ib ].s ); 744 } 745 746* s = sumf ; 747} 748 749void 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 ) { 750assert (nrc == 1 ); 751UNUSED (nrc ); 752UNUSED (bx ); 753UNUSED (by ); 754UNUSED (bs ); 755assert (n %QK_MXFP4 == 0 ); 756static_assert (QK_MXFP4 == QK8_0 ,"QK_MXFP4 and QK8_0 must be the same" ); 757 758const block_mxfp4 * GGML_RESTRICT x = vx ; 759const block_q8_0 * GGML_RESTRICT y = vy ; 760 761const int nb = n /QK_MXFP4 ; 762 763int ib = 0 ; 764float sumf = 0 ; 765 766#if defined__ARM_NEON 767const int8x16_t values = vld1q_s8 (kvalues_mxfp4 ); 768const uint8x16_t m4b = vdupq_n_u8 (0x0f ); 769uint8x16x2_t q4bits ; 770int8x16x4_t q4b ; 771int8x16x4_t q8b ; 772int32x4_t prod_1 ; 773int32x4_t prod_2 ; 774 775for (;ib + 1 < nb ;ib += 2 ) { 776q4bits .val [0 ]= vld1q_u8 (x [ib + 0 ].qs ); 777q4bits .val [1 ]= vld1q_u8 (x [ib + 1 ].qs ); 778q8b .val [0 ]= vld1q_s8 (y [ib + 0 ].qs ); 779q8b .val [1 ]= vld1q_s8 (y [ib + 0 ].qs + 16 ); 780q8b .val [2 ]= vld1q_s8 (y [ib + 1 ].qs ); 781q8b .val [3 ]= vld1q_s8 (y [ib + 1 ].qs + 16 ); 782 783q4b .val [0 ]= ggml_vqtbl1q_s8 (values ,vandq_u8 (q4bits .val [0 ],m4b )); 784q4b .val [1 ]= ggml_vqtbl1q_s8 (values ,vshrq_n_u8 (q4bits .val [0 ],4 )); 785q4b .val [2 ]= ggml_vqtbl1q_s8 (values ,vandq_u8 (q4bits .val [1 ],m4b )); 786q4b .val [3 ]= ggml_vqtbl1q_s8 (values ,vshrq_n_u8 (q4bits .val [1 ],4 )); 787 788prod_1 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q4b .val [0 ],q8b .val [0 ]),q4b .val [1 ],q8b .val [1 ]); 789prod_2 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q4b .val [2 ],q8b .val [2 ]),q4b .val [3 ],q8b .val [3 ]); 790 791sumf += 792GGML_E8M0_TO_FP32_HALF (x [ib + 0 ].e )* GGML_CPU_FP16_TO_FP32 (y [ib + 0 ].d )* vaddvq_s32 (prod_1 )+ 793GGML_E8M0_TO_FP32_HALF (x [ib + 1 ].e )* GGML_CPU_FP16_TO_FP32 (y [ib + 1 ].d )* vaddvq_s32 (prod_2 ); 794 } 795 796#endif 797for (;ib < nb ;++ ib ) { 798const float d = GGML_CPU_FP16_TO_FP32 (y [ib ].d )* GGML_E8M0_TO_FP32_HALF (x [ib ].e ); 799int sumi1 = 0 ; 800int sumi2 = 0 ; 801for (int j = 0 ;j < QK_MXFP4 /2 ;++ j ) { 802sumi1 += y [ib ].qs [j + 0 ]* kvalues_mxfp4 [x [ib ].qs [j ]& 0xf ]; 803sumi2 += y [ib ].qs [j + QK_MXFP4 /2 ]* kvalues_mxfp4 [x [ib ].qs [j ] >>4 ]; 804 } 805sumf += d * (sumi1 + sumi2 ); 806 } 807* s = sumf ; 808} 809 810void 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 ) { 811assert (nrc == 1 ); 812UNUSED (nrc ); 813UNUSED (bx ); 814UNUSED (by ); 815UNUSED (bs ); 816assert (n %QK_NVFP4 == 0 ); 817 818const block_nvfp4 * GGML_RESTRICT x = vx ; 819const block_q8_0 * GGML_RESTRICT y = vy ; 820 821// Each NVFP4 super-block (64 elements) spans 2 q8_0 blocks 822const int nb = n /QK_NVFP4 ; 823 824float sumf = 0 ; 825 826#if defined(__ARM_NEON )&& defined(__ARM_FEATURE_FMA ) 827const int8x16_t values = vld1q_s8 (kvalues_mxfp4 ); 828const uint8x16_t m4b = vdupq_n_u8 (0x0f ); 829float32x4_t acc = vdupq_n_f32 (0.0f ); 830 831for (int ib = 0 ;ib < nb ;++ ib ) { 832const uint8x16_t q4bits_0 = vld1q_u8 (x [ib ].qs ); 833const uint8x16_t q4bits_1 = vld1q_u8 (x [ib ].qs + 16 ); 834 835const int8x16_t q4_lo_0 = ggml_vqtbl1q_s8 (values ,vandq_u8 (q4bits_0 ,m4b )); 836const int8x16_t q4_hi_0 = ggml_vqtbl1q_s8 (values ,vshrq_n_u8 (q4bits_0 ,4 )); 837const int8x16_t q4_lo_1 = ggml_vqtbl1q_s8 (values ,vandq_u8 (q4bits_1 ,m4b )); 838const int8x16_t q4_hi_1 = ggml_vqtbl1q_s8 (values ,vshrq_n_u8 (q4bits_1 ,4 )); 839 840#if defined(__ARM_FEATURE_DOTPROD ) 841const int8x16_t q8_0a = vld1q_s8 (y [2 * ib ].qs ); 842const int8x16_t q8_0b = vld1q_s8 (y [2 * ib ].qs + 16 ); 843const int8x16_t q8_lo_0 = vcombine_s8 (vget_low_s8 (q8_0a ),vget_low_s8 (q8_0b )); 844const int8x16_t q8_hi_0 = vcombine_s8 (vget_high_s8 (q8_0a ),vget_high_s8 (q8_0b )); 845 846const int8x16_t q8_1a = vld1q_s8 (y [2 * ib + 1 ].qs ); 847const int8x16_t q8_1b = vld1q_s8 (y [2 * ib + 1 ].qs + 16 ); 848const int8x16_t q8_lo_1 = vcombine_s8 (vget_low_s8 (q8_1a ),vget_low_s8 (q8_1b )); 849const int8x16_t q8_hi_1 = vcombine_s8 (vget_high_s8 (q8_1a ),vget_high_s8 (q8_1b )); 850 851const int32x4_t p0 = vaddq_s32 ( 852vdotq_s32 (vdupq_n_s32 (0 ),q4_lo_0 ,q8_lo_0 ), 853vdotq_s32 (vdupq_n_s32 (0 ),q4_hi_0 ,q8_hi_0 )); 854const int32x4_t p1 = vaddq_s32 ( 855vdotq_s32 (vdupq_n_s32 (0 ),q4_lo_1 ,q8_lo_1 ), 856vdotq_s32 (vdupq_n_s32 (0 ),q4_hi_1 ,q8_hi_1 )); 857 858const int32x4_t sumi = vpaddq_s32 (p0 ,p1 ); 859#else 860const int8x8_t q4_0_lo = vget_low_s8 (q4_lo_0 ); 861const int8x8_t q4_0_hi = vget_low_s8 (q4_hi_0 ); 862const int8x8_t q4_1_lo = vget_high_s8 (q4_lo_0 ); 863const int8x8_t q4_1_hi = vget_high_s8 (q4_hi_0 ); 864const int8x8_t q4_2_lo = vget_low_s8 (q4_lo_1 ); 865const int8x8_t q4_2_hi = vget_low_s8 (q4_hi_1 ); 866const int8x8_t q4_3_lo = vget_high_s8 (q4_lo_1 ); 867const int8x8_t q4_3_hi = vget_high_s8 (q4_hi_1 ); 868 869const int8x8_t q8_0_lo = vld1_s8 (y [2 * ib ].qs ); 870const int8x8_t q8_0_hi = vld1_s8 (y [2 * ib ].qs + 8 ); 871const int8x8_t q8_1_lo = vld1_s8 (y [2 * ib ].qs + 16 ); 872const int8x8_t q8_1_hi = vld1_s8 (y [2 * ib ].qs + 24 ); 873const int8x8_t q8_2_lo = vld1_s8 (y [2 * ib + 1 ].qs ); 874const int8x8_t q8_2_hi = vld1_s8 (y [2 * ib + 1 ].qs + 8 ); 875const int8x8_t q8_3_lo = vld1_s8 (y [2 * ib + 1 ].qs + 16 ); 876const int8x8_t q8_3_hi = vld1_s8 (y [2 * ib + 1 ].qs + 24 ); 877 878const int32x4_t sumi = (int32x4_t ){ 879vaddvq_s32 (ggml_nvfp4_dot8 (q4_0_lo ,q8_0_lo ,q4_0_hi ,q8_0_hi )), 880vaddvq_s32 (ggml_nvfp4_dot8 (q4_1_lo ,q8_1_lo ,q4_1_hi ,q8_1_hi )), 881vaddvq_s32 (ggml_nvfp4_dot8 (q4_2_lo ,q8_2_lo ,q4_2_hi ,q8_2_hi )), 882vaddvq_s32 (ggml_nvfp4_dot8 (q4_3_lo ,q8_3_lo ,q4_3_hi ,q8_3_hi )), 883 }; 884#endif 885 886const float dy0 = GGML_CPU_FP16_TO_FP32 (y [2 * ib ].d ); 887const float dy1 = GGML_CPU_FP16_TO_FP32 (y [2 * ib + 1 ].d ); 888const float32x4_t nvsc = { 889GGML_CPU_UE4M3_TO_FP32 (x [ib ].d [0 ]), 890GGML_CPU_UE4M3_TO_FP32 (x [ib ].d [1 ]), 891GGML_CPU_UE4M3_TO_FP32 (x [ib ].d [2 ]), 892GGML_CPU_UE4M3_TO_FP32 (x [ib ].d [3 ]) 893 }; 894const float32x4_t scales = vmulq_f32 (nvsc , (float32x4_t ){dy0 ,dy0 ,dy1 ,dy1 }); 895 896acc = vfmaq_f32 (acc ,vcvtq_f32_s32 (sumi ),scales ); 897 } 898sumf = vaddvq_f32 (acc ); 899#else 900for (int ib = 0 ;ib < nb ;++ ib ) { 901for (int si = 0 ;si < 4 ;++ si ) { 902const float d = ggml_ue4m3_to_fp32 (x [ib ].d [si ]); 903const int q8b = si /2 ; 904const int q8o = (si %2 )* QK_NVFP4_SUB ; 905const float dy = GGML_CPU_FP16_TO_FP32 (y [2 * ib + q8b ].d ); 906 907int sumi_lo = 0 ,sumi_hi = 0 ; 908for (int j = 0 ;j < QK_NVFP4_SUB /2 ;++ j ) { 909const uint8_t qv = x [ib ].qs [si * (QK_NVFP4_SUB /2 )+ j ]; 910sumi_lo += y [2 * ib + q8b ].qs [q8o + j + 0 ]* kvalues_mxfp4 [qv & 0xf ]; 911sumi_hi += y [2 * ib + q8b ].qs [q8o + j + QK_NVFP4_SUB /2 ]* kvalues_mxfp4 [qv >>4 ]; 912 } 913sumf += dy * d * (sumi_lo + sumi_hi ); 914 } 915 } 916#endif 917* s = sumf ; 918} 919 920void 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 ) { 921const int qk = QK8_0 ; 922const int nb = n /qk ; 923 924int ib = 0 ; 925float sumf = 0 ; 926 927assert (n %qk == 0 ); 928assert (qk == QK5_0 ); 929assert (nrc == 1 ); 930UNUSED (nrc ); 931UNUSED (bx ); 932UNUSED (by ); 933UNUSED (bs ); 934 935const block_q5_0 * GGML_RESTRICT x = vx ; 936const block_q8_0 * GGML_RESTRICT y = vy ; 937 938#if defined(__ARM_NEON ) 939float32x4_t sumv0 = vdupq_n_f32 (0.0f ); 940float32x4_t sumv1 = vdupq_n_f32 (0.0f ); 941 942uint32_t qh0 ; 943uint32_t qh1 ; 944 945uint64_t tmp0 [4 ]; 946uint64_t tmp1 [4 ]; 947 948for (;ib + 1 < nb ;ib += 2 ) { 949const block_q5_0 * GGML_RESTRICT x0 = & x [ib ]; 950const block_q5_0 * GGML_RESTRICT x1 = & x [ib + 1 ]; 951const block_q8_0 * GGML_RESTRICT y0 = & y [ib ]; 952const block_q8_0 * GGML_RESTRICT y1 = & y [ib + 1 ]; 953 954const uint8x16_t m4b = vdupq_n_u8 (0x0F ); 955 956// extract the 5th bit via lookup table ((!b) << 4) 957memcpy (& qh0 ,x0 -> qh ,sizeof (qh0 )); 958memcpy (& qh1 ,x1 -> qh ,sizeof (qh1 )); 959 960tmp0 [0 ]= table_b2b_1 [(qh0 >>0 )& 0xFF ]; 961tmp0 [1 ]= table_b2b_1 [(qh0 >>8 )& 0xFF ]; 962tmp0 [2 ]= table_b2b_1 [(qh0 >>16 )& 0xFF ]; 963tmp0 [3 ]= table_b2b_1 [(qh0 >>24 ) ]; 964 965tmp1 [0 ]= table_b2b_1 [(qh1 >>0 )& 0xFF ]; 966tmp1 [1 ]= table_b2b_1 [(qh1 >>8 )& 0xFF ]; 967tmp1 [2 ]= table_b2b_1 [(qh1 >>16 )& 0xFF ]; 968tmp1 [3 ]= table_b2b_1 [(qh1 >>24 ) ]; 969 970const int8x16_t qhl0 = vld1q_s8 ((const int8_t * )(tmp0 + 0 )); 971const int8x16_t qhh0 = vld1q_s8 ((const int8_t * )(tmp0 + 2 )); 972const int8x16_t qhl1 = vld1q_s8 ((const int8_t * )(tmp1 + 0 )); 973const int8x16_t qhh1 = vld1q_s8 ((const int8_t * )(tmp1 + 2 )); 974 975const uint8x16_t v0_0 = vld1q_u8 (x0 -> qs ); 976const uint8x16_t v0_1 = vld1q_u8 (x1 -> qs ); 977 978// 4-bit -> 8-bit 979int8x16_t v0_0l = vreinterpretq_s8_u8 (vandq_u8 (v0_0 ,m4b )); 980int8x16_t v0_0h = vreinterpretq_s8_u8 (vshrq_n_u8 (v0_0 ,4 )); 981int8x16_t v0_1l = vreinterpretq_s8_u8 (vandq_u8 (v0_1 ,m4b )); 982int8x16_t v0_1h = vreinterpretq_s8_u8 (vshrq_n_u8 (v0_1 ,4 )); 983 984// add high bit and sub 16 (equivalent to sub 0x10 when bit is zero) 985const int8x16_t v0_0lf = vsubq_s8 (v0_0l ,qhl0 ); 986const int8x16_t v0_0hf = vsubq_s8 (v0_0h ,qhh0 ); 987const int8x16_t v0_1lf = vsubq_s8 (v0_1l ,qhl1 ); 988const int8x16_t v0_1hf = vsubq_s8 (v0_1h ,qhh1 ); 989 990// load y 991const int8x16_t v1_0l = vld1q_s8 (y0 -> qs ); 992const int8x16_t v1_0h = vld1q_s8 (y0 -> qs + 16 ); 993const int8x16_t v1_1l = vld1q_s8 (y1 -> qs ); 994const int8x16_t v1_1h = vld1q_s8 (y1 -> qs + 16 ); 995 996sumv0 = vmlaq_n_f32 (sumv0 ,vcvtq_f32_s32 (vaddq_s32 ( 997ggml_vdotq_s32 (vdupq_n_s32 (0 ),v0_0lf ,v1_0l ), 998ggml_vdotq_s32 (vdupq_n_s32 (0 ),v0_0hf ,v1_0h ))),GGML_CPU_FP16_TO_FP32 (x0 -> d )* GGML_CPU_FP16_TO_FP32 (y0 -> d )); 999sumv1 = vmlaq_n_f32 (sumv1 ,vcvtq_f32_s32 (vaddq_s32 ( 1000ggml_vdotq_s32 (vdupq_n_s32 (0 ),v0_1lf ,v1_1l ), 1001ggml_vdotq_s32 (vdupq_n_s32 (0 ),v0_1hf ,v1_1h ))),GGML_CPU_FP16_TO_FP32 (x1 -> d )* GGML_CPU_FP16_TO_FP32 (y1 -> d )); 1002 } 1003 1004sumf = vaddvq_f32 (sumv0 )+ vaddvq_f32 (sumv1 ); 1005 1006#endif 1007for (;ib < nb ;++ ib ) { 1008uint32_t qh ; 1009memcpy (& qh ,x [ib ].qh ,sizeof (qh )); 1010 1011int sumi0 = 0 ; 1012int sumi1 = 0 ; 1013 1014for (int j = 0 ;j < qk /2 ;++ j ) { 1015const uint8_t xh_0 = ((qh & (1u << (j + 0 ))) >> (j + 0 )) <<4 ; 1016const uint8_t xh_1 = ((qh & (1u << (j + 16 ))) >> (j + 12 )); 1017 1018const int32_t x0 = (int8_t )(((x [ib ].qs [j ]& 0x0F ) |xh_0 )- 16 ); 1019const int32_t x1 = (int8_t )(((x [ib ].qs [j ] >>4 ) |xh_1 )- 16 ); 1020 1021sumi0 += (x0 * y [ib ].qs [j ]); 1022sumi1 += (x1 * y [ib ].qs [j + qk /2 ]); 1023 } 1024 1025int sumi = sumi0 + sumi1 ; 1026sumf += (GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ))* sumi ; 1027 } 1028 1029* s = sumf ; 1030} 1031 1032void 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 ) { 1033const int qk = QK8_1 ; 1034const int nb = n /qk ; 1035 1036int ib = 0 ; 1037float sumf = 0 ; 1038 1039assert (n %qk == 0 ); 1040assert (qk == QK5_1 ); 1041assert (nrc == 1 ); 1042UNUSED (nrc ); 1043UNUSED (bx ); 1044UNUSED (by ); 1045UNUSED (bs ); 1046 1047const block_q5_1 * GGML_RESTRICT x = vx ; 1048const block_q8_1 * GGML_RESTRICT y = vy ; 1049 1050#if defined(__ARM_NEON ) 1051float32x4_t sumv0 = vdupq_n_f32 (0.0f ); 1052float32x4_t sumv1 = vdupq_n_f32 (0.0f ); 1053 1054float summs0 = 0.0f ; 1055float summs1 = 0.0f ; 1056 1057uint32_t qh0 ; 1058uint32_t qh1 ; 1059 1060uint64_t tmp0 [4 ]; 1061uint64_t tmp1 [4 ]; 1062 1063for (;ib + 1 < nb ;ib += 2 ) { 1064const block_q5_1 * GGML_RESTRICT x0 = & x [ib ]; 1065const block_q5_1 * GGML_RESTRICT x1 = & x [ib + 1 ]; 1066const block_q8_1 * GGML_RESTRICT y0 = & y [ib ]; 1067const block_q8_1 * GGML_RESTRICT y1 = & y [ib + 1 ]; 1068 1069const uint8x16_t m4b = vdupq_n_u8 (0x0F ); 1070 1071summs0 += GGML_CPU_FP16_TO_FP32 (x0 -> m )* GGML_CPU_FP16_TO_FP32 (y0 -> s ); 1072summs1 += GGML_CPU_FP16_TO_FP32 (x1 -> m )* GGML_CPU_FP16_TO_FP32 (y1 -> s ); 1073 1074// extract the 5th bit via lookup table ((b) << 4) 1075memcpy (& qh0 ,x0 -> qh ,sizeof (qh0 )); 1076memcpy (& qh1 ,x1 -> qh ,sizeof (qh1 )); 1077 1078tmp0 [0 ]= table_b2b_0 [(qh0 >>0 )& 0xFF ]; 1079tmp0 [1 ]= table_b2b_0 [(qh0 >>8 )& 0xFF ]; 1080tmp0 [2 ]= table_b2b_0 [(qh0 >>16 )& 0xFF ]; 1081tmp0 [3 ]= table_b2b_0 [(qh0 >>24 ) ]; 1082 1083tmp1 [0 ]= table_b2b_0 [(qh1 >>0 )& 0xFF ]; 1084tmp1 [1 ]= table_b2b_0 [(qh1 >>8 )& 0xFF ]; 1085tmp1 [2 ]= table_b2b_0 [(qh1 >>16 )& 0xFF ]; 1086tmp1 [3 ]= table_b2b_0 [(qh1 >>24 ) ]; 1087 1088const int8x16_t qhl0 = vld1q_s8 ((const int8_t * )(tmp0 + 0 )); 1089const int8x16_t qhh0 = vld1q_s8 ((const int8_t * )(tmp0 + 2 )); 1090const int8x16_t qhl1 = vld1q_s8 ((const int8_t * )(tmp1 + 0 )); 1091const int8x16_t qhh1 = vld1q_s8 ((const int8_t * )(tmp1 + 2 )); 1092 1093const uint8x16_t v0_0 = vld1q_u8 (x0 -> qs ); 1094const uint8x16_t v0_1 = vld1q_u8 (x1 -> qs ); 1095 1096// 4-bit -> 8-bit 1097const int8x16_t v0_0l = vreinterpretq_s8_u8 (vandq_u8 (v0_0 ,m4b )); 1098const int8x16_t v0_0h = vreinterpretq_s8_u8 (vshrq_n_u8 (v0_0 ,4 )); 1099const int8x16_t v0_1l = vreinterpretq_s8_u8 (vandq_u8 (v0_1 ,m4b )); 1100const int8x16_t v0_1h = vreinterpretq_s8_u8 (vshrq_n_u8 (v0_1 ,4 )); 1101 1102// add high bit 1103const int8x16_t v0_0lf = vorrq_s8 (v0_0l ,qhl0 ); 1104const int8x16_t v0_0hf = vorrq_s8 (v0_0h ,qhh0 ); 1105const int8x16_t v0_1lf = vorrq_s8 (v0_1l ,qhl1 ); 1106const int8x16_t v0_1hf = vorrq_s8 (v0_1h ,qhh1 ); 1107 1108// load y 1109const int8x16_t v1_0l = vld1q_s8 (y0 -> qs ); 1110const int8x16_t v1_0h = vld1q_s8 (y0 -> qs + 16 ); 1111const int8x16_t v1_1l = vld1q_s8 (y1 -> qs ); 1112const int8x16_t v1_1h = vld1q_s8 (y1 -> qs + 16 ); 1113 1114sumv0 = vmlaq_n_f32 (sumv0 ,vcvtq_f32_s32 (vaddq_s32 ( 1115ggml_vdotq_s32 (vdupq_n_s32 (0 ),v0_0lf ,v1_0l ), 1116ggml_vdotq_s32 (vdupq_n_s32 (0 ),v0_0hf ,v1_0h ))),GGML_CPU_FP16_TO_FP32 (x0 -> d )* GGML_CPU_FP16_TO_FP32 (y0 -> d )); 1117sumv1 = vmlaq_n_f32 (sumv1 ,vcvtq_f32_s32 (vaddq_s32 ( 1118ggml_vdotq_s32 (vdupq_n_s32 (0 ),v0_1lf ,v1_1l ), 1119ggml_vdotq_s32 (vdupq_n_s32 (0 ),v0_1hf ,v1_1h ))),GGML_CPU_FP16_TO_FP32 (x1 -> d )* GGML_CPU_FP16_TO_FP32 (y1 -> d )); 1120 } 1121 1122sumf = vaddvq_f32 (sumv0 )+ vaddvq_f32 (sumv1 )+ summs0 + summs1 ; 1123 1124#endif 1125for (;ib < nb ;++ ib ) { 1126uint32_t qh ; 1127memcpy (& qh ,x [ib ].qh ,sizeof (qh )); 1128 1129int sumi0 = 0 ; 1130int sumi1 = 0 ; 1131 1132for (int j = 0 ;j < qk /2 ;++ j ) { 1133const uint8_t xh_0 = ((qh >> (j + 0 )) <<4 )& 0x10 ; 1134const uint8_t xh_1 = ((qh >> (j + 12 )) )& 0x10 ; 1135 1136const int32_t x0 = (x [ib ].qs [j ]& 0xF ) |xh_0 ; 1137const int32_t x1 = (x [ib ].qs [j ] >>4 ) |xh_1 ; 1138 1139sumi0 += (x0 * y [ib ].qs [j ]); 1140sumi1 += (x1 * y [ib ].qs [j + qk /2 ]); 1141 } 1142 1143int sumi = sumi0 + sumi1 ; 1144sumf += (GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ))* sumi + GGML_CPU_FP16_TO_FP32 (x [ib ].m )* GGML_CPU_FP16_TO_FP32 (y [ib ].s ); 1145 } 1146 1147* s = sumf ; 1148} 1149 1150void 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 ) { 1151const int qk = QK8_0 ; 1152const int nb = n /qk ; 1153 1154assert (n %qk == 0 ); 1155#if defined(__ARM_FEATURE_MATMUL_INT8 ) 1156assert ((nrc == 2 )|| (nrc == 1 )); 1157#else 1158assert (nrc == 1 ); 1159#endif 1160UNUSED (nrc ); 1161UNUSED (bx ); 1162UNUSED (by ); 1163UNUSED (bs ); 1164 1165const block_q8_0 * GGML_RESTRICT x = vx ; 1166const block_q8_0 * GGML_RESTRICT y = vy ; 1167 1168#if defined(__ARM_FEATURE_MATMUL_INT8 ) 1169if (nrc == 2 ) { 1170const block_q8_0 * GGML_RESTRICT vx0 = vx ; 1171const block_q8_0 * GGML_RESTRICT vx1 = (const block_q8_0 * ) ((const uint8_t * )vx + bx ); 1172const block_q8_0 * GGML_RESTRICT vy0 = vy ; 1173const block_q8_0 * GGML_RESTRICT vy1 = (const block_q8_0 * ) ((const uint8_t * )vy + by ); 1174 1175float32x4_t sumv0 = vdupq_n_f32 (0.0f ); 1176 1177for (int i = 0 ;i < nb ;i ++ ) { 1178const block_q8_0 * GGML_RESTRICT b_x0 = & vx0 [i ]; 1179const block_q8_0 * GGML_RESTRICT b_y0 = & vy0 [i ]; 1180 1181const block_q8_0 * GGML_RESTRICT b_x1 = & vx1 [i ]; 1182const block_q8_0 * GGML_RESTRICT b_y1 = & vy1 [i ]; 1183 1184const int8x16_t x0_l = vld1q_s8 (b_x0 -> qs ); 1185const int8x16_t x0_h = vld1q_s8 (b_x0 -> qs + 16 ); 1186const int8x16_t x1_l = vld1q_s8 (b_x1 -> qs ); 1187const int8x16_t x1_h = vld1q_s8 (b_x1 -> qs + 16 ); 1188 1189// load y 1190const int8x16_t y0_l = vld1q_s8 (b_y0 -> qs ); 1191const int8x16_t y0_h = vld1q_s8 (b_y0 -> qs + 16 ); 1192const int8x16_t y1_l = vld1q_s8 (b_y1 -> qs ); 1193const int8x16_t y1_h = vld1q_s8 (b_y1 -> qs + 16 ); 1194 1195float32_t _scale [4 ]= { 1196GGML_CPU_FP16_TO_FP32 (b_x0 -> d )* GGML_CPU_FP16_TO_FP32 (b_y0 -> d ), 1197GGML_CPU_FP16_TO_FP32 (b_x0 -> d )* GGML_CPU_FP16_TO_FP32 (b_y1 -> d ), 1198GGML_CPU_FP16_TO_FP32 (b_x1 -> d )* GGML_CPU_FP16_TO_FP32 (b_y0 -> d ), 1199GGML_CPU_FP16_TO_FP32 (b_x1 -> d )* GGML_CPU_FP16_TO_FP32 (b_y1 -> d ) 1200 }; 1201float32x4_t scale = vld1q_f32 (_scale ); 1202 1203int8x16_t l0 = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (x0_l ),vreinterpretq_s64_s8 (x1_l ))); 1204int8x16_t l1 = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (x0_l ),vreinterpretq_s64_s8 (x1_l ))); 1205 1206int8x16_t l2 = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (x0_h ),vreinterpretq_s64_s8 (x1_h ))); 1207int8x16_t l3 = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (x0_h ),vreinterpretq_s64_s8 (x1_h ))); 1208 1209int8x16_t r0 = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (y0_l ),vreinterpretq_s64_s8 (y1_l ))); 1210int8x16_t r1 = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (y0_l ),vreinterpretq_s64_s8 (y1_l ))); 1211 1212int8x16_t r2 = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (y0_h ),vreinterpretq_s64_s8 (y1_h ))); 1213int8x16_t r3 = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (y0_h ),vreinterpretq_s64_s8 (y1_h ))); 1214 1215sumv0 = vmlaq_f32 (sumv0 ,(vcvtq_f32_s32 (vmmlaq_s32 ((vmmlaq_s32 ((vmmlaq_s32 ((vmmlaq_s32 (vdupq_n_s32 (0 ),l0 ,r0 )), 1216l1 ,r1 )),l2 ,r2 )),l3 ,r3 ))),scale ); 1217 } 1218 1219float32x4_t sumv1 = vextq_f32 (sumv0 ,sumv0 ,2 ); 1220float32x4_t sumv2 = vzip1q_f32 (sumv0 ,sumv1 ); 1221 1222vst1_f32 (s ,vget_low_f32 (sumv2 )); 1223vst1_f32 (s + bs ,vget_high_f32 (sumv2 )); 1224 1225return ; 1226 } 1227#endif 1228 1229int ib = 0 ; 1230float sumf = 0 ; 1231 1232#if defined(__ARM_FEATURE_SVE ) 1233svfloat32_t sumv0 = svdup_n_f32 (0.0f ); 1234svfloat32_t sumv1 = svdup_n_f32 (0.0f ); 1235 1236const int vector_length = ggml_cpu_get_sve_cnt ()* 8 ; 1237 1238//VLA Implementation for SVE 1239switch (vector_length ) { 1240case 128 : 1241 { 1242// predicate for activating lanes for 16 Int8 elements 1243const svbool_t ph16 = svptrue_pat_b8 (SV_VL16 ); 1244const svbool_t pl16 = svptrue_pat_b32 (SV_VL4 ); 1245 1246for (;ib + 1 < nb ;ib += 2 ) { 1247const block_q8_0 * GGML_RESTRICT x0 = & x [ib + 0 ]; 1248const block_q8_0 * GGML_RESTRICT x1 = & x [ib + 1 ]; 1249const block_q8_0 * GGML_RESTRICT y0 = & y [ib + 0 ]; 1250const block_q8_0 * GGML_RESTRICT y1 = & y [ib + 1 ]; 1251 1252// load x 1253const svint8_t qx0_0 = svld1_s8 (ph16 ,x0 -> qs ); 1254const svint8_t qx0_1 = svld1_s8 (ph16 ,x0 -> qs + 16 ); 1255const svint8_t qx1_0 = svld1_s8 (ph16 ,x1 -> qs ); 1256const svint8_t qx1_1 = svld1_s8 (ph16 ,x1 -> qs + 16 ); 1257 1258// load y 1259const svint8_t qy0_0 = svld1_s8 (ph16 ,y0 -> qs ); 1260const svint8_t qy0_1 = svld1_s8 (ph16 ,y0 -> qs + 16 ); 1261const svint8_t qy1_0 = svld1_s8 (ph16 ,y1 -> qs ); 1262const svint8_t qy1_1 = svld1_s8 (ph16 ,y1 -> qs + 16 ); 1263 1264sumv0 = svmla_n_f32_x (pl16 ,sumv0 ,svcvt_f32_s32_x (pl16 ,svadd_x (pl16 , 1265svdot_s32 (svdup_n_s32 (0 ),qx0_0 ,qy0_0 ), 1266svdot_s32 (svdup_n_s32 (0 ),qx0_1 ,qy0_1 ))),GGML_CPU_FP16_TO_FP32 (x0 -> d )* GGML_CPU_FP16_TO_FP32 (y0 -> d )); 1267sumv1 = svmla_n_f32_x (pl16 ,sumv1 ,svcvt_f32_s32_x (pl16 ,svadd_x (pl16 , 1268svdot_s32 (svdup_n_s32 (0 ),qx1_0 ,qy1_0 ), 1269svdot_s32 (svdup_n_s32 (0 ),qx1_1 ,qy1_1 ))),GGML_CPU_FP16_TO_FP32 (x1 -> d )* GGML_CPU_FP16_TO_FP32 (y1 -> d )); 1270 } 1271 1272sumf = svaddv_f32 (pl16 ,svadd_f32_x (pl16 ,sumv0 ,sumv1 )); 1273 }break ; 1274case 256 : 1275 { 1276//printf("sve256"); 1277for (;ib + 1 < nb ;ib += 2 ) { 1278const block_q8_0 * GGML_RESTRICT x0 = & x [ib + 0 ]; 1279const block_q8_0 * GGML_RESTRICT x1 = & x [ib + 1 ]; 1280const block_q8_0 * GGML_RESTRICT y0 = & y [ib + 0 ]; 1281const block_q8_0 * GGML_RESTRICT y1 = & y [ib + 1 ]; 1282 1283// load x 1284const svint8_t qx0 = svld1_s8 (svptrue_b8 (),x0 -> qs ); 1285const svint8_t qx1 = svld1_s8 (svptrue_b8 (),x1 -> qs ); 1286 1287// load y 1288const svint8_t qy0 = svld1_s8 (svptrue_b8 (),y0 -> qs ); 1289const svint8_t qy1 = svld1_s8 (svptrue_b8 (),y1 -> qs ); 1290 1291sumv0 = svmla_n_f32_x (svptrue_b32 (),sumv0 ,svcvt_f32_s32_x (svptrue_b32 (), 1292svdot_s32 (svdup_n_s32 (0 ),qx0 ,qy0 )),GGML_CPU_FP16_TO_FP32 (x0 -> d )* GGML_CPU_FP16_TO_FP32 (y0 -> d )); 1293sumv1 = svmla_n_f32_x (svptrue_b32 (),sumv1 ,svcvt_f32_s32_x (svptrue_b32 (), 1294svdot_s32 (svdup_n_s32 (0 ),qx1 ,qy1 )),GGML_CPU_FP16_TO_FP32 (x1 -> d )* GGML_CPU_FP16_TO_FP32 (y1 -> d )); 1295 } 1296 1297sumf = svaddv_f32 (svptrue_b32 (),svadd_f32_x (svptrue_b32 (),sumv0 ,sumv1 )); 1298 }break ; 1299case 512 : 1300 { 1301// predicate for activating high 256 bit 1302const svbool_t ph32 = svptrue_pat_b8 (SV_VL32 ); 1303// predicate for activating low 256 bit 1304const svbool_t pl32 = svnot_b_z (svptrue_b8 (),ph32 ); 1305 1306// predicate for activating high lanes for 8 float32 elements 1307const svbool_t ph8 = svptrue_pat_b32 (SV_VL8 ); 1308// predicate for activating low lanes for 8 float32 elements 1309const svbool_t pl8 = svnot_b_z (svptrue_b32 (),ph8 ); 1310 1311svfloat32_t sumv00 = svdup_n_f32 (0.0f ); 1312 1313for (;ib + 1 < nb ;ib += 2 ) { 1314const block_q8_0 * GGML_RESTRICT x0 = & x [ib + 0 ]; 1315const block_q8_0 * GGML_RESTRICT x1 = & x [ib + 1 ]; 1316const block_q8_0 * GGML_RESTRICT y0 = & y [ib + 0 ]; 1317const block_q8_0 * GGML_RESTRICT y1 = & y [ib + 1 ]; 1318 1319//load 32 int8_t in first half of vector and put another 32 int8_t in second vector lower bits 1320// and add them to make one 64 element vector 1321// load x 1322const svint8_t qx_32 = svld1_s8 (ph32 ,x0 -> qs ); 1323svint8_t qx_64 = svld1_s8 (pl32 ,x0 -> qs + 2 ); 1324 1325qx_64 = svadd_s8_x (svptrue_b8 (),qx_32 ,qx_64 ); 1326 1327// load y 1328const svint8_t qy_32 = svld1_s8 (ph32 ,y0 -> qs ); 1329svint8_t qy_64 = svld1_s8 (pl32 ,y0 -> qs + 2 ); 1330 1331qy_64 = svadd_s8_x (svptrue_b8 (),qy_32 ,qy_64 ); 1332 1333// scale creation 1334const float32_t deq1 = GGML_CPU_FP16_TO_FP32 (x0 -> d )* GGML_CPU_FP16_TO_FP32 (y0 -> d ); 1335const float32_t deq2 = GGML_CPU_FP16_TO_FP32 (x1 -> d )* GGML_CPU_FP16_TO_FP32 (y1 -> d ); 1336 1337// duplicate deq1 in first half of vector and deq2 in second half of vector 1338const svfloat32_t temp = svdup_f32_m (svdup_f32_z (ph8 ,deq1 ),pl8 ,deq2 ); 1339 1340const svfloat32_t sumvt = svcvt_f32_s32_x (svptrue_b32 (),svdot_s32 (svdup_n_s32 (0 ),qx_64 ,qy_64 )); 1341 1342sumv00 = svmla_f32_m (svptrue_b32 (),sumv00 ,sumvt ,temp ); 1343 } 1344 1345sumf = svaddv_f32 (svptrue_b32 (),sumv00 ); 1346break ; 1347 } 1348default : 1349assert (false&& "Unsupported vector length" ); 1350break ; 1351 } 1352#elif defined(__ARM_NEON ) 1353float32x4_t sumv0 = vdupq_n_f32 (0.0f ); 1354float32x4_t sumv1 = vdupq_n_f32 (0.0f ); 1355 1356for (;ib + 1 < nb ;ib += 2 ) { 1357const block_q8_0 * GGML_RESTRICT x0 = & x [ib + 0 ]; 1358const block_q8_0 * GGML_RESTRICT x1 = & x [ib + 1 ]; 1359const block_q8_0 * GGML_RESTRICT y0 = & y [ib + 0 ]; 1360const block_q8_0 * GGML_RESTRICT y1 = & y [ib + 1 ]; 1361 1362const int8x16_t x0_0 = vld1q_s8 (x0 -> qs ); 1363const int8x16_t x0_1 = vld1q_s8 (x0 -> qs + 16 ); 1364const int8x16_t x1_0 = vld1q_s8 (x1 -> qs ); 1365const int8x16_t x1_1 = vld1q_s8 (x1 -> qs + 16 ); 1366 1367// load y 1368const int8x16_t y0_0 = vld1q_s8 (y0 -> qs ); 1369const int8x16_t y0_1 = vld1q_s8 (y0 -> qs + 16 ); 1370const int8x16_t y1_0 = vld1q_s8 (y1 -> qs ); 1371const int8x16_t y1_1 = vld1q_s8 (y1 -> qs + 16 ); 1372 1373sumv0 = vmlaq_n_f32 (sumv0 ,vcvtq_f32_s32 (vaddq_s32 ( 1374ggml_vdotq_s32 (vdupq_n_s32 (0 ),x0_0 ,y0_0 ), 1375ggml_vdotq_s32 (vdupq_n_s32 (0 ),x0_1 ,y0_1 ))),GGML_CPU_FP16_TO_FP32 (x0 -> d )* GGML_CPU_FP16_TO_FP32 (y0 -> d )); 1376 1377sumv1 = vmlaq_n_f32 (sumv1 ,vcvtq_f32_s32 (vaddq_s32 ( 1378ggml_vdotq_s32 (vdupq_n_s32 (0 ),x1_0 ,y1_0 ), 1379ggml_vdotq_s32 (vdupq_n_s32 (0 ),x1_1 ,y1_1 ))),GGML_CPU_FP16_TO_FP32 (x1 -> d )* GGML_CPU_FP16_TO_FP32 (y1 -> d )); 1380 } 1381 1382sumf = vaddvq_f32 (sumv0 )+ vaddvq_f32 (sumv1 ); 1383#endif 1384for (;ib < nb ;++ ib ) { 1385int sumi = 0 ; 1386 1387for (int j = 0 ;j < qk ;j ++ ) { 1388sumi += x [ib ].qs [j ]* y [ib ].qs [j ]; 1389 } 1390 1391sumf += sumi * (GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d )); 1392 } 1393 1394* s = sumf ; 1395} 1396 1397void 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 ) { 1398assert (nrc == 1 ); 1399UNUSED (nrc ); 1400UNUSED (bx ); 1401UNUSED (by ); 1402UNUSED (bs ); 1403 1404const block_tq1_0 * GGML_RESTRICT x = vx ; 1405const block_q8_K * GGML_RESTRICT y = vy ; 1406 1407const int nb = n /QK_K ; 1408 1409#if defined(__ARM_NEON ) 1410float sumf = 0.0f ; 1411 1412uint8_t k_shift [16 ]= {1 ,1 ,1 ,1 ,3 ,3 ,3 ,3 ,9 ,9 ,9 ,9 ,27 ,27 ,27 ,27 }; 1413 1414const uint8x16_t shift = vld1q_u8 (k_shift ); 1415 1416for (int i = 0 ;i < nb ;++ i ) { 1417#if defined(__ARM_FEATURE_DOTPROD ) 1418int32x4_t sumi0 = vdupq_n_s32 (0 ); 1419int32x4_t sumi1 = vdupq_n_s32 (0 ); 1420#else 1421int16x8_t sumi0 = vdupq_n_s16 (0 ); 1422int16x8_t sumi1 = vdupq_n_s16 (0 ); 1423#endif 1424 1425// first 32 bytes of 5 elements 1426 { 1427uint8x16_t qx0 = vld1q_u8 (x [i ].qs + 0 ); 1428uint8x16_t qx1 = vld1q_u8 (x [i ].qs + 16 ); 1429uint8x16_t qx2 = vmulq_u8 (qx0 ,vdupq_n_u8 (3 )); 1430uint8x16_t qx3 = vmulq_u8 (qx1 ,vdupq_n_u8 (3 )); 1431uint8x16_t qx4 = vmulq_u8 (qx0 ,vdupq_n_u8 (9 )); 1432uint8x16_t qx5 = vmulq_u8 (qx1 ,vdupq_n_u8 (9 )); 1433uint8x16_t qx6 = vmulq_u8 (qx0 ,vdupq_n_u8 (27 )); 1434uint8x16_t qx7 = vmulq_u8 (qx1 ,vdupq_n_u8 (27 )); 1435uint8x16_t qx8 = vmulq_u8 (qx0 ,vdupq_n_u8 (81 )); 1436uint8x16_t qx9 = vmulq_u8 (qx1 ,vdupq_n_u8 (81 )); 1437 1438// multiply by 3 and keep the 2 bits above 8 bits 1439int8x16_t sqx0 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx0 ,vshrq_n_u8 (qx0 ,1 )),6 )); 1440int8x16_t sqx1 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx1 ,vshrq_n_u8 (qx1 ,1 )),6 )); 1441int8x16_t sqx2 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx2 ,vshrq_n_u8 (qx2 ,1 )),6 )); 1442int8x16_t sqx3 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx3 ,vshrq_n_u8 (qx3 ,1 )),6 )); 1443int8x16_t sqx4 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx4 ,vshrq_n_u8 (qx4 ,1 )),6 )); 1444int8x16_t sqx5 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx5 ,vshrq_n_u8 (qx5 ,1 )),6 )); 1445int8x16_t sqx6 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx6 ,vshrq_n_u8 (qx6 ,1 )),6 )); 1446int8x16_t sqx7 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx7 ,vshrq_n_u8 (qx7 ,1 )),6 )); 1447int8x16_t sqx8 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx8 ,vshrq_n_u8 (qx8 ,1 )),6 )); 1448int8x16_t sqx9 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx9 ,vshrq_n_u8 (qx9 ,1 )),6 )); 1449 1450const int8x16_t qy0 = vld1q_s8 (y [i ].qs + 0 ); 1451const int8x16_t qy1 = vld1q_s8 (y [i ].qs + 16 ); 1452const int8x16_t qy2 = vld1q_s8 (y [i ].qs + 32 ); 1453const int8x16_t qy3 = vld1q_s8 (y [i ].qs + 48 ); 1454const int8x16_t qy4 = vld1q_s8 (y [i ].qs + 64 ); 1455const int8x16_t qy5 = vld1q_s8 (y [i ].qs + 80 ); 1456const int8x16_t qy6 = vld1q_s8 (y [i ].qs + 96 ); 1457const int8x16_t qy7 = vld1q_s8 (y [i ].qs + 112 ); 1458const int8x16_t qy8 = vld1q_s8 (y [i ].qs + 128 ); 1459const int8x16_t qy9 = vld1q_s8 (y [i ].qs + 144 ); 1460 1461#if defined(__ARM_FEATURE_DOTPROD ) 1462sumi0 = vdotq_s32 (sumi0 ,sqx0 ,qy0 ); 1463sumi1 = vdotq_s32 (sumi1 ,sqx1 ,qy1 ); 1464sumi0 = vdotq_s32 (sumi0 ,sqx2 ,qy2 ); 1465sumi1 = vdotq_s32 (sumi1 ,sqx3 ,qy3 ); 1466sumi0 = vdotq_s32 (sumi0 ,sqx4 ,qy4 ); 1467sumi1 = vdotq_s32 (sumi1 ,sqx5 ,qy5 ); 1468sumi0 = vdotq_s32 (sumi0 ,sqx6 ,qy6 ); 1469sumi1 = vdotq_s32 (sumi1 ,sqx7 ,qy7 ); 1470sumi0 = vdotq_s32 (sumi0 ,sqx8 ,qy8 ); 1471sumi1 = vdotq_s32 (sumi1 ,sqx9 ,qy9 ); 1472#else 1473sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx0 ),vget_low_s8 (qy0 )); 1474sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx0 ),vget_high_s8 (qy0 )); 1475sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx1 ),vget_low_s8 (qy1 )); 1476sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx1 ),vget_high_s8 (qy1 )); 1477sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx2 ),vget_low_s8 (qy2 )); 1478sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx2 ),vget_high_s8 (qy2 )); 1479sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx3 ),vget_low_s8 (qy3 )); 1480sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx3 ),vget_high_s8 (qy3 )); 1481sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx4 ),vget_low_s8 (qy4 )); 1482sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx4 ),vget_high_s8 (qy4 )); 1483sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx5 ),vget_low_s8 (qy5 )); 1484sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx5 ),vget_high_s8 (qy5 )); 1485sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx6 ),vget_low_s8 (qy6 )); 1486sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx6 ),vget_high_s8 (qy6 )); 1487sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx7 ),vget_low_s8 (qy7 )); 1488sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx7 ),vget_high_s8 (qy7 )); 1489sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx8 ),vget_low_s8 (qy8 )); 1490sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx8 ),vget_high_s8 (qy8 )); 1491sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx9 ),vget_low_s8 (qy9 )); 1492sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx9 ),vget_high_s8 (qy9 )); 1493#endif 1494 } 1495 1496// last 16 bytes of 5-element, along with the 4 bytes of 4 elements 1497 { 1498uint8x16_t qx0 = vld1q_u8 (x [i ].qs + 32 ); 1499uint8x16_t qx1 = vmulq_u8 (qx0 ,vdupq_n_u8 (3 )); 1500uint8x16_t qx2 = vmulq_u8 (qx0 ,vdupq_n_u8 (9 )); 1501uint8x16_t qx3 = vmulq_u8 (qx0 ,vdupq_n_u8 (27 )); 1502uint8x16_t qx4 = vmulq_u8 (qx0 ,vdupq_n_u8 (81 )); 1503uint32_t qh ; 1504memcpy (& qh ,x [i ].qh ,sizeof (qh ));// potentially unaligned 1505uint8x16_t qx5 = vreinterpretq_u8_u32 (vdupq_n_u32 (qh )); 1506qx5 = vmulq_u8 (qx5 ,shift ); 1507 1508// multiply by 3 and keep the 2 bits above 8 bits 1509int8x16_t sqx0 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx0 ,vshrq_n_u8 (qx0 ,1 )),6 )); 1510int8x16_t sqx1 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx1 ,vshrq_n_u8 (qx1 ,1 )),6 )); 1511int8x16_t sqx2 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx2 ,vshrq_n_u8 (qx2 ,1 )),6 )); 1512int8x16_t sqx3 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx3 ,vshrq_n_u8 (qx3 ,1 )),6 )); 1513int8x16_t sqx4 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx4 ,vshrq_n_u8 (qx4 ,1 )),6 )); 1514int8x16_t sqx5 = vreinterpretq_s8_u8 (vshrq_n_u8 (vhaddq_u8 (qx5 ,vshrq_n_u8 (qx5 ,1 )),6 )); 1515 1516const int8x16_t qy0 = vld1q_s8 (y [i ].qs + 160 ); 1517const int8x16_t qy1 = vld1q_s8 (y [i ].qs + 176 ); 1518const int8x16_t qy2 = vld1q_s8 (y [i ].qs + 192 ); 1519const int8x16_t qy3 = vld1q_s8 (y [i ].qs + 208 ); 1520const int8x16_t qy4 = vld1q_s8 (y [i ].qs + 224 ); 1521const int8x16_t qy5 = vld1q_s8 (y [i ].qs + 240 ); 1522 1523#if defined(__ARM_FEATURE_DOTPROD ) 1524sumi0 = vdotq_s32 (sumi0 ,sqx0 ,qy0 ); 1525sumi1 = vdotq_s32 (sumi1 ,sqx1 ,qy1 ); 1526sumi0 = vdotq_s32 (sumi0 ,sqx2 ,qy2 ); 1527sumi1 = vdotq_s32 (sumi1 ,sqx3 ,qy3 ); 1528sumi0 = vdotq_s32 (sumi0 ,sqx4 ,qy4 ); 1529sumi1 = vdotq_s32 (sumi1 ,sqx5 ,qy5 ); 1530#else 1531sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx0 ),vget_low_s8 (qy0 )); 1532sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx0 ),vget_high_s8 (qy0 )); 1533sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx1 ),vget_low_s8 (qy1 )); 1534sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx1 ),vget_high_s8 (qy1 )); 1535sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx2 ),vget_low_s8 (qy2 )); 1536sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx2 ),vget_high_s8 (qy2 )); 1537sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx3 ),vget_low_s8 (qy3 )); 1538sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx3 ),vget_high_s8 (qy3 )); 1539sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx4 ),vget_low_s8 (qy4 )); 1540sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx4 ),vget_high_s8 (qy4 )); 1541sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx5 ),vget_low_s8 (qy5 )); 1542sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx5 ),vget_high_s8 (qy5 )); 1543#endif 1544 } 1545 1546const int16x8_t ysum0 = vld1q_s16 (y [i ].bsums ); 1547const int16x8_t ysum1 = vld1q_s16 (y [i ].bsums + 8 ); 1548 1549const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 1550 1551#if defined(__ARM_FEATURE_DOTPROD ) 1552sumi0 = vaddq_s32 (sumi0 ,sumi1 ); 1553sumi0 = vsubq_s32 (sumi0 ,vpaddlq_s16 (vaddq_s16 (ysum0 ,ysum1 ))); 1554 1555sumf += d * (float )vaddvq_s32 (sumi0 ); 1556#else 1557sumi0 = vaddq_s16 (sumi0 ,sumi1 ); 1558sumi0 = vsubq_s16 (sumi0 ,vaddq_s16 (ysum0 ,ysum1 )); 1559 1560sumf += d * (float )vaddlvq_s16 (sumi0 ); 1561#endif 1562 } 1563 1564* s = sumf ; 1565 1566#else 1567UNUSED (x ); 1568UNUSED (y ); 1569UNUSED (nb ); 1570ggml_vec_dot_tq1_0_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1571#endif 1572} 1573 1574void 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 ) { 1575assert (nrc == 1 ); 1576UNUSED (nrc ); 1577UNUSED (bx ); 1578UNUSED (by ); 1579UNUSED (bs ); 1580 1581const block_tq2_0 * GGML_RESTRICT x = vx ; 1582const block_q8_K * GGML_RESTRICT y = vy ; 1583 1584const int nb = n /QK_K ; 1585 1586#if defined(__ARM_NEON ) 1587float sumf = 0.0f ; 1588 1589const uint8x16_t m3 = vdupq_n_u8 (3 ); 1590 1591for (int i = 0 ;i < nb ;++ i ) { 1592#if defined(__ARM_FEATURE_DOTPROD ) 1593int32x4_t sumi0 = vdupq_n_s32 (0 ); 1594int32x4_t sumi1 = vdupq_n_s32 (0 ); 1595#else 1596int16x8_t sumi0 = vdupq_n_s16 (0 ); 1597int16x8_t sumi1 = vdupq_n_s16 (0 ); 1598#endif 1599 1600for (size_t j = 0 ;j < sizeof (x -> qs );j += 32 ) { 1601uint8x16_t qx0 = vld1q_u8 (x [i ].qs + j ); 1602uint8x16_t qx1 = vld1q_u8 (x [i ].qs + j + 16 ); 1603uint8x16_t qx2 = vshrq_n_u8 (qx0 ,2 ); 1604uint8x16_t qx3 = vshrq_n_u8 (qx1 ,2 ); 1605uint8x16_t qx4 = vshrq_n_u8 (qx0 ,4 ); 1606uint8x16_t qx5 = vshrq_n_u8 (qx1 ,4 ); 1607uint8x16_t qx6 = vshrq_n_u8 (qx0 ,6 ); 1608uint8x16_t qx7 = vshrq_n_u8 (qx1 ,6 ); 1609 1610int8x16_t sqx0 = vreinterpretq_s8_u8 (vandq_u8 (qx0 ,m3 )); 1611int8x16_t sqx1 = vreinterpretq_s8_u8 (vandq_u8 (qx1 ,m3 )); 1612int8x16_t sqx2 = vreinterpretq_s8_u8 (vandq_u8 (qx2 ,m3 )); 1613int8x16_t sqx3 = vreinterpretq_s8_u8 (vandq_u8 (qx3 ,m3 )); 1614int8x16_t sqx4 = vreinterpretq_s8_u8 (vandq_u8 (qx4 ,m3 )); 1615int8x16_t sqx5 = vreinterpretq_s8_u8 (vandq_u8 (qx5 ,m3 )); 1616int8x16_t sqx6 = vreinterpretq_s8_u8 (vandq_u8 (qx6 ,m3 )); 1617int8x16_t sqx7 = vreinterpretq_s8_u8 (vandq_u8 (qx7 ,m3 )); 1618 1619const int8x16_t qy0 = vld1q_s8 (y [i ].qs + j * 4 + 0 ); 1620const int8x16_t qy1 = vld1q_s8 (y [i ].qs + j * 4 + 16 ); 1621const int8x16_t qy2 = vld1q_s8 (y [i ].qs + j * 4 + 32 ); 1622const int8x16_t qy3 = vld1q_s8 (y [i ].qs + j * 4 + 48 ); 1623const int8x16_t qy4 = vld1q_s8 (y [i ].qs + j * 4 + 64 ); 1624const int8x16_t qy5 = vld1q_s8 (y [i ].qs + j * 4 + 80 ); 1625const int8x16_t qy6 = vld1q_s8 (y [i ].qs + j * 4 + 96 ); 1626const int8x16_t qy7 = vld1q_s8 (y [i ].qs + j * 4 + 112 ); 1627 1628#if defined(__ARM_FEATURE_DOTPROD ) 1629sumi0 = vdotq_s32 (sumi0 ,sqx0 ,qy0 ); 1630sumi1 = vdotq_s32 (sumi1 ,sqx1 ,qy1 ); 1631sumi0 = vdotq_s32 (sumi0 ,sqx2 ,qy2 ); 1632sumi1 = vdotq_s32 (sumi1 ,sqx3 ,qy3 ); 1633sumi0 = vdotq_s32 (sumi0 ,sqx4 ,qy4 ); 1634sumi1 = vdotq_s32 (sumi1 ,sqx5 ,qy5 ); 1635sumi0 = vdotq_s32 (sumi0 ,sqx6 ,qy6 ); 1636sumi1 = vdotq_s32 (sumi1 ,sqx7 ,qy7 ); 1637#else 1638sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx0 ),vget_low_s8 (qy0 )); 1639sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx0 ),vget_high_s8 (qy0 )); 1640sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx1 ),vget_low_s8 (qy1 )); 1641sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx1 ),vget_high_s8 (qy1 )); 1642sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx2 ),vget_low_s8 (qy2 )); 1643sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx2 ),vget_high_s8 (qy2 )); 1644sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx3 ),vget_low_s8 (qy3 )); 1645sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx3 ),vget_high_s8 (qy3 )); 1646sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx4 ),vget_low_s8 (qy4 )); 1647sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx4 ),vget_high_s8 (qy4 )); 1648sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx5 ),vget_low_s8 (qy5 )); 1649sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx5 ),vget_high_s8 (qy5 )); 1650sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx6 ),vget_low_s8 (qy6 )); 1651sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx6 ),vget_high_s8 (qy6 )); 1652sumi0 = vmlal_s8 (sumi0 ,vget_low_s8 (sqx7 ),vget_low_s8 (qy7 )); 1653sumi1 = vmlal_s8 (sumi1 ,vget_high_s8 (sqx7 ),vget_high_s8 (qy7 )); 1654#endif 1655 } 1656 1657const int16x8_t ysum0 = vld1q_s16 (y [i ].bsums ); 1658const int16x8_t ysum1 = vld1q_s16 (y [i ].bsums + 8 ); 1659 1660const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 1661 1662#if defined(__ARM_FEATURE_DOTPROD ) 1663sumi0 = vaddq_s32 (sumi0 ,sumi1 ); 1664sumi0 = vsubq_s32 (sumi0 ,vpaddlq_s16 (vaddq_s16 (ysum0 ,ysum1 ))); 1665 1666sumf += d * (float )vaddvq_s32 (sumi0 ); 1667#else 1668sumi0 = vaddq_s16 (sumi0 ,sumi1 ); 1669sumi0 = vsubq_s16 (sumi0 ,vaddq_s16 (ysum0 ,ysum1 )); 1670 1671sumf += d * (float )vaddlvq_s16 (sumi0 ); 1672#endif 1673 } 1674 1675* s = sumf ; 1676 1677#else 1678UNUSED (x ); 1679UNUSED (y ); 1680UNUSED (nb ); 1681ggml_vec_dot_tq2_0_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1682#endif 1683} 1684 1685void 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 ) { 1686assert (nrc == 1 ); 1687UNUSED (nrc ); 1688UNUSED (bx ); 1689UNUSED (by ); 1690UNUSED (bs ); 1691 1692const block_q2_K * GGML_RESTRICT x = vx ; 1693const block_q8_K * GGML_RESTRICT y = vy ; 1694 1695const int nb = n /QK_K ; 1696 1697#ifdef __ARM_FEATURE_SVE 1698const int vector_length = svcntb ()* 8 ; 1699const svuint8_t m3s = svdup_n_u8 (0x3 ); 1700const svuint32_t m4s = svdup_n_u32 (0xF ); 1701const svint32_t vzero_sv = svdup_n_s32 (0 ); 1702svfloat32_t acc_sum = svdup_n_f32 (0 ); 1703svbool_t pred_s32 = svptrue_pat_b32 (SV_VL4 ); 1704 1705switch (vector_length ) { 1706case 128 : 1707for (int i = 0 ;i < nb ;++ i ) { 1708const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1709svfloat32_t d_broad = svdup_n_f32 ((float32_t )d ); 1710const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 1711svfloat32_t dmin_broad = svdup_n_f32 ((float32_t )dmin ); 1712 1713const uint8_t * GGML_RESTRICT q2 = x [i ].qs ; 1714const int8_t * GGML_RESTRICT q8_sv = y [i ].qs ; 1715const uint8_t * GGML_RESTRICT sc = x [i ].scales ; 1716 1717svuint32_t mins_and_scales_sve = svld1ub_u32 (svptrue_b32 (),sc ); 1718const svint32_t mins_sv_1 = svreinterpret_s32_u32 (svlsr_n_u32_x (svptrue_b32 (),mins_and_scales_sve ,4 )); 1719 1720mins_and_scales_sve = svld1ub_u32 (svptrue_b32 (),sc + 4 ); 1721const svint32_t mins_sv_2 = svreinterpret_s32_u32 (svlsr_n_u32_x (svptrue_b32 (),mins_and_scales_sve ,4 )); 1722 1723svint32_t q8sums_sv_1 = svld1sh_s32 (svptrue_b32 (),y [i ].bsums ); 1724svint32_t q8sums_sv_2 = svld1sh_s32 (svptrue_b32 (),y [i ].bsums + 4 ); 1725 1726const svint32_t s0 = svadd_s32_x (svptrue_b32 (),svmul_s32_x (svptrue_b32 (),mins_sv_1 ,q8sums_sv_1 ),svmul_s32_x (svptrue_b32 (),mins_sv_2 ,q8sums_sv_2 )); 1727 1728mins_and_scales_sve = svld1ub_u32 (svptrue_b32 (),sc + 8 ); 1729const svint32_t mins_sv_3 = svreinterpret_s32_u32 (svlsr_n_u32_x (svptrue_b32 (),mins_and_scales_sve ,4 )); 1730 1731mins_and_scales_sve = svld1ub_u32 (svptrue_b32 (),sc + 12 ); 1732const svint32_t mins_sv_4 = svreinterpret_s32_u32 (svlsr_n_u32_x (svptrue_b32 (),mins_and_scales_sve ,4 )); 1733 1734q8sums_sv_1 = svld1sh_s32 (svptrue_b32 (),y [i ].bsums + 8 ); 1735q8sums_sv_2 = svld1sh_s32 (svptrue_b32 (),y [i ].bsums + 12 ); 1736 1737svint32_t s1 = svadd_s32_x (svptrue_b32 (),svmul_s32_x (svptrue_b32 (),mins_sv_3 ,q8sums_sv_1 ),svmul_s32_x (svptrue_b32 (),mins_sv_4 ,q8sums_sv_2 )); 1738 1739svfloat32_t temp = svcvt_f32_s32_x (svptrue_b32 (),svadd_s32_x (svptrue_b32 (),s0 ,s1 )); 1740 1741acc_sum = svmla_f32_m (svptrue_b32 (),acc_sum ,temp ,dmin_broad ); 1742 1743svint32_t sumi1 = svdup_n_s32 (0 ); 1744 1745 { 1746const svuint8_t q2bits_1 = svld1_u8 (svptrue_b8 (),q2 ); 1747svint8_t q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),q2bits_1 ,m3s )); 1748svint8_t q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1749const svint32_t scales_sv = svreinterpret_s32_u32 (svand_u32_m (svptrue_b32 (),svld1ub_u32 (svptrue_b32 (),sc ),m4s )); 1750 1751sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv ,0 )); 1752 1753const svuint8_t q2bits_3 = svld1_u8 (svptrue_b8 (),q2 + 16 ); 1754q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),q2bits_3 ,m3s )); 1755q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1756 1757sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv ,1 )); 1758 1759q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q2bits_1 ,2 ),m3s )); 1760q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1761 1762sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv ,2 )); 1763 1764q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q2bits_3 ,2 ),m3s )); 1765q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1766 1767sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv ,3 )); 1768 1769 1770const svint32_t scales_sv_1 = svreinterpret_s32_u32 (svand_u32_m (svptrue_b32 (),svld1ub_u32 (svptrue_b32 (),sc + 4 ),m4s )); 1771 1772q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q2bits_1 ,4 ),m3s )); 1773q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1774 1775sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv_1 ,0 )); 1776 1777q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q2bits_3 ,4 ),m3s )); 1778q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1779 1780sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv_1 ,1 )); 1781 1782q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q2bits_1 ,6 ),m3s )); 1783q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1784 1785sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv_1 ,2 )); 1786 1787q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q2bits_3 ,6 ),m3s )); 1788q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1789 1790sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv_1 ,3 )); 1791 1792//------------------------------- 1793 1794q2 += 32 ; 1795const svint32_t scales_sv_2 = svreinterpret_s32_u32 (svand_u32_m (svptrue_b32 (),svld1ub_u32 (svptrue_b32 (),sc + 8 ),m4s )); 1796const svuint8_t q2bits_2 = svld1_u8 (svptrue_b8 (),q2 ); 1797 1798q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),q2bits_2 ,m3s )); 1799q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1800 1801sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv_2 ,0 )); 1802 1803const svuint8_t q2bits_4 = svld1_u8 (svptrue_b8 (),q2 + 16 ); 1804q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),q2bits_4 ,m3s )); 1805q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1806 1807sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv_2 ,1 )); 1808 1809 1810q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q2bits_2 ,2 ),m3s )); 1811q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1812 1813sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv_2 ,2 )); 1814 1815q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q2bits_4 ,2 ),m3s )); 1816q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1817 1818sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv_2 ,3 )); 1819 1820 1821const svint32_t scales_sv_3 = svreinterpret_s32_u32 (svand_u32_m (svptrue_b32 (),svld1ub_u32 (svptrue_b32 (),sc + 12 ),m4s )); 1822 1823q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q2bits_2 ,4 ),m3s )); 1824q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1825 1826sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv_3 ,0 )); 1827 1828q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q2bits_4 ,4 ),m3s )); 1829q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1830 1831sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv_3 ,1 )); 1832 1833 1834 1835q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q2bits_2 ,6 ),m3s )); 1836q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1837 1838sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv_3 ,2 )); 1839 1840q2bytes_sv = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q2bits_4 ,6 ),m3s )); 1841q8bytes_sv = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 1842 1843sumi1 = svmla_s32_m (svptrue_b32 (),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),svdup_lane_s32 (scales_sv_3 ,3 )); 1844 } 1845acc_sum = svmla_f32_m (svptrue_b32 (),acc_sum ,svcvt_f32_s32_x (svptrue_b32 (),sumi1 ),d_broad ); 1846 } 1847* s = svaddv_f32 (svptrue_b32 (),acc_sum ); 1848break ; 1849 1850case 256 : 1851case 512 : 1852for (int i = 0 ;i < nb ;++ i ) { 1853const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1854svfloat32_t d_broad = svdup_n_f32 ((float32_t )d ); 1855const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 1856svfloat32_t dmin_broad = svdup_n_f32 ((float32_t )dmin ); 1857 1858const uint8_t * GGML_RESTRICT q2 = x [i ].qs ; 1859const int8_t * GGML_RESTRICT q8_sv = y [i ].qs ; 1860const uint8_t * GGML_RESTRICT sc = x [i ].scales ; 1861 1862const svuint32_t mins_and_scales_sve = svld1ub_u32 (svptrue_pat_b32 (SV_VL8 ),sc );sc += 8 ; 1863const svint32_t scales_sv = svreinterpret_s32_u32 (svand_u32_m (svptrue_pat_b32 (SV_VL8 ),mins_and_scales_sve ,m4s )); 1864const svint32_t mins_sv_1 = svreinterpret_s32_u32 (svlsr_n_u32_x (svptrue_pat_b32 (SV_VL8 ),mins_and_scales_sve ,4 )); 1865svint32_t q8sums_sv_1 = svld1sh_s32 (svptrue_pat_b32 (SV_VL8 ),y [i ].bsums ); 1866 1867const svuint32_t mins_and_scales_sve_1 = svld1ub_u32 (svptrue_pat_b32 (SV_VL8 ),sc ); 1868const svint32_t scales_sv_1 = svreinterpret_s32_u32 (svand_u32_m (svptrue_pat_b32 (SV_VL8 ),mins_and_scales_sve_1 ,m4s )); 1869const svint32_t mins_sv_2 = svreinterpret_s32_u32 (svlsr_n_u32_x (svptrue_pat_b32 (SV_VL8 ),mins_and_scales_sve_1 ,4 )); 1870 1871svint32_t q8sums_sv_2 = svld1sh_s32 (svptrue_pat_b32 (SV_VL8 ),y [i ].bsums + 8 ); 1872 1873svfloat32_t temp = svcvt_f32_s32_x (svptrue_pat_b32 (SV_VL8 ),svadd_s32_x (svptrue_pat_b32 (SV_VL8 ),svmul_s32_x (svptrue_pat_b32 (SV_VL8 ),mins_sv_1 ,q8sums_sv_1 ),svmul_s32_x (svptrue_pat_b32 (SV_VL8 ),mins_sv_2 ,q8sums_sv_2 ))); 1874 1875acc_sum = svmla_f32_m (svptrue_pat_b32 (SV_VL8 ),acc_sum ,temp ,dmin_broad ); 1876 1877svint32_t sumi1 = svdup_n_s32 (0 ); 1878 1879 { 1880const svuint8_t q2bits_1 = svld1_u8 (svptrue_pat_b8 (SV_VL32 ),q2 ); 1881svint8_t q2bytes_sv = svreinterpret_s8_u8 (svand_u8_m (svptrue_pat_b8 (SV_VL32 ),q2bits_1 ,m3s )); 1882svint8_t q8bytes_sv = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8_sv );q8_sv += 32 ; 1883 1884svint32_t scale_1 = svsel (pred_s32 ,svdup_lane_s32 (scales_sv ,0 ),svdup_lane_s32 (scales_sv ,1 )); 1885sumi1 = svmla_s32_m (svptrue_pat_b32 (SV_VL8 ),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),scale_1 ); 1886 1887q2bytes_sv = svreinterpret_s8_u8 (svand_u8_m (svptrue_pat_b8 (SV_VL32 ),svlsr_n_u8_x (svptrue_pat_b8 (SV_VL32 ),q2bits_1 ,2 ),m3s )); 1888q8bytes_sv = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8_sv );q8_sv += 32 ; 1889 1890svint32_t scale_2 = svsel (pred_s32 ,svdup_lane_s32 (scales_sv ,2 ),svdup_lane_s32 (scales_sv ,3 )); 1891sumi1 = svmla_s32_m (svptrue_pat_b32 (SV_VL8 ),sumi1 ,svdot_s32 (svdup_n_s32 (0 ),q2bytes_sv ,q8bytes_sv ),scale_2 ); 1892 1893q2bytes_sv = svreinterpret_s8_u8 (svand_u8_m (svptrue_pat_b8 (SV_VL32 ),svlsr_n_u8_x (svptrue_pat_b8 (SV_VL32 ),q2bits_1 ,4 ),m3s )); 1894q8bytes_sv = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8_sv );q8_sv += 32 ; 1895 1896scale_1 = svsel (pred_s32 ,svdup_lane_s32 (scales_sv ,4 ),svdup_lane_s32 (scales_sv ,5 )); 1897sumi1 = svmla_s32_m (svptrue_pat_b32 (SV_VL8 ),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),scale_1 ); 1898 1899q2bytes_sv = svreinterpret_s8_u8 (svand_u8_m (svptrue_pat_b8 (SV_VL32 ),svlsr_n_u8_x (svptrue_pat_b8 (SV_VL32 ),q2bits_1 ,6 ),m3s )); 1900q8bytes_sv = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8_sv );q8_sv += 32 ; 1901 1902scale_2 = svsel (pred_s32 ,svdup_lane_s32 (scales_sv ,6 ),svdup_lane_s32 (scales_sv ,7 )); 1903sumi1 = svmla_s32_m (svptrue_pat_b32 (SV_VL8 ),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),scale_2 ); 1904 1905q2 += 32 ; 1906 1907const svuint8_t q2bits_2 = svld1_u8 (svptrue_pat_b8 (SV_VL32 ),q2 ); 1908q2bytes_sv = svreinterpret_s8_u8 (svand_u8_m (svptrue_pat_b8 (SV_VL32 ),q2bits_2 ,m3s )); 1909q8bytes_sv = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8_sv );q8_sv += 32 ; 1910 1911scale_1 = svsel (pred_s32 ,svdup_lane_s32 (scales_sv_1 ,0 ),svdup_lane_s32 (scales_sv_1 ,1 )); 1912sumi1 = svmla_s32_m (svptrue_pat_b32 (SV_VL8 ),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),scale_1 ); 1913 1914q2bytes_sv = svreinterpret_s8_u8 (svand_u8_m (svptrue_pat_b8 (SV_VL32 ),svlsr_n_u8_x (svptrue_pat_b8 (SV_VL32 ),q2bits_2 ,2 ),m3s )); 1915q8bytes_sv = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8_sv );q8_sv += 32 ; 1916 1917scale_2 = svsel (pred_s32 ,svdup_lane_s32 (scales_sv_1 ,2 ),svdup_lane_s32 (scales_sv_1 ,3 )); 1918sumi1 = svmla_s32_m (svptrue_pat_b32 (SV_VL8 ),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),scale_2 ); 1919 1920q2bytes_sv = svreinterpret_s8_u8 (svand_u8_m (svptrue_pat_b8 (SV_VL32 ),svlsr_n_u8_x (svptrue_pat_b8 (SV_VL32 ),q2bits_2 ,4 ),m3s )); 1921q8bytes_sv = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8_sv );q8_sv += 32 ; 1922 1923scale_1 = svsel (pred_s32 ,svdup_lane_s32 (scales_sv_1 ,4 ),svdup_lane_s32 (scales_sv_1 ,5 )); 1924sumi1 = svmla_s32_m (svptrue_pat_b32 (SV_VL8 ),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),scale_1 ); 1925 1926q2bytes_sv = svreinterpret_s8_u8 (svand_u8_m (svptrue_pat_b8 (SV_VL32 ),svlsr_n_u8_x (svptrue_pat_b8 (SV_VL32 ),q2bits_2 ,6 ),m3s )); 1927q8bytes_sv = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8_sv );q8_sv += 32 ; 1928 1929scale_2 = svsel (pred_s32 ,svdup_lane_s32 (scales_sv_1 ,6 ),svdup_lane_s32 (scales_sv_1 ,7 )); 1930sumi1 = svmla_s32_m (svptrue_pat_b32 (SV_VL8 ),sumi1 ,svdot_s32 (vzero_sv ,q2bytes_sv ,q8bytes_sv ),scale_2 ); 1931 } 1932acc_sum = svmla_f32_m (svptrue_pat_b32 (SV_VL8 ),acc_sum ,svcvt_f32_s32_x (svptrue_pat_b32 (SV_VL8 ),sumi1 ),d_broad ); 1933 } 1934* s = svaddv_f32 (svptrue_pat_b32 (SV_VL8 ),acc_sum ); 1935break ; 1936 1937default : 1938assert (false&& "Unsupported vector length" ); 1939break ; 1940 } 1941 1942#elif __ARM_NEON 1943const uint8x16_t m3 = vdupq_n_u8 (0x3 ); 1944const uint8x16_t m4 = vdupq_n_u8 (0xF ); 1945 1946const int32x4_t vzero = vdupq_n_s32 (0 ); 1947 1948ggml_int8x16x2_t q2bytes ; 1949uint8_t aux [16 ]; 1950 1951float sum = 0 ; 1952 1953for (int i = 0 ;i < nb ;++ i ) { 1954const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1955const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 1956 1957const uint8_t * GGML_RESTRICT q2 = x [i ].qs ; 1958const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1959const uint8_t * GGML_RESTRICT sc = x [i ].scales ; 1960 1961const uint8x16_t mins_and_scales = vld1q_u8 (sc ); 1962const uint8x16_t scales = vandq_u8 (mins_and_scales ,m4 ); 1963vst1q_u8 (aux ,scales ); 1964 1965const uint8x16_t mins = vshrq_n_u8 (mins_and_scales ,4 ); 1966const ggml_int16x8x2_t q8sums = ggml_vld1q_s16_x2 (y [i ].bsums ); 1967const ggml_int16x8x2_t mins16 = {{vreinterpretq_s16_u16 (vmovl_u8 (vget_low_u8 (mins ))),vreinterpretq_s16_u16 (vmovl_u8 (vget_high_u8 (mins )))}}; 1968const int32x4_t s0 = vaddq_s32 (vmull_s16 (vget_low_s16 (mins16 .val [0 ]),vget_low_s16 (q8sums .val [0 ])), 1969vmull_s16 (vget_high_s16 (mins16 .val [0 ]),vget_high_s16 (q8sums .val [0 ]))); 1970const int32x4_t s1 = vaddq_s32 (vmull_s16 (vget_low_s16 (mins16 .val [1 ]),vget_low_s16 (q8sums .val [1 ])), 1971vmull_s16 (vget_high_s16 (mins16 .val [1 ]),vget_high_s16 (q8sums .val [1 ]))); 1972sum += dmin * vaddvq_s32 (vaddq_s32 (s0 ,s1 )); 1973 1974int isum = 0 ; 1975int is = 0 ; 1976 1977// We use this macro instead of a function call because for some reason 1978// the code runs 2-3% slower, even if the function is declared inline 1979#define MULTIPLY_ACCUM_WITH_SCALE (index )\ 1980 isum += vaddvq_s32(ggml_vdotq_s32(vzero, q2bytes.val[0], q8bytes.val[0])) * aux[is+(index)];\ 1981 isum += vaddvq_s32(ggml_vdotq_s32(vzero, q2bytes.val[1], q8bytes.val[1])) * aux[is+1+(index)]; 1982 1983#define SHIFT_MULTIPLY_ACCUM_WITH_SCALE (shift ,index )\ 1984 q8bytes = ggml_vld1q_s8_x2(q8); q8 += 32;\ 1985 q2bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q2bits.val[0], (shift)), m3));\ 1986 q2bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q2bits.val[1], (shift)), m3));\ 1987 MULTIPLY_ACCUM_WITH_SCALE((index)); 1988 1989for (int j = 0 ;j < QK_K /128 ;++ j ) { 1990const ggml_uint8x16x2_t q2bits = ggml_vld1q_u8_x2 (q2 );q2 += 32 ; 1991 1992ggml_int8x16x2_t q8bytes = ggml_vld1q_s8_x2 (q8 );q8 += 32 ; 1993q2bytes .val [0 ]= vreinterpretq_s8_u8 (vandq_u8 (q2bits .val [0 ],m3 )); 1994q2bytes .val [1 ]= vreinterpretq_s8_u8 (vandq_u8 (q2bits .val [1 ],m3 )); 1995 1996MULTIPLY_ACCUM_WITH_SCALE (0 ); 1997 1998SHIFT_MULTIPLY_ACCUM_WITH_SCALE (2 ,2 ); 1999SHIFT_MULTIPLY_ACCUM_WITH_SCALE (4 ,4 ); 2000SHIFT_MULTIPLY_ACCUM_WITH_SCALE (6 ,6 ); 2001 2002is += 8 ; 2003 } 2004 2005sum += d * isum ; 2006 } 2007 2008* s = sum ; 2009 2010#else 2011UNUSED (x ); 2012UNUSED (y ); 2013UNUSED (nb ); 2014ggml_vec_dot_q2_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2015#endif 2016} 2017 2018void 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 ) { 2019assert (n %QK_K == 0 ); 2020assert (nrc == 1 ); 2021UNUSED (nrc ); 2022UNUSED (bx ); 2023UNUSED (by ); 2024UNUSED (bs ); 2025 2026const uint32_t kmask1 = 0x03030303 ; 2027const uint32_t kmask2 = 0x0f0f0f0f ; 2028 2029const block_q3_K * GGML_RESTRICT x = vx ; 2030const block_q8_K * GGML_RESTRICT y = vy ; 2031 2032const int nb = n /QK_K ; 2033 2034#if defined(__ARM_FEATURE_SVE ) 2035 2036uint32_t aux [3 ]; 2037uint32_t utmp [4 ]; 2038 2039const int8_t m32 = 32 ; 2040const int vector_length = svcntb ()* 8 ; 2041const svuint8_t m3b_sv = svdup_n_u8 (0x3 ); 2042const svint32_t vzero_sv = svdup_n_s32 (0 ); 2043 2044const svuint8_t m0_sv = svdup_n_u8 (1 ); 2045const svuint8_t m1_sv = svlsl_n_u8_x (svptrue_b8 (),m0_sv ,1 ); 2046const svuint8_t m2_sv = svlsl_n_u8_x (svptrue_b8 (),m0_sv ,2 ); 2047const svuint8_t m3_sv = svlsl_n_u8_x (svptrue_b8 (),m0_sv ,3 ); 2048 2049float sum = 0 ; 2050 2051for (int i = 0 ;i < nb ;++ i ) { 2052 2053const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 2054 2055const uint8_t * GGML_RESTRICT q3_sv = x [i ].qs ; 2056const uint8_t * GGML_RESTRICT qh_sv = x [i ].hmask ; 2057const int8_t * GGML_RESTRICT q8_sv = y [i ].qs ; 2058 2059// Set up scales 2060memcpy (aux ,x [i ].scales ,12 ); 2061utmp [3 ]= ((aux [1 ] >>4 )& kmask2 ) | (((aux [2 ] >>6 )& kmask1 ) <<4 ); 2062utmp [2 ]= ((aux [0 ] >>4 )& kmask2 ) | (((aux [2 ] >>4 )& kmask1 ) <<4 ); 2063utmp [1 ]= (aux [1 ]& kmask2 ) | (((aux [2 ] >>2 )& kmask1 ) <<4 ); 2064utmp [0 ]= (aux [0 ]& kmask2 ) | (((aux [2 ] >>0 )& kmask1 ) <<4 ); 2065 2066int8_t * scale = (int8_t * )utmp ; 2067 2068for (int j = 0 ;j < 16 ;++ j )scale [j ]-= m32 ; 2069 2070switch (vector_length ) { 2071case 128 : 2072 { 2073svuint8_t qhbits_sv_1 = svld1_u8 (svptrue_b8 (),qh_sv ); 2074svuint8_t qhbits_sv_2 = svld1_u8 (svptrue_b8 (),qh_sv + 16 ); 2075svuint8_t q3h_sv ; 2076 2077svint32_t sumi1_1 = svdup_n_s32 (0 ); 2078svint8_t q3bytes_sv ; 2079 2080for (int j = 0 ;j < QK_K /128 ;++ j ) { 2081 2082const svuint8_t q3bits_sv = svld1_u8 (svptrue_b8 (),q3_sv );q3_sv += 16 ; 2083const svuint8_t q3bits_sv_1 = svld1_u8 (svptrue_b8 (),q3_sv );q3_sv += 16 ; 2084svint8_t q8bytes_1_sv_1 = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 2085svint8_t q8bytes_1_sv_2 = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 2086 2087q3h_sv = svlsl_n_u8_x (svptrue_b8 (),svbic_u8_x (svptrue_b8 (),m0_sv ,qhbits_sv_1 ),2 ); 2088q3bytes_sv = svsub_s8_x (svptrue_b8 (),svreinterpret_s8_u8 (svand_u8_m (svptrue_b8 (),q3bits_sv ,m3b_sv )),svreinterpret_s8_u8 (q3h_sv )); 2089 2090sumi1_1 = svmla_s32_m (svptrue_b32 (),sumi1_1 ,svdot_s32 (vzero_sv ,q3bytes_sv ,q8bytes_1_sv_1 ),svdup_n_s32 ((int32_t )scale [0 ])); 2091 2092q3h_sv = svlsl_n_u8_x (svptrue_b8 (),svbic_u8_x (svptrue_b8 (),m0_sv ,qhbits_sv_2 ),2 ); 2093q3bytes_sv = svsub_s8_x (svptrue_b8 (),svreinterpret_s8_u8 (svand_u8_m (svptrue_b8 (),q3bits_sv_1 ,m3b_sv )),svreinterpret_s8_u8 (q3h_sv )); 2094 2095sumi1_1 = svmla_s32_m (svptrue_b32 (),sumi1_1 ,svdot_s32 (vzero_sv ,q3bytes_sv ,q8bytes_1_sv_2 ),svdup_n_s32 ((int32_t )scale [1 ])); 2096 2097q8bytes_1_sv_1 = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 2098q8bytes_1_sv_2 = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 2099 2100q3h_sv = svlsl_n_u8_x (svptrue_b8 (),svbic_u8_x (svptrue_b8 (),m1_sv ,qhbits_sv_1 ),1 ); 2101q3bytes_sv = svsub_s8_x (svptrue_b8 (),svreinterpret_s8_u8 (svand_u8_m (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q3bits_sv ,2 ),m3b_sv )),svreinterpret_s8_u8 (q3h_sv )); 2102 2103sumi1_1 = svmla_s32_m (svptrue_b32 (),sumi1_1 ,svdot_s32 (vzero_sv ,q3bytes_sv ,q8bytes_1_sv_1 ),svdup_n_s32 ((int32_t )scale [2 ])); 2104 2105q3h_sv = svlsl_n_u8_x (svptrue_b8 (),svbic_u8_x (svptrue_b8 (),m1_sv ,qhbits_sv_2 ),1 ); 2106q3bytes_sv = svsub_s8_x (svptrue_b8 (),svreinterpret_s8_u8 (svand_u8_m (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q3bits_sv_1 ,2 ),m3b_sv )),svreinterpret_s8_u8 (q3h_sv )); 2107 2108sumi1_1 = svmla_s32_m (svptrue_b32 (),sumi1_1 ,svdot_s32 (vzero_sv ,q3bytes_sv ,q8bytes_1_sv_2 ),svdup_n_s32 ((int32_t )scale [3 ])); 2109 2110 2111scale += 4 ; 2112q8bytes_1_sv_1 = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 2113q8bytes_1_sv_2 = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 2114 2115q3h_sv = svbic_u8_x (svptrue_b8 (),m2_sv ,qhbits_sv_1 ); 2116q3bytes_sv = svsub_s8_x (svptrue_b8 (),svreinterpret_s8_u8 (svand_u8_m (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q3bits_sv ,4 ),m3b_sv )),svreinterpret_s8_u8 (q3h_sv )); 2117 2118sumi1_1 = svmla_s32_m (svptrue_b32 (),sumi1_1 ,svdot_s32 (vzero_sv ,q3bytes_sv ,q8bytes_1_sv_1 ),svdup_n_s32 ((int32_t )scale [0 ])); 2119 2120q3h_sv = svbic_u8_x (svptrue_b8 (),m2_sv ,qhbits_sv_2 ); 2121q3bytes_sv = svsub_s8_x (svptrue_b8 (),svreinterpret_s8_u8 (svand_u8_m (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q3bits_sv_1 ,4 ),m3b_sv )),svreinterpret_s8_u8 (q3h_sv )); 2122 2123sumi1_1 = svmla_s32_m (svptrue_b32 (),sumi1_1 ,svdot_s32 (vzero_sv ,q3bytes_sv ,q8bytes_1_sv_2 ),svdup_n_s32 ((int32_t )scale [1 ])); 2124 2125 2126q8bytes_1_sv_1 = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 2127q8bytes_1_sv_2 = svld1_s8 (svptrue_b8 (),q8_sv );q8_sv += 16 ; 2128 2129q3h_sv = svlsr_n_u8_x (svptrue_b8 (),svbic_u8_x (svptrue_b8 (),m3_sv ,qhbits_sv_1 ),1 ); 2130q3bytes_sv = svsub_s8_x (svptrue_b8 (),svreinterpret_s8_u8 (svand_u8_m (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q3bits_sv ,6 ),m3b_sv )),svreinterpret_s8_u8 (q3h_sv )); 2131 2132sumi1_1 = svmla_s32_m (svptrue_b32 (),sumi1_1 ,svdot_s32 (vzero_sv ,q3bytes_sv ,q8bytes_1_sv_1 ),svdup_n_s32 ((int32_t )scale [2 ])); 2133 2134q3h_sv = svlsr_n_u8_x (svptrue_b8 (),svbic_u8_x (svptrue_b8 (),m3_sv ,qhbits_sv_2 ),1 ); 2135q3bytes_sv = svsub_s8_x (svptrue_b8 (),svreinterpret_s8_u8 (svand_u8_m (svptrue_b8 (),svlsr_n_u8_x (svptrue_b8 (),q3bits_sv_1 ,6 ),m3b_sv )),svreinterpret_s8_u8 (q3h_sv )); 2136 2137sumi1_1 = svmla_s32_m (svptrue_b32 (),sumi1_1 ,svdot_s32 (vzero_sv ,q3bytes_sv ,q8bytes_1_sv_2 ),svdup_n_s32 ((int32_t )scale [3 ])); 2138 2139if (j == 0 ) { 2140qhbits_sv_1 = svlsr_n_u8_x (svptrue_b8 (),qhbits_sv_1 ,4 ); 2141qhbits_sv_2 = svlsr_n_u8_x (svptrue_b8 (),qhbits_sv_2 ,4 ); 2142 } 2143 2144scale += 4 ; 2145 } 2146 2147sum += d * (svaddv_s32 (svptrue_b32 (),sumi1_1 )); 2148 }break ; 2149case 256 : 2150case 512 : 2151 { 2152svuint8_t qhbits_sv = svld1_u8 (svptrue_pat_b8 (SV_VL32 ),qh_sv ); 2153svuint8_t q3h_sv ; 2154 2155svint32_t sumi1_1 = svdup_n_s32 (0 ); 2156svint8_t q3bytes_sv ; 2157 2158for (int j = 0 ;j < QK_K /128 ;++ j ) { 2159 2160const svuint8_t q3bits_sv = svld1_u8 (svptrue_pat_b8 (SV_VL32 ),q3_sv );q3_sv += 32 ; 2161svint8_t q8bytes_1_sv_1 = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8_sv );q8_sv += 32 ; 2162svint8_t q8bytes_1_sv_2 = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8_sv );q8_sv += 32 ; 2163 2164q3h_sv = svlsl_n_u8_x (svptrue_pat_b8 (SV_VL32 ),svbic_u8_x (svptrue_pat_b8 (SV_VL32 ),m0_sv ,qhbits_sv ),2 ); 2165q3bytes_sv = svsub_s8_x (svptrue_pat_b8 (SV_VL32 ),svreinterpret_s8_u8 (svand_u8_m (svptrue_pat_b8 (SV_VL32 ),q3bits_sv ,m3b_sv )),svreinterpret_s8_u8 (q3h_sv )); 2166 2167 2168svint32_t scale_1 = svsel_s32 (svptrue_pat_b32 (SV_VL4 ),svdup_n_s32 ((int32_t )scale [0 ]),svdup_n_s32 ((int32_t )scale [1 ])); 2169sumi1_1 = svmla_s32_m (svptrue_pat_b32 (SV_VL8 ),sumi1_1 ,svdot_s32 (vzero_sv ,q3bytes_sv ,q8bytes_1_sv_1 ),scale_1 ); 2170 2171q3h_sv = svlsl_n_u8_x (svptrue_pat_b8 (SV_VL32 ),svbic_u8_x (svptrue_pat_b8 (SV_VL32 ),m1_sv ,qhbits_sv ),1 ); 2172q3bytes_sv = svsub_s8_x (svptrue_pat_b8 (SV_VL32 ),svreinterpret_s8_u8 (svand_u8_m (svptrue_pat_b8 (SV_VL32 ),svlsr_n_u8_x (svptrue_pat_b8 (SV_VL32 ),q3bits_sv ,2 ),m3b_sv )),svreinterpret_s8_u8 (q3h_sv )); 2173 2174scale_1 = svsel_s32 (svptrue_pat_b32 (SV_VL4 ),svdup_n_s32 ((int32_t )scale [2 ]),svdup_n_s32 ((int32_t )scale [3 ])); 2175sumi1_1 = svmla_s32_m (svptrue_pat_b32 (SV_VL8 ),sumi1_1 ,svdot_s32 (vzero_sv ,q3bytes_sv ,q8bytes_1_sv_2 ),scale_1 ); 2176 2177scale += 4 ; 2178q8bytes_1_sv_1 = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8_sv );q8_sv += 32 ; 2179q8bytes_1_sv_2 = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8_sv );q8_sv += 32 ; 2180 2181q3h_sv = svbic_u8_x (svptrue_pat_b8 (SV_VL32 ),m2_sv ,qhbits_sv ); 2182q3bytes_sv = svsub_s8_x (svptrue_pat_b8 (SV_VL32 ),svreinterpret_s8_u8 (svand_u8_m (svptrue_pat_b8 (SV_VL32 ),svlsr_n_u8_x (svptrue_pat_b8 (SV_VL32 ),q3bits_sv ,4 ),m3b_sv )),svreinterpret_s8_u8 (q3h_sv )); 2183 2184scale_1 = svsel_s32 (svptrue_pat_b32 (SV_VL4 ),svdup_n_s32 ((int32_t )scale [0 ]),svdup_n_s32 ((int32_t )scale [1 ])); 2185sumi1_1 = svmla_s32_m (svptrue_pat_b32 (SV_VL8 ),sumi1_1 ,svdot_s32 (vzero_sv ,q3bytes_sv ,q8bytes_1_sv_1 ),scale_1 ); 2186 2187q3h_sv = svlsr_n_u8_x (svptrue_pat_b8 (SV_VL32 ),svbic_u8_x (svptrue_pat_b8 (SV_VL32 ),m3_sv ,qhbits_sv ),1 ); 2188q3bytes_sv = svsub_s8_x (svptrue_pat_b8 (SV_VL32 ),svreinterpret_s8_u8 (svand_u8_m (svptrue_pat_b8 (SV_VL32 ),svlsr_n_u8_x (svptrue_pat_b8 (SV_VL32 ),q3bits_sv ,6 ),m3b_sv )),svreinterpret_s8_u8 (q3h_sv )); 2189 2190scale_1 = svsel_s32 (svptrue_pat_b32 (SV_VL4 ),svdup_n_s32 ((int32_t )scale [2 ]),svdup_n_s32 ((int32_t )scale [3 ])); 2191sumi1_1 = svmla_s32_m (svptrue_pat_b32 (SV_VL8 ),sumi1_1 ,svdot_s32 (vzero_sv ,q3bytes_sv ,q8bytes_1_sv_2 ),scale_1 ); 2192 2193if (j == 0 ) { 2194qhbits_sv = svlsr_n_u8_x (svptrue_pat_b8 (SV_VL32 ),qhbits_sv ,4 ); 2195 } 2196 2197scale += 4 ; 2198 } 2199 2200sum += d * (svaddv_s32 (svptrue_pat_b32 (SV_VL8 ),sumi1_1 )); 2201 }break ; 2202default : 2203assert (false&& "Unsupported vector length" ); 2204break ; 2205 } 2206 } 2207* s = sum ; 2208 2209#elif __ARM_NEON 2210 2211uint32_t aux [3 ]; 2212uint32_t utmp [4 ]; 2213 2214const uint8x16_t m3b = vdupq_n_u8 (0x3 ); 2215const int32x4_t vzero = vdupq_n_s32 (0 ); 2216 2217const uint8x16_t m0 = vdupq_n_u8 (1 ); 2218const uint8x16_t m1 = vshlq_n_u8 (m0 ,1 ); 2219const uint8x16_t m2 = vshlq_n_u8 (m0 ,2 ); 2220const uint8x16_t m3 = vshlq_n_u8 (m0 ,3 ); 2221const int8_t m32 = 32 ; 2222 2223ggml_int8x16x4_t q3bytes ; 2224 2225float sum = 0 ; 2226 2227for (int i = 0 ;i < nb ;++ i ) { 2228 2229const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 2230 2231const uint8_t * GGML_RESTRICT q3 = x [i ].qs ; 2232const uint8_t * GGML_RESTRICT qh = x [i ].hmask ; 2233const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2234 2235ggml_uint8x16x2_t qhbits = ggml_vld1q_u8_x2 (qh ); 2236 2237ggml_uint8x16x4_t q3h ; 2238 2239int32_t isum = 0 ; 2240 2241// Set up scales 2242memcpy (aux ,x [i ].scales ,12 ); 2243utmp [3 ]= ((aux [1 ] >>4 )& kmask2 ) | (((aux [2 ] >>6 )& kmask1 ) <<4 ); 2244utmp [2 ]= ((aux [0 ] >>4 )& kmask2 ) | (((aux [2 ] >>4 )& kmask1 ) <<4 ); 2245utmp [1 ]= (aux [1 ]& kmask2 ) | (((aux [2 ] >>2 )& kmask1 ) <<4 ); 2246utmp [0 ]= (aux [0 ]& kmask2 ) | (((aux [2 ] >>0 )& kmask1 ) <<4 ); 2247 2248int8_t * scale = (int8_t * )utmp ; 2249for (int j = 0 ;j < 16 ;++ j )scale [j ]-= m32 ; 2250 2251for (int j = 0 ;j < QK_K /128 ;++ j ) { 2252 2253const ggml_uint8x16x2_t q3bits = ggml_vld1q_u8_x2 (q3 );q3 += 32 ; 2254const ggml_int8x16x4_t q8bytes_1 = ggml_vld1q_s8_x4 (q8 );q8 += 64 ; 2255const ggml_int8x16x4_t q8bytes_2 = ggml_vld1q_s8_x4 (q8 );q8 += 64 ; 2256 2257q3h .val [0 ]= vshlq_n_u8 (vbicq_u8 (m0 ,qhbits .val [0 ]),2 ); 2258q3h .val [1 ]= vshlq_n_u8 (vbicq_u8 (m0 ,qhbits .val [1 ]),2 ); 2259q3h .val [2 ]= vshlq_n_u8 (vbicq_u8 (m1 ,qhbits .val [0 ]),1 ); 2260q3h .val [3 ]= vshlq_n_u8 (vbicq_u8 (m1 ,qhbits .val [1 ]),1 ); 2261 2262q3bytes .val [0 ]= vsubq_s8 (vreinterpretq_s8_u8 (vandq_u8 (q3bits .val [0 ],m3b )),vreinterpretq_s8_u8 (q3h .val [0 ])); 2263q3bytes .val [1 ]= vsubq_s8 (vreinterpretq_s8_u8 (vandq_u8 (q3bits .val [1 ],m3b )),vreinterpretq_s8_u8 (q3h .val [1 ])); 2264q3bytes .val [2 ]= vsubq_s8 (vreinterpretq_s8_u8 (vandq_u8 (vshrq_n_u8 (q3bits .val [0 ],2 ),m3b )),vreinterpretq_s8_u8 (q3h .val [2 ])); 2265q3bytes .val [3 ]= vsubq_s8 (vreinterpretq_s8_u8 (vandq_u8 (vshrq_n_u8 (q3bits .val [1 ],2 ),m3b )),vreinterpretq_s8_u8 (q3h .val [3 ])); 2266 2267isum += vaddvq_s32 (ggml_vdotq_s32 (vzero ,q3bytes .val [0 ],q8bytes_1 .val [0 ]))* scale [0 ]; 2268isum += vaddvq_s32 (ggml_vdotq_s32 (vzero ,q3bytes .val [1 ],q8bytes_1 .val [1 ]))* scale [1 ]; 2269isum += vaddvq_s32 (ggml_vdotq_s32 (vzero ,q3bytes .val [2 ],q8bytes_1 .val [2 ]))* scale [2 ]; 2270isum += vaddvq_s32 (ggml_vdotq_s32 (vzero ,q3bytes .val [3 ],q8bytes_1 .val [3 ]))* scale [3 ]; 2271 2272scale += 4 ; 2273 2274q3h .val [0 ]= vbicq_u8 (m2 ,qhbits .val [0 ]); 2275q3h .val [1 ]= vbicq_u8 (m2 ,qhbits .val [1 ]); 2276q3h .val [2 ]= vshrq_n_u8 (vbicq_u8 (m3 ,qhbits .val [0 ]),1 ); 2277q3h .val [3 ]= vshrq_n_u8 (vbicq_u8 (m3 ,qhbits .val [1 ]),1 ); 2278 2279q3bytes .val [0 ]= vsubq_s8 (vreinterpretq_s8_u8 (vandq_u8 (vshrq_n_u8 (q3bits .val [0 ],4 ),m3b )),vreinterpretq_s8_u8 (q3h .val [0 ])); 2280q3bytes .val [1 ]= vsubq_s8 (vreinterpretq_s8_u8 (vandq_u8 (vshrq_n_u8 (q3bits .val [1 ],4 ),m3b )),vreinterpretq_s8_u8 (q3h .val [1 ])); 2281q3bytes .val [2 ]= vsubq_s8 (vreinterpretq_s8_u8 (vandq_u8 (vshrq_n_u8 (q3bits .val [0 ],6 ),m3b )),vreinterpretq_s8_u8 (q3h .val [2 ])); 2282q3bytes .val [3 ]= vsubq_s8 (vreinterpretq_s8_u8 (vandq_u8 (vshrq_n_u8 (q3bits .val [1 ],6 ),m3b )),vreinterpretq_s8_u8 (q3h .val [3 ])); 2283 2284isum += vaddvq_s32 (ggml_vdotq_s32 (vzero ,q3bytes .val [0 ],q8bytes_2 .val [0 ]))* scale [0 ]; 2285isum += vaddvq_s32 (ggml_vdotq_s32 (vzero ,q3bytes .val [1 ],q8bytes_2 .val [1 ]))* scale [1 ]; 2286isum += vaddvq_s32 (ggml_vdotq_s32 (vzero ,q3bytes .val [2 ],q8bytes_2 .val [2 ]))* scale [2 ]; 2287isum += vaddvq_s32 (ggml_vdotq_s32 (vzero ,q3bytes .val [3 ],q8bytes_2 .val [3 ]))* scale [3 ]; 2288 2289scale += 4 ; 2290 2291if (j == 0 ) { 2292qhbits .val [0 ]= vshrq_n_u8 (qhbits .val [0 ],4 ); 2293qhbits .val [1 ]= vshrq_n_u8 (qhbits .val [1 ],4 ); 2294 } 2295 2296 } 2297sum += d * isum ; 2298 2299 } 2300 2301* s = sum ; 2302 2303#else 2304UNUSED (kmask1 ); 2305UNUSED (kmask2 ); 2306UNUSED (x ); 2307UNUSED (y ); 2308UNUSED (nb ); 2309ggml_vec_dot_q3_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2310#endif 2311 2312} 2313 2314#ifdef __ARM_FEATURE_SVE 2315static inline svuint32_t ggml_decode_q4scales_and_mins_for_mmla (const uint32_t * vx_scales ) { 2316const svbool_t pg_all = svptrue_pat_b32 (SV_VL4 ); 2317const svbool_t pg_false = svpfalse_b ();// 0x0000 2318const svbool_t pg_lo_8 = svwhilelt_b8_s32 (0 ,8 );// 0x00ff 2319const svbool_t pg_odd = svzip1_b32 (pg_false ,pg_lo_8 ); 2320 2321svuint32_t vutmp_hi ,vutmp_lo ; 2322svuint32_t vx01 = svld1_u32 (pg_lo_8 ,vx_scales ); 2323vutmp_hi = svzip1_u32 (vx01 ,vx01 ); 2324vutmp_hi = svlsr_n_u32_m (pg_odd ,vutmp_hi ,2 ); 2325vutmp_hi = svreinterpret_u32_u64 (svand_n_u64_x (pg_all ,svreinterpret_u64_u32 (vutmp_hi ),UINT64_C (0x303030303f3f3f3f ))); 2326const svuint32_t vx2 = svdup_u32 (vx_scales [2 ]); 2327vutmp_lo = svlsr_u32_x (pg_all ,vx2 ,svreinterpret_u32_s32 (svindex_s32 (-2 ,2 ))); 2328vutmp_lo = svand_n_u32_z (pg_odd ,vutmp_lo ,UINT32_C (0x0f0f0f0f )); 2329svuint32_t vutmp = svorr_u32_z (pg_all ,vutmp_hi ,vutmp_lo ); 2330return vutmp ; 2331} 2332#endif 2333 2334void 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 ) { 2335assert (n %QK_K == 0 ); 2336#ifdef __ARM_FEATURE_MATMUL_INT8 2337assert ((nrc == 2 )|| (nrc == 1 )); 2338#else 2339assert (nrc == 1 ); 2340#endif 2341UNUSED (nrc ); 2342UNUSED (bx ); 2343UNUSED (by ); 2344UNUSED (bs ); 2345 2346const block_q4_K * GGML_RESTRICT x = vx ; 2347const block_q8_K * GGML_RESTRICT y = vy ; 2348 2349const int nb = n /QK_K ; 2350 2351static const uint32_t kmask1 = 0x3f3f3f3f ; 2352static const uint32_t kmask2 = 0x0f0f0f0f ; 2353static const uint32_t kmask3 = 0x03030303 ; 2354 2355uint32_t utmp [4 ]; 2356#ifdef __ARM_FEATURE_SVE 2357const int vector_length = ggml_cpu_get_sve_cnt ()* 8 ; 2358#endif 2359 2360#if defined(__ARM_FEATURE_SVE )&& defined(__ARM_FEATURE_MATMUL_INT8 ) 2361if (nrc == 2 ) { 2362svbool_t pg32_2 = svptrue_pat_b32 (SV_VL2 ); 2363 2364const block_q4_K * GGML_RESTRICT vx0 = vx ; 2365const block_q8_K * GGML_RESTRICT vy0 = vy ; 2366const block_q4_K * GGML_RESTRICT vx1 = (const block_q4_K * ) ((const uint8_t * )vx + bx ); 2367const block_q8_K * GGML_RESTRICT vy1 = (const block_q8_K * ) ((const uint8_t * )vy + by ); 2368 2369union { 2370uint32_t u32 [8 ]; 2371uint64_t u64 [4 ]; 2372 }new_utmp ; 2373 2374svfloat32_t sumf1 = svdup_n_f32 (0 ); 2375 2376switch (vector_length ) { 2377case 128 : 2378 { 2379svbool_t pg_false = svpfalse_b (); 2380svbool_t pg_lo_8 = svwhilelt_b8_s32 (0 ,8 ); 2381svbool_t vmins_mask1 = svzip1_b32 (pg_lo_8 ,pg_false ); 2382svbool_t vmins_mask2 = svzip1_b32 (pg_false ,pg_lo_8 ); 2383svbool_t pg128_all = svptrue_pat_b8 (SV_VL16 ); 2384for (int i = 0 ;i < nb ;++ i ) { 2385svfloat32_t vy_d = svuzp1_f32 (svdup_n_f32 (vy0 [i ].d ),svdup_n_f32 (vy1 [i ].d )); 2386svfloat32_t vx_d = svzip1_f32 (svdup_n_f32 (GGML_FP16_TO_FP32 (vx0 [i ].d )),svdup_n_f32 (GGML_FP16_TO_FP32 (vx1 [i ].d ))); 2387svfloat32_t svsuper_block_scales = svmul_f32_x (pg128_all ,vy_d ,vx_d ); 2388svfloat32_t vx_dmins = svzip1_f32 (svdup_n_f32 (GGML_FP16_TO_FP32 (vx0 [i ].dmin )),svdup_n_f32 (GGML_FP16_TO_FP32 (vx1 [i ].dmin ))); 2389svfloat32_t vy_dmins = svuzp1_f32 (svdup_n_f32 (vy0 [i ].d ),svdup_n_f32 (vy1 [i ].d )); 2390svfloat32_t svdmins = svmul_n_f32_x (pg128_all ,svmul_f32_x (pg128_all ,vy_dmins ,vx_dmins ),-1 ); 2391const uint8_t * GGML_RESTRICT q4_0 = vx0 [i ].qs ; 2392const int8_t * GGML_RESTRICT q8_0 = vy0 [i ].qs ; 2393const uint8_t * GGML_RESTRICT q4_1 = vx1 [i ].qs ; 2394const int8_t * GGML_RESTRICT q8_1 = vy1 [i ].qs ; 2395svint16_t lo = svld1_s16 (pg128_all ,vy0 [i ].bsums + 0 ); 2396svint16_t hi = svld1_s16 (pg128_all ,vy0 [i ].bsums + 8 ); 2397svint16_t sum_tmp1 = svuzp1_s16 (lo ,hi ); 2398svint16_t sum_tmp2 = svuzp2_s16 (lo ,hi ); 2399svint16_t svq8sums_0 = svadd_s16_x (pg128_all ,sum_tmp1 ,sum_tmp2 ); 2400lo = svld1_s16 (pg128_all ,vy1 [i ].bsums + 0 ); 2401hi = svld1_s16 (pg128_all ,vy1 [i ].bsums + 8 ); 2402sum_tmp1 = svuzp1 (lo ,hi ); 2403sum_tmp2 = svuzp2 (lo ,hi ); 2404svint16_t svq8sums_1 = svadd_s16_x (pg128_all ,sum_tmp1 ,sum_tmp2 ); 2405svuint32_t decoded_scales0 = ggml_decode_q4scales_and_mins_for_mmla ((const uint32_t * )vx0 [i ].scales ); 2406svuint32_t decoded_scales1 = ggml_decode_q4scales_and_mins_for_mmla ((const uint32_t * )vx1 [i ].scales ); 2407svuint32x2_t decoded_scales = svcreate2_u32 (decoded_scales0 ,decoded_scales1 ); 2408svst2_u32 (pg128_all ,new_utmp .u32 ,decoded_scales ); 2409svint16_t svmins8_0 = svreinterpret_s16_u16 (svunpklo_u16 (svreinterpret_u8_u32 (svuzp1_u32 (svld1_u32 (vmins_mask1 ,new_utmp .u32 + 4 ),svdup_n_u32 (0 ))))); 2410svint16_t svmins8_1 = svreinterpret_s16_u16 (svunpklo_u16 (svreinterpret_u8_u32 (svuzp2_u32 (svld1_u32 (vmins_mask2 ,new_utmp .u32 + 4 ),svdup_n_u32 (0 ))))); 2411svint32_t svsumfs_tmp1 = svreinterpret_s32_s64 (svdot_s64 (svdup_n_s64 (0 ),svq8sums_0 ,svmins8_0 )); 2412svint32_t svsumfs_tmp2 = svreinterpret_s32_s64 (svdot_s64 (svdup_n_s64 (0 ),svq8sums_0 ,svmins8_1 )); 2413svint32_t svsumfs_tmp3 = svtrn1_s32 (svsumfs_tmp1 ,svsumfs_tmp2 ); 2414svint32_t svsumfs_tmp4 = svreinterpret_s32_s64 (svdot_s64 (svdup_n_s64 (0 ),svq8sums_1 ,svmins8_0 )); 2415svint32_t svsumfs_tmp5 = svreinterpret_s32_s64 (svdot_s64 (svdup_n_s64 (0 ),svq8sums_1 ,svmins8_1 )); 2416svint32_t svsumfs_tmp6 = svtrn1_s32 (svsumfs_tmp4 ,svsumfs_tmp5 ); 2417svint32_t svsumfs_tmp7 = svreinterpret_s32_s64 (svtrn2_s64 (svreinterpret_s64_s32 (svsumfs_tmp3 ),svreinterpret_s64_s32 (svsumfs_tmp6 ))); 2418svint32_t svsumfs_tmp8 = svreinterpret_s32_s64 (svtrn1_s64 (svreinterpret_s64_s32 (svsumfs_tmp3 ),svreinterpret_s64_s32 (svsumfs_tmp6 ))); 2419svint32_t svsumfs_tmp = svadd_s32_x (pg128_all ,svsumfs_tmp7 ,svsumfs_tmp8 ); 2420svint32_t svscales ,sumi1 ,sumi2 ; 2421svint32_t acc_sumif1 = svdup_n_s32 (0 ); 2422svint32_t acc_sumif2 = svdup_n_s32 (0 ); 2423svint8_t q4bytes_0_l ,q4bytes_0_h ,q4bytes_1_l ,q4bytes_1_h ,l0 ,l1 ,l2 ,l3 , 2424q8bytes_0_h ,q8bytes_0_l ,q8bytes_1_h ,q8bytes_1_l ,r0 ,r1 ,r2 ,r3 ; 2425#pragma GCC unroll 1 2426for (int j = 0 ;j < QK_K /64 ;++ j ) { 2427q4bytes_0_l = svreinterpret_s8_u8 (svand_n_u8_x (pg128_all ,svld1_u8 (pg128_all ,q4_0 ),0xf )); 2428q4bytes_1_l = svreinterpret_s8_u8 (svand_n_u8_x (pg128_all ,svld1_u8 (pg128_all ,q4_1 ),0xf )); 2429q4bytes_0_h = svreinterpret_s8_u8 (svand_n_u8_x (pg128_all ,svld1_u8 (pg128_all ,q4_0 + 16 ),0xf )); 2430q4bytes_1_h = svreinterpret_s8_u8 (svand_n_u8_x (pg128_all ,svld1_u8 (pg128_all ,q4_1 + 16 ),0xf )); 2431l0 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q4bytes_0_l ),svreinterpret_s64_s8 (q4bytes_1_l ))); 2432l1 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q4bytes_0_l ),svreinterpret_s64_s8 (q4bytes_1_l ))); 2433l2 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q4bytes_0_h ),svreinterpret_s64_s8 (q4bytes_1_h ))); 2434l3 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q4bytes_0_h ),svreinterpret_s64_s8 (q4bytes_1_h ))); 2435q8bytes_0_h = svld1_s8 (pg128_all ,q8_0 ); 2436q8bytes_1_h = svld1_s8 (pg128_all ,q8_1 ); 2437q8bytes_0_l = svld1_s8 (pg128_all ,q8_0 + 16 ); 2438q8bytes_1_l = svld1_s8 (pg128_all ,q8_1 + 16 ); 2439r0 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q8bytes_0_h ),svreinterpret_s64_s8 (q8bytes_1_h ))); 2440r1 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q8bytes_0_h ),svreinterpret_s64_s8 (q8bytes_1_h ))); 2441r2 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q8bytes_0_l ),svreinterpret_s64_s8 (q8bytes_1_l ))); 2442r3 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q8bytes_0_l ),svreinterpret_s64_s8 (q8bytes_1_l ))); 2443sumi1 = svmmla_s32 (svmmla_s32 (svmmla_s32 (svmmla_s32 (svdup_n_s32 (0 ),r0 ,l0 ),r1 ,l1 ),r2 ,l2 ),r3 ,l3 ); 2444svscales = svreinterpret_s32_u32 (svlsr_n_u32_x (pg128_all ,svlsl_n_u32_x (pg128_all ,svreinterpret_u32_u64 (svdup_n_u64 (new_utmp .u64 [j /2 ])),8 * (4 - 2 * (j %2 )- 1 )),24 )); 2445acc_sumif1 = svmla_s32_x (pg128_all ,acc_sumif1 ,svscales ,sumi1 ); 2446 2447q4bytes_0_l = svreinterpret_s8_u8 (svlsr_n_u8_x (pg128_all ,svld1_u8 (pg128_all ,q4_0 ),4 )); 2448q4bytes_1_l = svreinterpret_s8_u8 (svlsr_n_u8_x (pg128_all ,svld1_u8 (pg128_all ,q4_1 ),4 )); 2449q4bytes_0_h = svreinterpret_s8_u8 (svlsr_n_u8_x (pg128_all ,svld1_u8 (pg128_all ,q4_0 + 16 ),4 )); 2450q4bytes_1_h = svreinterpret_s8_u8 (svlsr_n_u8_x (pg128_all ,svld1_u8 (pg128_all ,q4_1 + 16 ),4 )); 2451l0 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q4bytes_0_l ),svreinterpret_s64_s8 (q4bytes_1_l ))); 2452l1 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q4bytes_0_l ),svreinterpret_s64_s8 (q4bytes_1_l ))); 2453l2 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q4bytes_0_h ),svreinterpret_s64_s8 (q4bytes_1_h ))); 2454l3 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q4bytes_0_h ),svreinterpret_s64_s8 (q4bytes_1_h ))); 2455q8bytes_0_h = svld1_s8 (pg128_all ,q8_0 + 32 ); 2456q8bytes_1_h = svld1_s8 (pg128_all ,q8_1 + 32 ); 2457q8bytes_0_l = svld1_s8 (pg128_all ,q8_0 + 48 ); 2458q8bytes_1_l = svld1_s8 (pg128_all ,q8_1 + 48 ); 2459r0 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q8bytes_0_h ),svreinterpret_s64_s8 (q8bytes_1_h ))); 2460r1 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q8bytes_0_h ),svreinterpret_s64_s8 (q8bytes_1_h ))); 2461r2 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q8bytes_0_l ),svreinterpret_s64_s8 (q8bytes_1_l ))); 2462r3 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q8bytes_0_l ),svreinterpret_s64_s8 (q8bytes_1_l ))); 2463sumi2 = svmmla_s32 (svmmla_s32 (svmmla_s32 (svmmla_s32 (svdup_n_s32 (0 ),r0 ,l0 ),r1 ,l1 ),r2 ,l2 ),r3 ,l3 ); 2464svscales = svreinterpret_s32_u32 (svlsr_n_u32_x (pg128_all ,svlsl_n_u32_x (pg128_all ,svreinterpret_u32_u64 (svdup_n_u64 (new_utmp .u64 [j /2 ])),8 * (4 - 2 * (j %2 )- 2 )),24 )); 2465acc_sumif2 = svmla_s32_x (pg128_all ,acc_sumif2 ,svscales ,sumi2 ); 2466q4_0 += 32 ;q4_1 += 32 ;q8_0 += 64 ;q8_1 += 64 ; 2467 } 2468sumf1 = svmla_f32_x (pg128_all , 2469svmla_f32_x (pg128_all , 2470sumf1 , 2471svcvt_f32_x (pg128_all , 2472svadd_s32_x (pg128_all ,acc_sumif1 ,acc_sumif2 )), 2473svsuper_block_scales ), 2474svdmins , 2475svcvt_f32_s32_x (pg128_all ,svsumfs_tmp )); 2476 }//end of for nb 2477 }// end of case 128 2478break ; 2479case 256 : 2480case 512 : 2481 { 2482const svbool_t pg32_4 = svptrue_pat_b32 (SV_VL4 ); 2483const svbool_t pg8_16 = svptrue_pat_b8 (SV_VL16 ); 2484const svbool_t pg256_all = svptrue_pat_b8 (SV_ALL ); 2485for (int i = 0 ;i < nb ;++ i ) { 2486const uint8_t * GGML_RESTRICT q4_0 = vx0 [i ].qs ; 2487const int8_t * GGML_RESTRICT q8_0 = vy0 [i ].qs ; 2488const uint8_t * GGML_RESTRICT q4_1 = vx1 [i ].qs ; 2489const int8_t * GGML_RESTRICT q8_1 = vy1 [i ].qs ; 2490svint32_t svscales ,sumi1 ,sumi2 ; 2491svint32_t acc_sumif1 = svdup_n_s32 (0 ); 2492svint32_t acc_sumif2 = svdup_n_s32 (0 ); 2493svint8_t l0 ,l1 ,l2 ,l3 ,r0 ,r1 ,r2 ,r3 ; 2494svfloat32_t vx_d = svzip1_f32 (svdup_n_f32 (GGML_FP16_TO_FP32 (vx0 [i ].d )),svdup_n_f32 (GGML_FP16_TO_FP32 (vx1 [i ].d ))); 2495svfloat64_t vy_d_tmp = svreinterpret_f64_f32 (svuzp1_f32 (svdup_n_f32 (vy0 [i ].d ),svdup_n_f32 (vy1 [i ].d ))); 2496svfloat32_t vy_d = svreinterpret_f32_f64 (svuzp1_f64 (vy_d_tmp ,vy_d_tmp )); 2497svfloat32_t svsuper_block_scales = svmul_f32_z (pg32_4 ,vy_d ,vx_d ); 2498svfloat32_t vx_dmins = svzip1_f32 (svdup_n_f32 (GGML_FP16_TO_FP32 (vx0 [i ].dmin )),svdup_n_f32 (GGML_FP16_TO_FP32 (vx1 [i ].dmin ))); 2499svfloat64_t vy_dmins_tmp = svreinterpret_f64_f32 (svuzp1_f32 (svdup_n_f32 (vy0 [i ].d ),svdup_n_f32 (vy1 [i ].d ))); 2500svfloat32_t vy_dmins = svreinterpret_f32_f64 (svuzp1_f64 (vy_dmins_tmp ,vy_dmins_tmp )); 2501svfloat32_t svdmins = svmul_n_f32_x (pg32_4 ,svmul_f32_x (pg32_4 ,vx_dmins ,vy_dmins ),-1 ); 2502svint16_t rc1 = svuzp1_s16 (svld1_s16 (pg256_all ,vy0 [i ].bsums ),svld1_s16 (pg256_all ,vy1 [i ].bsums )); 2503svint16_t rc2 = svuzp2_s16 (svld1_s16 (pg256_all ,vy0 [i ].bsums ),svld1_s16 (pg256_all ,vy1 [i ].bsums )); 2504svint16_t svq8sums = svadd_s16_x (pg256_all ,rc1 ,rc2 ); 2505svuint32_t decoded_scales0 = ggml_decode_q4scales_and_mins_for_mmla ((const uint32_t * )vx0 [i ].scales ); 2506svuint32_t decoded_scales1 = ggml_decode_q4scales_and_mins_for_mmla ((const uint32_t * )vx1 [i ].scales ); 2507svuint32x2_t decoded_scales = svcreate2_u32 (decoded_scales0 ,decoded_scales1 ); 2508svst2_u32 (pg8_16 ,new_utmp .u32 ,decoded_scales ); 2509svint16_t new_svq8sums_0 = svreinterpret_s16_u64 (svtrn1_u64 (svreinterpret_u64_s16 (svq8sums ),svreinterpret_u64_s16 (svq8sums ))); 2510svint16_t new_svq8sums_1 = svreinterpret_s16_u64 (svtrn2_u64 (svreinterpret_u64_s16 (svq8sums ),svreinterpret_u64_s16 (svq8sums ))); 2511svuint64_t new_mins_0 = svdup_u64 (new_utmp .u64 [2 ]); 2512svuint64_t new_mins_1 = svdup_u64 (new_utmp .u64 [3 ]); 2513svint16_t new_svmins8_0 = svreinterpret_s16_u16 (svunpklo_u16 (svreinterpret_u8_u64 (new_mins_0 ))); 2514svint16_t new_svmins8_1 = svreinterpret_s16_u16 (svunpklo_u16 (svreinterpret_u8_u64 (new_mins_1 ))); 2515svint64_t dot_prod_0 = svdot_s64 (svdup_s64 (0 ),new_svmins8_0 ,new_svq8sums_0 ); 2516svint64_t dot_prod_1 = svdot_s64 (dot_prod_0 ,new_svmins8_1 ,new_svq8sums_1 ); 2517svfloat32_t converted_dot_prod_1 = svcvt_f32_s64_x (pg256_all ,dot_prod_1 ); 2518svfloat32_t svsumfs_tmp = svuzp1_f32 (converted_dot_prod_1 ,converted_dot_prod_1 ); 2519 2520#pragma GCC unroll 1 2521for (int j = 0 ;j < QK_K /64 ;++ j ) { 2522svuint8_t q4bytes_0 = svand_n_u8_x (pg256_all ,svld1_u8 (pg256_all ,q4_0 ),0xf ); 2523svuint8_t q4bytes_1 = svand_n_u8_x (pg256_all ,svld1_u8 (pg256_all ,q4_1 ),0xf ); 2524svuint8_t q4bytes_2 = svlsr_n_u8_x (pg256_all ,svld1_u8 (pg256_all ,q4_0 ),4 ); 2525svuint8_t q4bytes_3 = svlsr_n_u8_x (pg256_all ,svld1_u8 (pg256_all ,q4_1 ),4 ); 2526l0 = svreinterpret_s8_u64 (svzip1_u64 (svreinterpret_u64_u8 (q4bytes_0 ),svreinterpret_u64_u8 (q4bytes_1 ))); 2527l1 = svreinterpret_s8_u64 (svzip2_u64 (svreinterpret_u64_u8 (q4bytes_0 ),svreinterpret_u64_u8 (q4bytes_1 ))); 2528l2 = svreinterpret_s8_u64 (svzip1_u64 (svreinterpret_u64_u8 (q4bytes_2 ),svreinterpret_u64_u8 (q4bytes_3 ))); 2529l3 = svreinterpret_s8_u64 (svzip2_u64 (svreinterpret_u64_u8 (q4bytes_2 ),svreinterpret_u64_u8 (q4bytes_3 ))); 2530svint8_t q8bytes_0 = svld1_s8 (pg256_all ,q8_0 ); 2531svint8_t q8bytes_1 = svld1_s8 (pg256_all ,q8_1 ); 2532svint8_t q8bytes_2 = svld1_s8 (pg256_all ,q8_0 + 32 ); 2533svint8_t q8bytes_3 = svld1_s8 (pg256_all ,q8_1 + 32 ); 2534r0 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q8bytes_0 ),svreinterpret_s64_s8 (q8bytes_1 ))); 2535r1 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q8bytes_0 ),svreinterpret_s64_s8 (q8bytes_1 ))); 2536r2 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q8bytes_2 ),svreinterpret_s64_s8 (q8bytes_3 ))); 2537r3 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q8bytes_2 ),svreinterpret_s64_s8 (q8bytes_3 ))); 2538sumi1 = svmmla (svmmla (svdup_n_s32 (0 ),r0 ,l0 ),r1 ,l1 ); 2539svscales = svreinterpret_s32_u32 (svlsr_n_u32_x (pg256_all ,svlsl_n_u32_x (pg256_all ,svreinterpret_u32_u64 (svdup_n_u64 (new_utmp .u64 [j /2 ])),8 * (4 - 2 * (j %2 )- 1 )),24 )); 2540acc_sumif1 = svmla_s32_x (pg256_all ,acc_sumif1 ,svscales ,sumi1 ); 2541sumi2 = svmmla (svmmla (svdup_n_s32 (0 ),r2 ,l2 ),r3 ,l3 ); 2542svscales = svreinterpret_s32_u32 (svlsr_n_u32_x (pg256_all ,svlsl_n_u32_x (pg256_all ,svreinterpret_u32_u64 (svdup_n_u64 (new_utmp .u64 [j /2 ])),8 * (4 - 2 * (j %2 )- 2 )),24 )); 2543acc_sumif2 = svmla_s32_x (pg256_all ,acc_sumif2 ,svscales ,sumi2 ); 2544q4_0 += 32 ;q4_1 += 32 ;q8_0 += 64 ;q8_1 += 64 ; 2545 } 2546svint32_t acc_sumif = svadd_s32_x (pg256_all ,acc_sumif1 ,acc_sumif2 ); 2547svint32_t swap_acc_sumif = svext_s32 (acc_sumif ,acc_sumif ,4 ); 2548acc_sumif = svadd_s32_x (pg32_4 ,acc_sumif ,swap_acc_sumif ); 2549sumf1 = svmla_f32_x (pg32_4 , 2550svmla_f32_x (pg32_4 , 2551sumf1 , 2552svcvt_f32_x (pg32_4 ,acc_sumif ), 2553svsuper_block_scales ), 2554svdmins , 2555svsumfs_tmp ); 2556 }// end of for nb 2557 }// end of case 256-512 2558break ; 2559default : 2560assert (false&& "Unsupported vector length" ); 2561break ; 2562 } 2563 2564svst1_f32 (pg32_2 ,s ,sumf1 ); 2565svst1_f32 (pg32_2 ,s + bs ,svreinterpret_f32_u8 (svext_u8 (svreinterpret_u8_f32 (sumf1 ),svdup_n_u8 (0 ),8 ))); 2566 2567return ; 2568 } 2569#elif defined(__ARM_FEATURE_MATMUL_INT8 ) 2570if (nrc == 2 ) { 2571const block_q4_K * GGML_RESTRICT x0 = x ; 2572const block_q4_K * GGML_RESTRICT x1 = (const block_q4_K * ) ((const uint8_t * )vx + bx ); 2573const block_q8_K * GGML_RESTRICT y0 = y ; 2574const block_q8_K * GGML_RESTRICT y1 = (const block_q8_K * ) ((const uint8_t * )vy + by ); 2575 2576const uint8x16_t m4b = vdupq_n_u8 (0x0f ); 2577 2578float32x4_t vfsum = vdupq_n_f32 (0.0f ); 2579 2580for (int i = 0 ;i < nb ;++ i ,++ x0 ,++ x1 ,++ y0 ,++ y1 ) { 2581const uint8_t * GGML_RESTRICT qx0 = x0 -> qs ; 2582const uint8_t * GGML_RESTRICT qx1 = x1 -> qs ; 2583const int8_t * GGML_RESTRICT qy0 = y0 -> qs ; 2584const int8_t * GGML_RESTRICT qy1 = y1 -> qs ; 2585 2586// decode scales and mins 2587int8_t x0_scales [8 ],x1_scales [8 ]; 2588int16x8_t x0_mins ,x1_mins ; 2589 { 2590uint32_t scales_mins [3 ]; 2591memcpy (scales_mins ,x0 -> scales ,12 ); 2592const uint32_t mins_0_3 = scales_mins [1 ]& kmask1 ; 2593const uint32_t mins_4_7 = ((scales_mins [2 ] >>4 )& kmask2 ) | (((scales_mins [1 ] >>6 )& kmask3 ) <<4 ); 2594const uint32x2_t mins = {mins_0_3 ,mins_4_7 }; 2595x0_mins = vreinterpretq_s16_u16 (vmovl_u8 (vreinterpret_u8_u32 (mins ))); 2596uint32_t scales [2 ]; 2597scales [0 ]= scales_mins [0 ]& kmask1 ;// scales 0~3 2598scales [1 ]= (scales_mins [2 ]& kmask2 ) | (((scales_mins [0 ] >>6 )& kmask3 ) <<4 );// scales 4~7 2599memcpy (x0_scales ,scales ,8 ); 2600 } 2601 { 2602uint32_t scales_mins [3 ]; 2603memcpy (scales_mins ,x1 -> scales ,12 ); 2604const uint32_t mins_0_3 = scales_mins [1 ]& kmask1 ; 2605const uint32_t mins_4_7 = ((scales_mins [2 ] >>4 )& kmask2 ) | (((scales_mins [1 ] >>6 )& kmask3 ) <<4 ); 2606const uint32x2_t mins = {mins_0_3 ,mins_4_7 }; 2607x1_mins = vreinterpretq_s16_u16 (vmovl_u8 (vreinterpret_u8_u32 (mins ))); 2608uint32_t scales [2 ]; 2609scales [0 ]= scales_mins [0 ]& kmask1 ;// scales 0~3 2610scales [1 ]= (scales_mins [2 ]& kmask2 ) | (((scales_mins [0 ] >>6 )& kmask3 ) <<4 );// scales 4~7 2611memcpy (x1_scales ,scales ,8 ); 2612 } 2613 2614int32x4_t visum = {0 }; 2615 2616// process 64 data points per iteration, totally 256 data points 2617for (int j = 0 ;j < QK_K /64 ;++ j ,qx0 += 32 ,qx1 += 32 ,qy0 += 64 ,qy1 += 64 ) { 2618const int8x16x4_t vy0 = vld1q_s8_x4 (qy0 ); 2619const int8x16x4_t vy1 = vld1q_s8_x4 (qy1 ); 2620 2621int8x16_t vx0 [4 ],vx1 [4 ]; 2622 { 2623const uint8x16x2_t vv = vld1q_u8_x2 (qx0 ); 2624vx0 [0 ]= vreinterpretq_s8_u8 (vandq_u8 (vv .val [0 ],m4b )); 2625vx0 [1 ]= vreinterpretq_s8_u8 (vandq_u8 (vv .val [1 ],m4b )); 2626vx0 [2 ]= vreinterpretq_s8_u8 (vshrq_n_u8 (vv .val [0 ],4 )); 2627vx0 [3 ]= vreinterpretq_s8_u8 (vshrq_n_u8 (vv .val [1 ],4 )); 2628 } 2629 { 2630const uint8x16x2_t vv = vld1q_u8_x2 (qx1 ); 2631vx1 [0 ]= vreinterpretq_s8_u8 (vandq_u8 (vv .val [0 ],m4b )); 2632vx1 [1 ]= vreinterpretq_s8_u8 (vandq_u8 (vv .val [1 ],m4b )); 2633vx1 [2 ]= vreinterpretq_s8_u8 (vshrq_n_u8 (vv .val [0 ],4 )); 2634vx1 [3 ]= vreinterpretq_s8_u8 (vshrq_n_u8 (vv .val [1 ],4 )); 2635 } 2636 2637// process 32 data points (share same block scale) per iteration 2638for (int k = 0 ;k < 2 ;++ k ) { 2639const int blk = j * 2 + k ; 2640const int32x4_t block_scale = { 2641x0_scales [blk ], 2642x0_scales [blk ], 2643x1_scales [blk ], 2644x1_scales [blk ], 2645 }; 2646 2647int32x4_t vr = {0 }; 2648for (int l = 0 ;l < 2 ;++ l ) { 2649const int idx = k * 2 + l ; 2650const int64x2_t vx0_s64 = vreinterpretq_s64_s8 (vx0 [idx ]); 2651const int64x2_t vx1_s64 = vreinterpretq_s64_s8 (vx1 [idx ]); 2652const int64x2_t vy0_s64 = vreinterpretq_s64_s8 (vy0 .val [idx ]); 2653const int64x2_t vy1_s64 = vreinterpretq_s64_s8 (vy1 .val [idx ]); 2654const int8x16_t vx_l = vreinterpretq_s8_s64 (vzip1q_s64 (vx0_s64 ,vx1_s64 )); 2655const int8x16_t vx_h = vreinterpretq_s8_s64 (vzip2q_s64 (vx0_s64 ,vx1_s64 )); 2656const int8x16_t vy_l = vreinterpretq_s8_s64 (vzip1q_s64 (vy0_s64 ,vy1_s64 )); 2657const int8x16_t vy_h = vreinterpretq_s8_s64 (vzip2q_s64 (vy0_s64 ,vy1_s64 )); 2658vr = vmmlaq_s32 (vr ,vx_l ,vy_l ); 2659vr = vmmlaq_s32 (vr ,vx_h ,vy_h ); 2660 } 2661// apply block scale, will NOT overflow 2662// block_scale * sum_256(int4*int8) <= 2^(8+8+4+8) = 28 bits 2663visum = vmlaq_s32 (visum ,vr ,block_scale ); 2664 } 2665 } 2666 2667// adjust bias, apply superblock scale 2668 { 2669int32_t bias [4 ]; 2670// no obvious uplift from sve sdot-16, just use neon mul add 2671const int16x8_t y0_sums = vpaddq_s16 (vld1q_s16 (y0 -> bsums ),vld1q_s16 (y0 -> bsums + 8 )); 2672const int16x8_t y1_sums = vpaddq_s16 (vld1q_s16 (y1 -> bsums ),vld1q_s16 (y1 -> bsums + 8 )); 2673bias [0 ]= vaddvq_s32 (vaddq_s32 (vmull_s16 (vget_low_s16 (y0_sums ),vget_low_s16 (x0_mins )), 2674vmull_s16 (vget_high_s16 (y0_sums ),vget_high_s16 (x0_mins )))); 2675bias [1 ]= vaddvq_s32 (vaddq_s32 (vmull_s16 (vget_low_s16 (y1_sums ),vget_low_s16 (x0_mins )), 2676vmull_s16 (vget_high_s16 (y1_sums ),vget_high_s16 (x0_mins )))); 2677bias [2 ]= vaddvq_s32 (vaddq_s32 (vmull_s16 (vget_low_s16 (y0_sums ),vget_low_s16 (x1_mins )), 2678vmull_s16 (vget_high_s16 (y0_sums ),vget_high_s16 (x1_mins )))); 2679bias [3 ]= vaddvq_s32 (vaddq_s32 (vmull_s16 (vget_low_s16 (y1_sums ),vget_low_s16 (x1_mins )), 2680vmull_s16 (vget_high_s16 (y1_sums ),vget_high_s16 (x1_mins )))); 2681const float32x4_t dmins = { 2682GGML_CPU_FP16_TO_FP32 (x0 -> dmin )* y0 -> d , 2683GGML_CPU_FP16_TO_FP32 (x0 -> dmin )* y1 -> d , 2684GGML_CPU_FP16_TO_FP32 (x1 -> dmin )* y0 -> d , 2685GGML_CPU_FP16_TO_FP32 (x1 -> dmin )* y1 -> d , 2686 }; 2687vfsum = vmlsq_f32 (vfsum ,vcvtq_f32_s32 (vld1q_s32 (bias )),dmins ); 2688 2689const float32x4_t superblock_scale = { 2690GGML_CPU_FP16_TO_FP32 (x0 -> d )* y0 -> d , 2691GGML_CPU_FP16_TO_FP32 (x0 -> d )* y1 -> d , 2692GGML_CPU_FP16_TO_FP32 (x1 -> d )* y0 -> d , 2693GGML_CPU_FP16_TO_FP32 (x1 -> d )* y1 -> d , 2694 }; 2695vfsum = vmlaq_f32 (vfsum ,vcvtq_f32_s32 (visum ),superblock_scale ); 2696 } 2697 } 2698 2699// vfsum = ABCD -> ACBD 2700// AC -> s, BD -> (s+bs) 2701vfsum = vzip1q_f32 (vfsum ,vextq_f32 (vfsum ,vfsum ,2 )); 2702vst1_f32 (s ,vget_low_f32 (vfsum )); 2703vst1_f32 (s + bs ,vget_high_f32 (vfsum )); 2704 2705return ; 2706 } 2707#endif 2708 2709#ifdef __ARM_FEATURE_SVE 2710float sumf = 0 ; 2711for (int i = 0 ;i < nb ;++ i ) { 2712 2713const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 2714const float dmin = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 2715 2716const int16x8_t q8sums = vpaddq_s16 (vld1q_s16 (y [i ].bsums ),vld1q_s16 (y [i ].bsums + 8 )); 2717 2718memcpy (utmp ,x [i ].scales ,K_SCALE_SIZE ); 2719 2720uint32x2_t mins8 = {0 }; 2721mins8 = vset_lane_u32 (utmp [1 ]& kmask1 ,mins8 ,0 ); 2722mins8 = vset_lane_u32 (((utmp [2 ] >>4 )& kmask2 ) | (((utmp [1 ] >>6 )& kmask3 ) <<4 ),mins8 ,1 ); 2723 2724utmp [1 ]= (utmp [2 ]& kmask2 ) | (((utmp [0 ] >>6 )& kmask3 ) <<4 ); 2725utmp [0 ] &=kmask1 ; 2726 2727const int16x8_t mins = vreinterpretq_s16_u16 (vmovl_u8 (vreinterpret_u8_u32 (mins8 ))); 2728const int32x4_t prod = vaddq_s32 (vmull_s16 (vget_low_s16 (q8sums ),vget_low_s16 (mins )), 2729vmull_s16 (vget_high_s16 (q8sums ),vget_high_s16 (mins ))); 2730sumf -= dmin * vaddvq_s32 (prod ); 2731 2732const uint8_t * scales = (const uint8_t * )utmp ; 2733 2734const uint8_t * GGML_RESTRICT q4 = x [i ].qs ; 2735const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2736 2737const svuint8_t m4b = svdup_n_u8 (0xf ); 2738const svint32_t mzero = svdup_n_s32 (0 ); 2739svint32_t sumi1 = svdup_n_s32 (0 ); 2740svint32_t sumi1_1 = svdup_n_s32 (0 ); 2741svint32_t sumi1_2 = svdup_n_s32 (0 ); 2742svint32_t sumi2 = svdup_n_s32 (0 ); 2743svint32_t sumi2_1 = svdup_n_s32 (0 ); 2744svint32_t sumi2_2 = svdup_n_s32 (0 ); 2745switch (vector_length ) { 2746case 128 : 2747 { 2748for (int j = 0 ;j < QK_K /64 ;++ j ) { 2749svint8_t q4bytes = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svld1_u8 (svptrue_b8 (),q4 ),m4b )); 2750svint8_t q8bytes = svld1_s8 (svptrue_b8 (),q8 );q8 += 16 ; 2751sumi1_1 = svmla_n_s32_x (svptrue_b32 (),sumi1_1 ,svdot_s32 (mzero ,q4bytes ,q8bytes ),scales [2 * j + 0 ]); 2752q4bytes = svreinterpret_s8_u8 (svand_u8_x (svptrue_b8 (),svld1_u8 (svptrue_b8 (),q4 + 16 ),m4b )); 2753q8bytes = svld1_s8 (svptrue_b8 (),q8 );q8 += 16 ; 2754sumi1_2 = svmla_n_s32_x (svptrue_b32 (),sumi1_2 ,svdot_s32 (mzero ,q4bytes ,q8bytes ),scales [2 * j + 0 ]); 2755 2756q4bytes = svreinterpret_s8_u8 (svlsr_n_u8_x (svptrue_b8 (),svld1_u8 (svptrue_b8 (),q4 ),4 )); 2757q8bytes = svld1_s8 (svptrue_b8 (),q8 );q8 += 16 ; 2758sumi2_1 = svmla_n_s32_x (svptrue_b32 (),sumi2_1 ,svdot_s32 (mzero ,q4bytes ,q8bytes ),scales [2 * j + 1 ]); 2759q4bytes = svreinterpret_s8_u8 (svlsr_n_u8_x (svptrue_b8 (),svld1_u8 (svptrue_b8 (),q4 + 16 ),4 )); 2760q8bytes = svld1_s8 (svptrue_b8 (),q8 );q8 += 16 ; 2761sumi2_2 = svmla_n_s32_x (svptrue_b32 (),sumi2_2 ,svdot_s32 (mzero ,q4bytes ,q8bytes ),scales [2 * j + 1 ]); 2762q4 += 32 ; 2763 } 2764sumi1 = svadd_s32_x (svptrue_b32 (),sumi1_1 ,sumi1_2 ); 2765sumi2 = svadd_s32_x (svptrue_b32 (),sumi2_1 ,sumi2_2 ); 2766sumf += d * (svaddv_s32 (svptrue_b32 (),svadd_s32_x (svptrue_b32 (),sumi1 ,sumi2 ))); 2767 }break ; 2768case 256 : 2769case 512 : 2770 { 2771for (int j = 0 ;j < QK_K /64 ;++ j ) { 2772const svuint8_t q4bits = svld1_u8 (svptrue_pat_b8 (SV_VL32 ),q4 );q4 += 32 ; 2773svint8_t q4bytes = svreinterpret_s8_u8 (svand_u8_x (svptrue_pat_b8 (SV_VL32 ),q4bits ,m4b )); 2774svint8_t q8bytes = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8 );q8 += 32 ; 2775sumi1 = svmla_n_s32_x (svptrue_pat_b32 (SV_VL8 ),sumi1 ,svdot_s32 (mzero ,q4bytes ,q8bytes ),scales [2 * j + 0 ]); 2776 2777q4bytes = svreinterpret_s8_u8 (svlsr_n_u8_x (svptrue_pat_b8 (SV_VL32 ),q4bits ,4 )); 2778q8bytes = svld1_s8 (svptrue_pat_b8 (SV_VL32 ),q8 );q8 += 32 ; 2779sumi2 = svmla_n_s32_x (svptrue_pat_b32 (SV_VL8 ),sumi2 ,svdot_s32 (mzero ,q4bytes ,q8bytes ),scales [2 * j + 1 ]); 2780 } 2781sumf += d * (svaddv_s32 (svptrue_pat_b32 (SV_VL8 ),svadd_s32_x (svptrue_pat_b32 (SV_VL8 ),sumi1 ,sumi2 ))); 2782 }break ; 2783default : 2784assert (false&& "Unsupported vector length" ); 2785break ; 2786 } 2787 } 2788* s = sumf ; 2789#elif defined__ARM_NEON 2790const uint8x16_t m4b = vdupq_n_u8 (0xf ); 2791const int32x4_t mzero = vdupq_n_s32 (0 ); 2792 2793ggml_int8x16x2_t q4bytes ; 2794ggml_int8x16x2_t q8bytes ; 2795 2796float sumf = 0 ; 2797 2798for (int i = 0 ;i < nb ;++ i ) { 2799 2800const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 2801const float dmin = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 2802 2803const int16x8_t q8sums = vpaddq_s16 (vld1q_s16 (y [i ].bsums ),vld1q_s16 (y [i ].bsums + 8 )); 2804 2805memcpy (utmp ,x [i ].scales ,12 ); 2806 2807uint32x2_t mins8 = {0 }; 2808mins8 = vset_lane_u32 (utmp [1 ]& kmask1 ,mins8 ,0 ); 2809mins8 = vset_lane_u32 (((utmp [2 ] >>4 )& kmask2 ) | (((utmp [1 ] >>6 )& kmask3 ) <<4 ),mins8 ,1 ); 2810 2811utmp [1 ]= (utmp [2 ]& kmask2 ) | (((utmp [0 ] >>6 )& kmask3 ) <<4 ); 2812utmp [0 ] &=kmask1 ; 2813 2814const int16x8_t mins = vreinterpretq_s16_u16 (vmovl_u8 (vreinterpret_u8_u32 (mins8 ))); 2815const int32x4_t prod = vaddq_s32 (vmull_s16 (vget_low_s16 (q8sums ),vget_low_s16 (mins )), 2816vmull_s16 (vget_high_s16 (q8sums ),vget_high_s16 (mins ))); 2817sumf -= dmin * vaddvq_s32 (prod ); 2818 2819const uint8_t * scales = (const uint8_t * )utmp ; 2820 2821const uint8_t * GGML_RESTRICT q4 = x [i ].qs ; 2822const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2823 2824int32_t sumi1 = 0 ; 2825int32_t sumi2 = 0 ; 2826 2827for (int j = 0 ;j < QK_K /64 ;++ j ) { 2828const ggml_uint8x16x2_t q4bits = ggml_vld1q_u8_x2 (q4 );q4 += 32 ; 2829 2830q8bytes = ggml_vld1q_s8_x2 (q8 );q8 += 32 ; 2831q4bytes .val [0 ]= vreinterpretq_s8_u8 (vandq_u8 (q4bits .val [0 ],m4b )); 2832q4bytes .val [1 ]= vreinterpretq_s8_u8 (vandq_u8 (q4bits .val [1 ],m4b )); 2833 2834const int32x4_t p1 = ggml_vdotq_s32 (ggml_vdotq_s32 (mzero ,q4bytes .val [0 ],q8bytes .val [0 ]),q4bytes .val [1 ],q8bytes .val [1 ]); 2835sumi1 += vaddvq_s32 (p1 )* scales [2 * j + 0 ]; 2836 2837q8bytes = ggml_vld1q_s8_x2 (q8 );q8 += 32 ; 2838q4bytes .val [0 ]= vreinterpretq_s8_u8 (vshrq_n_u8 (q4bits .val [0 ],4 )); 2839q4bytes .val [1 ]= vreinterpretq_s8_u8 (vshrq_n_u8 (q4bits .val [1 ],4 )); 2840 2841const int32x4_t p2 = ggml_vdotq_s32 (ggml_vdotq_s32 (mzero ,q4bytes .val [0 ],q8bytes .val [0 ]),q4bytes .val [1 ],q8bytes .val [1 ]); 2842 2843sumi2 += vaddvq_s32 (p2 )* scales [2 * j + 1 ]; 2844 } 2845 2846sumf += d * (sumi1 + sumi2 ); 2847 2848 } 2849 2850* s = sumf ; 2851 2852#else 2853UNUSED (x ); 2854UNUSED (y ); 2855UNUSED (nb ); 2856UNUSED (kmask1 ); 2857UNUSED (kmask2 ); 2858UNUSED (kmask3 ); 2859UNUSED (utmp ); 2860ggml_vec_dot_q4_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2861#endif 2862} 2863 2864void 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 ) { 2865assert (n %QK_K == 0 ); 2866assert (nrc == 1 ); 2867UNUSED (nrc ); 2868UNUSED (bx ); 2869UNUSED (by ); 2870UNUSED (bs ); 2871 2872const block_q5_K * GGML_RESTRICT x = vx ; 2873const block_q8_K * GGML_RESTRICT y = vy ; 2874 2875const int nb = n /QK_K ; 2876 2877static const uint32_t kmask1 = 0x3f3f3f3f ; 2878static const uint32_t kmask2 = 0x0f0f0f0f ; 2879static const uint32_t kmask3 = 0x03030303 ; 2880 2881uint32_t utmp [4 ]; 2882 2883 2884#ifdef __ARM_NEON 2885const uint8x16_t m4b = vdupq_n_u8 (0xf ); 2886const uint8x16_t mone = vdupq_n_u8 (1 ); 2887const uint8x16_t mtwo = vdupq_n_u8 (2 ); 2888const int32x4_t mzero = vdupq_n_s32 (0 ); 2889 2890ggml_int8x16x4_t q5bytes ; 2891 2892float sumf = 0 ; 2893 2894for (int i = 0 ;i < nb ;++ i ) { 2895 2896const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 2897const float dmin = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 2898 2899const int16x8_t q8sums = vpaddq_s16 (vld1q_s16 (y [i ].bsums ),vld1q_s16 (y [i ].bsums + 8 )); 2900 2901memcpy (utmp ,x [i ].scales ,12 ); 2902utmp [3 ]= ((utmp [2 ] >>4 )& kmask2 ) | (((utmp [1 ] >>6 )& kmask3 ) <<4 ); 2903const uint32_t uaux = utmp [1 ]& kmask1 ; 2904utmp [1 ]= (utmp [2 ]& kmask2 ) | (((utmp [0 ] >>6 )& kmask3 ) <<4 ); 2905utmp [2 ]= uaux ; 2906utmp [0 ] &=kmask1 ; 2907 2908const uint8x8_t mins8 = vld1_u8 ((const uint8_t * )utmp + 8 ); 2909const int16x8_t mins = vreinterpretq_s16_u16 (vmovl_u8 (mins8 )); 2910const int32x4_t prod = vaddq_s32 (vmull_s16 (vget_low_s16 (q8sums ),vget_low_s16 (mins )), 2911vmull_s16 (vget_high_s16 (q8sums ),vget_high_s16 (mins ))); 2912int32_t sumi_mins = vaddvq_s32 (prod ); 2913 2914const uint8_t * scales = (const uint8_t * )utmp ; 2915 2916const uint8_t * GGML_RESTRICT q5 = x [i ].qs ; 2917const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 2918const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2919 2920ggml_uint8x16x2_t qhbits = ggml_vld1q_u8_x2 (qh ); 2921 2922ggml_uint8x16x4_t q5h ; 2923 2924int32_t sumi = 0 ; 2925 2926for (int j = 0 ;j < QK_K /64 ;++ j ) { 2927 2928const ggml_uint8x16x2_t q5bits = ggml_vld1q_u8_x2 (q5 );q5 += 32 ; 2929const ggml_int8x16x4_t q8bytes = ggml_vld1q_s8_x4 (q8 );q8 += 64 ; 2930 2931q5h .val [0 ]= vshlq_n_u8 (vandq_u8 (mone ,qhbits .val [0 ]),4 ); 2932q5h .val [1 ]= vshlq_n_u8 (vandq_u8 (mone ,qhbits .val [1 ]),4 ); 2933q5h .val [2 ]= vshlq_n_u8 (vandq_u8 (mtwo ,qhbits .val [0 ]),3 ); 2934q5h .val [3 ]= vshlq_n_u8 (vandq_u8 (mtwo ,qhbits .val [1 ]),3 ); 2935qhbits .val [0 ]= vshrq_n_u8 (qhbits .val [0 ],2 ); 2936qhbits .val [1 ]= vshrq_n_u8 (qhbits .val [1 ],2 ); 2937 2938q5bytes .val [0 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (q5bits .val [0 ],m4b ),q5h .val [0 ])); 2939q5bytes .val [1 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (q5bits .val [1 ],m4b ),q5h .val [1 ])); 2940q5bytes .val [2 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (q5bits .val [0 ],4 ),q5h .val [2 ])); 2941q5bytes .val [3 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (q5bits .val [1 ],4 ),q5h .val [3 ])); 2942 2943sumi += vaddvq_s32 (ggml_vdotq_s32 (ggml_vdotq_s32 (mzero ,q5bytes .val [0 ],q8bytes .val [0 ]),q5bytes .val [1 ],q8bytes .val [1 ]))* * scales ++ ; 2944sumi += vaddvq_s32 (ggml_vdotq_s32 (ggml_vdotq_s32 (mzero ,q5bytes .val [2 ],q8bytes .val [2 ]),q5bytes .val [3 ],q8bytes .val [3 ]))* * scales ++ ; 2945 } 2946 2947sumf += d * sumi - dmin * sumi_mins ; 2948 } 2949 2950* s = sumf ; 2951 2952#else 2953UNUSED (x ); 2954UNUSED (y ); 2955UNUSED (nb ); 2956UNUSED (kmask1 ); 2957UNUSED (kmask2 ); 2958UNUSED (kmask3 ); 2959UNUSED (utmp ); 2960ggml_vec_dot_q5_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2961#endif 2962} 2963 2964void 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 ) { 2965assert (n %QK_K == 0 ); 2966#ifdef __ARM_FEATURE_MATMUL_INT8 2967assert ((nrc == 2 )|| (nrc == 1 )); 2968#else 2969assert (nrc == 1 ); 2970#endif 2971UNUSED (nrc ); 2972UNUSED (bx ); 2973UNUSED (by ); 2974UNUSED (bs ); 2975 2976const block_q6_K * GGML_RESTRICT x = vx ; 2977const block_q8_K * GGML_RESTRICT y = vy ; 2978 2979const int nb = n /QK_K ; 2980 2981#ifdef __ARM_FEATURE_SVE 2982const int vector_length = ggml_cpu_get_sve_cnt ()* 8 ; 2983#endif 2984#if defined(__ARM_FEATURE_SVE )&& defined(__ARM_FEATURE_MATMUL_INT8 ) 2985if (nrc == 2 ) { 2986const svbool_t pg32_2 = svptrue_pat_b32 (SV_VL2 ); 2987 2988svfloat32_t sum = svdup_n_f32 (0 ); 2989 2990const block_q6_K * GGML_RESTRICT vx0 = vx ; 2991const block_q8_K * GGML_RESTRICT vy0 = vy ; 2992const block_q6_K * GGML_RESTRICT vx1 = (const block_q6_K * ) ((const uint8_t * )vx + bx ); 2993const block_q8_K * GGML_RESTRICT vy1 = (const block_q8_K * ) ((const uint8_t * )vy + by ); 2994 2995switch (vector_length ) { 2996case 128 : 2997 { 2998const svbool_t pg128_all = svptrue_pat_b8 (SV_ALL ); 2999for (int i = 0 ;i < nb ;++ i ) { 3000const uint8_t * GGML_RESTRICT ql0 = vx0 [i ].ql ; 3001const uint8_t * GGML_RESTRICT qh0 = vx0 [i ].qh ; 3002const uint8_t * GGML_RESTRICT ql1 = vx1 [i ].ql ; 3003const uint8_t * GGML_RESTRICT qh1 = vx1 [i ].qh ; 3004const int8_t * GGML_RESTRICT q80 = vy0 [i ].qs ; 3005const int8_t * GGML_RESTRICT q81 = vy1 [i ].qs ; 3006 3007const int8_t * GGML_RESTRICT scale0 = vx0 [i ].scales ; 3008const int8_t * GGML_RESTRICT scale1 = vx1 [i ].scales ; 3009 3010svfloat32_t vy_d = svuzp1_f32 (svdup_n_f32 (vy0 [i ].d ),svdup_n_f32 (vy1 [i ].d )); 3011svfloat32_t vx_d = svzip1_f32 (svdup_n_f32 (GGML_FP16_TO_FP32 (vx0 [i ].d )),svdup_n_f32 (GGML_FP16_TO_FP32 (vx1 [i ].d ))); 3012svfloat32_t svsuper_block_scales = svmul_f32_x (pg128_all ,vy_d ,vx_d ); 3013// process q8sum summation 128 bit route 3014const svint16_t q8sums_01 = svld1_s16 (pg128_all ,vy0 [i ].bsums ); 3015const svint16_t q8sums_02 = svld1_s16 (pg128_all ,vy0 [i ].bsums + 8 ); 3016const svint16_t q8sums_11 = svld1_s16 (pg128_all ,vy1 [i ].bsums ); 3017const svint16_t q8sums_12 = svld1_s16 (pg128_all ,vy1 [i ].bsums + 8 ); 3018const svint64x2_t q6scales_0_tmp = svld2_s64 (pg128_all , (const int64_t * )scale0 ); 3019const svint16_t q6scales_01 = svunpklo_s16 (svreinterpret_s8_s64 (svget2_s64 (q6scales_0_tmp ,0 ))); 3020const svint16_t q6scales_02 = svunpklo_s16 (svreinterpret_s8_s64 (svget2_s64 (q6scales_0_tmp ,1 ))); 3021const svint64x2_t q6scales_1_tmp = svld2_s64 (pg128_all , (const int64_t * )scale1 ); 3022const svint16_t q6scales_11 = svunpklo_s16 (svreinterpret_s8_s64 (svget2_s64 (q6scales_1_tmp ,0 ))); 3023const svint16_t q6scales_12 = svunpklo_s16 (svreinterpret_s8_s64 (svget2_s64 (q6scales_1_tmp ,1 ))); 3024const svint64_t prod = svdup_n_s64 (0 ); 3025 3026svint32_t isum_tmp1 = svreinterpret_s32_s64 (svdot_s64 (svdot_s64 (prod ,q8sums_01 ,q6scales_01 ),q8sums_02 ,q6scales_02 )); 3027svint32_t isum_tmp2 = svreinterpret_s32_s64 (svdot_s64 (svdot_s64 (prod ,q8sums_01 ,q6scales_11 ),q8sums_02 ,q6scales_12 )); 3028svint32_t isum_tmp3 = svtrn1_s32 (isum_tmp1 ,isum_tmp2 ); 3029svint32_t isum_tmp4 = svreinterpret_s32_s64 (svdot_s64 (svdot_s64 (prod ,q8sums_11 ,q6scales_01 ),q8sums_12 ,q6scales_02 )); 3030svint32_t isum_tmp5 = svreinterpret_s32_s64 (svdot_s64 (svdot_s64 (prod ,q8sums_11 ,q6scales_11 ),q8sums_12 ,q6scales_12 )); 3031svint32_t isum_tmp6 = svtrn1_s32 (isum_tmp4 ,isum_tmp5 ); 3032svint32_t isum_tmp7 = svreinterpret_s32_s64 (svtrn2_s64 (svreinterpret_s64_s32 (isum_tmp3 ),svreinterpret_s64_s32 (isum_tmp6 ))); 3033svint32_t isum_tmp8 = svreinterpret_s32_s64 (svtrn1_s64 (svreinterpret_s64_s32 (isum_tmp3 ),svreinterpret_s64_s32 (isum_tmp6 ))); 3034svint32_t svisum_mins = svadd_s32_x (pg128_all ,isum_tmp7 ,isum_tmp8 ); 3035 3036// process mmla 3037svint8_t l0 ,l1 ,r0 ,r1 ; 3038svint32_t isum_tmp = svdup_n_s32 (0 ); 3039for (int j = 0 ;j < QK_K /128 ;++ j ) { 3040for (int k = 0 ;k < 8 ;++ k ) { 3041svuint8_t qhbits_0 = svld1_u8 (pg128_all ,qh0 + 16 * (k %2 )); 3042svuint8_t qhbits_1 = svld1_u8 (pg128_all ,qh1 + 16 * (k %2 )); 3043svuint8_t q6bits_0 = svld1_u8 (pg128_all ,ql0 + 16 * (k %4 )); 3044svuint8_t q6bits_1 = svld1_u8 (pg128_all ,ql1 + 16 * (k %4 )); 3045const int ql_pos = (k /4 )* 4 ; 3046svuint8_t q6bytes_0_lo = (ql_pos < 4 ) ?svand_n_u8_x (pg128_all ,q6bits_0 ,0xf ) :svlsr_n_u8_x (pg128_all ,q6bits_0 ,4 ); 3047svuint8_t q6bytes_1_lo = (ql_pos < 4 ) ?svand_n_u8_x (pg128_all ,q6bits_1 ,0xf ) :svlsr_n_u8_x (pg128_all ,q6bits_1 ,4 ); 3048const int qh_pos = (k /2 )* 2 ; 3049svuint8_t q6bytes_0_hi = svand_n_u8_x (pg128_all ,qhbits_0 ,0x3 <<qh_pos ); 3050svuint8_t q6bytes_1_hi = svand_n_u8_x (pg128_all ,qhbits_1 ,0x3 <<qh_pos ); 3051svint8_t q6bytes_0 ,q6bytes_1 ; 3052if (qh_pos <=4 ) { 3053q6bytes_0 = svreinterpret_s8_u8 (svmla_n_u8_x (pg128_all ,q6bytes_0_lo ,q6bytes_0_hi ,1 << (4 - qh_pos ))); 3054q6bytes_1 = svreinterpret_s8_u8 (svmla_n_u8_x (pg128_all ,q6bytes_1_lo ,q6bytes_1_hi ,1 << (4 - qh_pos ))); 3055 }else { 3056q6bytes_0 = svreinterpret_s8_u8 (svorr_u8_x (pg128_all ,q6bytes_0_lo ,svlsr_n_u8_x (pg128_all ,q6bytes_0_hi , (qh_pos - 4 )))); 3057q6bytes_1 = svreinterpret_s8_u8 (svorr_u8_x (pg128_all ,q6bytes_1_lo ,svlsr_n_u8_x (pg128_all ,q6bytes_1_hi , (qh_pos - 4 )))); 3058 } 3059svint8_t q8bytes_0 = svld1_s8 (pg128_all ,q80 + 16 * (k %8 )); 3060svint8_t q8bytes_1 = svld1_s8 (pg128_all ,q81 + 16 * (k %8 )); 3061l0 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q6bytes_0 ),svreinterpret_s64_s8 (q6bytes_1 ))); 3062l1 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q6bytes_0 ),svreinterpret_s64_s8 (q6bytes_1 ))); 3063r0 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q8bytes_0 ),svreinterpret_s64_s8 (q8bytes_1 ))); 3064r1 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q8bytes_0 ),svreinterpret_s64_s8 (q8bytes_1 ))); 3065svint32_t svscale = svzip1_s32 (svdup_n_s32 (scale0 [k ]),svdup_n_s32 (scale1 [k ])); 3066isum_tmp = svmla_s32_x (pg128_all ,isum_tmp ,svmmla_s32 (svmmla_s32 (svdup_n_s32 (0 ),r0 ,l0 ),r1 ,l1 ),svscale ); 3067 } 3068qh0 += 32 ;qh1 += 32 ; 3069ql0 += 64 ;ql1 += 64 ; 3070q80 += 128 ;q81 += 128 ; 3071scale0 += 8 ;scale1 += 8 ; 3072 } 3073sum = svmla_f32_x (pg128_all ,sum , 3074svcvt_f32_x (pg128_all ,svmla_s32_x (pg128_all ,isum_tmp , 3075svisum_mins ,svdup_n_s32 (-32 ))), 3076svsuper_block_scales ); 3077 } 3078 }// end of case 128 3079break ; 3080case 256 : 3081case 512 : 3082 { 3083const svbool_t pg256_all = svptrue_pat_b8 (SV_ALL ); 3084const svbool_t pg32_4 = svptrue_pat_b32 (SV_VL4 ); 3085for (int i = 0 ;i < nb ;++ i ) { 3086const uint8_t * GGML_RESTRICT ql0 = vx0 [i ].ql ; 3087const uint8_t * GGML_RESTRICT qh0 = vx0 [i ].qh ; 3088const uint8_t * GGML_RESTRICT ql1 = vx1 [i ].ql ; 3089const uint8_t * GGML_RESTRICT qh1 = vx1 [i ].qh ; 3090const int8_t * GGML_RESTRICT q80 = vy0 [i ].qs ; 3091const int8_t * GGML_RESTRICT q81 = vy1 [i ].qs ; 3092 3093const int8_t * GGML_RESTRICT scale0 = vx0 [i ].scales ; 3094const int8_t * GGML_RESTRICT scale1 = vx1 [i ].scales ; 3095svfloat32_t vx_d = svzip1_f32 (svdup_n_f32 (GGML_FP16_TO_FP32 (vx0 [i ].d )),svdup_n_f32 (GGML_FP16_TO_FP32 (vx1 [i ].d ))); 3096svfloat64_t vy_d_tmp = svreinterpret_f64_f32 (svuzp1_f32 (svdup_n_f32 (vy0 [i ].d ),svdup_n_f32 (vy1 [i ].d ))); 3097svfloat32_t vy_d = svreinterpret_f32_f64 (svuzp1_f64 (vy_d_tmp ,vy_d_tmp )); 3098svfloat32_t svsuper_block_scales = svmul_f32_x (pg32_4 ,vy_d ,vx_d ); 3099// process q8sum summation 256 bit route 3100const svint16_t q8sums_0 = svld1_s16 (pg256_all ,vy0 [i ].bsums ); 3101const svint16_t q8sums_1 = svld1_s16 (pg256_all ,vy1 [i ].bsums ); 3102const svint16_t q6scales_0 = svunpklo_s16 (svld1_s8 (pg256_all ,scale0 )); 3103const svint16_t q6scales_1 = svunpklo_s16 (svld1_s8 (pg256_all ,scale1 )); 3104const svint64_t prod = svdup_n_s64 (0 ); 3105svint32_t isum_tmp1 = svreinterpret_s32_s64 (svdot_s64 (prod ,q8sums_0 ,q6scales_0 )); 3106svint32_t isum_tmp2 = svreinterpret_s32_s64 (svdot_s64 (prod ,q8sums_0 ,q6scales_1 )); 3107svint32_t isum_tmp3 = svreinterpret_s32_s64 (svdot_s64 (prod ,q8sums_1 ,q6scales_0 )); 3108svint32_t isum_tmp4 = svreinterpret_s32_s64 (svdot_s64 (prod ,q8sums_1 ,q6scales_1 )); 3109svint32_t isum_tmp5 = svtrn1_s32 (isum_tmp1 ,isum_tmp2 ); 3110svint32_t isum_tmp6 = svtrn1_s32 (isum_tmp3 ,isum_tmp4 ); 3111svint32_t isum_tmp7 = svreinterpret_s32_s64 (svtrn2_s64 (svreinterpret_s64_s32 (isum_tmp5 ),svreinterpret_s64_s32 (isum_tmp6 ))); 3112svint32_t isum_tmp8 = svreinterpret_s32_s64 (svtrn1_s64 (svreinterpret_s64_s32 (isum_tmp5 ),svreinterpret_s64_s32 (isum_tmp6 ))); 3113svint32_t isum_tmp9 = svadd_s32_x (pg256_all ,isum_tmp7 ,isum_tmp8 ); 3114svint32_t isum_tmp10 = svreinterpret_s32_u8 (svext_u8 (svreinterpret_u8_s32 (isum_tmp9 ),svreinterpret_u8_s32 (isum_tmp9 ),16 )); 3115svint32_t svisum_mins = svadd_s32_z (pg32_4 ,isum_tmp9 ,isum_tmp10 ); 3116 3117// process mmla 3118svint8_t l0 ,l1 ,r0 ,r1 ; 3119svint32_t isum_tmp = svdup_n_s32 (0 ); 3120for (int j = 0 ;j < QK_K /128 ;++ j ) { 3121for (int k = 0 ;k < 8 ;k += 2 ) {// process 2 block 3122svuint8_t qhbits_0 = svld1_u8 (pg256_all ,qh0 ); 3123svuint8_t qhbits_1 = svld1_u8 (pg256_all ,qh1 ); 3124svuint8_t q6bits_0 = svld1_u8 (pg256_all ,ql0 + 32 * ((k %4 )/2 )); 3125svuint8_t q6bits_1 = svld1_u8 (pg256_all ,ql1 + 32 * ((k %4 )/2 )); 3126const int ql_pos = (k /4 )* 4 ; 3127svuint8_t q6bytes_0_lo = (ql_pos < 4 ) ?svand_n_u8_x (pg256_all ,q6bits_0 ,0xf ) :svlsr_n_u8_x (pg256_all ,q6bits_0 ,4 ); 3128svuint8_t q6bytes_1_lo = (ql_pos < 4 ) ?svand_n_u8_x (pg256_all ,q6bits_1 ,0xf ) :svlsr_n_u8_x (pg256_all ,q6bits_1 ,4 ); 3129const int qh_pos = (k /2 )* 2 ; 3130svuint8_t q6bytes_0_hi = svand_n_u8_x (pg256_all ,qhbits_0 ,0x3 <<qh_pos ); 3131svuint8_t q6bytes_1_hi = svand_n_u8_x (pg256_all ,qhbits_1 ,0x3 <<qh_pos ); 3132svint8_t q6bytes_0 ,q6bytes_1 ; 3133if (qh_pos <=4 ) { 3134q6bytes_0 = svreinterpret_s8_u8 (svmla_n_u8_x (pg256_all ,q6bytes_0_lo ,q6bytes_0_hi ,1 << (4 - qh_pos ))); 3135q6bytes_1 = svreinterpret_s8_u8 (svmla_n_u8_x (pg256_all ,q6bytes_1_lo ,q6bytes_1_hi ,1 << (4 - qh_pos ))); 3136 }else { 3137q6bytes_0 = svreinterpret_s8_u8 (svorr_u8_x (pg256_all ,q6bytes_0_lo ,svlsr_n_u8_x (pg256_all ,q6bytes_0_hi , (qh_pos - 4 )))); 3138q6bytes_1 = svreinterpret_s8_u8 (svorr_u8_x (pg256_all ,q6bytes_1_lo ,svlsr_n_u8_x (pg256_all ,q6bytes_1_hi , (qh_pos - 4 )))); 3139 } 3140svint8_t q8bytes_0 = svld1_s8 (pg256_all ,q80 + 32 * (k /2 )); 3141svint8_t q8bytes_1 = svld1_s8 (pg256_all ,q81 + 32 * (k /2 )); 3142l0 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q6bytes_0 ),svreinterpret_s64_s8 (q6bytes_1 ))); 3143l1 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q6bytes_0 ),svreinterpret_s64_s8 (q6bytes_1 ))); 3144r0 = svreinterpret_s8_s64 (svzip1_s64 (svreinterpret_s64_s8 (q8bytes_0 ),svreinterpret_s64_s8 (q8bytes_1 ))); 3145r1 = svreinterpret_s8_s64 (svzip2_s64 (svreinterpret_s64_s8 (q8bytes_0 ),svreinterpret_s64_s8 (q8bytes_1 ))); 3146svint32_t svscale0 = svzip1_s32 (svdup_n_s32 (scale0 [k ]),svdup_n_s32 (scale1 [k ])); 3147svint32_t svscale1 = svzip1_s32 (svdup_n_s32 (scale0 [k + 1 ]),svdup_n_s32 (scale1 [k + 1 ])); 3148isum_tmp = svmla_s32_x (pg256_all ,isum_tmp ,svmmla_s32 (svdup_n_s32 (0 ),r0 ,l0 ),svscale0 ); 3149isum_tmp = svmla_s32_x (pg256_all ,isum_tmp ,svmmla_s32 (svdup_n_s32 (0 ),r1 ,l1 ),svscale1 ); 3150 } 3151qh0 += 32 ;qh1 += 32 ; 3152ql0 += 64 ;ql1 += 64 ; 3153q80 += 128 ;q81 += 128 ; 3154scale0 += 8 ;scale1 += 8 ; 3155 }// end of for 3156svint32_t swap_isum_tmp = svext_s32 (isum_tmp ,isum_tmp ,4 ); 3157isum_tmp = svadd_s32_x (pg32_4 ,isum_tmp ,swap_isum_tmp ); 3158sum = svmla_f32_x (pg32_4 ,sum , 3159svcvt_f32_x (pg32_4 ,svmla_s32_x (pg32_4 ,isum_tmp , 3160svisum_mins ,svdup_n_s32 (-32 ))), 3161svsuper_block_scales ); 3162 } 3163 }// end of case 256 3164break ; 3165default : 3166assert (false&& "Unsupported vector length" ); 3167break ; 3168 }// end of switch 3169 3170svst1_f32 (pg32_2 ,s ,sum ); 3171svst1_f32 (pg32_2 ,s + bs ,svreinterpret_f32_u8 (svext_u8 (svreinterpret_u8_f32 (sum ),svdup_n_u8 (0 ),8 ))); 3172 3173return ; 3174 } 3175#elif defined(__ARM_FEATURE_MATMUL_INT8 ) 3176if (nrc == 2 ) { 3177const block_q6_K * GGML_RESTRICT x0 = x ; 3178const block_q6_K * GGML_RESTRICT x1 = (const block_q6_K * ) ((const uint8_t * )vx + bx ); 3179const block_q8_K * GGML_RESTRICT y0 = y ; 3180const block_q8_K * GGML_RESTRICT y1 = (const block_q8_K * ) ((const uint8_t * )vy + by ); 3181 3182float32x4_t vfsum = vdupq_n_f32 (0.0f ); 3183 3184for (int i = 0 ;i < nb ;++ i ,++ x0 ,++ x1 ,++ y0 ,++ y1 ) { 3185const uint8_t * GGML_RESTRICT ql0 = x0 -> ql ; 3186const uint8_t * GGML_RESTRICT ql1 = x1 -> ql ; 3187const uint8_t * GGML_RESTRICT qh0 = x0 -> qh ; 3188const uint8_t * GGML_RESTRICT qh1 = x1 -> qh ; 3189const int8_t * GGML_RESTRICT qy0 = y0 -> qs ; 3190const int8_t * GGML_RESTRICT qy1 = y1 -> qs ; 3191 3192const uint8x16_t mone = vdupq_n_u8 (0x30 ); 3193const uint8x16_t m4b = vdupq_n_u8 (0x0f ); 3194 3195int32x4_t visum = vdupq_n_s32 (0 ); 3196 3197// process 8 blocks per iteration, totally 16 blocks 3198for (int j = 0 ;j < 2 ;++ j ,qh0 += 32 ,ql0 += 64 ,qh1 += 32 ,ql1 += 64 ) { 3199int8x16_t vx0 [8 ],vx1 [8 ]; 3200 3201// de-quantize vx0[8] 3202 { 3203const uint8x16x2_t qh_bits = vld1q_u8_x2 (qh0 ); 3204const uint8x16x4_t ql_bits = vld1q_u8_x4 (ql0 ); 3205 3206uint8x16_t q6h_0 = vandq_u8 (mone ,vshlq_n_u8 (qh_bits .val [0 ],4 )); 3207uint8x16_t q6h_1 = vandq_u8 (mone ,vshlq_n_u8 (qh_bits .val [1 ],4 )); 3208uint8x16_t q6h_2 = vandq_u8 (mone ,vshlq_n_u8 (qh_bits .val [0 ],2 )); 3209uint8x16_t q6h_3 = vandq_u8 (mone ,vshlq_n_u8 (qh_bits .val [1 ],2 )); 3210 3211vx0 [0 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (ql_bits .val [0 ],m4b ),q6h_0 )); 3212vx0 [1 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (ql_bits .val [1 ],m4b ),q6h_1 )); 3213vx0 [2 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (ql_bits .val [2 ],m4b ),q6h_2 )); 3214vx0 [3 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (ql_bits .val [3 ],m4b ),q6h_3 )); 3215 3216q6h_0 = vandq_u8 (mone ,qh_bits .val [0 ]); 3217q6h_1 = vandq_u8 (mone ,qh_bits .val [1 ]); 3218q6h_2 = vandq_u8 (mone ,vshrq_n_u8 (qh_bits .val [0 ],2 )); 3219q6h_3 = vandq_u8 (mone ,vshrq_n_u8 (qh_bits .val [1 ],2 )); 3220 3221vx0 [4 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (ql_bits .val [0 ],4 ),q6h_0 )); 3222vx0 [5 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (ql_bits .val [1 ],4 ),q6h_1 )); 3223vx0 [6 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (ql_bits .val [2 ],4 ),q6h_2 )); 3224vx0 [7 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (ql_bits .val [3 ],4 ),q6h_3 )); 3225 } 3226 3227// de-quantize vx1[8] 3228 { 3229const uint8x16x2_t qh_bits = vld1q_u8_x2 (qh1 ); 3230const uint8x16x4_t ql_bits = vld1q_u8_x4 (ql1 ); 3231 3232uint8x16_t q6h_0 = vandq_u8 (mone ,vshlq_n_u8 (qh_bits .val [0 ],4 )); 3233uint8x16_t q6h_1 = vandq_u8 (mone ,vshlq_n_u8 (qh_bits .val [1 ],4 )); 3234uint8x16_t q6h_2 = vandq_u8 (mone ,vshlq_n_u8 (qh_bits .val [0 ],2 )); 3235uint8x16_t q6h_3 = vandq_u8 (mone ,vshlq_n_u8 (qh_bits .val [1 ],2 )); 3236 3237vx1 [0 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (ql_bits .val [0 ],m4b ),q6h_0 )); 3238vx1 [1 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (ql_bits .val [1 ],m4b ),q6h_1 )); 3239vx1 [2 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (ql_bits .val [2 ],m4b ),q6h_2 )); 3240vx1 [3 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (ql_bits .val [3 ],m4b ),q6h_3 )); 3241 3242q6h_0 = vandq_u8 (mone ,qh_bits .val [0 ]); 3243q6h_1 = vandq_u8 (mone ,qh_bits .val [1 ]); 3244q6h_2 = vandq_u8 (mone ,vshrq_n_u8 (qh_bits .val [0 ],2 )); 3245q6h_3 = vandq_u8 (mone ,vshrq_n_u8 (qh_bits .val [1 ],2 )); 3246 3247vx1 [4 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (ql_bits .val [0 ],4 ),q6h_0 )); 3248vx1 [5 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (ql_bits .val [1 ],4 ),q6h_1 )); 3249vx1 [6 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (ql_bits .val [2 ],4 ),q6h_2 )); 3250vx1 [7 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (ql_bits .val [3 ],4 ),q6h_3 )); 3251 } 3252 3253// process 16 elements (one block with same scale) per iteration 3254// - vx = concat(ql, qh) - 32 3255// - r1,r2,r3,r4 = smmla(vx, vy) 3256for (int k = 0 ;k < 8 ;++ k ) { 3257const int blk = j * 8 + k ; 3258 3259const int8x16_t vy0 = vld1q_s8 (qy0 ); 3260const int8x16_t vy1 = vld1q_s8 (qy1 ); 3261qy0 += 16 ; 3262qy1 += 16 ; 3263 3264const int32x4_t block_scale = { 3265x0 -> scales [blk ], 3266x0 -> scales [blk ], 3267x1 -> scales [blk ], 3268x1 -> scales [blk ], 3269 }; 3270 3271// calculate four results at once with outer product 3272const int8x16_t vx_l = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (vx0 [k ]),vreinterpretq_s64_s8 (vx1 [k ]))); 3273const int8x16_t vx_h = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (vx0 [k ]),vreinterpretq_s64_s8 (vx1 [k ]))); 3274const int8x16_t vy_l = vreinterpretq_s8_s64 (vzip1q_s64 (vreinterpretq_s64_s8 (vy0 ),vreinterpretq_s64_s8 (vy1 ))); 3275const int8x16_t vy_h = vreinterpretq_s8_s64 (vzip2q_s64 (vreinterpretq_s64_s8 (vy0 ),vreinterpretq_s64_s8 (vy1 ))); 3276int32x4_t vr = vdupq_n_s32 (0 ); 3277vr = vmmlaq_s32 (vr ,vx_l ,vy_l ); 3278vr = vmmlaq_s32 (vr ,vx_h ,vy_h ); 3279 3280// apply block scale, will NOT overflow 3281// block_scale * sum_256(int6*int8) <= 2^(8+8+6+8) = 30 bits 3282visum = vmlaq_s32 (visum ,vr ,block_scale ); 3283 } 3284 } 3285 3286// adjust bias, apply superblock scale 3287 { 3288int32_t bias [4 ]; 3289// NEON doesn't support int16 dot product, fallback to separated mul and add 3290const int16x8x2_t q8sums0 = vld1q_s16_x2 (y0 -> bsums ); 3291const int16x8x2_t q8sums1 = vld1q_s16_x2 (y1 -> bsums ); 3292 3293int8x16_t scales_s8 = vld1q_s8 (x0 -> scales ); 3294const int16x8x2_t q6scales0 = {{vmovl_s8 (vget_low_s8 (scales_s8 )),vmovl_s8 (vget_high_s8 (scales_s8 ))}}; 3295scales_s8 = vld1q_s8 (x1 -> scales ); 3296const int16x8x2_t q6scales1 = {{vmovl_s8 (vget_low_s8 (scales_s8 )),vmovl_s8 (vget_high_s8 (scales_s8 ))}}; 3297 3298int32x4_t prod ; 3299prod = vaddq_s32 (vaddq_s32 (vmull_s16 (vget_low_s16 (q8sums0 .val [0 ]),vget_low_s16 (q6scales0 .val [0 ])), 3300vmull_s16 (vget_high_s16 (q8sums0 .val [0 ]),vget_high_s16 (q6scales0 .val [0 ]))), 3301vaddq_s32 (vmull_s16 (vget_low_s16 (q8sums0 .val [1 ]),vget_low_s16 (q6scales0 .val [1 ])), 3302vmull_s16 (vget_high_s16 (q8sums0 .val [1 ]),vget_high_s16 (q6scales0 .val [1 ])))); 3303bias [0 ]= vaddvq_s32 (prod ); 3304prod = vaddq_s32 (vaddq_s32 (vmull_s16 (vget_low_s16 (q8sums1 .val [0 ]),vget_low_s16 (q6scales0 .val [0 ])), 3305vmull_s16 (vget_high_s16 (q8sums1 .val [0 ]),vget_high_s16 (q6scales0 .val [0 ]))), 3306vaddq_s32 (vmull_s16 (vget_low_s16 (q8sums1 .val [1 ]),vget_low_s16 (q6scales0 .val [1 ])), 3307vmull_s16 (vget_high_s16 (q8sums1 .val [1 ]),vget_high_s16 (q6scales0 .val [1 ])))); 3308bias [1 ]= vaddvq_s32 (prod ); 3309prod = vaddq_s32 (vaddq_s32 (vmull_s16 (vget_low_s16 (q8sums0 .val [0 ]),vget_low_s16 (q6scales1 .val [0 ])), 3310vmull_s16 (vget_high_s16 (q8sums0 .val [0 ]),vget_high_s16 (q6scales1 .val [0 ]))), 3311vaddq_s32 (vmull_s16 (vget_low_s16 (q8sums0 .val [1 ]),vget_low_s16 (q6scales1 .val [1 ])), 3312vmull_s16 (vget_high_s16 (q8sums0 .val [1 ]),vget_high_s16 (q6scales1 .val [1 ])))); 3313bias [2 ]= vaddvq_s32 (prod ); 3314prod = vaddq_s32 (vaddq_s32 (vmull_s16 (vget_low_s16 (q8sums1 .val [0 ]),vget_low_s16 (q6scales1 .val [0 ])), 3315vmull_s16 (vget_high_s16 (q8sums1 .val [0 ]),vget_high_s16 (q6scales1 .val [0 ]))), 3316vaddq_s32 (vmull_s16 (vget_low_s16 (q8sums1 .val [1 ]),vget_low_s16 (q6scales1 .val [1 ])), 3317vmull_s16 (vget_high_s16 (q8sums1 .val [1 ]),vget_high_s16 (q6scales1 .val [1 ])))); 3318bias [3 ]= vaddvq_s32 (prod ); 3319 3320const int32x4_t vibias = vmulq_n_s32 (vld1q_s32 (bias ),32 ); 3321 3322const float32x4_t superblock_scale = { 3323GGML_CPU_FP16_TO_FP32 (x0 -> d )* y0 -> d , 3324GGML_CPU_FP16_TO_FP32 (x0 -> d )* y1 -> d , 3325GGML_CPU_FP16_TO_FP32 (x1 -> d )* y0 -> d , 3326GGML_CPU_FP16_TO_FP32 (x1 -> d )* y1 -> d , 3327 }; 3328 3329visum = vsubq_s32 (visum ,vibias ); 3330vfsum = vmlaq_f32 (vfsum ,vcvtq_f32_s32 (visum ),superblock_scale ); 3331 } 3332 } 3333 3334// vfsum = ABCD -> ACBD 3335// AC -> s, BD -> (s+bs) 3336vfsum = vzip1q_f32 (vfsum ,vextq_f32 (vfsum ,vfsum ,2 )); 3337vst1_f32 (s ,vget_low_f32 (vfsum )); 3338vst1_f32 (s + bs ,vget_high_f32 (vfsum )); 3339 3340return ; 3341 } 3342#endif 3343 3344#ifdef __ARM_FEATURE_SVE 3345float sum = 0 ; 3346svuint8_t m4b = svdup_n_u8 (0xf ); 3347svint32_t vzero = svdup_n_s32 (0 ); 3348svuint8_t mone = svdup_n_u8 (0x30 ); 3349svint8_t q6bytes_1 ,q6bytes_2 ,q6bytes_3 ,q6bytes_4 ; 3350svuint8_t q6h_1 ,q6h_2 ,q6h_3 ,q6h_4 ; 3351 3352for (int i = 0 ;i < nb ;++ i ) { 3353const float d_all = GGML_CPU_FP16_TO_FP32 (x [i ].d ); 3354 3355const uint8_t * GGML_RESTRICT q6 = x [i ].ql ; 3356const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 3357const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3358 3359const int8_t * GGML_RESTRICT scale = x [i ].scales ; 3360 3361const svbool_t pg16_8 = svptrue_pat_b16 (SV_VL8 ); 3362const svint16_t q8sums_1 = svld1_s16 (pg16_8 ,y [i ].bsums ); 3363const svint16_t q8sums_2 = svld1_s16 (pg16_8 ,y [i ].bsums + 8 ); 3364const svint16_t q6scales_1 = svunpklo_s16 (svld1_s8 (svptrue_pat_b8 (SV_VL8 ),scale )); 3365const svint16_t q6scales_2 = svunpklo_s16 (svld1_s8 (svptrue_pat_b8 (SV_VL8 ),scale + 8 )); 3366const svint64_t prod = svdup_n_s64 (0 ); 3367int32_t isum_mins = svaddv_s64 (svptrue_b64 (),svadd_s64_x (svptrue_b64 (),svdot_s64 (prod ,q8sums_1 ,q6scales_1 ), 3368svdot_s64 (prod ,q8sums_2 ,q6scales_2 ))); 3369int32_t isum = 0 ; 3370 3371switch (vector_length ) { 3372case 128 : 3373 { 3374const svbool_t pg32_4 = svptrue_pat_b32 (SV_VL4 ); 3375const svbool_t pg8_16 = svptrue_pat_b8 (SV_VL16 ); 3376svint32_t isum_tmp = svdup_n_s32 (0 ); 3377for (int j = 0 ;j < QK_K /128 ;++ j ) { 3378svuint8_t qhbits_1 = svld1_u8 (pg8_16 ,qh ); 3379svuint8_t qhbits_2 = svld1_u8 (pg8_16 ,qh + 16 ); 3380qh += 32 ; 3381svuint8_t q6bits_1 = svld1_u8 (pg8_16 ,q6 ); 3382svuint8_t q6bits_2 = svld1_u8 (pg8_16 ,q6 + 16 ); 3383svuint8_t q6bits_3 = svld1_u8 (pg8_16 ,q6 + 32 ); 3384svuint8_t q6bits_4 = svld1_u8 (pg8_16 ,q6 + 48 ); 3385q6 += 64 ; 3386svint8_t q8bytes_1 = svld1_s8 (pg8_16 ,q8 ); 3387svint8_t q8bytes_2 = svld1_s8 (pg8_16 ,q8 + 16 ); 3388svint8_t q8bytes_3 = svld1_s8 (pg8_16 ,q8 + 32 ); 3389svint8_t q8bytes_4 = svld1_s8 (pg8_16 ,q8 + 48 ); 3390q8 += 64 ; 3391 3392q6h_1 = svand_u8_x (pg16_8 ,mone ,svlsl_n_u8_x (pg16_8 ,qhbits_1 ,4 )); 3393q6h_2 = svand_u8_x (pg16_8 ,mone ,svlsl_n_u8_x (pg16_8 ,qhbits_2 ,4 )); 3394q6h_3 = svand_u8_x (pg16_8 ,mone ,svlsl_n_u8_x (pg16_8 ,qhbits_1 ,2 )); 3395q6h_4 = svand_u8_x (pg16_8 ,mone ,svlsl_n_u8_x (pg16_8 ,qhbits_2 ,2 )); 3396q6bytes_1 = svreinterpret_s8_u8 (svorr_u8_x (pg8_16 ,svand_u8_x (pg8_16 ,q6bits_1 ,m4b ),q6h_1 )); 3397q6bytes_2 = svreinterpret_s8_u8 (svorr_u8_x (pg8_16 ,svand_u8_x (pg8_16 ,q6bits_2 ,m4b ),q6h_2 )); 3398q6bytes_3 = svreinterpret_s8_u8 (svorr_u8_x (pg8_16 ,svand_u8_x (pg8_16 ,q6bits_3 ,m4b ),q6h_3 )); 3399q6bytes_4 = svreinterpret_s8_u8 (svorr_u8_x (pg8_16 ,svand_u8_x (pg8_16 ,q6bits_4 ,m4b ),q6h_4 )); 3400isum_tmp = svmla_n_s32_x (pg32_4 ,isum_tmp ,svdot_s32 (vzero ,q6bytes_1 ,q8bytes_1 ),scale [0 ]); 3401isum_tmp = svmla_n_s32_x (pg32_4 ,isum_tmp ,svdot_s32 (vzero ,q6bytes_2 ,q8bytes_2 ),scale [1 ]); 3402isum_tmp = svmla_n_s32_x (pg32_4 ,isum_tmp ,svdot_s32 (vzero ,q6bytes_3 ,q8bytes_3 ),scale [2 ]); 3403isum_tmp = svmla_n_s32_x (pg32_4 ,isum_tmp ,svdot_s32 (vzero ,q6bytes_4 ,q8bytes_4 ),scale [3 ]); 3404 3405scale += 4 ; 3406q8bytes_1 = svld1_s8 (pg8_16 ,q8 ); 3407q8bytes_2 = svld1_s8 (pg8_16 ,q8 + 16 ); 3408q8bytes_3 = svld1_s8 (pg8_16 ,q8 + 32 ); 3409q8bytes_4 = svld1_s8 (pg8_16 ,q8 + 48 ); 3410q8 += 64 ; 3411 3412q6h_1 = svand_u8_x (pg16_8 ,mone ,qhbits_1 ); 3413q6h_2 = svand_u8_x (pg16_8 ,mone ,qhbits_2 ); 3414q6h_3 = svand_u8_x (pg16_8 ,mone ,svlsr_n_u8_x (pg16_8 ,qhbits_1 ,2 )); 3415q6h_4 = svand_u8_x (pg16_8 ,mone ,svlsr_n_u8_x (pg16_8 ,qhbits_2 ,2 )); 3416q6bytes_1 = svreinterpret_s8_u8 (svorr_u8_x (pg8_16 ,svlsr_n_u8_x (pg8_16 ,q6bits_1 ,4 ),q6h_1 )); 3417q6bytes_2 = svreinterpret_s8_u8 (svorr_u8_x (pg8_16 ,svlsr_n_u8_x (pg8_16 ,q6bits_2 ,4 ),q6h_2 )); 3418q6bytes_3 = svreinterpret_s8_u8 (svorr_u8_x (pg8_16 ,svlsr_n_u8_x (pg8_16 ,q6bits_3 ,4 ),q6h_3 )); 3419q6bytes_4 = svreinterpret_s8_u8 (svorr_u8_x (pg8_16 ,svlsr_n_u8_x (pg8_16 ,q6bits_4 ,4 ),q6h_4 )); 3420isum_tmp = svmla_n_s32_x (pg32_4 ,isum_tmp ,svdot_s32 (vzero ,q6bytes_1 ,q8bytes_1 ),scale [0 ]); 3421isum_tmp = svmla_n_s32_x (pg32_4 ,isum_tmp ,svdot_s32 (vzero ,q6bytes_2 ,q8bytes_2 ),scale [1 ]); 3422isum_tmp = svmla_n_s32_x (pg32_4 ,isum_tmp ,svdot_s32 (vzero ,q6bytes_3 ,q8bytes_3 ),scale [2 ]); 3423isum_tmp = svmla_n_s32_x (pg32_4 ,isum_tmp ,svdot_s32 (vzero ,q6bytes_4 ,q8bytes_4 ),scale [3 ]); 3424scale += 4 ; 3425 } 3426isum += svaddv_s32 (pg32_4 ,isum_tmp ); 3427sum += d_all * y [i ].d * (isum - 32 * isum_mins ); 3428 } 3429break ; 3430case 256 : 3431case 512 : 3432 { 3433const svbool_t pg8_2 = svptrue_pat_b8 (SV_VL2 ); 3434const svbool_t pg32_8 = svptrue_pat_b32 (SV_VL8 ); 3435const svbool_t pg8_32 = svptrue_pat_b8 (SV_VL32 ); 3436svint32_t isum_tmp = svdup_n_s32 (0 ); 3437for (int j = 0 ;j < QK_K /128 ;j ++ ) { 3438svuint8_t qhbits_1 = svld1_u8 (pg8_32 ,qh ); 3439qh += 32 ; 3440svuint8_t q6bits_1 = svld1_u8 (pg8_32 ,q6 ); 3441svuint8_t q6bits_2 = svld1_u8 (pg8_32 ,q6 + 32 ); 3442q6 += 64 ; 3443svint8_t q8bytes_1 = svld1_s8 (pg8_32 ,q8 ); 3444svint8_t q8bytes_2 = svld1_s8 (pg8_32 ,q8 + 32 ); 3445svint8_t q8bytes_3 = svld1_s8 (pg8_32 ,q8 + 64 ); 3446svint8_t q8bytes_4 = svld1_s8 (pg8_32 ,q8 + 96 ); 3447q8 += 128 ; 3448q6h_1 = svand_u8_x (pg8_32 ,mone ,svlsl_n_u8_x (pg8_32 ,qhbits_1 ,4 )); 3449q6h_2 = svand_u8_x (pg8_32 ,mone ,svlsl_n_u8_x (pg8_32 ,qhbits_1 ,2 )); 3450q6h_3 = svand_u8_x (pg8_32 ,mone ,qhbits_1 ); 3451q6h_4 = svand_u8_x (pg8_32 ,mone ,svlsr_n_u8_x (pg8_32 ,qhbits_1 ,2 )); 3452q6bytes_1 = svreinterpret_s8_u8 (svorr_u8_x (pg8_32 ,svand_u8_x (pg8_32 ,q6bits_1 ,m4b ),q6h_1 )); 3453q6bytes_2 = svreinterpret_s8_u8 (svorr_u8_x (pg8_32 ,svand_u8_x (pg8_32 ,q6bits_2 ,m4b ),q6h_2 )); 3454q6bytes_3 = svreinterpret_s8_u8 (svorr_u8_x (pg8_32 ,svlsr_n_u8_x (pg8_32 ,q6bits_1 ,4 ),q6h_3 )); 3455q6bytes_4 = svreinterpret_s8_u8 (svorr_u8_x (pg8_32 ,svlsr_n_u8_x (pg8_32 ,q6bits_2 ,4 ),q6h_4 )); 3456 3457svint8_t scale_lane_1_tmp = svld1_s8 (pg8_2 ,scale ); 3458scale_lane_1_tmp = svzip1_s8 (scale_lane_1_tmp ,scale_lane_1_tmp ); 3459scale_lane_1_tmp = svzip1_s8 (scale_lane_1_tmp ,scale_lane_1_tmp ); 3460svint8_t scale_lane_2_tmp = svld1_s8 (pg8_2 ,scale + 2 ); 3461scale_lane_2_tmp = svzip1_s8 (scale_lane_2_tmp ,scale_lane_2_tmp ); 3462scale_lane_2_tmp = svzip1_s8 (scale_lane_2_tmp ,scale_lane_2_tmp ); 3463svint8_t scale_lane_3_tmp = svld1_s8 (pg8_2 ,scale + 4 ); 3464scale_lane_3_tmp = svzip1_s8 (scale_lane_3_tmp ,scale_lane_3_tmp ); 3465scale_lane_3_tmp = svzip1_s8 (scale_lane_3_tmp ,scale_lane_3_tmp ); 3466svint8_t scale_lane_4_tmp = svld1_s8 (pg8_2 ,scale + 6 ); 3467scale_lane_4_tmp = svzip1_s8 (scale_lane_4_tmp ,scale_lane_4_tmp ); 3468scale_lane_4_tmp = svzip1_s8 (scale_lane_4_tmp ,scale_lane_4_tmp ); 3469svint32_t scale_lane_1 = svunpklo_s32 (svunpklo_s16 (scale_lane_1_tmp )); 3470svint32_t scale_lane_2 = svunpklo_s32 (svunpklo_s16 (scale_lane_2_tmp )); 3471svint32_t scale_lane_3 = svunpklo_s32 (svunpklo_s16 (scale_lane_3_tmp )); 3472svint32_t scale_lane_4 = svunpklo_s32 (svunpklo_s16 (scale_lane_4_tmp )); 3473 3474isum_tmp = svmla_s32_x (pg32_8 ,isum_tmp ,svdot_s32 (vzero ,q6bytes_1 ,q8bytes_1 ),scale_lane_1 ); 3475isum_tmp = svmla_s32_x (pg32_8 ,isum_tmp ,svdot_s32 (vzero ,q6bytes_2 ,q8bytes_2 ),scale_lane_2 ); 3476isum_tmp = svmla_s32_x (pg32_8 ,isum_tmp ,svdot_s32 (vzero ,q6bytes_3 ,q8bytes_3 ),scale_lane_3 ); 3477isum_tmp = svmla_s32_x (pg32_8 ,isum_tmp ,svdot_s32 (vzero ,q6bytes_4 ,q8bytes_4 ),scale_lane_4 ); 3478scale += 8 ; 3479 } 3480isum += svaddv_s32 (pg32_8 ,isum_tmp ); 3481sum += d_all * y [i ].d * (isum - 32 * isum_mins ); 3482 } 3483break ; 3484default : 3485assert (false&& "Unsupported vector length" ); 3486break ; 3487 } 3488 } 3489 3490* s = sum ; 3491 3492#elif __ARM_NEON 3493float sum = 0 ; 3494 3495const uint8x16_t m4b = vdupq_n_u8 (0xF ); 3496const int32x4_t vzero = vdupq_n_s32 (0 ); 3497//const int8x16_t m32s = vdupq_n_s8(32); 3498 3499const uint8x16_t mone = vdupq_n_u8 (3 ); 3500 3501ggml_int8x16x4_t q6bytes ; 3502ggml_uint8x16x4_t q6h ; 3503 3504for (int i = 0 ;i < nb ;++ i ) { 3505 3506const float d_all = GGML_CPU_FP16_TO_FP32 (x [i ].d ); 3507 3508const uint8_t * GGML_RESTRICT q6 = x [i ].ql ; 3509const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 3510const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3511 3512const int8_t * GGML_RESTRICT scale = x [i ].scales ; 3513 3514const ggml_int16x8x2_t q8sums = ggml_vld1q_s16_x2 (y [i ].bsums ); 3515const int8x16_t scales = vld1q_s8 (scale ); 3516const ggml_int16x8x2_t q6scales = {{vmovl_s8 (vget_low_s8 (scales )),vmovl_s8 (vget_high_s8 (scales ))}}; 3517 3518const int32x4_t prod = vaddq_s32 (vaddq_s32 (vmull_s16 (vget_low_s16 (q8sums .val [0 ]),vget_low_s16 (q6scales .val [0 ])), 3519vmull_s16 (vget_high_s16 (q8sums .val [0 ]),vget_high_s16 (q6scales .val [0 ]))), 3520vaddq_s32 (vmull_s16 (vget_low_s16 (q8sums .val [1 ]),vget_low_s16 (q6scales .val [1 ])), 3521vmull_s16 (vget_high_s16 (q8sums .val [1 ]),vget_high_s16 (q6scales .val [1 ])))); 3522int32_t isum_mins = vaddvq_s32 (prod ); 3523 3524int32_t isum = 0 ; 3525 3526for (int j = 0 ;j < QK_K /128 ;++ j ) { 3527 3528ggml_uint8x16x2_t qhbits = ggml_vld1q_u8_x2 (qh );qh += 32 ; 3529ggml_uint8x16x4_t q6bits = ggml_vld1q_u8_x4 (q6 );q6 += 64 ; 3530ggml_int8x16x4_t q8bytes = ggml_vld1q_s8_x4 (q8 );q8 += 64 ; 3531 3532q6h .val [0 ]= vshlq_n_u8 (vandq_u8 (mone ,qhbits .val [0 ]),4 ); 3533q6h .val [1 ]= vshlq_n_u8 (vandq_u8 (mone ,qhbits .val [1 ]),4 ); 3534uint8x16_t shifted = vshrq_n_u8 (qhbits .val [0 ],2 ); 3535q6h .val [2 ]= vshlq_n_u8 (vandq_u8 (mone ,shifted ),4 ); 3536shifted = vshrq_n_u8 (qhbits .val [1 ],2 ); 3537q6h .val [3 ]= vshlq_n_u8 (vandq_u8 (mone ,shifted ),4 ); 3538 3539//q6bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[0], m4b), q6h.val[0])), m32s); 3540//q6bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[1], m4b), q6h.val[1])), m32s); 3541//q6bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[2], m4b), q6h.val[2])), m32s); 3542//q6bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[3], m4b), q6h.val[3])), m32s); 3543q6bytes .val [0 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (q6bits .val [0 ],m4b ),q6h .val [0 ])); 3544q6bytes .val [1 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (q6bits .val [1 ],m4b ),q6h .val [1 ])); 3545q6bytes .val [2 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (q6bits .val [2 ],m4b ),q6h .val [2 ])); 3546q6bytes .val [3 ]= vreinterpretq_s8_u8 (vorrq_u8 (vandq_u8 (q6bits .val [3 ],m4b ),q6h .val [3 ])); 3547 3548isum += vaddvq_s32 (ggml_vdotq_s32 (vzero ,q6bytes .val [0 ],q8bytes .val [0 ]))* scale [0 ]+ 3549vaddvq_s32 (ggml_vdotq_s32 (vzero ,q6bytes .val [1 ],q8bytes .val [1 ]))* scale [1 ]+ 3550vaddvq_s32 (ggml_vdotq_s32 (vzero ,q6bytes .val [2 ],q8bytes .val [2 ]))* scale [2 ]+ 3551vaddvq_s32 (ggml_vdotq_s32 (vzero ,q6bytes .val [3 ],q8bytes .val [3 ]))* scale [3 ]; 3552 3553scale += 4 ; 3554 3555q8bytes = ggml_vld1q_s8_x4 (q8 );q8 += 64 ; 3556 3557shifted = vshrq_n_u8 (qhbits .val [0 ],4 ); 3558q6h .val [0 ]= vshlq_n_u8 (vandq_u8 (mone ,shifted ),4 ); 3559shifted = vshrq_n_u8 (qhbits .val [1 ],4 ); 3560q6h .val [1 ]= vshlq_n_u8 (vandq_u8 (mone ,shifted ),4 ); 3561shifted = vshrq_n_u8 (qhbits .val [0 ],6 ); 3562q6h .val [2 ]= vshlq_n_u8 (vandq_u8 (mone ,shifted ),4 ); 3563shifted = vshrq_n_u8 (qhbits .val [1 ],6 ); 3564q6h .val [3 ]= vshlq_n_u8 (vandq_u8 (mone ,shifted ),4 ); 3565 3566//q6bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[0], 4), q6h.val[0])), m32s); 3567//q6bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[1], 4), q6h.val[1])), m32s); 3568//q6bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[2], 4), q6h.val[2])), m32s); 3569//q6bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[3], 4), q6h.val[3])), m32s); 3570q6bytes .val [0 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (q6bits .val [0 ],4 ),q6h .val [0 ])); 3571q6bytes .val [1 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (q6bits .val [1 ],4 ),q6h .val [1 ])); 3572q6bytes .val [2 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (q6bits .val [2 ],4 ),q6h .val [2 ])); 3573q6bytes .val [3 ]= vreinterpretq_s8_u8 (vorrq_u8 (vshrq_n_u8 (q6bits .val [3 ],4 ),q6h .val [3 ])); 3574 3575isum += vaddvq_s32 (ggml_vdotq_s32 (vzero ,q6bytes .val [0 ],q8bytes .val [0 ]))* scale [0 ]+ 3576vaddvq_s32 (ggml_vdotq_s32 (vzero ,q6bytes .val [1 ],q8bytes .val [1 ]))* scale [1 ]+ 3577vaddvq_s32 (ggml_vdotq_s32 (vzero ,q6bytes .val [2 ],q8bytes .val [2 ]))* scale [2 ]+ 3578vaddvq_s32 (ggml_vdotq_s32 (vzero ,q6bytes .val [3 ],q8bytes .val [3 ]))* scale [3 ]; 3579scale += 4 ; 3580 } 3581//sum += isum * d_all * y[i].d; 3582sum += d_all * y [i ].d * (isum - 32 * isum_mins ); 3583 3584 } 3585* s = sum ; 3586#else 3587UNUSED (x ); 3588UNUSED (y ); 3589UNUSED (nb ); 3590ggml_vec_dot_q6_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3591#endif 3592} 3593 3594#if defined (__ARM_NEON ) 3595static const int8_t keven_signs_q2xs [1024 ]= { 35961 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,-1 ,1 ,1 ,1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,1 ,1 , 35971 ,1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,-1 , 35981 ,1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,-1 , 35991 ,1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,1 , 36001 ,1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,-1 , 36011 ,1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,1 , 36021 ,1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,1 , 36031 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 , 36041 ,1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,-1 , 36051 ,1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,1 , 36061 ,1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 , 36071 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 , 36081 ,1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,1 , 36091 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 , 36101 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 , 36111 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 , 36121 ,1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,-1 , 36131 ,1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,1 , 36141 ,1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 , 36151 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 , 36161 ,1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 , 36171 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 , 36181 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 , 36191 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 , 36201 ,1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,1 , 36211 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 , 36221 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 , 36231 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 , 36241 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 , 36251 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 , 36261 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 , 36271 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 , 3628}; 3629#endif 3630 3631void 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 ) { 3632assert (n %QK_K == 0 ); 3633assert (nrc == 1 ); 3634UNUSED (nrc ); 3635UNUSED (bx ); 3636UNUSED (by ); 3637UNUSED (bs ); 3638 3639const block_iq2_xxs * GGML_RESTRICT x = vx ; 3640const block_q8_K * GGML_RESTRICT y = vy ; 3641 3642const int nb = n /QK_K ; 3643 3644#if defined(__ARM_NEON ) 3645 3646const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 3647 3648uint32_t aux32 [4 ]; 3649const uint8_t * aux8 = (const uint8_t * )aux32 ; 3650 3651ggml_int8x16x4_t q2u ; 3652ggml_int8x16x4_t q2s ; 3653ggml_int8x16x4_t q8b ; 3654 3655float sumf = 0 ; 3656for (int i = 0 ;i < nb ;++ i ) { 3657const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3658const uint16_t * GGML_RESTRICT q2 = x [i ].qs ; 3659const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3660float sumf1 = 0 ,sumf2 = 0 ; 3661for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 3662q8b = ggml_vld1q_s8_x4 (q8 );q8 += 64 ; 3663memcpy (aux32 ,q2 ,4 * sizeof (uint32_t ));q2 += 8 ; 3664q2u .val [0 ]= vcombine_s8 (vld1_s8 ((const void * )(iq2xxs_grid + aux8 [0 ])),vld1_s8 ((const void * )(iq2xxs_grid + aux8 [1 ]))); 3665q2u .val [1 ]= vcombine_s8 (vld1_s8 ((const void * )(iq2xxs_grid + aux8 [2 ])),vld1_s8 ((const void * )(iq2xxs_grid + aux8 [3 ]))); 3666q2u .val [2 ]= vcombine_s8 (vld1_s8 ((const void * )(iq2xxs_grid + aux8 [8 ])),vld1_s8 ((const void * )(iq2xxs_grid + aux8 [9 ]))); 3667q2u .val [3 ]= vcombine_s8 (vld1_s8 ((const void * )(iq2xxs_grid + aux8 [10 ])),vld1_s8 ((const void * )(iq2xxs_grid + aux8 [11 ]))); 3668q2s .val [0 ]= vcombine_s8 (vld1_s8 ((const void * )(signs64 + ((aux32 [1 ] >>0 )& 127 ))),vld1_s8 ((const void * )(signs64 + ((aux32 [1 ] >>7 )& 127 )))); 3669q2s .val [1 ]= vcombine_s8 (vld1_s8 ((const void * )(signs64 + ((aux32 [1 ] >>14 )& 127 ))),vld1_s8 ((const void * )(signs64 + ((aux32 [1 ] >>21 )& 127 )))); 3670q2s .val [2 ]= vcombine_s8 (vld1_s8 ((const void * )(signs64 + ((aux32 [3 ] >>0 )& 127 ))),vld1_s8 ((const void * )(signs64 + ((aux32 [3 ] >>7 )& 127 )))); 3671q2s .val [3 ]= vcombine_s8 (vld1_s8 ((const void * )(signs64 + ((aux32 [3 ] >>14 )& 127 ))),vld1_s8 ((const void * )(signs64 + ((aux32 [3 ] >>21 )& 127 )))); 3672q2u .val [0 ]= vmulq_s8 (q2u .val [0 ],q2s .val [0 ]); 3673q2u .val [1 ]= vmulq_s8 (q2u .val [1 ],q2s .val [1 ]); 3674q2u .val [2 ]= vmulq_s8 (q2u .val [2 ],q2s .val [2 ]); 3675q2u .val [3 ]= vmulq_s8 (q2u .val [3 ],q2s .val [3 ]); 3676const int32x4_t p1 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q2u .val [0 ],q8b .val [0 ]),q2u .val [1 ],q8b .val [1 ]); 3677const int32x4_t p2 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q2u .val [2 ],q8b .val [2 ]),q2u .val [3 ],q8b .val [3 ]); 3678sumf1 += vaddvq_s32 (p1 )* (0.5f + (aux32 [1 ] >>28 )); 3679sumf2 += vaddvq_s32 (p2 )* (0.5f + (aux32 [3 ] >>28 )); 3680 } 3681sumf += d * (sumf1 + sumf2 ); 3682 } 3683* s = 0.25f * sumf ; 3684 3685#else 3686UNUSED (x ); 3687UNUSED (y ); 3688UNUSED (nb ); 3689ggml_vec_dot_iq2_xxs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3690#endif 3691} 3692 3693void 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 ) { 3694assert (n %QK_K == 0 ); 3695assert (nrc == 1 ); 3696UNUSED (nrc ); 3697UNUSED (bx ); 3698UNUSED (by ); 3699UNUSED (bs ); 3700 3701const block_iq2_xs * GGML_RESTRICT x = vx ; 3702const block_q8_K * GGML_RESTRICT y = vy ; 3703 3704const int nb = n /QK_K ; 3705 3706#if defined(__ARM_NEON ) 3707 3708const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 3709 3710ggml_int8x16x4_t q2u ; 3711ggml_int8x16x4_t q2s ; 3712ggml_int8x16x4_t q8b ; 3713 3714int32x4x4_t scales32 ; 3715 3716float sumf = 0 ; 3717for (int i = 0 ;i < nb ;++ i ) { 3718const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3719const uint16_t * GGML_RESTRICT q2 = x [i ].qs ; 3720const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3721const uint8x8_t scales8 = vld1_u8 (x [i ].scales ); 3722const uint8x8_t scales_l = vand_u8 (scales8 ,vdup_n_u8 (0xf )); 3723const uint8x8_t scales_h = vshr_n_u8 (scales8 ,4 ); 3724uint8x16_t scales = vcombine_u8 (vzip1_u8 (scales_l ,scales_h ),vzip2_u8 (scales_l ,scales_h )); 3725scales = vaddq_u8 (vshlq_n_u8 (scales ,1 ),vdupq_n_u8 (1 )); 3726const uint16x8_t scales1 = vmovl_u8 (vget_low_u8 (scales )); 3727const uint16x8_t scales2 = vmovl_u8 (vget_high_u8 (scales )); 3728scales32 .val [0 ]= vreinterpretq_s32_u32 (vmovl_u16 (vget_low_u16 (scales1 ))); 3729scales32 .val [1 ]= vreinterpretq_s32_u32 (vmovl_u16 (vget_high_u16 (scales1 ))); 3730scales32 .val [2 ]= vreinterpretq_s32_u32 (vmovl_u16 (vget_low_u16 (scales2 ))); 3731scales32 .val [3 ]= vreinterpretq_s32_u32 (vmovl_u16 (vget_high_u16 (scales2 ))); 3732int32x4_t sumi = vdupq_n_s32 (0 ); 3733for (int ib64 = 0 ;ib64 < QK_K /64 ;++ ib64 ) { 3734q8b = ggml_vld1q_s8_x4 (q8 );q8 += 64 ; 3735q2u .val [0 ]= vcombine_s8 (vld1_s8 ((const void * )(iq2xs_grid + (q2 [0 ]& 511 ))),vld1_s8 ((const void * )(iq2xs_grid + (q2 [1 ]& 511 )))); 3736q2u .val [1 ]= vcombine_s8 (vld1_s8 ((const void * )(iq2xs_grid + (q2 [2 ]& 511 ))),vld1_s8 ((const void * )(iq2xs_grid + (q2 [3 ]& 511 )))); 3737q2u .val [2 ]= vcombine_s8 (vld1_s8 ((const void * )(iq2xs_grid + (q2 [4 ]& 511 ))),vld1_s8 ((const void * )(iq2xs_grid + (q2 [5 ]& 511 )))); 3738q2u .val [3 ]= vcombine_s8 (vld1_s8 ((const void * )(iq2xs_grid + (q2 [6 ]& 511 ))),vld1_s8 ((const void * )(iq2xs_grid + (q2 [7 ]& 511 )))); 3739q2s .val [0 ]= vcombine_s8 (vld1_s8 ((const void * )(signs64 + (q2 [0 ] >>9 ))),vld1_s8 ((const void * )(signs64 + (q2 [1 ] >>9 )))); 3740q2s .val [1 ]= vcombine_s8 (vld1_s8 ((const void * )(signs64 + (q2 [2 ] >>9 ))),vld1_s8 ((const void * )(signs64 + (q2 [3 ] >>9 )))); 3741q2s .val [2 ]= vcombine_s8 (vld1_s8 ((const void * )(signs64 + (q2 [4 ] >>9 ))),vld1_s8 ((const void * )(signs64 + (q2 [5 ] >>9 )))); 3742q2s .val [3 ]= vcombine_s8 (vld1_s8 ((const void * )(signs64 + (q2 [6 ] >>9 ))),vld1_s8 ((const void * )(signs64 + (q2 [7 ] >>9 )))); 3743q2u .val [0 ]= vmulq_s8 (q2u .val [0 ],q2s .val [0 ]); 3744q2u .val [1 ]= vmulq_s8 (q2u .val [1 ],q2s .val [1 ]); 3745q2u .val [2 ]= vmulq_s8 (q2u .val [2 ],q2s .val [2 ]); 3746q2u .val [3 ]= vmulq_s8 (q2u .val [3 ],q2s .val [3 ]); 3747const int32x4_t p1 = ggml_vdotq_s32 (vdupq_n_s32 (0 ),q2u .val [0 ],q8b .val [0 ]); 3748const int32x4_t p2 = ggml_vdotq_s32 (vdupq_n_s32 (0 ),q2u .val [1 ],q8b .val [1 ]); 3749const int32x4_t p3 = ggml_vdotq_s32 (vdupq_n_s32 (0 ),q2u .val [2 ],q8b .val [2 ]); 3750const int32x4_t p4 = ggml_vdotq_s32 (vdupq_n_s32 (0 ),q2u .val [3 ],q8b .val [3 ]); 3751const int32x4_t p = vpaddq_s32 (vpaddq_s32 (p1 ,p2 ),vpaddq_s32 (p3 ,p4 )); 3752sumi = vmlaq_s32 (sumi ,p ,scales32 .val [ib64 ]); 3753q2 += 8 ; 3754 } 3755sumf += d * vaddvq_s32 (sumi ); 3756 } 3757* s = 0.125f * sumf ; 3758 3759#else 3760UNUSED (x ); 3761UNUSED (y ); 3762UNUSED (nb ); 3763ggml_vec_dot_iq2_xs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3764#endif 3765} 3766 3767void 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 ) { 3768assert (n %QK_K == 0 ); 3769assert (nrc == 1 ); 3770UNUSED (nrc ); 3771UNUSED (bx ); 3772UNUSED (by ); 3773UNUSED (bs ); 3774 3775const block_iq2_s * GGML_RESTRICT x = vx ; 3776const block_q8_K * GGML_RESTRICT y = vy ; 3777 3778const int nb = n /QK_K ; 3779 3780#if defined(__ARM_NEON ) 3781 3782static const uint8_t k_mask1 [32 ]= {0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 , 37830x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 3784 }; 3785 3786static const uint8_t k_mask2 [16 ]= {0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,}; 3787 3788const ggml_uint8x16x2_t mask1 = ggml_vld1q_u8_x2 (k_mask1 ); 3789const uint8x16_t mask2 = vld1q_u8 (k_mask2 ); 3790const uint8x16_t m1 = vdupq_n_u8 (1 ); 3791const int32x4_t vzero = vdupq_n_s32 (0 ); 3792 3793uint8x16x2_t vs ; 3794ggml_int8x16x4_t q2s ; 3795ggml_int8x16x4_t q8b ; 3796 3797float sumf = 0 ; 3798for (int i = 0 ;i < nb ;++ i ) { 3799 3800const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3801 3802const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 3803const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 3804const uint16_t * GGML_RESTRICT signs = (const uint16_t * )(x [i ].qs + QK_K /8 ); 3805const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3806 3807int sumi1 = 0 ,sumi2 = 0 ; 3808for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 3809q8b = ggml_vld1q_s8_x4 (q8 );q8 += 64 ; 3810q2s .val [0 ]= vcombine_s8 (vld1_s8 ((const int8_t * )(iq2s_grid + (qs [0 ] | ((qh [ib32 + 0 ] <<8 )& 0x300 )))), 3811vld1_s8 ((const int8_t * )(iq2s_grid + (qs [1 ] | ((qh [ib32 + 0 ] <<6 )& 0x300 ))))); 3812q2s .val [1 ]= vcombine_s8 (vld1_s8 ((const int8_t * )(iq2s_grid + (qs [2 ] | ((qh [ib32 + 0 ] <<4 )& 0x300 )))), 3813vld1_s8 ((const int8_t * )(iq2s_grid + (qs [3 ] | ((qh [ib32 + 0 ] <<2 )& 0x300 ))))); 3814q2s .val [2 ]= vcombine_s8 (vld1_s8 ((const int8_t * )(iq2s_grid + (qs [4 ] | ((qh [ib32 + 1 ] <<8 )& 0x300 )))), 3815vld1_s8 ((const int8_t * )(iq2s_grid + (qs [5 ] | ((qh [ib32 + 1 ] <<6 )& 0x300 ))))); 3816q2s .val [3 ]= vcombine_s8 (vld1_s8 ((const int8_t * )(iq2s_grid + (qs [6 ] | ((qh [ib32 + 1 ] <<4 )& 0x300 )))), 3817vld1_s8 ((const int8_t * )(iq2s_grid + (qs [7 ] | ((qh [ib32 + 1 ] <<2 )& 0x300 ))))); 3818qs += 8 ; 3819 3820vs .val [0 ]= vreinterpretq_u8_u32 (vdupq_n_u32 (signs [0 ] | ((uint32_t )signs [1 ] <<16 ))); 3821vs .val [1 ]= vandq_u8 (ggml_vqtbl1q_u8 (vs .val [0 ],mask1 .val [1 ]),mask2 ); 3822vs .val [0 ]= vandq_u8 (ggml_vqtbl1q_u8 (vs .val [0 ],mask1 .val [0 ]),mask2 ); 3823vs .val [0 ]= vceqq_u8 (vs .val [0 ],mask2 ); 3824vs .val [1 ]= vceqq_u8 (vs .val [1 ],mask2 ); 3825 3826q2s .val [0 ]= vmulq_s8 (vreinterpretq_s8_u8 (vorrq_u8 (vs .val [0 ],m1 )),q2s .val [0 ]); 3827q2s .val [1 ]= vmulq_s8 (vreinterpretq_s8_u8 (vorrq_u8 (vs .val [1 ],m1 )),q2s .val [1 ]); 3828 3829vs .val [0 ]= vreinterpretq_u8_u32 (vdupq_n_u32 (signs [2 ] | ((uint32_t )signs [3 ] <<16 ))); 3830vs .val [1 ]= vandq_u8 (ggml_vqtbl1q_u8 (vs .val [0 ],mask1 .val [1 ]),mask2 ); 3831vs .val [0 ]= vandq_u8 (ggml_vqtbl1q_u8 (vs .val [0 ],mask1 .val [0 ]),mask2 ); 3832vs .val [0 ]= vceqq_u8 (vs .val [0 ],mask2 ); 3833vs .val [1 ]= vceqq_u8 (vs .val [1 ],mask2 ); 3834 3835signs += 4 ; 3836 3837q2s .val [2 ]= vmulq_s8 (vreinterpretq_s8_u8 (vorrq_u8 (vs .val [0 ],m1 )),q2s .val [2 ]); 3838q2s .val [3 ]= vmulq_s8 (vreinterpretq_s8_u8 (vorrq_u8 (vs .val [1 ],m1 )),q2s .val [3 ]); 3839 3840const int32x4_t p1 = ggml_vdotq_s32 (vzero ,q2s .val [0 ],q8b .val [0 ]); 3841const int32x4_t p2 = ggml_vdotq_s32 (vzero ,q2s .val [1 ],q8b .val [1 ]); 3842const int32x4_t p3 = ggml_vdotq_s32 (vzero ,q2s .val [2 ],q8b .val [2 ]); 3843const int32x4_t p4 = ggml_vdotq_s32 (vzero ,q2s .val [3 ],q8b .val [3 ]); 3844 3845sumi1 += vaddvq_s32 (p1 )* (1 + 2 * (x [i ].scales [ib32 + 0 ]& 0xf )); 3846sumi2 += vaddvq_s32 (p2 )* (1 + 2 * (x [i ].scales [ib32 + 0 ] >>4 )); 3847sumi1 += vaddvq_s32 (p3 )* (1 + 2 * (x [i ].scales [ib32 + 1 ]& 0xf )); 3848sumi2 += vaddvq_s32 (p4 )* (1 + 2 * (x [i ].scales [ib32 + 1 ] >>4 )); 3849 } 3850sumf += d * (sumi1 + sumi2 ); 3851 } 3852 3853* s = 0.125f * sumf ; 3854 3855#else 3856UNUSED (x ); 3857UNUSED (y ); 3858UNUSED (nb ); 3859ggml_vec_dot_iq2_s_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3860#endif 3861 3862} 3863 3864void 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 ) { 3865assert (n %QK_K == 0 ); 3866assert (nrc == 1 ); 3867UNUSED (nrc ); 3868UNUSED (bx ); 3869UNUSED (by ); 3870UNUSED (bs ); 3871 3872const block_iq3_xxs * GGML_RESTRICT x = vx ; 3873const block_q8_K * GGML_RESTRICT y = vy ; 3874 3875const int nb = n /QK_K ; 3876 3877#if defined(__ARM_NEON ) 3878 3879const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 3880 3881uint32_t aux32 [2 ]; 3882 3883ggml_int8x16x4_t q3s ; 3884ggml_int8x16x4_t q8b ; 3885 3886float sumf = 0 ; 3887for (int i = 0 ;i < nb ;++ i ) { 3888const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3889const uint8_t * GGML_RESTRICT q3 = x [i ].qs ; 3890const uint8_t * GGML_RESTRICT gas = x [i ].qs + QK_K /4 ; 3891const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3892float sumf1 = 0 ,sumf2 = 0 ; 3893for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 3894q8b = ggml_vld1q_s8_x4 (q8 );q8 += 64 ; 3895memcpy (aux32 ,gas ,2 * sizeof (uint32_t ));gas += 2 * sizeof (uint32_t ); 3896const uint32x4_t aux32x4_0 = ggml_vld1q_u32 (iq3xxs_grid [q3 [0 ]],iq3xxs_grid [q3 [1 ]],iq3xxs_grid [q3 [2 ]],iq3xxs_grid [q3 [3 ]]); 3897const uint32x4_t aux32x4_1 = ggml_vld1q_u32 (iq3xxs_grid [q3 [4 ]],iq3xxs_grid [q3 [5 ]],iq3xxs_grid [q3 [6 ]],iq3xxs_grid [q3 [7 ]]); 3898const uint32x4_t aux32x4_2 = ggml_vld1q_u32 (iq3xxs_grid [q3 [8 ]],iq3xxs_grid [q3 [9 ]],iq3xxs_grid [q3 [10 ]],iq3xxs_grid [q3 [11 ]]); 3899const uint32x4_t aux32x4_3 = ggml_vld1q_u32 (iq3xxs_grid [q3 [12 ]],iq3xxs_grid [q3 [13 ]],iq3xxs_grid [q3 [14 ]],iq3xxs_grid [q3 [15 ]]); 3900q3 += 16 ; 3901q3s .val [0 ]= vcombine_s8 (vld1_s8 ((const void * )(signs64 + ((aux32 [0 ] >>0 )& 127 ))),vld1_s8 ((const void * )(signs64 + ((aux32 [0 ] >>7 )& 127 )))); 3902q3s .val [1 ]= vcombine_s8 (vld1_s8 ((const void * )(signs64 + ((aux32 [0 ] >>14 )& 127 ))),vld1_s8 ((const void * )(signs64 + ((aux32 [0 ] >>21 )& 127 )))); 3903q3s .val [2 ]= vcombine_s8 (vld1_s8 ((const void * )(signs64 + ((aux32 [1 ] >>0 )& 127 ))),vld1_s8 ((const void * )(signs64 + ((aux32 [1 ] >>7 )& 127 )))); 3904q3s .val [3 ]= vcombine_s8 (vld1_s8 ((const void * )(signs64 + ((aux32 [1 ] >>14 )& 127 ))),vld1_s8 ((const void * )(signs64 + ((aux32 [1 ] >>21 )& 127 )))); 3905q3s .val [0 ]= vmulq_s8 (q3s .val [0 ],vreinterpretq_s8_u32 (aux32x4_0 )); 3906q3s .val [1 ]= vmulq_s8 (q3s .val [1 ],vreinterpretq_s8_u32 (aux32x4_1 )); 3907q3s .val [2 ]= vmulq_s8 (q3s .val [2 ],vreinterpretq_s8_u32 (aux32x4_2 )); 3908q3s .val [3 ]= vmulq_s8 (q3s .val [3 ],vreinterpretq_s8_u32 (aux32x4_3 )); 3909const int32x4_t p1 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q3s .val [0 ],q8b .val [0 ]),q3s .val [1 ],q8b .val [1 ]); 3910const int32x4_t p2 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q3s .val [2 ],q8b .val [2 ]),q3s .val [3 ],q8b .val [3 ]); 3911sumf1 += vaddvq_s32 (p1 )* (0.5f + (aux32 [0 ] >>28 )); 3912sumf2 += vaddvq_s32 (p2 )* (0.5f + (aux32 [1 ] >>28 )); 3913 } 3914sumf += d * (sumf1 + sumf2 ); 3915 } 3916* s = 0.5f * sumf ; 3917 3918#else 3919UNUSED (x ); 3920UNUSED (y ); 3921UNUSED (nb ); 3922ggml_vec_dot_iq3_xxs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3923#endif 3924} 3925 3926void 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 ) { 3927assert (n %QK_K == 0 ); 3928assert (nrc == 1 ); 3929UNUSED (nrc ); 3930UNUSED (bx ); 3931UNUSED (by ); 3932UNUSED (bs ); 3933 3934const block_iq3_s * GGML_RESTRICT x = vx ; 3935const block_q8_K * GGML_RESTRICT y = vy ; 3936 3937const int nb = n /QK_K ; 3938 3939#if defined(__ARM_NEON ) 3940 3941typedef union { 3942uint16x8_t vec_index ; 3943uint16_t index [8 ]; 3944 }vec_index_t ; 3945 3946static const uint8_t k_mask1 [32 ]= {0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 , 39470x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 3948 }; 3949 3950static const uint8_t k_mask2 [16 ]= {0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,}; 3951 3952static const int16_t k_shift [8 ]= {8 ,7 ,6 ,5 ,4 ,3 ,2 ,1 }; 3953 3954const ggml_uint8x16x2_t mask1 = ggml_vld1q_u8_x2 (k_mask1 ); 3955const uint8x16_t mask2 = vld1q_u8 (k_mask2 ); 3956 3957const int16x8_t hshift = vld1q_s16 (k_shift ); 3958const uint16x8_t m256 = vdupq_n_u16 (256 ); 3959const uint8x16_t m1 = vdupq_n_u8 (1 ); 3960 3961uint8x16x2_t vs ; 3962ggml_int8x16x4_t q3s ; 3963ggml_int8x16x4_t q8b ; 3964vec_index_t idx ; 3965 3966uint32_t scales32 [2 ]; 3967const uint8_t * scales8 = (const uint8_t * )scales32 ; 3968 3969float sumf = 0 ; 3970for (int i = 0 ;i < nb ;++ i ) { 3971const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3972const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 3973const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 3974const uint16_t * GGML_RESTRICT signs = (const uint16_t * )x [i ].signs ; 3975const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3976 3977memcpy (scales32 ,x [i ].scales ,4 ); 3978scales32 [1 ]= (((scales32 [0 ] >>4 )& 0x0f0f0f0f ) <<1 ) |0x01010101 ; 3979scales32 [0 ]= ((scales32 [0 ]& 0x0f0f0f0f ) <<1 ) |0x01010101 ; 3980 3981int sumi1 = 0 ,sumi2 = 0 ; 3982for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 3983q8b = ggml_vld1q_s8_x4 (q8 );q8 += 64 ; 3984 3985const uint8x16_t idx_l = vld1q_u8 (qs );qs += 16 ; 3986idx .vec_index = vorrq_u16 (vmovl_u8 (vget_low_u8 (idx_l )),vandq_u16 (vshlq_u16 (vdupq_n_u16 (qh [ib32 + 0 ]),hshift ),m256 )); 3987const uint32x4_t aux32x4_0 = ggml_vld1q_u32 (iq3s_grid [idx .index [0 ]],iq3s_grid [idx .index [1 ]], 3988iq3s_grid [idx .index [2 ]],iq3s_grid [idx .index [3 ]]); 3989const uint32x4_t aux32x4_1 = ggml_vld1q_u32 (iq3s_grid [idx .index [4 ]],iq3s_grid [idx .index [5 ]], 3990iq3s_grid [idx .index [6 ]],iq3s_grid [idx .index [7 ]]); 3991idx .vec_index = vorrq_u16 (vmovl_u8 (vget_high_u8 (idx_l )),vandq_u16 (vshlq_u16 (vdupq_n_u16 (qh [ib32 + 1 ]),hshift ),m256 )); 3992const uint32x4_t aux32x4_2 = ggml_vld1q_u32 (iq3s_grid [idx .index [0 ]],iq3s_grid [idx .index [1 ]], 3993iq3s_grid [idx .index [2 ]],iq3s_grid [idx .index [3 ]]); 3994const uint32x4_t aux32x4_3 = ggml_vld1q_u32 (iq3s_grid [idx .index [4 ]],iq3s_grid [idx .index [5 ]], 3995iq3s_grid [idx .index [6 ]],iq3s_grid [idx .index [7 ]]); 3996 3997 3998vs .val [0 ]= vreinterpretq_u8_u32 (vdupq_n_u32 (signs [0 ] | ((uint32_t )signs [1 ] <<16 ))); 3999vs .val [1 ]= vandq_u8 (ggml_vqtbl1q_u8 (vs .val [0 ],mask1 .val [1 ]),mask2 ); 4000vs .val [0 ]= vandq_u8 (ggml_vqtbl1q_u8 (vs .val [0 ],mask1 .val [0 ]),mask2 ); 4001vs .val [0 ]= vorrq_u8 (vceqq_u8 (vs .val [0 ],mask2 ),m1 ); 4002vs .val [1 ]= vorrq_u8 (vceqq_u8 (vs .val [1 ],mask2 ),m1 ); 4003 4004q3s .val [0 ]= vmulq_s8 (vreinterpretq_s8_u8 (vs .val [0 ]),vreinterpretq_s8_u32 (aux32x4_0 )); 4005q3s .val [1 ]= vmulq_s8 (vreinterpretq_s8_u8 (vs .val [1 ]),vreinterpretq_s8_u32 (aux32x4_1 )); 4006 4007vs .val [0 ]= vreinterpretq_u8_u32 (vdupq_n_u32 (signs [2 ] | ((uint32_t )signs [3 ] <<16 ))); 4008vs .val [1 ]= vandq_u8 (ggml_vqtbl1q_u8 (vs .val [0 ],mask1 .val [1 ]),mask2 ); 4009vs .val [0 ]= vandq_u8 (ggml_vqtbl1q_u8 (vs .val [0 ],mask1 .val [0 ]),mask2 ); 4010vs .val [0 ]= vorrq_u8 (vceqq_u8 (vs .val [0 ],mask2 ),m1 ); 4011vs .val [1 ]= vorrq_u8 (vceqq_u8 (vs .val [1 ],mask2 ),m1 ); 4012 4013signs += 4 ; 4014 4015q3s .val [2 ]= vmulq_s8 (vreinterpretq_s8_u8 (vs .val [0 ]),vreinterpretq_s8_u32 (aux32x4_2 )); 4016q3s .val [3 ]= vmulq_s8 (vreinterpretq_s8_u8 (vs .val [1 ]),vreinterpretq_s8_u32 (aux32x4_3 )); 4017 4018const int32x4_t p1 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q3s .val [0 ],q8b .val [0 ]),q3s .val [1 ],q8b .val [1 ]); 4019const int32x4_t p2 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q3s .val [2 ],q8b .val [2 ]),q3s .val [3 ],q8b .val [3 ]); 4020 4021sumi1 += vaddvq_s32 (p1 )* scales8 [ib32 /2 + 0 ]; 4022sumi2 += vaddvq_s32 (p2 )* scales8 [ib32 /2 + 4 ]; 4023 } 4024sumf += d * (sumi1 + sumi2 ); 4025 } 4026* s = sumf ; 4027 4028#else 4029UNUSED (x ); 4030UNUSED (y ); 4031UNUSED (nb ); 4032ggml_vec_dot_iq3_s_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4033#endif 4034} 4035 4036void 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 ) { 4037assert (n %QK_K == 0 ); 4038assert (nrc == 1 ); 4039UNUSED (nrc ); 4040UNUSED (bx ); 4041UNUSED (by ); 4042UNUSED (bs ); 4043 4044const block_iq1_s * GGML_RESTRICT x = vx ; 4045const block_q8_K * GGML_RESTRICT y = vy ; 4046 4047const int nb = n /QK_K ; 4048 4049#if defined__ARM_NEON 4050 4051ggml_int8x16x4_t q1b ; 4052ggml_int8x16x4_t q8b ; 4053 4054float sumf = 0 ; 4055for (int i = 0 ;i < nb ;++ i ) { 4056 4057const int8_t * q8 = y [i ].qs ; 4058const uint8_t * qs = x [i ].qs ; 4059const uint16_t * qh = x [i ].qh ; 4060 4061int sumi1 = 0 ,sumi2 = 0 ,sumi3 = 0 ; 4062 4063for (int ib = 0 ;ib < QK_K /32 ;ib += 2 ) { 4064 4065q1b .val [0 ]= vcombine_s8 (vld1_s8 ((const int8_t * )(iq1s_grid + (qs [0 ] | ((qh [ib + 0 ] <<8 )& 0x700 )))), 4066vld1_s8 ((const int8_t * )(iq1s_grid + (qs [1 ] | ((qh [ib + 0 ] <<5 )& 0x700 ))))); 4067q1b .val [1 ]= vcombine_s8 (vld1_s8 ((const int8_t * )(iq1s_grid + (qs [2 ] | ((qh [ib + 0 ] <<2 )& 0x700 )))), 4068vld1_s8 ((const int8_t * )(iq1s_grid + (qs [3 ] | ((qh [ib + 0 ] >>1 )& 0x700 ))))); 4069q1b .val [2 ]= vcombine_s8 (vld1_s8 ((const int8_t * )(iq1s_grid + (qs [4 ] | ((qh [ib + 1 ] <<8 )& 0x700 )))), 4070vld1_s8 ((const int8_t * )(iq1s_grid + (qs [5 ] | ((qh [ib + 1 ] <<5 )& 0x700 ))))); 4071q1b .val [3 ]= vcombine_s8 (vld1_s8 ((const int8_t * )(iq1s_grid + (qs [6 ] | ((qh [ib + 1 ] <<2 )& 0x700 )))), 4072vld1_s8 ((const int8_t * )(iq1s_grid + (qs [7 ] | ((qh [ib + 1 ] >>1 )& 0x700 ))))); 4073qs += 8 ; 4074 4075q8b = ggml_vld1q_s8_x4 (q8 );q8 += 64 ; 4076 4077const int32x4_t p1 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q1b .val [0 ],q8b .val [0 ]),q1b .val [1 ],q8b .val [1 ]); 4078const int32x4_t p2 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q1b .val [2 ],q8b .val [2 ]),q1b .val [3 ],q8b .val [3 ]); 4079 4080const int ls1 = 2 * ((qh [ib + 0 ] >>12 )& 7 )+ 1 ; 4081const int ls2 = 2 * ((qh [ib + 1 ] >>12 )& 7 )+ 1 ; 4082sumi1 += vaddvq_s32 (p1 )* ls1 ; 4083sumi2 += vaddvq_s32 (p2 )* ls2 ; 4084sumi3 += (y [i ].bsums [2 * ib + 0 ]+ y [i ].bsums [2 * ib + 1 ])* ls1 * (qh [ib + 0 ]& 0x8000 ?-1 :1 ) 4085+ (y [i ].bsums [2 * ib + 2 ]+ y [i ].bsums [2 * ib + 3 ])* ls2 * (qh [ib + 1 ]& 0x8000 ?-1 :1 ); 4086 4087 } 4088 4089sumf += y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d )* (sumi1 + sumi2 + IQ1S_DELTA * sumi3 ); 4090 } 4091 4092* s = sumf ; 4093 4094#else 4095UNUSED (x ); 4096UNUSED (y ); 4097UNUSED (nb ); 4098ggml_vec_dot_iq1_s_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4099#endif 4100} 4101 4102void 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 ) { 4103assert (n %QK_K == 0 ); 4104assert (nrc == 1 ); 4105UNUSED (nrc ); 4106UNUSED (bx ); 4107UNUSED (by ); 4108UNUSED (bs ); 4109 4110const block_iq1_m * GGML_RESTRICT x = vx ; 4111const block_q8_K * GGML_RESTRICT y = vy ; 4112 4113const int nb = n /QK_K ; 4114 4115iq1m_scale_t scale ; 4116 4117#if defined__ARM_NEON 4118const int32x4_t mask = vdupq_n_s32 (0x7 ); 4119const int32x4_t mone = vdupq_n_s32 (1 ); 4120const int32x4_t mzero = vdupq_n_s32 (0 ); 4121 4122ggml_int8x16x4_t deltas ; 4123deltas .val [0 ]= vcombine_s8 (vdup_n_s8 (+1 ),vdup_n_s8 (+1 )); 4124deltas .val [1 ]= vcombine_s8 (vdup_n_s8 (-1 ),vdup_n_s8 (+1 )); 4125deltas .val [2 ]= vcombine_s8 (vdup_n_s8 (+1 ),vdup_n_s8 (-1 )); 4126deltas .val [3 ]= vcombine_s8 (vdup_n_s8 (-1 ),vdup_n_s8 (-1 )); 4127 4128ggml_int8x16x4_t q1b ; 4129ggml_int8x16x4_t q8b ; 4130 4131uint32_t aux32 ; 4132const uint8_t * aux8 = (const uint8_t * )& aux32 ; 4133 4134float sumf = 0 ; 4135for (int i = 0 ;i < nb ;++ i ) { 4136 4137const int8_t * q8 = y [i ].qs ; 4138const uint8_t * qs = x [i ].qs ; 4139const uint8_t * qh = x [i ].qh ; 4140const uint16_t * sc = (const uint16_t * )x [i ].scales ; 4141 4142scale .u16 = (sc [0 ] >>12 ) | ((sc [1 ] >>8 )& 0x00f0 ) | ((sc [2 ] >>4 )& 0x0f00 ) | (sc [3 ]& 0xf000 ); 4143 4144int32x4_t sumi1 = mzero ; 4145int32x4_t sumi2 = mzero ; 4146 4147for (int ib = 0 ;ib < QK_K /32 ;ib += 2 ) { 4148 4149q1b .val [0 ]= vcombine_s8 (vld1_s8 ((const int8_t * )(iq1s_grid + (qs [0 ] | ((qh [0 ] <<8 )& 0x700 )))), 4150vld1_s8 ((const int8_t * )(iq1s_grid + (qs [1 ] | ((qh [0 ] <<4 )& 0x700 ))))); 4151q1b .val [1 ]= vcombine_s8 (vld1_s8 ((const int8_t * )(iq1s_grid + (qs [2 ] | ((qh [1 ] <<8 )& 0x700 )))), 4152vld1_s8 ((const int8_t * )(iq1s_grid + (qs [3 ] | ((qh [1 ] <<4 )& 0x700 ))))); 4153q1b .val [2 ]= vcombine_s8 (vld1_s8 ((const int8_t * )(iq1s_grid + (qs [4 ] | ((qh [2 ] <<8 )& 0x700 )))), 4154vld1_s8 ((const int8_t * )(iq1s_grid + (qs [5 ] | ((qh [2 ] <<4 )& 0x700 ))))); 4155q1b .val [3 ]= vcombine_s8 (vld1_s8 ((const int8_t * )(iq1s_grid + (qs [6 ] | ((qh [3 ] <<8 )& 0x700 )))), 4156vld1_s8 ((const int8_t * )(iq1s_grid + (qs [7 ] | ((qh [3 ] <<4 )& 0x700 ))))); 4157 4158q8b = ggml_vld1q_s8_x4 (q8 );q8 += 64 ; 4159 4160const int32x4_t p1 = vpaddq_s32 (ggml_vdotq_s32 (mzero ,q1b .val [0 ],q8b .val [0 ]),ggml_vdotq_s32 (mzero ,q1b .val [1 ],q8b .val [1 ])); 4161const int32x4_t p2 = vpaddq_s32 (ggml_vdotq_s32 (mzero ,q1b .val [2 ],q8b .val [2 ]),ggml_vdotq_s32 (mzero ,q1b .val [3 ],q8b .val [3 ])); 4162const int32x4_t p12 = vpaddq_s32 (p1 ,p2 ); 4163 4164const uint32_t * qh32 = (const uint32_t * )qh ;// we are 4-byte aligned, so we can do that 4165aux32 = ((qh32 [0 ] >>3 )& 0x01010101 ) | ((qh32 [0 ] >>6 )& 0x02020202 ); 4166 4167const int32x4_t p3 = vpaddq_s32 (ggml_vdotq_s32 (mzero ,deltas .val [aux8 [0 ]],q8b .val [0 ]),ggml_vdotq_s32 (mzero ,deltas .val [aux8 [1 ]],q8b .val [1 ])); 4168const int32x4_t p4 = vpaddq_s32 (ggml_vdotq_s32 (mzero ,deltas .val [aux8 [2 ]],q8b .val [2 ]),ggml_vdotq_s32 (mzero ,deltas .val [aux8 [3 ]],q8b .val [3 ])); 4169const int32x4_t p34 = vpaddq_s32 (p3 ,p4 ); 4170 4171int32x4_t scales_4 = ggml_vld1q_u32 (sc [ib /2 ] >>0 ,sc [ib /2 ] >>3 ,sc [ib /2 ] >>6 ,sc [ib /2 ] >>9 ); 4172 4173scales_4 = vaddq_s32 (vshlq_n_s32 (vandq_s32 (scales_4 ,mask ),1 ),mone ); 4174 4175sumi1 = vmlaq_s32 (sumi1 ,scales_4 ,p12 ); 4176sumi2 = vmlaq_s32 (sumi2 ,scales_4 ,p34 ); 4177 4178qs += 8 ;qh += 4 ; 4179 4180 } 4181 4182sumf += y [i ].d * GGML_CPU_FP16_TO_FP32 (scale .f16 )* (vaddvq_s32 (sumi1 )+ IQ1M_DELTA * vaddvq_s32 (sumi2 )); 4183 } 4184 4185* s = sumf ; 4186 4187#else 4188UNUSED (x ); 4189UNUSED (y ); 4190UNUSED (nb ); 4191UNUSED (scale ); 4192ggml_vec_dot_iq1_m_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4193#endif 4194} 4195 4196void 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 ) { 4197assert (nrc == 1 ); 4198UNUSED (nrc ); 4199UNUSED (bx ); 4200UNUSED (by ); 4201UNUSED (bs ); 4202assert (n %QK4_NL == 0 ); 4203static_assert (QK4_NL == QK8_0 ,"QK4_NL and QK8_0 must be the same" ); 4204 4205const block_iq4_nl * GGML_RESTRICT x = vx ; 4206const block_q8_0 * GGML_RESTRICT y = vy ; 4207 4208const int nb = n /QK4_NL ; 4209 4210int ib = 0 ; 4211float sumf = 0 ; 4212 4213#if defined__ARM_NEON 4214const int8x16_t values = vld1q_s8 (kvalues_iq4nl ); 4215const uint8x16_t m4b = vdupq_n_u8 (0x0f ); 4216uint8x16x2_t q4bits ; 4217int8x16x4_t q4b ; 4218int8x16x4_t q8b ; 4219int32x4_t prod_1 ,prod_2 ; 4220 4221for (;ib + 1 < nb ;ib += 2 ) { 4222 4223q4bits .val [0 ]= vld1q_u8 (x [ib + 0 ].qs ); 4224q4bits .val [1 ]= vld1q_u8 (x [ib + 1 ].qs ); 4225q8b .val [0 ]= vld1q_s8 (y [ib + 0 ].qs ); 4226q8b .val [1 ]= vld1q_s8 (y [ib + 0 ].qs + 16 ); 4227q8b .val [2 ]= vld1q_s8 (y [ib + 1 ].qs ); 4228q8b .val [3 ]= vld1q_s8 (y [ib + 1 ].qs + 16 ); 4229 4230q4b .val [0 ]= ggml_vqtbl1q_s8 (values ,vandq_u8 (q4bits .val [0 ],m4b )); 4231q4b .val [1 ]= ggml_vqtbl1q_s8 (values ,vshrq_n_u8 (q4bits .val [0 ],4 )); 4232q4b .val [2 ]= ggml_vqtbl1q_s8 (values ,vandq_u8 (q4bits .val [1 ],m4b )); 4233q4b .val [3 ]= ggml_vqtbl1q_s8 (values ,vshrq_n_u8 (q4bits .val [1 ],4 )); 4234 4235prod_1 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q4b .val [0 ],q8b .val [0 ]),q4b .val [1 ],q8b .val [1 ]); 4236prod_2 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q4b .val [2 ],q8b .val [2 ]),q4b .val [3 ],q8b .val [3 ]); 4237 4238sumf += 4239GGML_CPU_FP16_TO_FP32 (x [ib + 0 ].d )* GGML_CPU_FP16_TO_FP32 (y [ib + 0 ].d )* vaddvq_s32 (prod_1 )+ 4240GGML_CPU_FP16_TO_FP32 (x [ib + 1 ].d )* GGML_CPU_FP16_TO_FP32 (y [ib + 1 ].d )* vaddvq_s32 (prod_2 ); 4241 } 4242 4243#endif 4244for (;ib < nb ;++ ib ) { 4245const float d = GGML_CPU_FP16_TO_FP32 (y [ib ].d )* GGML_CPU_FP16_TO_FP32 (x [ib ].d ); 4246int sumi1 = 0 ,sumi2 = 0 ; 4247for (int j = 0 ;j < QK4_NL /2 ;++ j ) { 4248sumi1 += y [ib ].qs [j + 0 ]* kvalues_iq4nl [x [ib ].qs [j ]& 0xf ]; 4249sumi2 += y [ib ].qs [j + QK4_NL /2 ]* kvalues_iq4nl [x [ib ].qs [j ] >>4 ]; 4250 } 4251sumf += d * (sumi1 + sumi2 ); 4252 } 4253* s = sumf ; 4254} 4255 4256void 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 ) { 4257assert (nrc == 1 ); 4258UNUSED (nrc ); 4259UNUSED (bx ); 4260UNUSED (by ); 4261UNUSED (bs ); 4262assert (n %QK_K == 0 ); 4263 4264const block_iq4_xs * GGML_RESTRICT x = vx ; 4265const block_q8_K * GGML_RESTRICT y = vy ; 4266 4267const int nb = n /QK_K ; 4268 4269#if defined__ARM_NEON 4270const int8x16_t values = vld1q_s8 (kvalues_iq4nl ); 4271const uint8x16_t m4b = vdupq_n_u8 (0x0f ); 4272ggml_uint8x16x2_t q4bits ; 4273ggml_int8x16x4_t q4b ; 4274ggml_int8x16x4_t q8b ; 4275int32x4_t prod_1 ,prod_2 ; 4276 4277float sumf = 0 ; 4278 4279for (int ibl = 0 ;ibl < nb ;++ ibl ) { 4280 4281const int8_t * q8 = y [ibl ].qs ; 4282const uint8_t * q4 = x [ibl ].qs ; 4283uint16_t h = x [ibl ].scales_h ; 4284 4285int sumi1 = 0 ,sumi2 = 0 ; 4286for (int ib = 0 ;ib < QK_K /64 ;++ ib ) { 4287 4288q4bits = ggml_vld1q_u8_x2 (q4 );q4 += 32 ; 4289q8b = ggml_vld1q_s8_x4 (q8 );q8 += 64 ; 4290 4291q4b .val [0 ]= ggml_vqtbl1q_s8 (values ,vandq_u8 (q4bits .val [0 ],m4b )); 4292q4b .val [1 ]= ggml_vqtbl1q_s8 (values ,vshrq_n_u8 (q4bits .val [0 ],4 )); 4293q4b .val [2 ]= ggml_vqtbl1q_s8 (values ,vandq_u8 (q4bits .val [1 ],m4b )); 4294q4b .val [3 ]= ggml_vqtbl1q_s8 (values ,vshrq_n_u8 (q4bits .val [1 ],4 )); 4295 4296prod_1 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q4b .val [0 ],q8b .val [0 ]),q4b .val [1 ],q8b .val [1 ]); 4297prod_2 = ggml_vdotq_s32 (ggml_vdotq_s32 (vdupq_n_s32 (0 ),q4b .val [2 ],q8b .val [2 ]),q4b .val [3 ],q8b .val [3 ]); 4298 4299int ls1 = ((x [ibl ].scales_l [ib ]& 0xf ) | ((h <<4 )& 0x30 ))- 32 ; 4300int ls2 = ((x [ibl ].scales_l [ib ] >>4 ) | ((h <<2 )& 0x30 ))- 32 ; 4301h >>=4 ; 4302sumi1 += vaddvq_s32 (prod_1 )* ls1 ; 4303sumi2 += vaddvq_s32 (prod_2 )* ls2 ; 4304 4305 } 4306 4307sumf += GGML_CPU_FP16_TO_FP32 (x [ibl ].d )* y [ibl ].d * (sumi1 + sumi2 ); 4308 } 4309 4310* s = sumf ; 4311 4312#else 4313UNUSED (x ); 4314UNUSED (y ); 4315UNUSED (nb ); 4316ggml_vec_dot_iq4_xs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4317#endif 4318} 4319