char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
4ea6d1bb6
char/aliceai-t5-moe
1#define GGML_COMMON_IMPL_CPP 2#define GGML_COMMON_DECL_CPP 3#include "ggml-common.h" 4#include "ggml-backend-impl.h" 5 6#include "ggml-impl.h" 7#include "ggml-cpu.h" 8#include "ggml-cpu-impl.h" 9#include "simd-mappings.h" 10#include "traits.h" 11 12#include "arch-fallback.h" 13 14#include <cmath> 15#include <cstring> 16#include <cassert> 17#include <cstdio> // for GGML_ASSERT 18 19#include "repack.h" 20 21#if defined(__GNUC__ ) 22#pragma GCC diagnostic ignored "-Woverlength-strings" 23#endif 24 25#define UNUSED GGML_UNUSED 26 27static inline int nearest_int (float fval ) { 28assert (fabsf (fval ) <=4194303.f ); 29float val = fval + 12582912.f ; 30int i ;memcpy (& i ,& val ,sizeof (int )); 31return (i & 0x007fffff )- 0x00400000 ; 32} 33 34// Functions to create the interleaved data layout formats 35 36// interleave 4 block_q4_0s in blocks of blck_size_interleave 37// returns an interleaved block_q4_0x4 38// in the interleaved block_q4_0x4, place deltas for 4 block_q4_0 blocks 39// first, then interleave quants from 4 block_q4_0s in blocks of blck_size_interleave 40// 41// - in : an array of block_q4_0 pointers 42// - blck_size_interleave : the block_q4_0 quants bytes are interleaved in blocks of 43// blck_size_interleave bytes 44// - xor_mask : the mask to convert the nibbles in block_q4_0 quants bytes 45// from bias offset form to pure sign form (this saves subtract 46// operations durin unpacking) 47// 48 49extern "C" { 50 51#if defined__riscv_zvfh 52void ggml_quantize_mat_q8_0_4x1_generic (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t k ) { 53assert (QK8_0 == 32 ); 54assert (k %QK8_0 == 0 ); 55const int nb = k /QK8_0 ; 56 57block_q8_0x4 * GGML_RESTRICT y = (block_q8_0x4 * )vy ; 58 59// scalar 60const int blck_size_interleave = 1 ; 61float srcv [4 ][QK8_0 ]; 62float id [4 ]; 63 64for (int i = 0 ;i < nb ;i ++ ) { 65for (int row_iter = 0 ;row_iter < 4 ;row_iter ++ ) { 66float amax = 0.0f ;// absolute max 67 68for (int j = 0 ;j < QK8_0 ;j ++ ) { 69srcv [row_iter ][j ]= x [row_iter * k + i * QK8_0 + j ]; 70amax = MAX (amax ,fabsf (srcv [row_iter ][j ])); 71 } 72 73const float d = amax / ((1 <<7 )- 1 ); 74id [row_iter ]= d ?1.0f /d :0.0f ; 75 76y [i ].d [row_iter ]= GGML_CPU_FP32_TO_FP16 (d ); 77 } 78 79for (int j = 0 ;j < QK8_0 * 4 ;j ++ ) { 80int src_offset = (j / (4 * blck_size_interleave ))* blck_size_interleave ; 81int src_id = (j % (4 * blck_size_interleave )) /blck_size_interleave ; 82src_offset += (j %blck_size_interleave ); 83 84float x0 = srcv [src_id ][src_offset ]* id [src_id ]; 85y [i ].qs [j ]= roundf (x0 ); 86 } 87 } 88} 89 90void ggml_quantize_mat_q8_K_4x1_generic (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t k ) { 91assert (QK_K == 256 ); 92assert (k %QK_K == 0 ); 93const int nb = k /QK_K ; 94 95block_q8_Kx4 * GGML_RESTRICT y = (block_q8_Kx4 * )vy ; 96 97const int blck_size_interleave = 1 ; 98float srcv [4 ][QK_K ]; 99float iscale [4 ]; 100 101for (int i = 0 ;i < nb ;i ++ ) { 102for (int row_iter = 0 ;row_iter < 4 ;row_iter ++ ) { 103float amax = 0.0f ;// absolute max 104float max = 0 ; 105 106for (int j = 0 ;j < QK_K ;j ++ ) { 107srcv [row_iter ][j ]= x [row_iter * k + i * QK_K + j ]; 108// Update the maximum value of the corresponding super block 109if (amax < fabsf (srcv [row_iter ][j ])) { 110amax = fabsf (srcv [row_iter ][j ]); 111max = srcv [row_iter ][j ]; 112 } 113 } 114 115iscale [row_iter ]= amax ?-127.f /max :0 ; 116y [i ].d [row_iter ]= amax ?1 /iscale [row_iter ] :0 ; 117 } 118 119for (int j = 0 ;j < QK_K /4 ;j ++ ) { 120y [i ].bsums [j ]= 0 ; 121 } 122for (int j = 0 ;j < QK_K * 4 ;j ++ ) { 123int src_id = j %4 ; 124int src_offset = j /4 ; 125int index = ((j >>6 ) <<2 )+ (j & 3 ); 126 127float x0 = srcv [src_id ][src_offset ]* iscale [src_id ]; 128y [i ].qs [j ]= nearest_int (x0 ); 129y [i ].bsums [index ]+= y [i ].qs [j ]; 130 } 131 } 132} 133#endif 134 135void ggml_quantize_mat_q8_0_4x4_generic (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t k ) { 136assert (QK8_0 == 32 ); 137assert (k %QK8_0 == 0 ); 138const int nb = k /QK8_0 ; 139 140block_q8_0x4 * GGML_RESTRICT y = (block_q8_0x4 * )vy ; 141 142// scalar 143const int blck_size_interleave = 4 ; 144float srcv [4 ][QK8_0 ]; 145float id [4 ]; 146 147for (int i = 0 ;i < nb ;i ++ ) { 148for (int row_iter = 0 ;row_iter < 4 ;row_iter ++ ) { 149float amax = 0.0f ;// absolute max 150 151for (int j = 0 ;j < QK8_0 ;j ++ ) { 152srcv [row_iter ][j ]= x [row_iter * k + i * QK8_0 + j ]; 153amax = MAX (amax ,fabsf (srcv [row_iter ][j ])); 154 } 155 156const float d = amax / ((1 <<7 )- 1 ); 157id [row_iter ]= d ?1.0f /d :0.0f ; 158 159y [i ].d [row_iter ]= GGML_CPU_FP32_TO_FP16 (d ); 160 } 161 162for (int j = 0 ;j < QK8_0 * 4 ;j ++ ) { 163int src_offset = (j / (4 * blck_size_interleave ))* blck_size_interleave ; 164int src_id = (j % (4 * blck_size_interleave )) /blck_size_interleave ; 165src_offset += (j %blck_size_interleave ); 166 167float x0 = srcv [src_id ][src_offset ]* id [src_id ]; 168y [i ].qs [j ]= roundf (x0 ); 169 } 170 } 171} 172 173void ggml_quantize_mat_q8_0_4x8_generic (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t k ) { 174assert (QK8_0 == 32 ); 175assert (k %QK8_0 == 0 ); 176const int nb = k /QK8_0 ; 177 178block_q8_0x4 * GGML_RESTRICT y = (block_q8_0x4 * )vy ; 179 180// scalar 181const int blck_size_interleave = 8 ; 182float srcv [4 ][QK8_0 ]; 183float id [4 ]; 184 185for (int i = 0 ;i < nb ;i ++ ) { 186for (int row_iter = 0 ;row_iter < 4 ;row_iter ++ ) { 187float amax = 0.0f ;// absolute max 188 189for (int j = 0 ;j < QK8_0 ;j ++ ) { 190srcv [row_iter ][j ]= x [row_iter * k + i * QK8_0 + j ]; 191amax = MAX (amax ,fabsf (srcv [row_iter ][j ])); 192 } 193 194const float d = amax / ((1 <<7 )- 1 ); 195id [row_iter ]= d ?1.0f /d :0.0f ; 196 197y [i ].d [row_iter ]= GGML_CPU_FP32_TO_FP16 (d ); 198 } 199 200for (int j = 0 ;j < QK8_0 * 4 ;j ++ ) { 201int src_offset = (j / (4 * blck_size_interleave ))* blck_size_interleave ; 202int src_id = (j % (4 * blck_size_interleave )) /blck_size_interleave ; 203src_offset += (j %blck_size_interleave ); 204 205float x0 = srcv [src_id ][src_offset ]* id [src_id ]; 206y [i ].qs [j ]= roundf (x0 ); 207 } 208 } 209} 210 211void ggml_quantize_mat_q8_K_4x4_generic (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t k ) { 212assert (QK_K == 256 ); 213assert (k %QK_K == 0 ); 214const int nb = k /QK_K ; 215 216block_q8_Kx4 * GGML_RESTRICT y = (block_q8_Kx4 * )vy ; 217 218// scalar 219const int blck_size_interleave = 4 ; 220float srcv [4 ][QK_K ]; 221float iscale [4 ]; 222 223for (int i = 0 ;i < nb ;i ++ ) { 224for (int row_iter = 0 ;row_iter < 4 ;row_iter ++ ) { 225float amax = 0.0f ;// absolute max 226float max = 0 ; 227 228for (int j = 0 ;j < QK_K ;j ++ ) { 229srcv [row_iter ][j ]= x [row_iter * k + i * QK_K + j ]; 230// Update the maximum value of the corresponding super block 231if (amax < fabsf (srcv [row_iter ][j ])) { 232amax = fabsf (srcv [row_iter ][j ]); 233max = srcv [row_iter ][j ]; 234 } 235 } 236 237iscale [row_iter ]= amax ?-127.f /max :0 ; 238 239y [i ].d [row_iter ]= amax ?1 /iscale [row_iter ] :0 ; 240 } 241 242for (int j = 0 ;j < QK_K /4 ;j ++ ) { 243y [i ].bsums [j ]= 0 ; 244 } 245 246// Quants values are interleaved in sequence of four bytes from corresponding super blocks 247// Bsums values are interleaved in sequence of four bsums from each super block taken for interleaving 248// i.e first four bsums from the first super block, followed by first four bsums from second super block and so on 249for (int j = 0 ;j < QK_K * 4 ;j ++ ) { 250int src_offset = (j / (4 * blck_size_interleave ))* blck_size_interleave ; 251int src_id = (j % (4 * blck_size_interleave )) /blck_size_interleave ; 252src_offset += (j %blck_size_interleave ); 253int index = (((j & 15 ) >>2 ) <<2 )+ ((j >>8 ) <<4 )+ ((j >>6 )& 3 ); 254 255float x0 = srcv [src_id ][src_offset ]* iscale [src_id ]; 256y [i ].qs [j ]= nearest_int (x0 ); 257y [i ].bsums [index ]+= y [i ].qs [j ]; 258 } 259 } 260} 261 262void ggml_quantize_mat_q8_K_4x8_generic (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t k ) { 263assert (QK_K == 256 ); 264assert (k %QK_K == 0 ); 265const int nb = k /QK_K ; 266 267block_q8_Kx4 * GGML_RESTRICT y = (block_q8_Kx4 * )vy ; 268 269// scalar 270const int blck_size_interleave = 8 ; 271float srcv [4 ][QK_K ]; 272float iscale [4 ]; 273 274for (int i = 0 ;i < nb ;i ++ ) { 275for (int row_iter = 0 ;row_iter < 4 ;row_iter ++ ) { 276float amax = 0.0f ;// absolute max 277float max = 0 ; 278 279for (int j = 0 ;j < QK_K ;j ++ ) { 280srcv [row_iter ][j ]= x [row_iter * k + i * QK_K + j ]; 281// Update the maximum value of the corresponding super block 282if (amax < fabsf (srcv [row_iter ][j ])) { 283amax = fabsf (srcv [row_iter ][j ]); 284max = srcv [row_iter ][j ]; 285 } 286 } 287 288iscale [row_iter ]= amax ?-127.f /max :0 ; 289 290y [i ].d [row_iter ]= amax ?1 /iscale [row_iter ] :0 ; 291 } 292 293for (int j = 0 ;j < QK_K /4 ;j ++ ) { 294y [i ].bsums [j ]= 0 ; 295 } 296 297// Quants values are interleaved in sequence of eight bytes from corresponding super blocks 298// Bsums values are interleaved in sequence of four bsums from each super block taken for interleaving 299// i.e first four bsums from the first super block, followed by first four bsums from second super block and so on 300for (int j = 0 ;j < QK_K * 4 ;j ++ ) { 301int src_offset = (j / (4 * blck_size_interleave ))* blck_size_interleave ; 302int src_id = (j % (4 * blck_size_interleave )) /blck_size_interleave ; 303src_offset += (j %blck_size_interleave ); 304int index = (((j & 31 ) >>3 ) <<2 )+ ((j >>8 ) <<4 )+ ((j >>6 )& 3 ); 305 306float x0 = srcv [src_id ][src_offset ]* iscale [src_id ]; 307y [i ].qs [j ]= nearest_int (x0 ); 308y [i ].bsums [index ]+= y [i ].qs [j ]; 309 } 310 } 311} 312 313}// extern "C" 314 315template < int64_t INTER_SIZE ,ggml_type PARAM_TYPE > 316void ggml_quantize_mat_t (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t nrow ,int64_t n_per_row ); 317 318template <> void ggml_quantize_mat_t < 4 ,GGML_TYPE_Q8_0 > (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t nrow ,int64_t n_per_row ) { 319assert (nrow == 4 ); 320UNUSED (nrow ); 321ggml_quantize_mat_q8_0_4x4 (x ,vy ,n_per_row ); 322} 323 324template <> void ggml_quantize_mat_t < 8 ,GGML_TYPE_Q8_0 > (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t nrow ,int64_t n_per_row ) { 325assert (nrow == 4 ); 326UNUSED (nrow ); 327ggml_quantize_mat_q8_0_4x8 (x ,vy ,n_per_row ); 328} 329 330template <> void ggml_quantize_mat_t < 4 ,GGML_TYPE_Q8_K > (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t nrow ,int64_t n_per_row ) { 331assert (nrow == 4 ); 332UNUSED (nrow ); 333ggml_quantize_mat_q8_K_4x4 (x ,vy ,n_per_row ); 334} 335 336template <> void ggml_quantize_mat_t < 8 ,GGML_TYPE_Q8_K > (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t nrow ,int64_t n_per_row ) { 337assert (nrow == 4 ); 338UNUSED (nrow ); 339ggml_quantize_mat_q8_K_4x8 (x ,vy ,n_per_row ); 340} 341 342#if defined__riscv_zvfh 343template <> void ggml_quantize_mat_t < 1 ,GGML_TYPE_Q8_0 > (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t nrow ,int64_t n_per_row ) { 344assert (nrow == 4 ); 345UNUSED (nrow ); 346ggml_quantize_mat_q8_0_4x1 (x ,vy ,n_per_row ); 347} 348 349template <> void ggml_quantize_mat_t < 1 ,GGML_TYPE_Q8_K > (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t nrow ,int64_t n_per_row ) { 350assert (nrow == 4 ); 351UNUSED (nrow ); 352ggml_quantize_mat_q8_K_4x1 (x ,vy ,n_per_row ); 353} 354#endif 355 356template < int M ,int N > 357static void ggml_gemv_q6_K_NxM_q8_K_generic_impl (int n , 358float * GGML_RESTRICT s , 359size_t bs , 360const void * GGML_RESTRICT vx , 361const void * GGML_RESTRICT vy , 362int nr , 363int nc ) { 364constexpr int blocklen = M ; 365constexpr int ncols_interleaved = N ; 366const int qk = QK_K ; 367const int nb = n /qk ; 368const int blocks_per_half = 64 /blocklen ; 369 370assert (n %qk == 0 ); 371assert (nc %ncols_interleaved == 0 ); 372 373UNUSED (bs ); 374UNUSED (nr ); 375 376float sumf [8 ]; 377 378const block_q8_K * a_ptr = (const block_q8_K * )vy ; 379for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 380const block_q6_Kx8 * b_ptr = (const block_q6_Kx8 * )vx + (x * nb ); 381 382for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 383sumf [j ]= 0.0f ; 384 } 385 386for (int l = 0 ;l < nb ;l ++ ) { 387for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 388const int base_l = (k /blocks_per_half )* 128 + (k %blocks_per_half )* blocklen ; 389const int base_h = base_l + 64 ; 390 391const int scale_idx_l = base_l /16 ; 392const int scale_idx_h = base_h /16 ; 393 394const int qh_shift_l = ((base_l %128 ) /32 )* 2 ; 395const int qh_shift_h = ((base_h %128 ) /32 )* 2 ; 396 397const int qh_half_l = (base_l /128 )* 32 ; 398const int qh_half_h = (base_h /128 )* 32 ; 399 400for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 401const int8_t scale_l = b_ptr [l ].scales [scale_idx_l * ncols_interleaved + j ]; 402const int8_t scale_h = b_ptr [l ].scales [scale_idx_h * ncols_interleaved + j ]; 403 404int sumi_l = 0 ; 405int sumi_h = 0 ; 406 407for (int i = 0 ;i < blocklen ;i ++ ) { 408const int ql_pos = k * ncols_interleaved * blocklen + j * blocklen + i ; 409const int l_4 = b_ptr [l ].ql [ql_pos ]& 0xF ; 410const int hi_4 = (b_ptr [l ].ql [ql_pos ] >>4 )& 0xF ; 411 412const int qh_idx_l = qh_half_l + ((base_l + i ) %32 ); 413const int qh_chunk_l = qh_idx_l /blocklen ; 414const int qh_pos_l = qh_idx_l %blocklen ; 415const int qh_offset_l = qh_chunk_l * (blocklen * ncols_interleaved )+ j * blocklen + qh_pos_l ; 416const int hi_2_l = (b_ptr [l ].qh [qh_offset_l ] >>qh_shift_l )& 0x3 ; 417 418const int qh_idx_h = qh_half_h + ((base_h + i ) %32 ); 419const int qh_chunk_h = qh_idx_h /blocklen ; 420const int qh_pos_h = qh_idx_h %blocklen ; 421const int qh_offset_h = qh_chunk_h * (blocklen * ncols_interleaved )+ j * blocklen + qh_pos_h ; 422const int hi_2_h = (b_ptr [l ].qh [qh_offset_h ] >>qh_shift_h )& 0x3 ; 423 424const int q_l = ((hi_2_l <<4 ) |l_4 )- 32 ; 425const int q_h = ((hi_2_h <<4 ) |hi_4 )- 32 ; 426 427const int8_t a_l = a_ptr [l ].qs [base_l + i ]; 428const int8_t a_h = a_ptr [l ].qs [base_h + i ]; 429 430sumi_l += q_l * a_l ; 431sumi_h += q_h * a_h ; 432 } 433 434sumf [j ]+= 435 (sumi_l * scale_l + sumi_h * scale_h )* GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* a_ptr [l ].d ; 436 } 437 } 438 } 439 440for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 441s [x * ncols_interleaved + j ]= sumf [j ]; 442 } 443 } 444} 445 446template < int M ,int N > 447static void ggml_gemm_q6_K_NxM_q8_K_generic_impl (int n , 448float * GGML_RESTRICT s , 449size_t bs , 450const void * GGML_RESTRICT vx , 451const void * GGML_RESTRICT vy , 452int nr , 453int nc ) { 454constexpr int blocklen = M ; 455constexpr int ncols_interleaved = N ; 456const int qk = QK_K ; 457const int nb = n /qk ; 458const int blocks_per_half = 64 /blocklen ; 459const int q8_half_stride = 512 ; 460const int q8_low_high_step = 256 ; 461 462assert (n %qk == 0 ); 463assert (nr %4 == 0 ); 464assert (nc %ncols_interleaved == 0 ); 465 466UNUSED (bs ); 467 468float sumf [4 ][8 ]; 469 470for (int y = 0 ;y < nr /4 ;y ++ ) { 471const block_q8_Kx4 * a_ptr = (const block_q8_Kx4 * )vy + (y * nb ); 472for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 473const block_q6_Kx8 * b_ptr = (const block_q6_Kx8 * )vx + (x * nb ); 474 475for (int m = 0 ;m < 4 ;m ++ ) { 476for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 477sumf [m ][j ]= 0.0f ; 478 } 479 } 480 481for (int l = 0 ;l < nb ;l ++ ) { 482for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 483const int base_l = (k /blocks_per_half )* 128 + (k %blocks_per_half )* blocklen ; 484const int base_h = base_l + 64 ; 485 486const int scale_idx_l = base_l /16 ; 487const int scale_idx_h = base_h /16 ; 488 489const int qh_shift_l = ((base_l %128 ) /32 )* 2 ; 490const int qh_shift_h = ((base_h %128 ) /32 )* 2 ; 491 492const int qh_half_l = (base_l /128 )* 32 ; 493const int qh_half_h = (base_h /128 )* 32 ; 494 495const int q8_base = (k /blocks_per_half )* q8_half_stride + (k %blocks_per_half )* (blocklen * 4 ); 496 497for (int m = 0 ;m < 4 ;m ++ ) { 498for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 499const int8_t scale_l = b_ptr [l ].scales [scale_idx_l * ncols_interleaved + j ]; 500const int8_t scale_h = b_ptr [l ].scales [scale_idx_h * ncols_interleaved + j ]; 501 502int sumi_l = 0 ; 503int sumi_h = 0 ; 504 505for (int i = 0 ;i < blocklen ;i ++ ) { 506const int ql_pos = k * ncols_interleaved * blocklen + j * blocklen + i ; 507const int l_4 = b_ptr [l ].ql [ql_pos ]& 0xF ; 508const int hi_4 = (b_ptr [l ].ql [ql_pos ] >>4 )& 0xF ; 509 510const int qh_idx_l = qh_half_l + ((base_l + i ) %32 ); 511const int qh_chunk_l = qh_idx_l /blocklen ; 512const int qh_pos_l = qh_idx_l %blocklen ; 513const int qh_offset_l = 514qh_chunk_l * (blocklen * ncols_interleaved )+ j * blocklen + qh_pos_l ; 515const int hi_2_l = (b_ptr [l ].qh [qh_offset_l ] >>qh_shift_l )& 0x3 ; 516 517const int qh_idx_h = qh_half_h + ((base_h + i ) %32 ); 518const int qh_chunk_h = qh_idx_h /blocklen ; 519const int qh_pos_h = qh_idx_h %blocklen ; 520const int qh_offset_h = 521qh_chunk_h * (blocklen * ncols_interleaved )+ j * blocklen + qh_pos_h ; 522const int hi_2_h = (b_ptr [l ].qh [qh_offset_h ] >>qh_shift_h )& 0x3 ; 523 524const int q_l = ((hi_2_l <<4 ) |l_4 )- 32 ; 525const int q_h = ((hi_2_h <<4 ) |hi_4 )- 32 ; 526 527const int8_t q8_l = a_ptr [l ].qs [q8_base + m * blocklen + i ]; 528const int8_t q8_h = a_ptr [l ].qs [q8_base + m * blocklen + i + q8_low_high_step ]; 529 530sumi_l += q_l * q8_l ; 531sumi_h += q_h * q8_h ; 532 } 533 534sumf [m ][j ]+= (sumi_l * scale_l + sumi_h * scale_h )* GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* 535a_ptr [l ].d [m ]; 536 } 537 } 538 } 539 } 540 541for (int m = 0 ;m < 4 ;m ++ ) { 542for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 543s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]; 544 } 545 } 546 } 547 } 548} 549 550template < int M ,int N > 551static void ggml_gemv_q5_K_NxM_q8_K_generic_impl (int n , 552float * GGML_RESTRICT s , 553size_t bs , 554const void * GGML_RESTRICT vx , 555const void * GGML_RESTRICT vy , 556int nr , 557int nc ) { 558constexpr int blocklen = M ; 559constexpr int ncols_interleaved = N ; 560const int qk = QK_K ; 561const int nb = n /qk ; 562static const uint32_t kmask1 = 0x3f3f3f3f ; 563static const uint32_t kmask2 = 0x0f0f0f0f ; 564static const uint32_t kmask3 = 0x03030303 ; 565 566assert (n %qk == 0 ); 567assert (nc %ncols_interleaved == 0 ); 568 569UNUSED (bs ); 570UNUSED (nr ); 571 572float sumf [ncols_interleaved ]; 573float sum_minf [ncols_interleaved ]; 574uint32_t utmp [32 ]; 575int sumi1 ; 576int sumi2 ; 577int sumi ; 578 579const block_q8_K * a_ptr = (const block_q8_K * )vy ; 580for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 581const block_q5_Kx8 * b_ptr = (const block_q5_Kx8 * )vx + (x * nb ); 582 583for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 584sumf [j ]= 0.0 ; 585sum_minf [j ]= 0.0 ; 586 } 587for (int l = 0 ;l < nb ;l ++ ) { 588for (int sb = 0 ;sb < 8 ;sb ++ ) { 589memcpy (utmp + sb * 4 ,b_ptr [l ].scales + sb * K_SCALE_SIZE ,K_SCALE_SIZE ); 590utmp [sb * 4 + 3 ]= ((utmp [sb * 4 + 2 ] >>4 )& kmask2 ) | (((utmp [sb * 4 + 1 ] >>6 )& kmask3 ) <<4 ); 591const uint32_t uaux_0 = utmp [sb * 4 + 1 ]& kmask1 ; 592utmp [sb * 4 + 1 ]= (utmp [sb * 4 + 2 ]& kmask2 ) | (((utmp [sb * 4 + 0 ] >>6 )& kmask3 ) <<4 ); 593utmp [sb * 4 + 2 ]= uaux_0 ; 594utmp [sb * 4 + 0 ] &=kmask1 ; 595 } 596for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 597constexpr int scale_stride = 32 ; 598uint8_t * scales_0 = (uint8_t * )utmp + (k / (32 /blocklen ))* scale_stride ; 599uint8_t * scales_1 = (uint8_t * )utmp + (k / (32 /blocklen ))* scale_stride + 16 ; 600 601const int qh_shift = (k / (32 /blocklen ))* 2 ; 602for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 603sumi1 = 0 ; 604sumi2 = 0 ; 605sumi = 0 ; 606for (int i = 0 ;i < blocklen ;++ i ) { 607const int b_qs_offset = k * ncols_interleaved * blocklen + j * blocklen + i ; 608 609const int qh_idx = (k * blocklen + i ) %32 ; 610const int qh_chunk = qh_idx /blocklen ; 611const int qh_pos = qh_idx %blocklen ; 612const int b_qh_offset = qh_chunk * (blocklen * ncols_interleaved )+ j * blocklen + qh_pos ; 613 614const uint8_t qh_val = b_ptr [l ].qh [b_qh_offset ]; 615const uint8_t h0 = (qh_val >>qh_shift )& 1 ; 616const uint8_t h1 = (qh_val >> (qh_shift + 1 ))& 1 ; 617 618const int v0 = (int8_t ) ((b_ptr [l ].qs [b_qs_offset ]& 0xF ) | (h0 <<4 )); 619const int v1 = (int8_t ) ((b_ptr [l ].qs [b_qs_offset ] >>4 ) | (h1 <<4 )); 620 621const int q8_offset = (k / (32 /blocklen ))* 64 + (k % (32 /blocklen ))* blocklen + i ; 622 623sumi1 = (v0 * a_ptr [l ].qs [q8_offset ]); 624sumi2 = (v1 * a_ptr [l ].qs [q8_offset + 32 ]); 625sumi1 = sumi1 * scales_0 [j ]; 626sumi2 = sumi2 * scales_1 [j ]; 627sumi += sumi1 + sumi2 ; 628 } 629sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* a_ptr [l ].d ; 630 } 631 } 632for (int sb = 0 ;sb < 8 ;sb ++ ) { 633uint8_t * mins = (uint8_t * )utmp + 8 + sb * 16 ; 634for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 635sum_minf [j ]+= mins [j ]* (a_ptr [l ].bsums [sb * 2 ]+ a_ptr [l ].bsums [sb * 2 + 1 ])* 636GGML_CPU_FP16_TO_FP32 (b_ptr [l ].dmin [j ])* a_ptr [l ].d ; 637 } 638 } 639 } 640for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 641s [x * ncols_interleaved + j ]= sumf [j ]- sum_minf [j ]; 642 } 643 } 644} 645 646template < int M ,int N > 647static void ggml_gemm_q5_K_NxM_q8_K_generic_impl (int n , 648float * GGML_RESTRICT s , 649size_t bs , 650const void * GGML_RESTRICT vx , 651const void * GGML_RESTRICT vy , 652int nr , 653int nc ) { 654constexpr int blocklen = M ; 655constexpr int ncols_interleaved = N ; 656const int qk = QK_K ; 657const int nb = n /qk ; 658static const uint32_t kmask1 = 0x3f3f3f3f ; 659static const uint32_t kmask2 = 0x0f0f0f0f ; 660static const uint32_t kmask3 = 0x03030303 ; 661 662assert (n %qk == 0 ); 663assert (nr %4 == 0 ); 664assert (nc %ncols_interleaved == 0 ); 665 666float sumf [4 ][ncols_interleaved ]; 667float sum_minf [4 ][ncols_interleaved ]; 668uint32_t utmp [32 ]; 669int sumi1 ; 670int sumi2 ; 671int sumi ; 672 673for (int y = 0 ;y < nr /4 ;y ++ ) { 674const block_q8_Kx4 * a_ptr = (const block_q8_Kx4 * )vy + (y * nb ); 675for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 676const block_q5_Kx8 * b_ptr = (const block_q5_Kx8 * )vx + (x * nb ); 677for (int m = 0 ;m < 4 ;m ++ ) { 678for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 679sumf [m ][j ]= 0.0 ; 680sum_minf [m ][j ]= 0.0 ; 681 } 682 } 683for (int l = 0 ;l < nb ;l ++ ) { 684for (int sb = 0 ;sb < 8 ;sb ++ ) { 685memcpy (utmp + sb * 4 ,b_ptr [l ].scales + sb * K_SCALE_SIZE ,K_SCALE_SIZE ); 686utmp [sb * 4 + 3 ]= ((utmp [sb * 4 + 2 ] >>4 )& kmask2 ) | (((utmp [sb * 4 + 1 ] >>6 )& kmask3 ) <<4 ); 687const uint32_t uaux_0 = utmp [sb * 4 + 1 ]& kmask1 ; 688utmp [sb * 4 + 1 ]= (utmp [sb * 4 + 2 ]& kmask2 ) | (((utmp [sb * 4 + 0 ] >>6 )& kmask3 ) <<4 ); 689utmp [sb * 4 + 2 ]= uaux_0 ; 690utmp [sb * 4 + 0 ] &=kmask1 ; 691 } 692for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 693constexpr int scale_stride = 32 ; 694uint8_t * scales_0 = (uint8_t * )utmp + (k / (32 /blocklen ))* scale_stride ; 695uint8_t * scales_1 = (uint8_t * )utmp + (k / (32 /blocklen ))* scale_stride + 16 ; 696 697const int qh_shift = (k / (32 /blocklen ))* 2 ; 698for (int m = 0 ;m < 4 ;m ++ ) { 699for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 700sumi1 = 0 ; 701sumi2 = 0 ; 702sumi = 0 ; 703for (int i = 0 ;i < blocklen ;++ i ) { 704const int b_qs_offset = k * ncols_interleaved * blocklen + j * blocklen + i ; 705 706const int qh_idx = (k * blocklen + i ) %32 ; 707const int qh_chunk = qh_idx /blocklen ; 708const int qh_pos = qh_idx %blocklen ; 709const int b_qh_offset = 710qh_chunk * (blocklen * ncols_interleaved )+ j * blocklen + qh_pos ; 711 712const uint8_t qh_val = b_ptr [l ].qh [b_qh_offset ]; 713const uint8_t h0 = (qh_val >>qh_shift )& 1 ; 714const uint8_t h1 = (qh_val >> (qh_shift + 1 ))& 1 ; 715 716const int v0 = (int8_t ) ((b_ptr [l ].qs [b_qs_offset ]& 0xF ) | (h0 <<4 )); 717const int v1 = (int8_t ) ((b_ptr [l ].qs [b_qs_offset ] >>4 ) | (h1 <<4 )); 718 719const int q8_offset = (k / (32 /blocklen ))* 256 + 720 (k % (32 /blocklen ))* 4 * blocklen + m * blocklen + i ; 721 722sumi1 = (v0 * a_ptr [l ].qs [q8_offset ]); 723sumi2 = (v1 * a_ptr [l ].qs [q8_offset + 128 ]); 724sumi1 = sumi1 * scales_0 [j ]; 725sumi2 = sumi2 * scales_1 [j ]; 726sumi += sumi1 + sumi2 ; 727 } 728sumf [m ][j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* a_ptr [l ].d [m ]; 729 } 730 } 731 } 732for (int sb = 0 ;sb < 8 ;sb ++ ) { 733uint8_t * mins = (uint8_t * )utmp + 8 + sb * 16 ; 734for (int m = 0 ;m < 4 ;m ++ ) { 735const int16_t * bsums = a_ptr [l ].bsums + (sb * 8 )+ (m * 4 )- ((sb %2 )* 6 ); 736for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 737sum_minf [m ][j ]+= mins [j ]* (bsums [0 ]+ bsums [1 ])* 738GGML_CPU_FP16_TO_FP32 (b_ptr [l ].dmin [j ])* a_ptr [l ].d [m ]; 739 } 740 } 741 } 742 } 743for (int m = 0 ;m < 4 ;m ++ ) { 744for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 745s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]- sum_minf [m ][j ]; 746 } 747 } 748 } 749 } 750} 751 752extern "C" { 753 754void ggml_gemv_q4_0_4x4_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 755const int qk = QK8_0 ; 756const int nb = n /qk ; 757const int ncols_interleaved = 4 ; 758const int blocklen = 4 ; 759 760assert (nr == 1 ); 761assert (n %qk == 0 ); 762assert (nc %ncols_interleaved == 0 ); 763 764UNUSED (s ); 765UNUSED (bs ); 766UNUSED (vx ); 767UNUSED (vy ); 768UNUSED (nr ); 769UNUSED (nc ); 770UNUSED (nb ); 771UNUSED (ncols_interleaved ); 772UNUSED (blocklen ); 773 774float sumf [4 ]; 775int sumi ; 776 777const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 778for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 779const block_q4_0x4 * b_ptr = (const block_q4_0x4 * )vx + (x * nb ); 780 781for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [j ]= 0.0 ; 782for (int l = 0 ;l < nb ;l ++ ) { 783for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 784for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 785sumi = 0 ; 786for (int i = 0 ;i < blocklen ;++ i ) { 787const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] <<4 ); 788const int v1 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0xF0 ); 789sumi += ((v0 * a_ptr [l ].qs [k * blocklen + i ])+ (v1 * a_ptr [l ].qs [k * blocklen + i + qk /2 ])) >>4 ; 790 } 791sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d ); 792 } 793 } 794 } 795for (int j = 0 ;j < ncols_interleaved ;j ++ )s [x * ncols_interleaved + j ]= sumf [j ]; 796 } 797} 798 799void ggml_gemv_q4_0_4x8_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 800const int qk = QK8_0 ; 801const int nb = n /qk ; 802const int ncols_interleaved = 4 ; 803const int blocklen = 8 ; 804 805assert (n %qk == 0 ); 806assert (nc %ncols_interleaved == 0 ); 807 808UNUSED (s ); 809UNUSED (bs ); 810UNUSED (vx ); 811UNUSED (vy ); 812UNUSED (nr ); 813UNUSED (nc ); 814UNUSED (nb ); 815UNUSED (ncols_interleaved ); 816UNUSED (blocklen ); 817 818float sumf [4 ]; 819int sumi ; 820 821const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 822for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 823const block_q4_0x4 * b_ptr = (const block_q4_0x4 * )vx + (x * nb ); 824 825for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [j ]= 0.0 ; 826for (int l = 0 ;l < nb ;l ++ ) { 827for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 828for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 829sumi = 0 ; 830for (int i = 0 ;i < blocklen ;++ i ) { 831const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] <<4 ); 832const int v1 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0xF0 ); 833sumi += ((v0 * a_ptr [l ].qs [k * blocklen + i ])+ (v1 * a_ptr [l ].qs [k * blocklen + i + qk /2 ])) >>4 ; 834 } 835sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d ); 836 } 837 } 838 } 839for (int j = 0 ;j < ncols_interleaved ;j ++ )s [x * ncols_interleaved + j ]= sumf [j ]; 840 } 841} 842 843void ggml_gemv_q4_0_8x8_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 844const int qk = QK8_0 ; 845const int nb = n /qk ; 846const int ncols_interleaved = 8 ; 847const int blocklen = 8 ; 848 849assert (n %qk == 0 ); 850assert (nc %ncols_interleaved == 0 ); 851 852UNUSED (s ); 853UNUSED (bs ); 854UNUSED (vx ); 855UNUSED (vy ); 856UNUSED (nr ); 857UNUSED (nc ); 858UNUSED (nb ); 859UNUSED (ncols_interleaved ); 860UNUSED (blocklen ); 861 862float sumf [8 ]; 863int sumi ; 864 865const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 866for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 867const block_q4_0x8 * b_ptr = (const block_q4_0x8 * )vx + (x * nb ); 868 869for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [j ]= 0.0 ; 870for (int l = 0 ;l < nb ;l ++ ) { 871for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 872for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 873sumi = 0 ; 874for (int i = 0 ;i < blocklen ;++ i ) { 875const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] <<4 ); 876const int v1 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0xF0 ); 877sumi += ((v0 * a_ptr [l ].qs [k * blocklen + i ])+ (v1 * a_ptr [l ].qs [k * blocklen + i + qk /2 ])) >>4 ; 878 } 879sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d ); 880 } 881 } 882 } 883for (int j = 0 ;j < ncols_interleaved ;j ++ )s [x * ncols_interleaved + j ]= sumf [j ]; 884 } 885} 886 887void ggml_gemv_q4_K_8x4_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 888const int qk = QK_K ; 889const int nb = n /qk ; 890const int ncols_interleaved = 8 ; 891const int blocklen = 4 ; 892static const uint32_t kmask1 = 0x3f3f3f3f ; 893static const uint32_t kmask2 = 0x0f0f0f0f ; 894static const uint32_t kmask3 = 0x03030303 ; 895 896assert (n %qk == 0 ); 897assert (nc %ncols_interleaved == 0 ); 898 899UNUSED (bs ); 900UNUSED (nr ); 901 902float sumf [8 ]; 903float sum_minf [8 ]; 904uint32_t utmp [32 ]; 905int sumi1 ; 906int sumi2 ; 907int sumi ; 908 909const block_q8_K * a_ptr = (const block_q8_K * )vy ; 910for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 911const block_q4_Kx8 * b_ptr = (const block_q4_Kx8 * )vx + (x * nb ); 912 913for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 914sumf [j ]= 0.0 ; 915sum_minf [j ]= 0.0 ; 916 } 917for (int l = 0 ;l < nb ;l ++ ) { 918for (int sb = 0 ;sb < 8 ;sb ++ ) { 919memcpy (utmp + sb * 4 ,b_ptr [l ].scales + sb * 12 ,12 ); 920utmp [sb * 4 + 3 ]= ((utmp [sb * 4 + 2 ] >>4 )& kmask2 ) | (((utmp [sb * 4 + 1 ] >>6 )& kmask3 ) <<4 ); 921const uint32_t uaux_0 = utmp [sb * 4 + 1 ]& kmask1 ; 922utmp [sb * 4 + 1 ]= (utmp [sb * 4 + 2 ]& kmask2 ) | (((utmp [sb * 4 + 0 ] >>6 )& kmask3 ) <<4 ); 923utmp [sb * 4 + 2 ]= uaux_0 ; 924utmp [sb * 4 + 0 ] &=kmask1 ; 925 } 926for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 927uint8_t * scales_0 = (uint8_t * )utmp + (k /8 )* 32 ; 928uint8_t * scales_1 = (uint8_t * )utmp + (k /8 )* 32 + 16 ; 929for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 930sumi1 = 0 ; 931sumi2 = 0 ; 932sumi = 0 ; 933for (int i = 0 ;i < blocklen ;++ i ) { 934const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0xF ); 935const int v1 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ); 936sumi1 = (v0 * a_ptr [l ].qs [(k /8 )* 64 + (k %8 )* blocklen + i ]); 937sumi2 = (v1 * a_ptr [l ].qs [(k /8 )* 64 + (k %8 )* blocklen + i + 32 ]); 938sumi1 = sumi1 * scales_0 [j ]; 939sumi2 = sumi2 * scales_1 [j ]; 940sumi += sumi1 + sumi2 ; 941 } 942sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* a_ptr [l ].d ; 943 } 944 } 945for (int sb = 0 ;sb < 8 ;sb ++ ) { 946uint8_t * mins = (uint8_t * )utmp + 8 + sb * 16 ; 947for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 948sum_minf [j ]+= mins [j ]* (a_ptr [l ].bsums [sb * 2 ]+ a_ptr [l ].bsums [sb * 2 + 1 ])* GGML_CPU_FP16_TO_FP32 (b_ptr [l ].dmin [j ])* a_ptr [l ].d ; 949 } 950 } 951 } 952for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 953s [x * ncols_interleaved + j ]= sumf [j ]- sum_minf [j ]; 954 } 955 } 956} 957 958void ggml_gemv_q4_K_8x8_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 959const int qk = QK_K ; 960const int nb = n /qk ; 961const int ncols_interleaved = 8 ; 962const int blocklen = 8 ; 963static const uint32_t kmask1 = 0x3f3f3f3f ; 964static const uint32_t kmask2 = 0x0f0f0f0f ; 965static const uint32_t kmask3 = 0x03030303 ; 966 967assert (n %qk == 0 ); 968assert (nc %ncols_interleaved == 0 ); 969 970UNUSED (bs ); 971UNUSED (nr ); 972 973float sumf [8 ]; 974float sum_minf [8 ]; 975uint32_t utmp [32 ]; 976int sumi1 ; 977int sumi2 ; 978int sumi ; 979 980const block_q8_K * a_ptr = (const block_q8_K * )vy ; 981for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 982const block_q4_Kx8 * b_ptr = (const block_q4_Kx8 * )vx + (x * nb ); 983 984for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 985sumf [j ]= 0.0 ; 986sum_minf [j ]= 0.0 ; 987 } 988for (int l = 0 ;l < nb ;l ++ ) { 989for (int sb = 0 ;sb < 8 ;sb ++ ) { 990memcpy (utmp + sb * 4 ,b_ptr [l ].scales + sb * 12 ,12 ); 991utmp [sb * 4 + 3 ]= ((utmp [sb * 4 + 2 ] >>4 )& kmask2 ) | (((utmp [sb * 4 + 1 ] >>6 )& kmask3 ) <<4 ); 992const uint32_t uaux_0 = utmp [sb * 4 + 1 ]& kmask1 ; 993utmp [sb * 4 + 1 ]= (utmp [sb * 4 + 2 ]& kmask2 ) | (((utmp [sb * 4 + 0 ] >>6 )& kmask3 ) <<4 ); 994utmp [sb * 4 + 2 ]= uaux_0 ; 995utmp [sb * 4 + 0 ] &=kmask1 ; 996 } 997for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 998uint8_t * scales_0 = (uint8_t * )utmp + (k /4 )* 32 ; 999uint8_t * scales_1 = (uint8_t * )utmp + (k /4 )* 32 + 16 ; 1000for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1001sumi1 = 0 ; 1002sumi2 = 0 ; 1003sumi = 0 ; 1004for (int i = 0 ;i < blocklen ;++ i ) { 1005const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0xF ); 1006const int v1 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ); 1007sumi1 = (v0 * a_ptr [l ].qs [(k >>2 )* 64 + (k %4 )* blocklen + i ]); 1008sumi2 = (v1 * a_ptr [l ].qs [(k >>2 )* 64 + (k %4 )* blocklen + i + 32 ]); 1009sumi1 = sumi1 * scales_0 [j ]; 1010sumi2 = sumi2 * scales_1 [j ]; 1011sumi += sumi1 + sumi2 ; 1012 } 1013sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* a_ptr [l ].d ; 1014 } 1015 } 1016for (int sb = 0 ;sb < 8 ;sb ++ ) { 1017uint8_t * mins = (uint8_t * )utmp + 8 + sb * 16 ; 1018for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1019sum_minf [j ]+= mins [j ]* (a_ptr [l ].bsums [sb * 2 ]+ a_ptr [l ].bsums [sb * 2 + 1 ])* GGML_CPU_FP16_TO_FP32 (b_ptr [l ].dmin [j ])* a_ptr [l ].d ; 1020 } 1021 } 1022 } 1023for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1024s [x * ncols_interleaved + j ]= sumf [j ]- sum_minf [j ]; 1025 } 1026 } 1027} 1028 1029void ggml_gemv_q2_K_8x8_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1030const int qk = QK_K ; 1031const int nb = n /qk ; 1032const int ncols_interleaved = 8 ; 1033const int blocklen = 8 ; 1034 1035assert (n %qk == 0 ); 1036assert (nc %ncols_interleaved == 0 ); 1037 1038UNUSED (s ); 1039UNUSED (bs ); 1040UNUSED (vx ); 1041UNUSED (vy ); 1042UNUSED (nr ); 1043UNUSED (nc ); 1044UNUSED (nb ); 1045UNUSED (ncols_interleaved ); 1046UNUSED (blocklen ); 1047 1048float sumf [8 ]; 1049float sum_minf [8 ]; 1050int sumi1 ,sumi2 ,sumi3 ,sumi4 ; 1051int sumi ; 1052 1053const block_q8_K * a_ptr = (const block_q8_K * )vy ; 1054for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1055const block_q2_Kx8 * b_ptr = (const block_q2_Kx8 * )vx + (x * nb ); 1056for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1057sumf [j ]= 0.0 ; 1058sum_minf [j ]= 0.0 ; 1059 } 1060for (int l = 0 ;l < nb ;l ++ ) { 1061for (int k = 0 ;k < (qk / (4 * blocklen ));k ++ ) { 1062const uint8_t * scales_0 = b_ptr [l ].scales + (k /4 )* 64 ; 1063const uint8_t * scales_1 = b_ptr [l ].scales + (k /4 )* 64 + 16 ; 1064const uint8_t * scales_2 = b_ptr [l ].scales + (k /4 )* 64 + 32 ; 1065const uint8_t * scales_3 = b_ptr [l ].scales + (k /4 )* 64 + 48 ; 1066for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1067sumi1 = 0 ; 1068sumi2 = 0 ; 1069sumi3 = 0 ; 1070sumi4 = 0 ; 1071sumi = 0 ; 1072int offset = ((k /2 ) %2 )+ j * 2 ; 1073for (int i = 0 ;i < blocklen ;++ i ){ 1074const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 3 ); 1075const int v1 = (int8_t ) ((b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>2 )& 3 ); 1076const int v2 = (int8_t ) ((b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 )& 3 ); 1077const int v3 = (int8_t ) ((b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>6 )& 3 ); 1078sumi1 = (v0 * a_ptr [l ].qs [(k >>2 )* 128 + (k %4 )* blocklen + i ]); 1079sumi2 = (v1 * a_ptr [l ].qs [(k >>2 )* 128 + (k %4 )* blocklen + i + 32 ]); 1080sumi3 = (v2 * a_ptr [l ].qs [(k >>2 )* 128 + (k %4 )* blocklen + i + 64 ]); 1081sumi4 = (v3 * a_ptr [l ].qs [(k >>2 )* 128 + (k %4 )* blocklen + i + 96 ]); 1082 1083sumi1 = sumi1 * (scales_0 [offset ]& 0xF ); 1084sumi2 = sumi2 * (scales_1 [offset ]& 0xF ); 1085sumi3 = sumi3 * (scales_2 [offset ]& 0xF ); 1086sumi4 = sumi4 * (scales_3 [offset ]& 0xF ); 1087sumi += sumi1 + sumi2 + sumi3 + sumi4 ; 1088 } 1089sumf [j ]+= sumi * GGML_FP16_TO_FP32 (b_ptr [l ].d [j ])* a_ptr [l ].d ; 1090 } 1091 } 1092for (int sb = 0 ;sb < 8 ;sb ++ ) { 1093const uint8_t * mins = b_ptr [l ].scales + sb * 16 ; 1094for (int j = 0 ;j < ncols_interleaved ;j ++ ){ 1095sum_minf [j ]+= ((mins [j * 2 ] >>4 )* a_ptr [l ].bsums [sb * 2 ]+ (mins [(j * 2 )+ 1 ] >>4 )* a_ptr [l ].bsums [sb * 2 + 1 ])* GGML_FP16_TO_FP32 (b_ptr [l ].dmin [j ])* a_ptr [l ].d ; 1096 } 1097 } 1098 } 1099for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1100s [x * ncols_interleaved + j ]= sumf [j ]- sum_minf [j ]; 1101 } 1102 } 1103} 1104 1105void ggml_gemv_q5_K_8x4_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1106ggml_gemv_q5_K_NxM_q8_K_generic_impl < 4 ,8 > (n ,s ,bs ,vx ,vy ,nr ,nc ); 1107} 1108 1109void ggml_gemv_q5_K_8x8_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1110ggml_gemv_q5_K_NxM_q8_K_generic_impl < 8 ,8 > (n ,s ,bs ,vx ,vy ,nr ,nc ); 1111} 1112 1113 1114void ggml_gemv_q6_K_8x4_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1115ggml_gemv_q6_K_NxM_q8_K_generic_impl < 4 ,8 > (n ,s ,bs ,vx ,vy ,nr ,nc ); 1116} 1117 1118void ggml_gemv_q6_K_8x8_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1119ggml_gemv_q6_K_NxM_q8_K_generic_impl < 8 ,8 > (n ,s ,bs ,vx ,vy ,nr ,nc ); 1120} 1121 1122void ggml_gemv_iq4_nl_4x4_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1123const int qk = QK8_0 ; 1124const int nb = n /qk ; 1125const int ncols_interleaved = 4 ; 1126const int blocklen = 4 ; 1127 1128assert (nr == 1 ); 1129assert (n %qk == 0 ); 1130assert (nc %ncols_interleaved == 0 ); 1131 1132UNUSED (bs ); 1133UNUSED (nr ); 1134 1135float sumf [4 ]; 1136int sumi ; 1137 1138const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 1139for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1140const block_iq4_nlx4 * b_ptr = (const block_iq4_nlx4 * )vx + (x * nb ); 1141 1142for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [j ]= 0.0 ; 1143for (int l = 0 ;l < nb ;l ++ ) { 1144for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 1145for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1146sumi = 0 ; 1147for (int i = 0 ;i < blocklen ;++ i ) { 1148const int v0 = kvalues_iq4nl [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0x0F ]; 1149const int v1 = kvalues_iq4nl [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ]; 1150sumi += ((v0 * a_ptr [l ].qs [k * blocklen + i ])+ (v1 * a_ptr [l ].qs [k * blocklen + i + qk /2 ])); 1151 } 1152sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d ); 1153 } 1154 } 1155 } 1156for (int j = 0 ;j < ncols_interleaved ;j ++ )s [x * ncols_interleaved + j ]= sumf [j ]; 1157 } 1158} 1159 1160void ggml_gemv_iq4_nl_8x8_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1161const int qk = QK8_0 ; 1162const int nb = n /qk ; 1163const int ncols_interleaved = 8 ; 1164const int blocklen = 8 ; 1165 1166assert (nr == 1 ); 1167assert (n %qk == 0 ); 1168assert (nc %ncols_interleaved == 0 ); 1169 1170UNUSED (bs ); 1171UNUSED (nr ); 1172 1173float sumf [8 ]; 1174int sumi ; 1175 1176const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 1177for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1178const block_iq4_nlx8 * b_ptr = (const block_iq4_nlx8 * )vx + (x * nb ); 1179 1180for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [j ]= 0.0 ; 1181for (int l = 0 ;l < nb ;l ++ ) { 1182for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 1183for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1184sumi = 0 ; 1185for (int i = 0 ;i < blocklen ;++ i ) { 1186const int v0 = kvalues_iq4nl [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0x0F ]; 1187const int v1 = kvalues_iq4nl [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ]; 1188sumi += ((v0 * a_ptr [l ].qs [k * blocklen + i ])+ (v1 * a_ptr [l ].qs [k * blocklen + i + qk /2 ])); 1189 } 1190sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d ); 1191 } 1192 } 1193 } 1194for (int j = 0 ;j < ncols_interleaved ;j ++ )s [x * ncols_interleaved + j ]= sumf [j ]; 1195 } 1196} 1197 1198void ggml_gemv_mxfp4_4x4_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1199const int qk = QK8_0 ; 1200const int nb = n /qk ; 1201const int ncols_interleaved = 4 ; 1202const int blocklen = 4 ; 1203 1204assert (nr == 1 ); 1205assert (n %qk == 0 ); 1206assert (nc %ncols_interleaved == 0 ); 1207 1208UNUSED (bs ); 1209UNUSED (nr ); 1210 1211float sumf [4 ]; 1212int sumi ; 1213 1214const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 1215for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1216const block_mxfp4x4 * b_ptr = (const block_mxfp4x4 * )vx + (x * nb ); 1217 1218for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [j ]= 0.0 ; 1219for (int l = 0 ;l < nb ;l ++ ) { 1220for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 1221for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1222sumi = 0 ; 1223for (int i = 0 ;i < blocklen ;++ i ) { 1224const int v0 = kvalues_mxfp4 [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0x0F ]; 1225const int v1 = kvalues_mxfp4 [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ]; 1226sumi += ((v0 * a_ptr [l ].qs [k * blocklen + i ])+ (v1 * a_ptr [l ].qs [k * blocklen + i + qk /2 ])); 1227 } 1228sumf [j ]+= sumi * GGML_CPU_E8M0_TO_FP32_HALF (b_ptr [l ].e [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d ); 1229 } 1230 } 1231 } 1232for (int j = 0 ;j < ncols_interleaved ;j ++ )s [x * ncols_interleaved + j ]= sumf [j ]; 1233 } 1234} 1235 1236void ggml_gemv_mxfp4_8x8_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1237const int qk = QK8_0 ; 1238const int nb = n /qk ; 1239const int ncols_interleaved = 8 ; 1240const int blocklen = 8 ; 1241 1242assert (nr == 1 ); 1243assert (n %qk == 0 ); 1244assert (nc %ncols_interleaved == 0 ); 1245 1246UNUSED (bs ); 1247UNUSED (nr ); 1248 1249float sumf [8 ]; 1250int sumi ; 1251 1252const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 1253for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1254const block_mxfp4x8 * b_ptr = (const block_mxfp4x8 * )vx + (x * nb ); 1255 1256for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [j ]= 0.0 ; 1257for (int l = 0 ;l < nb ;l ++ ) { 1258for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 1259for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1260sumi = 0 ; 1261for (int i = 0 ;i < blocklen ;++ i ) { 1262const int v0 = kvalues_mxfp4 [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0x0F ]; 1263const int v1 = kvalues_mxfp4 [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ]; 1264sumi += ((v0 * a_ptr [l ].qs [k * blocklen + i ])+ (v1 * a_ptr [l ].qs [k * blocklen + i + qk /2 ])); 1265 } 1266sumf [j ]+= sumi * GGML_CPU_E8M0_TO_FP32_HALF (b_ptr [l ].e [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d ); 1267 } 1268 } 1269 } 1270for (int j = 0 ;j < ncols_interleaved ;j ++ )s [x * ncols_interleaved + j ]= sumf [j ]; 1271 } 1272} 1273 1274void ggml_gemv_q8_0_4x4_q8_0_generic (int n , 1275float * GGML_RESTRICT s , 1276size_t bs , 1277const void * GGML_RESTRICT vx , 1278const void * GGML_RESTRICT vy , 1279int nr , 1280int nc ) { 1281const int qk = QK8_0 ; 1282const int nb = n /qk ; 1283const int ncols_interleaved = 4 ; 1284const int blocklen = 4 ; 1285 1286assert (nr == 1 ); 1287assert (n %qk == 0 ); 1288assert (nc %ncols_interleaved == 0 ); 1289 1290UNUSED (bs ); 1291UNUSED (nr ); 1292 1293float sumf [4 ]; 1294int sumi ; 1295 1296const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 1297for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1298const block_q8_0x4 * b_ptr = (const block_q8_0x4 * )vx + (x * nb ); 1299 1300for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1301sumf [j ]= 0.0 ; 1302 } 1303for (int l = 0 ;l < nb ;l ++ ) { 1304for (int k = 0 ;k < (qk /blocklen );k ++ ) { 1305for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1306sumi = 0 ; 1307for (int i = 0 ;i < blocklen ;++ i ) { 1308const int v0 = b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]; 1309sumi += v0 * a_ptr [l ].qs [k * blocklen + i ]; 1310 } 1311sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d ); 1312 } 1313 } 1314 } 1315for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1316s [x * ncols_interleaved + j ]= sumf [j ]; 1317 } 1318 } 1319} 1320 1321void ggml_gemv_q8_0_4x8_q8_0_generic (int n , 1322float * GGML_RESTRICT s , 1323size_t bs , 1324const void * GGML_RESTRICT vx , 1325const void * GGML_RESTRICT vy , 1326int nr , 1327int nc ) { 1328const int qk = QK8_0 ; 1329const int nb = n /qk ; 1330const int ncols_interleaved = 4 ; 1331const int blocklen = 8 ; 1332 1333assert (nr == 1 ); 1334assert (n %qk == 0 ); 1335assert (nc %ncols_interleaved == 0 ); 1336 1337UNUSED (bs ); 1338UNUSED (nr ); 1339 1340float sumf [4 ]; 1341int sumi ; 1342 1343const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 1344for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1345const block_q8_0x4 * b_ptr = (const block_q8_0x4 * )vx + (x * nb ); 1346 1347for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1348sumf [j ]= 0.0 ; 1349 } 1350for (int l = 0 ;l < nb ;l ++ ) { 1351for (int k = 0 ;k < (qk /blocklen );k ++ ) { 1352for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1353sumi = 0 ; 1354for (int i = 0 ;i < blocklen ;++ i ) { 1355const int v0 = b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]; 1356sumi += v0 * a_ptr [l ].qs [k * blocklen + i ]; 1357 } 1358sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d ); 1359 } 1360 } 1361 } 1362for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1363s [x * ncols_interleaved + j ]= sumf [j ]; 1364 } 1365 } 1366} 1367 1368// Only enable these for RISC-V. 1369#if defined__riscv_zvfh 1370void ggml_gemv_q4_0_16x1_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1371const int qk = QK8_0 ; 1372const int nb = n /qk ; 1373const int ncols_interleaved = 16 ; 1374const int blocklen = 1 ; 1375 1376assert (n %qk == 0 ); 1377assert (nc %ncols_interleaved == 0 ); 1378 1379UNUSED (s ); 1380UNUSED (bs ); 1381UNUSED (vx ); 1382UNUSED (vy ); 1383UNUSED (nr ); 1384UNUSED (nc ); 1385UNUSED (nb ); 1386UNUSED (ncols_interleaved ); 1387UNUSED (blocklen ); 1388 1389float sumf [16 ]; 1390int sumi ; 1391 1392const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 1393for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1394const block_q4_0x16 * b_ptr = (const block_q4_0x16 * )vx + (x * nb ); 1395 1396for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [j ]= 0.0 ; 1397for (int l = 0 ;l < nb ;l ++ ) { 1398for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 1399for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1400sumi = 0 ; 1401for (int i = 0 ;i < blocklen ;++ i ) { 1402const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] <<4 ); 1403const int v1 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0xF0 ); 1404sumi += ((v0 * a_ptr [l ].qs [k * blocklen + i ])+ (v1 * a_ptr [l ].qs [k * blocklen + i + qk /2 ])) >>4 ; 1405 } 1406sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d ); 1407 } 1408 } 1409 } 1410for (int j = 0 ;j < ncols_interleaved ;j ++ )s [x * ncols_interleaved + j ]= sumf [j ]; 1411 } 1412} 1413 1414void ggml_gemv_q4_K_16x1_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1415const int qk = QK_K ; 1416const int nb = n /qk ; 1417const int ncols_interleaved = 16 ; 1418const int blocklen = 1 ; 1419assert (n %qk == 0 ); 1420assert (nc %ncols_interleaved == 0 ); 1421UNUSED (s ); 1422UNUSED (bs ); 1423UNUSED (vx ); 1424UNUSED (vy ); 1425UNUSED (nr ); 1426UNUSED (nc ); 1427UNUSED (nb ); 1428UNUSED (ncols_interleaved ); 1429UNUSED (blocklen ); 1430float sumf [16 ]; 1431float sum_minf [16 ]; 1432uint8_t scales [128 ]; 1433uint8_t mins [128 ]; 1434int sumi1 ; 1435int sumi2 ; 1436int sumi ; 1437const block_q8_K * a_ptr = (const block_q8_K * )vy ; 1438for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1439const block_q4_Kx16 * b_ptr = (const block_q4_Kx16 * )vx + (x * nb ); 1440for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1441sumf [j ]= 0.0f ; 1442sum_minf [j ]= 0.0f ; 1443 } 1444for (int l = 0 ;l < nb ;l ++ ) { 1445for (int i = 0 ;i < 128 ;i ++ ) { 1446scales [i ]= b_ptr [l ].scales [i ]& 0x0F ; 1447mins [i ]= b_ptr [l ].scales [i ] >>4 ; 1448 } 1449for (int i = 0 ;i < 64 ;i ++ ) { 1450scales [i ] |= (b_ptr [l ].scales [128 + i ]& 0x03 ) <<4 ; 1451mins [i ] |= (b_ptr [l ].scales [128 + i ]& 0x0C ) <<2 ; 1452scales [i + 64 ] |= (b_ptr [l ].scales [128 + i ]& 0x30 ); 1453mins [i + 64 ] |= (b_ptr [l ].scales [128 + i ]& 0xC0 ) >>2 ; 1454 } 1455for (int sb = 0 ;sb < 8 ;sb ++ ) { 1456uint8_t * min = & mins [sb * 16 ]; 1457for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1458sum_minf [j ]+= min [j ]* (a_ptr [l ].bsums [sb * 2 ]+ a_ptr [l ].bsums [sb * 2 + 1 ])* GGML_CPU_FP16_TO_FP32 (b_ptr [l ].dmin [j ])* a_ptr [l ].d ; 1459 } 1460 } 1461for (int sb = 0 ;sb < 8 ;sb += 2 ) { 1462uint8_t * scales_0 = & scales [sb * 16 ]; 1463uint8_t * scales_1 = & scales [(sb + 1 )* 16 ]; 1464for (int i = 0 ;i < QK4_0 ;i ++ ) { 1465for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1466sumi1 = 0 ; 1467sumi2 = 0 ; 1468sumi = 0 ; 1469const int v0 = (int8_t ) (b_ptr [l ].qs [sb * 256 + i * 16 + j ]& 0xF ); 1470const int v1 = (int8_t ) (b_ptr [l ].qs [sb * 256 + i * 16 + j ] >>4 ); 1471sumi1 = (v0 * a_ptr [l ].qs [sb * 32 + i ]); 1472sumi2 = (v1 * a_ptr [l ].qs [sb * 32 + 32 + i ]); 1473sumi1 = sumi1 * scales_0 [j ]; 1474sumi2 = sumi2 * scales_1 [j ]; 1475sumi += sumi1 + sumi2 ; 1476sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* a_ptr [l ].d ; 1477 } 1478 } 1479 } 1480 } 1481for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1482s [x * ncols_interleaved + j ]= sumf [j ]- sum_minf [j ]; 1483 } 1484 } 1485} 1486 1487void ggml_gemv_iq4_nl_16x1_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1488const int qk = QK8_0 ; 1489const int nb = n /qk ; 1490const int ncols_interleaved = 16 ; 1491const int blocklen = 1 ; 1492 1493assert (nr == 1 ); 1494assert (n %qk == 0 ); 1495assert (nc %ncols_interleaved == 0 ); 1496 1497UNUSED (bs ); 1498UNUSED (nr ); 1499 1500float sumf [16 ]; 1501int sumi ; 1502 1503const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 1504for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1505const block_iq4_nlx16 * b_ptr = (const block_iq4_nlx16 * )vx + (x * nb ); 1506 1507for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [j ]= 0.0 ; 1508for (int l = 0 ;l < nb ;l ++ ) { 1509for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 1510for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1511sumi = 0 ; 1512for (int i = 0 ;i < blocklen ;++ i ) { 1513const int v0 = kvalues_iq4nl [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0x0F ]; 1514const int v1 = kvalues_iq4nl [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ]; 1515sumi += ((v0 * a_ptr [l ].qs [k * blocklen + i ])+ (v1 * a_ptr [l ].qs [k * blocklen + i + qk /2 ])); 1516 } 1517sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d ); 1518 } 1519 } 1520 } 1521for (int j = 0 ;j < ncols_interleaved ;j ++ )s [x * ncols_interleaved + j ]= sumf [j ]; 1522 } 1523} 1524 1525void ggml_gemv_q8_0_16x1_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1526const int qk = QK8_0 ; 1527const int nb = n /qk ; 1528const int ncols_interleaved = 16 ; 1529const int blocklen = 1 ; 1530 1531assert (nr == 1 ); 1532assert (n %qk == 0 ); 1533assert (nc %ncols_interleaved == 0 ); 1534 1535UNUSED (bs ); 1536UNUSED (nr ); 1537 1538float sumf [16 ]; 1539int sumi ; 1540 1541const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 1542for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1543const block_q8_0x16 * b_ptr = (const block_q8_0x16 * )vx + (x * nb ); 1544 1545for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1546sumf [j ]= 0.0 ; 1547 } 1548for (int l = 0 ;l < nb ;l ++ ) { 1549for (int k = 0 ;k < (qk /blocklen );k ++ ) { 1550for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1551sumi = 0 ; 1552for (int i = 0 ;i < blocklen ;++ i ) { 1553const int v0 = b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]; 1554sumi += v0 * a_ptr [l ].qs [k * blocklen + i ]; 1555 } 1556sumf [j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d ); 1557 } 1558 } 1559 } 1560for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1561s [x * ncols_interleaved + j ]= sumf [j ]; 1562 } 1563 } 1564} 1565 1566void ggml_gemv_q2_K_16x1_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1567assert (n %QK_K == 0 ); 1568assert (nr == 1 ); 1569assert (nc %16 == 0 ); 1570 1571UNUSED (bs ); 1572UNUSED (nr ); 1573 1574const int nb = n /QK_K ; 1575const block_q2_Kx16 * x = (const block_q2_Kx16 * )vx ; 1576const block_q8_K * y = (const block_q8_K * )vy ; 1577 1578// Layout: Even-Low(0,2,4,6), Odd-Low(1,3,5,7), Even-High(8...), Odd-High(9...) 1579const int sb_perm [16 ]= { 15800 ,4 ,1 ,5 ,2 ,6 ,3 ,7 ,// 0-7 15818 ,12 ,9 ,13 ,10 ,14 ,11 ,15 // 8-15 1582 }; 1583 1584for (int col_tile = 0 ;col_tile < nc ;col_tile += 16 ) { 1585const block_q2_Kx16 * x_ptr = x + (col_tile /16 )* nb ; 1586const block_q8_K * y_ptr = y ; 1587 1588float sumf [16 ]= {0 }; 1589 1590// Loop over K-blocks 1591for (int k_block = 0 ;k_block < nb ;++ k_block ) { 1592int32_t isum [16 ]= {0 }; 1593int32_t summs [16 ]= {0 }; 1594 1595const uint8_t * qs_rhs = x_ptr [k_block ].qs ; 1596const uint8_t * sc_rhs = x_ptr [k_block ].scales ; 1597const int8_t * qs_lhs = y_ptr [k_block ].qs ; 1598const int16_t * bs_lhs = y_ptr [k_block ].bsums ; 1599 1600// Iterate over sub-blocks 0..15 1601for (int sb = 0 ;sb < 16 ;++ sb ) { 1602// Correction Term 1603int16_t bsum = bs_lhs [sb ]; 1604int scale_offset = sb_perm [sb ]* 16 ; 1605 1606for (int col = 0 ;col < 16 ;++ col ) { 1607uint8_t sc_val = sc_rhs [scale_offset + col ]; 1608summs [col ]+= bsum * (sc_val >>4 );// Min is high 4 bits 1609 } 1610 1611// Main Dot Product 1612// Calculate base offsets for Q2 unpacking based on SB 1613int byte_base ; 1614if (sb < 8 )byte_base = (sb %2 == 0 ) ?0 :16 ; 1615else byte_base = (sb %2 == 0 ) ?32 :48 ; 1616 1617int shift = ((sb /2 ) %4 )* 2 ; 1618 1619for (int col = 0 ;col < 16 ;++ col ) { 1620uint8_t sc_val = sc_rhs [scale_offset + col ]; 1621int32_t d_sb = sc_val & 0xF ;// Scale is low 4 bits 1622 1623// Process 16 elements (l=0..15) 1624for (int l = 0 ;l < 16 ;++ l ) { 1625// Q2: Interleaved by column. Byte `l` contains 4 k-values. 1626int qs_idx = (byte_base + l )* 16 + col ; 1627uint8_t q2_val = (qs_rhs [qs_idx ] >>shift )& 3 ; 1628 1629// Q8: Linear access 1630int k = sb * 16 + l ; 1631int8_t q8_val = qs_lhs [k ]; 1632 1633isum [col ]+= q8_val * q2_val * d_sb ; 1634 } 1635 } 1636 } 1637 1638// Finalize K-Block 1639for (int col = 0 ;col < 16 ;++ col ) { 1640float d_lhs = y_ptr [k_block ].d ; 1641float d_rhs = GGML_FP16_TO_FP32 (x_ptr [k_block ].d [col ]); 1642float dm_rhs = GGML_FP16_TO_FP32 (x_ptr [k_block ].dmin [col ]); 1643 1644float d_all = d_lhs * d_rhs ; 1645float d_min = d_lhs * dm_rhs ; 1646 1647sumf [col ]+= (isum [col ]* d_all )- (summs [col ]* d_min ); 1648 } 1649 } 1650 1651for (int col = 0 ;col < 16 ;++ col ) { 1652s [col_tile + col ]= sumf [col ]; 1653 } 1654 } 1655} 1656#endif 1657 1658void ggml_gemm_q4_0_4x4_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1659const int qk = QK8_0 ; 1660const int nb = n /qk ; 1661const int ncols_interleaved = 4 ; 1662const int blocklen = 4 ; 1663 1664assert (n %qk == 0 ); 1665assert (nr %4 == 0 ); 1666assert (nc %ncols_interleaved == 0 ); 1667 1668UNUSED (s ); 1669UNUSED (bs ); 1670UNUSED (vx ); 1671UNUSED (vy ); 1672UNUSED (nr ); 1673UNUSED (nc ); 1674UNUSED (nb ); 1675UNUSED (ncols_interleaved ); 1676UNUSED (blocklen ); 1677 1678 { 1679float sumf [4 ][4 ]; 1680int sumi ; 1681 1682for (int y = 0 ;y < nr /4 ;y ++ ) { 1683const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 1684for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1685const block_q4_0x4 * b_ptr = (const block_q4_0x4 * )vx + (x * nb ); 1686for (int m = 0 ;m < 4 ;m ++ ) { 1687for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [m ][j ]= 0.0 ; 1688 } 1689for (int l = 0 ;l < nb ;l ++ ) { 1690for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 1691for (int m = 0 ;m < 4 ;m ++ ) { 1692for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1693sumi = 0 ; 1694for (int i = 0 ;i < blocklen ;++ i ) { 1695const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] <<4 ); 1696const int v1 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0xF0 ); 1697sumi += ((v0 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i ])+ 1698 (v1 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i + qk /2 * 4 ])) >>4 ; 1699 } 1700sumf [m ][j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [m ]); 1701 } 1702 } 1703 } 1704 } 1705for (int m = 0 ;m < 4 ;m ++ ) { 1706for (int j = 0 ;j < ncols_interleaved ;j ++ ) 1707s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]; 1708 } 1709 } 1710 } 1711 } 1712} 1713 1714void ggml_gemm_q4_0_4x8_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1715const int qk = QK8_0 ; 1716const int nb = n /qk ; 1717const int ncols_interleaved = 4 ; 1718const int blocklen = 8 ; 1719 1720assert (n %qk == 0 ); 1721assert (nr %4 == 0 ); 1722assert (nc %ncols_interleaved == 0 ); 1723 1724UNUSED (s ); 1725UNUSED (bs ); 1726UNUSED (vx ); 1727UNUSED (vy ); 1728UNUSED (nr ); 1729UNUSED (nc ); 1730UNUSED (nb ); 1731UNUSED (ncols_interleaved ); 1732UNUSED (blocklen ); 1733 1734float sumf [4 ][4 ]; 1735int sumi ; 1736 1737for (int y = 0 ;y < nr /4 ;y ++ ) { 1738const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 1739for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1740const block_q4_0x4 * b_ptr = (const block_q4_0x4 * )vx + (x * nb ); 1741for (int m = 0 ;m < 4 ;m ++ ) { 1742for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [m ][j ]= 0.0 ; 1743 } 1744for (int l = 0 ;l < nb ;l ++ ) { 1745for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 1746for (int m = 0 ;m < 4 ;m ++ ) { 1747for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1748sumi = 0 ; 1749for (int i = 0 ;i < blocklen ;++ i ) { 1750const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] <<4 ); 1751const int v1 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0xF0 ); 1752sumi += ((v0 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i ])+ 1753 (v1 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i + qk /2 * 4 ])) >>4 ; 1754 } 1755sumf [m ][j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [m ]); 1756 } 1757 } 1758 } 1759 } 1760for (int m = 0 ;m < 4 ;m ++ ) { 1761for (int j = 0 ;j < ncols_interleaved ;j ++ ) 1762s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]; 1763 } 1764 } 1765 } 1766} 1767 1768void ggml_gemm_q4_0_8x8_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1769const int qk = QK8_0 ; 1770const int nb = n /qk ; 1771const int ncols_interleaved = 8 ; 1772const int blocklen = 8 ; 1773 1774assert (n %qk == 0 ); 1775assert (nr %4 == 0 ); 1776assert (nc %ncols_interleaved == 0 ); 1777 1778UNUSED (s ); 1779UNUSED (bs ); 1780UNUSED (vx ); 1781UNUSED (vy ); 1782UNUSED (nr ); 1783UNUSED (nc ); 1784UNUSED (nb ); 1785UNUSED (ncols_interleaved ); 1786UNUSED (blocklen ); 1787 1788float sumf [4 ][8 ]; 1789int sumi ; 1790 1791for (int y = 0 ;y < nr /4 ;y ++ ) { 1792const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 1793for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1794const block_q4_0x8 * b_ptr = (const block_q4_0x8 * )vx + (x * nb ); 1795for (int m = 0 ;m < 4 ;m ++ ) { 1796for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [m ][j ]= 0.0 ; 1797 } 1798for (int l = 0 ;l < nb ;l ++ ) { 1799for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 1800for (int m = 0 ;m < 4 ;m ++ ) { 1801for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1802sumi = 0 ; 1803for (int i = 0 ;i < blocklen ;++ i ) { 1804const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] <<4 ); 1805const int v1 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0xF0 ); 1806sumi += ((v0 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i ])+ 1807 (v1 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i + qk /2 * 4 ])) >>4 ; 1808 } 1809sumf [m ][j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [m ]); 1810 } 1811 } 1812 } 1813 } 1814for (int m = 0 ;m < 4 ;m ++ ) { 1815for (int j = 0 ;j < ncols_interleaved ;j ++ ) 1816s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]; 1817 } 1818 } 1819 } 1820} 1821 1822void ggml_gemm_q4_K_8x4_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1823const int qk = QK_K ; 1824const int nb = n /qk ; 1825const int ncols_interleaved = 8 ; 1826const int blocklen = 4 ; 1827static const uint32_t kmask1 = 0x3f3f3f3f ; 1828static const uint32_t kmask2 = 0x0f0f0f0f ; 1829static const uint32_t kmask3 = 0x03030303 ; 1830 1831assert (n %qk == 0 ); 1832assert (nr %4 == 0 ); 1833assert (nc %ncols_interleaved == 0 ); 1834 1835UNUSED (nb ); 1836UNUSED (ncols_interleaved ); 1837UNUSED (blocklen ); 1838 1839float sumf [4 ][8 ]; 1840float sum_minf [4 ][8 ]; 1841uint32_t utmp [32 ]; 1842int sumi1 ; 1843int sumi2 ; 1844int sumi ; 1845 1846for (int y = 0 ;y < nr /4 ;y ++ ) { 1847const block_q8_Kx4 * a_ptr = (const block_q8_Kx4 * )vy + (y * nb ); 1848for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1849const block_q4_Kx8 * b_ptr = (const block_q4_Kx8 * )vx + (x * nb ); 1850for (int m = 0 ;m < 4 ;m ++ ) { 1851for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1852sumf [m ][j ]= 0.0 ; 1853sum_minf [m ][j ]= 0.0 ; 1854 } 1855 } 1856for (int l = 0 ;l < nb ;l ++ ) { 1857for (int sb = 0 ;sb < 8 ;sb ++ ) { 1858memcpy (utmp + sb * 4 ,b_ptr [l ].scales + sb * 12 ,12 ); 1859utmp [sb * 4 + 3 ]= ((utmp [sb * 4 + 2 ] >>4 )& kmask2 ) | (((utmp [sb * 4 + 1 ] >>6 )& kmask3 ) <<4 ); 1860const uint32_t uaux_0 = utmp [sb * 4 + 1 ]& kmask1 ; 1861utmp [sb * 4 + 1 ]= (utmp [sb * 4 + 2 ]& kmask2 ) | (((utmp [sb * 4 + 0 ] >>6 )& kmask3 ) <<4 ); 1862utmp [sb * 4 + 2 ]= uaux_0 ; 1863utmp [sb * 4 + 0 ] &=kmask1 ; 1864 } 1865for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 1866uint8_t * scales_0 = (uint8_t * )utmp + (k /8 )* 32 ; 1867uint8_t * scales_1 = (uint8_t * )utmp + (k /8 )* 32 + 16 ; 1868for (int m = 0 ;m < 4 ;m ++ ) { 1869for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1870sumi1 = 0 ; 1871sumi2 = 0 ; 1872sumi = 0 ; 1873for (int i = 0 ;i < blocklen ;++ i ) { 1874const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0xF ); 1875const int v1 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ); 1876sumi1 = (v0 * a_ptr [l ].qs [(k /8 )* 256 + (k %8 )* 4 * blocklen + m * blocklen + i ]); 1877sumi2 = (v1 * a_ptr [l ].qs [(k /8 )* 256 + (k %8 )* 4 * blocklen + m * blocklen + i + 128 ]); 1878sumi1 = sumi1 * scales_0 [j ]; 1879sumi2 = sumi2 * scales_1 [j ]; 1880sumi += sumi1 + sumi2 ; 1881 } 1882sumf [m ][j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* a_ptr [l ].d [m ]; 1883 } 1884 } 1885 } 1886for (int sb = 0 ;sb < 8 ;sb ++ ) { 1887uint8_t * mins = (uint8_t * )utmp + 8 + sb * 16 ; 1888for (int m = 0 ;m < 4 ;m ++ ) { 1889const int16_t * bsums = a_ptr [l ].bsums + (sb * 8 )+ (m * 4 )- ((sb %2 )* 6 ); 1890for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1891sum_minf [m ][j ]+= mins [j ]* (bsums [0 ]+ bsums [1 ])* GGML_CPU_FP16_TO_FP32 (b_ptr [l ].dmin [j ])* a_ptr [l ].d [m ]; 1892 } 1893 } 1894 } 1895 } 1896for (int m = 0 ;m < 4 ;m ++ ) { 1897for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1898s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]- sum_minf [m ][j ]; 1899 } 1900 } 1901 } 1902 } 1903} 1904 1905void ggml_gemm_q4_K_8x8_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1906const int qk = QK_K ; 1907const int nb = n /qk ; 1908const int ncols_interleaved = 8 ; 1909const int blocklen = 8 ; 1910static const uint32_t kmask1 = 0x3f3f3f3f ; 1911static const uint32_t kmask2 = 0x0f0f0f0f ; 1912static const uint32_t kmask3 = 0x03030303 ; 1913 1914assert (n %qk == 0 ); 1915assert (nr %4 == 0 ); 1916assert (nc %ncols_interleaved == 0 ); 1917 1918UNUSED (bs ); 1919 1920float sumf [4 ][8 ]; 1921float sum_minf [4 ][8 ]; 1922uint32_t utmp [32 ]; 1923int sumi1 ; 1924int sumi2 ; 1925int sumi ; 1926 1927for (int y = 0 ;y < nr /4 ;y ++ ) { 1928const block_q8_Kx4 * a_ptr = (const block_q8_Kx4 * )vy + (y * nb ); 1929for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1930const block_q4_Kx8 * b_ptr = (const block_q4_Kx8 * )vx + (x * nb ); 1931for (int m = 0 ;m < 4 ;m ++ ) { 1932for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1933sumf [m ][j ]= 0.0 ; 1934sum_minf [m ][j ]= 0.0 ; 1935 } 1936 } 1937for (int l = 0 ;l < nb ;l ++ ) { 1938for (int sb = 0 ;sb < 8 ;sb ++ ) { 1939memcpy (utmp + sb * 4 ,b_ptr [l ].scales + sb * 12 ,12 ); 1940utmp [sb * 4 + 3 ]= ((utmp [sb * 4 + 2 ] >>4 )& kmask2 ) | (((utmp [sb * 4 + 1 ] >>6 )& kmask3 ) <<4 ); 1941const uint32_t uaux_0 = utmp [sb * 4 + 1 ]& kmask1 ; 1942utmp [sb * 4 + 1 ]= (utmp [sb * 4 + 2 ]& kmask2 ) | (((utmp [sb * 4 + 0 ] >>6 )& kmask3 ) <<4 ); 1943utmp [sb * 4 + 2 ]= uaux_0 ; 1944utmp [sb * 4 + 0 ] &=kmask1 ; 1945 } 1946for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 1947uint8_t * scales_0 = (uint8_t * )utmp + (k /4 )* 32 ; 1948uint8_t * scales_1 = (uint8_t * )utmp + (k /4 )* 32 + 16 ; 1949for (int m = 0 ;m < 4 ;m ++ ) { 1950for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1951sumi1 = 0 ; 1952sumi2 = 0 ; 1953sumi = 0 ; 1954for (int i = 0 ;i < blocklen ;++ i ) { 1955const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0xF ); 1956const int v1 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ); 1957sumi1 = (v0 * a_ptr [l ].qs [(k >>2 )* 256 + (k %4 )* 4 * blocklen + m * blocklen + i ]); 1958sumi2 = (v1 * a_ptr [l ].qs [(k >>2 )* 256 + (k %4 )* 4 * blocklen + m * blocklen + i + 128 ]); 1959sumi1 = sumi1 * scales_0 [j ]; 1960sumi2 = sumi2 * scales_1 [j ]; 1961sumi += sumi1 + sumi2 ; 1962 } 1963sumf [m ][j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* a_ptr [l ].d [m ]; 1964 } 1965 } 1966 } 1967for (int sb = 0 ;sb < 8 ;sb ++ ) { 1968uint8_t * mins = (uint8_t * )utmp + 8 + sb * 16 ; 1969for (int m = 0 ;m < 4 ;m ++ ) { 1970const int16_t * bsums = a_ptr [l ].bsums + (sb * 8 )+ (m * 4 )- ((sb %2 )* 6 ); 1971for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1972sum_minf [m ][j ]+= mins [j ]* (bsums [0 ]+ bsums [1 ])* GGML_CPU_FP16_TO_FP32 (b_ptr [l ].dmin [j ])* a_ptr [l ].d [m ]; 1973 } 1974 } 1975 } 1976 } 1977for (int m = 0 ;m < 4 ;m ++ ) { 1978for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 1979s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]- sum_minf [m ][j ]; 1980 } 1981 } 1982 } 1983 } 1984} 1985 1986void ggml_gemm_q2_K_8x8_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1987const int qk = QK_K ; 1988const int nb = n /qk ; 1989const int ncols_interleaved = 8 ; 1990const int blocklen = 8 ; 1991 1992assert (n %qk == 0 ); 1993assert (nr %4 == 0 ); 1994assert (nc %ncols_interleaved == 0 ); 1995 1996UNUSED (s ); 1997UNUSED (bs ); 1998UNUSED (vx ); 1999UNUSED (vy ); 2000UNUSED (nr ); 2001UNUSED (nc ); 2002UNUSED (nb ); 2003UNUSED (ncols_interleaved ); 2004UNUSED (blocklen ); 2005 2006float sumf [4 ][8 ]; 2007float sum_minf [4 ][8 ]; 2008int sumi1 ,sumi2 ,sumi3 ,sumi4 ; 2009int sumi ; 2010 2011for (int y = 0 ;y < nr /4 ;y ++ ) { 2012const block_q8_Kx4 * a_ptr = (const block_q8_Kx4 * )vy + (y * nb ); 2013for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 2014const block_q2_Kx8 * b_ptr = (const block_q2_Kx8 * )vx + (x * nb ); 2015for (int m = 0 ;m < 4 ;m ++ ) { 2016for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2017sumf [m ][j ]= 0.0 ; 2018sum_minf [m ][j ]= 0.0 ; 2019 } 2020 } 2021for (int l = 0 ;l < nb ;l ++ ) { 2022for (int k = 0 ;k < (qk / (4 * blocklen ));k ++ ) { 2023 2024const uint8_t * scales_0 = b_ptr [l ].scales + (k /4 )* 64 ; 2025const uint8_t * scales_1 = b_ptr [l ].scales + (k /4 )* 64 + 16 ; 2026const uint8_t * scales_2 = b_ptr [l ].scales + (k /4 )* 64 + 32 ; 2027const uint8_t * scales_3 = b_ptr [l ].scales + (k /4 )* 64 + 48 ; 2028for (int m = 0 ;m < 4 ;m ++ ) { 2029for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2030sumi1 = 0 ; 2031sumi2 = 0 ; 2032sumi3 = 0 ; 2033sumi4 = 0 ; 2034sumi = 0 ; 2035int offset = ((k /2 ) %2 )+ j * 2 ; 2036for (int i = 0 ;i < blocklen ;++ i ){ 2037const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 3 ); 2038const int v1 = (int8_t ) ((b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>2 )& 3 ); 2039const int v2 = (int8_t ) ((b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 )& 3 ); 2040const int v3 = (int8_t ) ((b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>6 )& 3 ); 2041sumi1 = (v0 * a_ptr [l ].qs [(k >>2 )* 512 + (k %4 )* 4 * blocklen + m * blocklen + i ]); 2042sumi2 = (v1 * a_ptr [l ].qs [(k >>2 )* 512 + (k %4 )* 4 * blocklen + m * blocklen + i + 128 ]); 2043sumi3 = (v2 * a_ptr [l ].qs [(k >>2 )* 512 + (k %4 )* 4 * blocklen + m * blocklen + i + 256 ]); 2044sumi4 = (v3 * a_ptr [l ].qs [(k >>2 )* 512 + (k %4 )* 4 * blocklen + m * blocklen + i + 384 ]); 2045sumi1 = sumi1 * (scales_0 [offset ]& 0xF ); 2046sumi2 = sumi2 * (scales_1 [offset ]& 0xF ); 2047sumi3 = sumi3 * (scales_2 [offset ]& 0xF ); 2048sumi4 = sumi4 * (scales_3 [offset ]& 0xF ); 2049sumi += sumi1 + sumi2 + sumi3 + sumi4 ; 2050 } 2051sumf [m ][j ]+= sumi * GGML_FP16_TO_FP32 (b_ptr [l ].d [j ])* a_ptr [l ].d [m ]; 2052 } 2053 } 2054 } 2055for (int sb = 0 ;sb < 8 ;sb ++ ) { 2056const uint8_t * mins = b_ptr [l ].scales + sb * 16 ; 2057for (int m = 0 ;m < 4 ;m ++ ) { 2058const int16_t * bsums = a_ptr [l ].bsums + (sb * 8 )+ (m * 4 )- ((sb %2 )* 6 ); 2059for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2060int mins_prod = ((mins [j * 2 ] >>4 )* bsums [0 ]+ (mins [(j * 2 )+ 1 ] >>4 )* bsums [1 ]); 2061sum_minf [m ][j ]+= (mins_prod )* GGML_FP16_TO_FP32 (b_ptr [l ].dmin [j ])* a_ptr [l ].d [m ]; 2062 } 2063 } 2064 } 2065 } 2066 2067for (int m = 0 ;m < 4 ;m ++ ) { 2068for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2069s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]- sum_minf [m ][j ]; 2070 } 2071 } 2072 } 2073 } 2074} 2075 2076void ggml_gemm_q5_K_8x4_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 2077ggml_gemm_q5_K_NxM_q8_K_generic_impl < 4 ,8 > (n ,s ,bs ,vx ,vy ,nr ,nc ); 2078} 2079 2080void ggml_gemm_q5_K_8x8_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 2081ggml_gemm_q5_K_NxM_q8_K_generic_impl < 8 ,8 > (n ,s ,bs ,vx ,vy ,nr ,nc ); 2082} 2083 2084void ggml_gemm_q6_K_8x4_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 2085ggml_gemm_q6_K_NxM_q8_K_generic_impl < 4 ,8 > (n ,s ,bs ,vx ,vy ,nr ,nc ); 2086} 2087 2088void ggml_gemm_q6_K_8x8_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 2089ggml_gemm_q6_K_NxM_q8_K_generic_impl < 8 ,8 > (n ,s ,bs ,vx ,vy ,nr ,nc ); 2090} 2091 2092void ggml_gemm_iq4_nl_4x4_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 2093const int qk = QK8_0 ; 2094const int nb = n /qk ; 2095const int ncols_interleaved = 4 ; 2096const int blocklen = 4 ; 2097 2098assert (n %qk == 0 ); 2099assert (nr %4 == 0 ); 2100assert (nc %ncols_interleaved == 0 ); 2101 2102UNUSED (s ); 2103UNUSED (bs ); 2104UNUSED (vx ); 2105UNUSED (vy ); 2106UNUSED (nr ); 2107UNUSED (nc ); 2108UNUSED (nb ); 2109UNUSED (ncols_interleaved ); 2110UNUSED (blocklen ); 2111 2112 { 2113float sumf [4 ][4 ]; 2114int sumi ; 2115 2116for (int y = 0 ;y < nr /4 ;y ++ ) { 2117const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 2118for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 2119const block_iq4_nlx4 * b_ptr = (const block_iq4_nlx4 * )vx + (x * nb ); 2120for (int m = 0 ;m < 4 ;m ++ ) { 2121for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [m ][j ]= 0.0 ; 2122 } 2123for (int l = 0 ;l < nb ;l ++ ) { 2124for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 2125for (int m = 0 ;m < 4 ;m ++ ) { 2126for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2127sumi = 0 ; 2128for (int i = 0 ;i < blocklen ;++ i ) { 2129const int v0 = kvalues_iq4nl [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0x0F ]; 2130const int v1 = kvalues_iq4nl [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ]; 2131sumi += ((v0 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i ])+ 2132 (v1 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i + qk /2 * 4 ])); 2133 } 2134sumf [m ][j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [m ]); 2135 } 2136 } 2137 } 2138 } 2139for (int m = 0 ;m < 4 ;m ++ ) { 2140for (int j = 0 ;j < ncols_interleaved ;j ++ ) 2141s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]; 2142 } 2143 } 2144 } 2145 } 2146} 2147 2148void ggml_gemm_iq4_nl_8x8_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 2149const int qk = QK8_0 ; 2150const int nb = n /qk ; 2151const int ncols_interleaved = 8 ; 2152const int blocklen = 8 ; 2153 2154assert (n %qk == 0 ); 2155assert (nr %4 == 0 ); 2156assert (nc %ncols_interleaved == 0 ); 2157 2158float sumf [4 ][8 ]; 2159int sumi ; 2160 2161for (int y = 0 ;y < nr /4 ;y ++ ) { 2162const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 2163for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 2164const block_iq4_nlx8 * b_ptr = (const block_iq4_nlx8 * )vx + (x * nb ); 2165for (int m = 0 ;m < 4 ;m ++ ) { 2166for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [m ][j ]= 0.0 ; 2167 } 2168for (int l = 0 ;l < nb ;l ++ ) { 2169for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 2170for (int m = 0 ;m < 4 ;m ++ ) { 2171for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2172sumi = 0 ; 2173for (int i = 0 ;i < blocklen ;++ i ) { 2174const int v0 = kvalues_iq4nl [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0x0F ]; 2175const int v1 = kvalues_iq4nl [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ]; 2176sumi += ((v0 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i ])+ 2177 (v1 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i + qk /2 * 4 ])); 2178 } 2179sumf [m ][j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [m ]); 2180 } 2181 } 2182 } 2183 } 2184for (int m = 0 ;m < 4 ;m ++ ) { 2185for (int j = 0 ;j < ncols_interleaved ;j ++ ) 2186s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]; 2187 } 2188 } 2189 } 2190} 2191 2192void ggml_gemm_mxfp4_4x4_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 2193const int qk = QK8_0 ; 2194const int nb = n /qk ; 2195const int ncols_interleaved = 4 ; 2196const int blocklen = 4 ; 2197 2198assert (n %qk == 0 ); 2199assert (nr %4 == 0 ); 2200assert (nc %ncols_interleaved == 0 ); 2201 2202float sumf [4 ][4 ]; 2203int sumi ; 2204 2205for (int y = 0 ;y < nr /4 ;y ++ ) { 2206const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 2207for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 2208const block_mxfp4x4 * b_ptr = (const block_mxfp4x4 * )vx + (x * nb ); 2209for (int m = 0 ;m < 4 ;m ++ ) { 2210for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [m ][j ]= 0.0 ; 2211 } 2212for (int l = 0 ;l < nb ;l ++ ) { 2213for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 2214for (int m = 0 ;m < 4 ;m ++ ) { 2215for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2216sumi = 0 ; 2217for (int i = 0 ;i < blocklen ;++ i ) { 2218const int v0 = kvalues_mxfp4 [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0x0F ]; 2219const int v1 = kvalues_mxfp4 [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ]; 2220sumi += ((v0 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i ])+ 2221 (v1 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i + qk /2 * 4 ])); 2222 } 2223sumf [m ][j ]+= sumi * GGML_CPU_E8M0_TO_FP32_HALF (b_ptr [l ].e [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [m ]); 2224 } 2225 } 2226 } 2227 } 2228for (int m = 0 ;m < 4 ;m ++ ) { 2229for (int j = 0 ;j < ncols_interleaved ;j ++ ) 2230s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]; 2231 } 2232 } 2233 } 2234} 2235 2236void ggml_gemm_mxfp4_8x8_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 2237const int qk = QK8_0 ; 2238const int nb = n /qk ; 2239const int ncols_interleaved = 8 ; 2240const int blocklen = 8 ; 2241 2242assert (n %qk == 0 ); 2243assert (nr %4 == 0 ); 2244assert (nc %ncols_interleaved == 0 ); 2245 2246float sumf [4 ][8 ]; 2247int sumi ; 2248 2249for (int y = 0 ;y < nr /4 ;y ++ ) { 2250const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 2251for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 2252const block_mxfp4x8 * b_ptr = (const block_mxfp4x8 * )vx + (x * nb ); 2253for (int m = 0 ;m < 4 ;m ++ ) { 2254for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [m ][j ]= 0.0 ; 2255 } 2256for (int l = 0 ;l < nb ;l ++ ) { 2257for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 2258for (int m = 0 ;m < 4 ;m ++ ) { 2259for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2260sumi = 0 ; 2261for (int i = 0 ;i < blocklen ;++ i ) { 2262const int v0 = kvalues_mxfp4 [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0x0F ]; 2263const int v1 = kvalues_mxfp4 [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ]; 2264sumi += ((v0 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i ])+ 2265 (v1 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i + qk /2 * 4 ])); 2266 } 2267sumf [m ][j ]+= sumi * GGML_CPU_E8M0_TO_FP32_HALF (b_ptr [l ].e [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [m ]); 2268 } 2269 } 2270 } 2271 } 2272for (int m = 0 ;m < 4 ;m ++ ) { 2273for (int j = 0 ;j < ncols_interleaved ;j ++ ) 2274s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]; 2275 } 2276 } 2277 } 2278} 2279 2280void ggml_gemm_q8_0_4x4_q8_0_generic (int n , 2281float * GGML_RESTRICT s , 2282size_t bs , 2283const void * GGML_RESTRICT vx , 2284const void * GGML_RESTRICT vy , 2285int nr , 2286int nc ) { 2287const int qk = QK8_0 ; 2288const int nb = n /qk ; 2289const int ncols_interleaved = 4 ; 2290const int blocklen = 4 ; 2291 2292assert (n %qk == 0 ); 2293assert (nr %4 == 0 ); 2294assert (nc %ncols_interleaved == 0 ); 2295 2296float sumf [4 ][4 ]; 2297int sumi ; 2298 2299for (int y = 0 ;y < nr /4 ;y ++ ) { 2300const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 2301for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 2302const block_q8_0x4 * b_ptr = (const block_q8_0x4 * )vx + (x * nb ); 2303for (int m = 0 ;m < 4 ;m ++ ) { 2304for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2305sumf [m ][j ]= 0.0 ; 2306 } 2307 } 2308for (int l = 0 ;l < nb ;l ++ ) { 2309for (int k = 0 ;k < (qk /blocklen );k ++ ) { 2310for (int m = 0 ;m < 4 ;m ++ ) { 2311for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2312sumi = 0 ; 2313for (int i = 0 ;i < blocklen ;++ i ) { 2314const int v0 = b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]; 2315sumi += v0 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i ]; 2316 } 2317sumf [m ][j ]+= 2318sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [m ]); 2319 } 2320 } 2321 } 2322 } 2323for (int m = 0 ;m < 4 ;m ++ ) { 2324for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2325s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]; 2326 } 2327 } 2328 } 2329 } 2330} 2331 2332 2333 2334void ggml_gemm_q8_0_4x8_q8_0_generic (int n , 2335float * GGML_RESTRICT s , 2336size_t bs , 2337const void * GGML_RESTRICT vx , 2338const void * GGML_RESTRICT vy , 2339int nr , 2340int nc ) { 2341const int qk = QK8_0 ; 2342const int nb = n /qk ; 2343const int ncols_interleaved = 4 ; 2344const int blocklen = 8 ; 2345 2346assert (n %qk == 0 ); 2347assert (nr %4 == 0 ); 2348assert (nc %ncols_interleaved == 0 ); 2349 2350float sumf [4 ][4 ]; 2351int sumi ; 2352 2353for (int y = 0 ;y < nr /4 ;y ++ ) { 2354const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 2355for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 2356const block_q8_0x4 * b_ptr = (const block_q8_0x4 * )vx + (x * nb ); 2357for (int m = 0 ;m < 4 ;m ++ ) { 2358for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2359sumf [m ][j ]= 0.0 ; 2360 } 2361 } 2362for (int l = 0 ;l < nb ;l ++ ) { 2363for (int k = 0 ;k < (qk /blocklen );k ++ ) { 2364for (int m = 0 ;m < 4 ;m ++ ) { 2365for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2366sumi = 0 ; 2367for (int i = 0 ;i < blocklen ;++ i ) { 2368const int v0 = b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]; 2369sumi += v0 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i ]; 2370 } 2371sumf [m ][j ]+= 2372sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [m ]); 2373 } 2374 } 2375 } 2376 } 2377for (int m = 0 ;m < 4 ;m ++ ) { 2378for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2379s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]; 2380 } 2381 } 2382 } 2383 } 2384} 2385 2386// Only enable these for RISC-V. 2387#if defined__riscv_zvfh 2388void ggml_gemm_q4_0_16x1_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 2389const int qk = QK8_0 ; 2390const int nb = n /qk ; 2391const int ncols_interleaved = 16 ; 2392const int blocklen = 1 ; 2393 2394assert (n %qk == 0 ); 2395assert (nr %4 == 0 ); 2396assert (nc %ncols_interleaved == 0 ); 2397 2398UNUSED (s ); 2399UNUSED (bs ); 2400UNUSED (vx ); 2401UNUSED (vy ); 2402UNUSED (nr ); 2403UNUSED (nc ); 2404UNUSED (nb ); 2405UNUSED (ncols_interleaved ); 2406UNUSED (blocklen ); 2407 2408float sumf [4 ][16 ]; 2409int sumi ; 2410 2411for (int y = 0 ;y < nr /4 ;y ++ ) { 2412const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 2413for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 2414const block_q4_0x16 * b_ptr = (const block_q4_0x16 * )vx + (x * nb ); 2415for (int m = 0 ;m < 4 ;m ++ ) { 2416for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [m ][j ]= 0.0 ; 2417 } 2418for (int l = 0 ;l < nb ;l ++ ) { 2419for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 2420for (int m = 0 ;m < 4 ;m ++ ) { 2421for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2422sumi = 0 ; 2423for (int i = 0 ;i < blocklen ;++ i ) { 2424const int v0 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] <<4 ); 2425const int v1 = (int8_t ) (b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0xF0 ); 2426sumi += ((v0 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i ])+ 2427 (v1 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i + qk /2 * 4 ])) >>4 ; 2428 } 2429sumf [m ][j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [m ]); 2430 } 2431 } 2432 } 2433 } 2434for (int m = 0 ;m < 4 ;m ++ ) { 2435for (int j = 0 ;j < ncols_interleaved ;j ++ ) 2436s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]; 2437 } 2438 } 2439 } 2440} 2441 2442void ggml_gemm_q4_K_16x1_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 2443const int qk = QK_K ; 2444const int nb = n /qk ; 2445const int ncols_interleaved = 16 ; 2446const int blocklen = 1 ; 2447 2448assert (n %qk == 0 ); 2449assert (nr %4 == 0 ); 2450assert (nc %ncols_interleaved == 0 ); 2451 2452UNUSED (s ); 2453UNUSED (bs ); 2454UNUSED (vx ); 2455UNUSED (vy ); 2456UNUSED (nr ); 2457UNUSED (nc ); 2458UNUSED (nb ); 2459UNUSED (ncols_interleaved ); 2460UNUSED (blocklen ); 2461 2462float sumf [4 ][16 ]; 2463float sum_minf [4 ][16 ]; 2464uint8_t scales [128 ]; 2465uint8_t mins [128 ]; 2466int sumi1 ; 2467int sumi2 ; 2468int sumi ; 2469 2470for (int y = 0 ;y < nr /4 ;y ++ ) { 2471const block_q8_Kx4 * a_ptr = (const block_q8_Kx4 * )vy + (y * nb ); 2472for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 2473const block_q4_Kx16 * b_ptr = (const block_q4_Kx16 * )vx + (x * nb ); 2474for (int m = 0 ;m < 4 ;m ++ ) { 2475for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2476sumf [m ][j ]= 0.0 ; 2477sum_minf [m ][j ]= 0.0 ; 2478 } 2479 } 2480for (int l = 0 ;l < nb ;l ++ ) { 2481for (int i = 0 ;i < 128 ;i ++ ) { 2482scales [i ]= b_ptr [l ].scales [i ]& 0x0F ; 2483mins [i ]= b_ptr [l ].scales [i ] >>4 ; 2484 } 2485for (int i = 0 ;i < 64 ;i ++ ) { 2486scales [i ] |= (b_ptr [l ].scales [128 + i ]& 0x03 ) <<4 ; 2487mins [i ] |= (b_ptr [l ].scales [128 + i ]& 0x0C ) <<2 ; 2488scales [i + 64 ] |= (b_ptr [l ].scales [128 + i ]& 0x30 ); 2489mins [i + 64 ] |= (b_ptr [l ].scales [128 + i ]& 0xC0 ) >>2 ; 2490 } 2491 2492for (int sb = 0 ;sb < 8 ;sb ++ ) { 2493uint8_t * min = & mins [sb * 16 ]; 2494for (int m = 0 ;m < 4 ;m ++ ) { 2495const int16_t bsums = a_ptr [l ].bsums [sb * 8 + m ]+ a_ptr [l ].bsums [sb * 8 + m + 4 ]; 2496for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2497sum_minf [m ][j ]+= min [j ]* bsums * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].dmin [j ])* a_ptr [l ].d [m ]; 2498 } 2499 } 2500 } 2501 2502for (int sb = 0 ;sb < 8 ;sb += 2 ) { 2503uint8_t * scales_0 = & scales [sb * 16 ]; 2504uint8_t * scales_1 = & scales [(sb + 1 )* 16 ]; 2505 2506for (int i = 0 ;i < QK4_0 ;i ++ ) { 2507for (int m = 0 ;m < 4 ;m ++ ) { 2508for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2509sumi1 = 0 ; 2510sumi2 = 0 ; 2511sumi = 0 ; 2512 2513const int v0 = (int8_t ) (b_ptr [l ].qs [sb * 256 + i * 16 + j ]& 0xF ); 2514const int v1 = (int8_t ) (b_ptr [l ].qs [sb * 256 + i * 16 + j ] >>4 ); 2515sumi1 = (v0 * a_ptr [l ].qs [sb * 4 * 32 + i * 4 + m ]); 2516sumi2 = (v1 * a_ptr [l ].qs [sb * 4 * 32 + 32 * 4 + i * 4 + m ]); 2517sumi1 = sumi1 * scales_0 [j ]; 2518sumi2 = sumi2 * scales_1 [j ]; 2519sumi += sumi1 + sumi2 ; 2520 2521sumf [m ][j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* a_ptr [l ].d [m ]; 2522 } 2523 } 2524 } 2525 } 2526 } 2527for (int m = 0 ;m < 4 ;m ++ ) { 2528for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2529s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]- sum_minf [m ][j ]; 2530 } 2531 } 2532 } 2533 } 2534} 2535 2536void ggml_gemm_iq4_nl_16x1_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 2537const int qk = QK8_0 ; 2538const int nb = n /qk ; 2539const int ncols_interleaved = 16 ; 2540const int blocklen = 1 ; 2541 2542assert (n %qk == 0 ); 2543assert (nr %4 == 0 ); 2544assert (nc %ncols_interleaved == 0 ); 2545 2546float sumf [4 ][16 ]; 2547int sumi ; 2548 2549for (int y = 0 ;y < nr /4 ;y ++ ) { 2550const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 2551for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 2552const block_iq4_nlx16 * b_ptr = (const block_iq4_nlx16 * )vx + (x * nb ); 2553for (int m = 0 ;m < 4 ;m ++ ) { 2554for (int j = 0 ;j < ncols_interleaved ;j ++ )sumf [m ][j ]= 0.0 ; 2555 } 2556for (int l = 0 ;l < nb ;l ++ ) { 2557for (int k = 0 ;k < (qk / (2 * blocklen ));k ++ ) { 2558for (int m = 0 ;m < 4 ;m ++ ) { 2559for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2560sumi = 0 ; 2561for (int i = 0 ;i < blocklen ;++ i ) { 2562const int v0 = kvalues_iq4nl [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]& 0x0F ]; 2563const int v1 = kvalues_iq4nl [b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ] >>4 ]; 2564sumi += ((v0 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i ])+ 2565 (v1 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i + (qk /2 )* 4 ])); 2566 } 2567sumf [m ][j ]+= sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [m ]); 2568 } 2569 } 2570 } 2571 } 2572for (int m = 0 ;m < 4 ;m ++ ) { 2573for (int j = 0 ;j < ncols_interleaved ;j ++ ) 2574s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]; 2575 } 2576 } 2577 } 2578} 2579 2580void ggml_gemm_q8_0_16x1_q8_0_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 2581const int qk = QK8_0 ; 2582const int nb = n /qk ; 2583const int ncols_interleaved = 16 ; 2584const int blocklen = 1 ; 2585 2586assert (n %qk == 0 ); 2587assert (nr %4 == 0 ); 2588assert (nc %ncols_interleaved == 0 ); 2589 2590float sumf [4 ][16 ]; 2591int sumi ; 2592 2593for (int y = 0 ;y < nr /4 ;y ++ ) { 2594const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 2595for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 2596const block_q8_0x16 * b_ptr = (const block_q8_0x16 * )vx + (x * nb ); 2597for (int m = 0 ;m < 4 ;m ++ ) { 2598for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2599sumf [m ][j ]= 0.0 ; 2600 } 2601 } 2602for (int l = 0 ;l < nb ;l ++ ) { 2603for (int k = 0 ;k < (qk /blocklen );k ++ ) { 2604for (int m = 0 ;m < 4 ;m ++ ) { 2605for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2606sumi = 0 ; 2607for (int i = 0 ;i < blocklen ;++ i ) { 2608const int v0 = b_ptr [l ].qs [k * ncols_interleaved * blocklen + j * blocklen + i ]; 2609sumi += v0 * a_ptr [l ].qs [k * 4 * blocklen + m * blocklen + i ]; 2610 } 2611sumf [m ][j ]+= 2612sumi * GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [j ])* GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [m ]); 2613 } 2614 } 2615 } 2616 } 2617for (int m = 0 ;m < 4 ;m ++ ) { 2618for (int j = 0 ;j < ncols_interleaved ;j ++ ) { 2619s [(y * 4 + m )* bs + x * ncols_interleaved + j ]= sumf [m ][j ]; 2620 } 2621 } 2622 } 2623 } 2624} 2625 2626 2627void ggml_gemm_q2_K_16x1_q8_K_generic (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 2628assert (n %QK_K == 0 ); 2629assert (nr %4 == 0 ); 2630assert (nc %16 == 0 ); 2631const int nb = n /QK_K ; 2632const block_q2_Kx16 * x = (const block_q2_Kx16 * )vx ; 2633const block_q8_Kx4 * y = (const block_q8_Kx4 * )vy ; 2634 2635const int sb_perm [16 ]= { 26360 ,4 ,1 ,5 ,2 ,6 ,3 ,7 , 26378 ,12 ,9 ,13 ,10 ,14 ,11 ,15 2638 }; 2639 2640// Iterate Rows in tiles of 4 2641for (int row_tile = 0 ;row_tile < nr ;row_tile += 4 ) { 2642// Iterate Columns in tiles of 16 2643for (int col_tile = 0 ;col_tile < nc ;col_tile += 16 ) { 2644 2645const block_q2_Kx16 * x_ptr = x + (col_tile /16 )* nb ; 2646const block_q8_Kx4 * y_ptr = y + (row_tile /4 )* nb ; 2647 2648float sumf [4 ][16 ]; 2649memset (sumf ,0 ,sizeof (sumf )); 2650 2651for (int k_block = 0 ;k_block < nb ;++ k_block ) { 2652int32_t isum [4 ][16 ]; 2653int32_t summs [4 ][16 ]; 2654memset (isum ,0 ,sizeof (isum )); 2655memset (summs ,0 ,sizeof (summs )); 2656 2657const uint8_t * qs_rhs = x_ptr [k_block ].qs ; 2658const uint8_t * sc_rhs = x_ptr [k_block ].scales ; 2659const int8_t * qs_lhs = y_ptr [k_block ].qs ; 2660const int16_t * bs_lhs = y_ptr [k_block ].bsums ; 2661 2662for (int sb = 0 ;sb < 16 ;++ sb ) { 2663int scale_offset = sb_perm [sb ]* 16 ; 2664 2665int byte_base ; 2666if (sb < 8 )byte_base = (sb %2 == 0 ) ?0 :16 ; 2667else byte_base = (sb %2 == 0 ) ?32 :48 ; 2668int shift = ((sb /2 ) %4 )* 2 ; 2669 2670for (int col = 0 ;col < 16 ;++ col ) { 2671uint8_t sc_val = sc_rhs [scale_offset + col ]; 2672int32_t d_sb = sc_val & 0xF ; 2673int32_t m_sb = sc_val >>4 ; 2674 2675// Correction Term 2676for (int r = 0 ;r < 4 ;++ r ) { 2677int bsum_idx = (sb /4 )* 16 + r * 4 + (sb %4 ); 2678summs [r ][col ]+= bs_lhs [bsum_idx ]* m_sb ; 2679 } 2680 2681// Main Dot Product 2682for (int l = 0 ;l < 16 ;++ l ) { 2683int qs_idx = (byte_base + l )* 16 + col ; 2684uint8_t q2_val = (qs_rhs [qs_idx ] >>shift )& 3 ; 2685 2686// Calculate Q8 index for this specific k and row 2687int k = sb * 16 + l ; 2688int q8_idx = (k /4 )* 16 + (k %4 ); 2689 2690for (int r = 0 ;r < 4 ;++ r ) { 2691// Add r*4 to jump to the correct row within the 4x4 chunk 2692int8_t q8_val = qs_lhs [q8_idx + r * 4 ]; 2693isum [r ][col ]+= q8_val * q2_val * d_sb ; 2694 } 2695 } 2696 } 2697 } 2698 2699// Finalize K-Block 2700for (int col = 0 ;col < 16 ;++ col ) { 2701float d_rhs = GGML_FP16_TO_FP32 (x_ptr [k_block ].d [col ]); 2702float dm_rhs = GGML_FP16_TO_FP32 (x_ptr [k_block ].dmin [col ]); 2703 2704for (int r = 0 ;r < 4 ;++ r ) { 2705float d_lhs = y_ptr [k_block ].d [r ]; 2706float d_all = d_lhs * d_rhs ; 2707float d_min = d_lhs * dm_rhs ; 2708sumf [r ][col ]+= (isum [r ][col ]* d_all )- (summs [r ][col ]* d_min ); 2709 } 2710 } 2711 } 2712 2713for (int r = 0 ;r < 4 ;++ r ) { 2714for (int col = 0 ;col < 16 ;++ col ) { 2715s [(row_tile + r )* bs + (col_tile + col )]= sumf [r ][col ]; 2716 } 2717 } 2718 } 2719 } 2720} 2721#endif 2722 2723}// extern "C" 2724 2725static block_q8_0x4 make_block_q8_0x4 (block_q8_0 * in ,unsigned int blck_size_interleave ) { 2726block_q8_0x4 out ; 2727 2728for (int i = 0 ;i < 4 ;i ++ ) { 2729out .d [i ]= in [i ].d ; 2730 } 2731 2732const int end = QK8_0 * 4 /blck_size_interleave ; 2733for (int i = 0 ;i < end ;++ i ) { 2734int src_id = i %4 ; 2735int src_offset = (i /4 )* blck_size_interleave ; 2736int dst_offset = i * blck_size_interleave ; 2737memcpy (& out .qs [dst_offset ],& in [src_id ].qs [src_offset ],blck_size_interleave ); 2738 } 2739return out ; 2740} 2741 2742static block_q4_0x4 make_block_q4_0x4 (block_q4_0 * in ,int blck_size_interleave ) { 2743block_q4_0x4 out ; 2744 2745for (int i = 0 ;i < 4 ;i ++ ) { 2746out .d [i ]= in [i ].d ; 2747 } 2748 2749const int end = QK4_0 * 2 /blck_size_interleave ; 2750 2751if (blck_size_interleave == 8 ) { 2752const uint64_t xor_mask = 0x8888888888888888ULL ; 2753for (int i = 0 ;i < end ;++ i ) { 2754int src_id = i %4 ; 2755int src_offset = (i /4 )* blck_size_interleave ; 2756int dst_offset = i * blck_size_interleave ; 2757 2758uint64_t elems ; 2759// Using memcpy to avoid unaligned memory accesses 2760memcpy (& elems ,& in [src_id ].qs [src_offset ],sizeof (uint64_t )); 2761elems ^=xor_mask ; 2762memcpy (& out .qs [dst_offset ],& elems ,sizeof (uint64_t )); 2763 } 2764 }else if (blck_size_interleave == 4 ) { 2765const uint32_t xor_mask = 0x88888888 ; 2766for (int i = 0 ;i < end ;++ i ) { 2767int src_id = i %4 ; 2768int src_offset = (i /4 )* blck_size_interleave ; 2769int dst_offset = i * blck_size_interleave ; 2770 2771uint32_t elems ; 2772memcpy (& elems ,& in [src_id ].qs [src_offset ],sizeof (uint32_t )); 2773elems ^=xor_mask ; 2774memcpy (& out .qs [dst_offset ],& elems ,sizeof (uint32_t )); 2775 } 2776 }else { 2777GGML_ASSERT (false); 2778 } 2779 2780return out ; 2781} 2782 2783// interleave 8 block_q4_0s in blocks of blck_size_interleave 2784// returns an interleaved block_q4_0x8 2785// in the interleaved block_q4_0x8, place deltas for 8 block_q4_0 blocks 2786// first, then interleave quants from 8 block_q4_0s in blocks of blck_size_interleave 2787static block_q4_0x8 make_block_q4_0x8 (block_q4_0 * in ,unsigned int blck_size_interleave ) { 2788block_q4_0x8 out ; 2789 2790for (int i = 0 ;i < 8 ;i ++ ) { 2791out .d [i ]= in [i ].d ; 2792 } 2793 2794const int end = QK4_0 * 4 /blck_size_interleave ; 2795const uint64_t xor_mask = 0x8888888888888888ULL ; 2796 2797for (int i = 0 ;i < end ;++ i ) { 2798int src_id = i %8 ; 2799int src_offset = (i /8 )* blck_size_interleave ; 2800int dst_offset = i * blck_size_interleave ; 2801 2802uint64_t elems ; 2803memcpy (& elems ,& in [src_id ].qs [src_offset ],sizeof (uint64_t )); 2804elems ^=xor_mask ; 2805memcpy (& out .qs [dst_offset ],& elems ,sizeof (uint64_t )); 2806 } 2807 2808return out ; 2809} 2810 2811static block_q4_0x16 make_block_q4_0x16 (block_q4_0 * in ,unsigned int blck_size_interleave ) { 2812block_q4_0x16 out ; 2813 2814for (int i = 0 ;i < 16 ;i ++ ) { 2815out .d [i ]= in [i ].d ; 2816 } 2817 2818const int end = QK4_0 * 8 /blck_size_interleave ; 2819 2820if (blck_size_interleave == 1 ) { 2821const uint8_t xor_mask = 0x88 ; 2822for (int i = 0 ;i < end ;++ i ) { 2823int src_id = i %16 ; 2824int src_offset = i /16 ; 2825int dst_offset = i ; 2826 2827out .qs [dst_offset ]= in [src_id ].qs [src_offset ] ^xor_mask ; 2828 } 2829 }else { 2830GGML_ASSERT (false); 2831 } 2832 2833return out ; 2834} 2835 2836static block_q4_Kx8 make_block_q4_Kx8 (block_q4_K * in ,unsigned int blck_size_interleave ) { 2837block_q4_Kx8 out ; 2838//Delta(scale) and dmin values of the eight Q4_K structures are copied onto the output interleaved structure 2839for (int i = 0 ;i < 8 ;i ++ ) { 2840out .d [i ]= in [i ].GGML_COMMON_AGGR_U .GGML_COMMON_AGGR_S .d ; 2841 } 2842 2843for (int i = 0 ;i < 8 ;i ++ ) { 2844out .dmin [i ]= in [i ].GGML_COMMON_AGGR_U .GGML_COMMON_AGGR_S .dmin ; 2845 } 2846 2847const int end = QK_K * 4 /blck_size_interleave ; 2848 2849// Interleave Q4_K quants by taking 8 bytes at a time 2850for (int i = 0 ;i < end ;++ i ) { 2851int src_id = i %8 ; 2852int src_offset = (i /8 )* blck_size_interleave ; 2853int dst_offset = i * blck_size_interleave ; 2854 2855// buffer large enough for the max interleave block size (8 bytes) 2856uint64_t elems ; 2857memcpy (& elems ,& in [src_id ].qs [src_offset ],blck_size_interleave ); 2858memcpy (& out .qs [dst_offset ],& elems ,blck_size_interleave ); 2859 } 2860 2861// The below logic is designed so as to unpack and rearrange scales and mins values in Q4_K 2862// Currently the Q4_K structure has 8 scales and 8 mins packed in 12 bytes ( 6 bits for each value) 2863// The output Q4_Kx8 structure has 96 bytes 2864// Every 12 byte is packed such that it contains scales and mins for corresponding sub blocks from Q4_K structure 2865// For eg - First 12 bytes contains 8 scales and 8 mins - each of first sub block from different Q4_K structures 2866uint8_t s [8 ],m [8 ]; 2867 2868for (int i = 0 ;i < 4 ;i ++ ) { 2869for (int j = 0 ;j < 8 ;j ++ ) { 2870s [j ]= in [j ].scales [i ]& 63 ; 2871m [j ]= in [j ].scales [i + 4 ]& 63 ; 2872 } 2873 2874out .scales [i * 12 ]= (s [0 ]& 63 )+ ((s [4 ]& 48 ) <<2 ); 2875out .scales [i * 12 + 1 ]= (s [1 ]& 63 )+ ((s [5 ]& 48 ) <<2 ); 2876out .scales [i * 12 + 2 ]= (s [2 ]& 63 )+ ((s [6 ]& 48 ) <<2 ); 2877out .scales [i * 12 + 3 ]= (s [3 ]& 63 )+ ((s [7 ]& 48 ) <<2 ); 2878out .scales [i * 12 + 4 ]= (m [0 ]& 63 )+ ((m [4 ]& 48 ) <<2 ); 2879out .scales [i * 12 + 5 ]= (m [1 ]& 63 )+ ((m [5 ]& 48 ) <<2 ); 2880out .scales [i * 12 + 6 ]= (m [2 ]& 63 )+ ((m [6 ]& 48 ) <<2 ); 2881out .scales [i * 12 + 7 ]= (m [3 ]& 63 )+ ((m [7 ]& 48 ) <<2 ); 2882out .scales [i * 12 + 8 ]= (s [4 ]& 15 )+ ((m [4 ]& 15 ) <<4 ); 2883out .scales [i * 12 + 9 ]= (s [5 ]& 15 )+ ((m [5 ]& 15 ) <<4 ); 2884out .scales [i * 12 + 10 ]= (s [6 ]& 15 )+ ((m [6 ]& 15 ) <<4 ); 2885out .scales [i * 12 + 11 ]= (s [7 ]& 15 )+ ((m [7 ]& 15 ) <<4 ); 2886 2887 } 2888 2889for (int i = 0 ;i < 4 ;i ++ ) { 2890for (int j = 0 ;j < 8 ;j ++ ) { 2891s [j ]= ((in [j ].scales [i ]& 192 ) >>2 ) | (in [j ].scales [i + 8 ]& 15 ); 2892m [j ]= ((in [j ].scales [i + 4 ]& 192 ) >>2 ) | ((in [j ].scales [i + 8 ]& 240 ) >>4 ); 2893 } 2894 2895out .scales [i * 12 + 48 ]= (s [0 ]& 63 )+ ((s [4 ]& 48 ) <<2 ); 2896out .scales [i * 12 + 49 ]= (s [1 ]& 63 )+ ((s [5 ]& 48 ) <<2 ); 2897out .scales [i * 12 + 50 ]= (s [2 ]& 63 )+ ((s [6 ]& 48 ) <<2 ); 2898out .scales [i * 12 + 51 ]= (s [3 ]& 63 )+ ((s [7 ]& 48 ) <<2 ); 2899out .scales [i * 12 + 52 ]= (m [0 ]& 63 )+ ((m [4 ]& 48 ) <<2 ); 2900out .scales [i * 12 + 53 ]= (m [1 ]& 63 )+ ((m [5 ]& 48 ) <<2 ); 2901out .scales [i * 12 + 54 ]= (m [2 ]& 63 )+ ((m [6 ]& 48 ) <<2 ); 2902out .scales [i * 12 + 55 ]= (m [3 ]& 63 )+ ((m [7 ]& 48 ) <<2 ); 2903out .scales [i * 12 + 56 ]= (s [4 ]& 15 )+ ((m [4 ]& 15 ) <<4 ); 2904out .scales [i * 12 + 57 ]= (s [5 ]& 15 )+ ((m [5 ]& 15 ) <<4 ); 2905out .scales [i * 12 + 58 ]= (s [6 ]& 15 )+ ((m [6 ]& 15 ) <<4 ); 2906out .scales [i * 12 + 59 ]= (s [7 ]& 15 )+ ((m [7 ]& 15 ) <<4 ); 2907 2908 } 2909 2910return out ; 2911} 2912 2913static block_q4_Kx16 make_block_q4_Kx16 (block_q4_K * in ,unsigned int blck_size_interleave ) { 2914block_q4_Kx16 out ; 2915//Delta(scale) and dmin values of the 16 Q4_K structures are copied onto the output interleaved structure 2916for (int i = 0 ;i < 16 ;i ++ ) { 2917out .d [i ]= in [i ].GGML_COMMON_AGGR_U .GGML_COMMON_AGGR_S .d ; 2918 } 2919 2920for (int i = 0 ;i < 16 ;i ++ ) { 2921out .dmin [i ]= in [i ].GGML_COMMON_AGGR_U .GGML_COMMON_AGGR_S .dmin ; 2922 } 2923 2924const int end = QK_K * 8 /blck_size_interleave ; 2925 2926if (blck_size_interleave == 1 ) { 2927for (int i = 0 ;i < end ;++ i ) { 2928int src_id = i %16 ; 2929int src_offset = i /16 ; 2930int dst_offset = i ; 2931 2932out .qs [dst_offset ]= in [src_id ].qs [src_offset ]; 2933 } 2934 2935// RVV repacking. 2936// 2937// Extract sums and mins for all 8 sub-blocks for each block of Q4_K. 2938uint8_t s [128 ],m [128 ]; 2939for (int i = 0 ;i < 4 ;i ++ ) { 2940for (int j = 0 ;j < 16 ;j ++ ) { 2941s [i * 16 + j ]= in [j ].scales [i ]& 63 ; 2942m [i * 16 + j ]= in [j ].scales [i + 4 ]& 63 ; 2943 } 2944 } 2945for (int i = 0 ;i < 4 ;i ++ ) { 2946for (int j = 0 ;j < 16 ;j ++ ) { 2947s [64 + i * 16 + j ]= ((in [j ].scales [i ]& 192 ) >>2 ) | (in [j ].scales [i + 8 ]& 15 ); 2948m [64 + i * 16 + j ]= ((in [j ].scales [i + 4 ]& 192 ) >>2 ) | ((in [j ].scales [i + 8 ]& 240 ) >>4 ); 2949 } 2950 } 2951 2952for (int i = 0 ;i < 128 ;i ++ ) { 2953out .scales [i ]= (s [i ]& 15 ) | ((m [i ]& 15 ) <<4 ); 2954 } 2955for (int i = 0 ;i < 64 ;i ++ ) { 2956out .scales [128 + i ]= ((s [i ]& 48 ) >>4 ) | ((m [i ]& 48 ) >>2 ) | (s [64 + i ]& 48 ) | ((m [64 + i ]& 48 ) <<2 ); 2957 } 2958 }else { 2959GGML_ASSERT (false); 2960 } 2961 2962return out ; 2963} 2964 2965static block_q2_Kx8 make_block_q2_Kx8 (block_q2_K * in ,unsigned int blck_size_interleave ) { 2966block_q2_Kx8 out ; 2967 2968// Delta(scale) and dmin values of the eight Q2_K structures are copied onto the output interleaved structure 2969for (int i = 0 ;i < 8 ;i ++ ) { 2970out .d [i ]= in [i ].GGML_COMMON_AGGR_U .GGML_COMMON_AGGR_S .d ; 2971 } 2972 2973for (int i = 0 ;i < 8 ;i ++ ) { 2974out .dmin [i ]= in [i ].GGML_COMMON_AGGR_U .GGML_COMMON_AGGR_S .dmin ; 2975 } 2976 2977const int end = QK_K * 2 /blck_size_interleave ; 2978 2979// Interleave Q2_K quants by taking 8 bytes at a time 2980for (int i = 0 ;i < end ;++ i ) { 2981int src_id = i %8 ; 2982int src_offset = (i /8 )* blck_size_interleave ; 2983int dst_offset = i * blck_size_interleave ; 2984 2985uint64_t elems ; 2986memcpy (& elems ,& in [src_id ].qs [src_offset ],sizeof (uint64_t )); 2987memcpy (& out .qs [dst_offset ],& elems ,sizeof (uint64_t )); 2988 } 2989 2990// The below logic is designed so as to unpack and rearrange scales and mins values in Q2_K 2991// Currently the Q2_K structure has 16 scales and 16 mins packed in 16 bytes ( 4 bits for each value) 2992// The output Q2_Kx8 structure has 128 bytes for storing scales and mins 2993// Every 16 byte is packed such that it contains scales and mins for corresponding sub blocks from Q2_K structure 2994// For eg - First 16 bytes contains 16 scales and 16 mins - each of first and second sub blocks from different Q2_K structures 2995 2996for (int i = 0 ;i < 128 ;i ++ ) { 2997// Index for selecting which q2k super block 2998int src1 = (i %16 ) /2 ; 2999// Index for selecting scale 3000int src2 = ((i /16 )* 2 )+ (i %2 ); 3001 3002out .scales [i ]= in [src1 ].scales [src2 ]; 3003 } 3004return out ; 3005} 3006 3007static block_q5_Kx8 make_block_q5_Kx8 (block_q5_K * in ,unsigned int blck_size_interleave ) { 3008block_q5_Kx8 out ; 3009//Delta(scale) and dmin values of the eight Q5_K structures are copied onto the output interleaved structure 3010for (int i = 0 ;i < 8 ;i ++ ) { 3011out .d [i ]= in [i ].GGML_COMMON_AGGR_U .GGML_COMMON_AGGR_S .d ; 3012 } 3013 3014for (int i = 0 ;i < 8 ;i ++ ) { 3015out .dmin [i ]= in [i ].GGML_COMMON_AGGR_U .GGML_COMMON_AGGR_S .dmin ; 3016 } 3017 3018const int end = QK_K * 4 /blck_size_interleave ; 3019 3020// Interleave Q5_K quants by taking blck_size_interleave bytes at a time 3021for (int i = 0 ;i < end ;++ i ) { 3022int src_id = i %8 ; 3023int src_offset = (i /8 )* blck_size_interleave ; 3024int dst_offset = i * blck_size_interleave ; 3025 3026memcpy (& out .qs [dst_offset ],& in [src_id ].qs [src_offset ],blck_size_interleave ); 3027 } 3028 3029// Repeat for high bits with the same chunk size, since 3030// the high bits are interleaved in Q5_K and the index is 3031// qh_idx = (qs_idx % 32); 3032// qh_val = qh[qh_idx] >> (qs_idx / 32); 3033for (int i = 0 ;i < end /4 ;++ i ) { 3034int src_id = i %8 ; 3035int src_offset = (i /8 )* blck_size_interleave ; 3036int dst_offset = i * blck_size_interleave ; 3037 3038memcpy (& out .qh [dst_offset ],& in [src_id ].qh [src_offset ],blck_size_interleave ); 3039 } 3040 3041// The below logic is copied over from Q4_K 3042// The point is to unpack all the scales and mins for each sub block every time we load 12 bytes. 3043// Currently the Q5_K structure has 8 scales and 8 mins packed in 12 bytes ( 6 bits for each value) 3044// The output Q5_Kx8 structure has 96 bytes 3045// Every 12 byte is packed such that it contains scales and mins for corresponding sub blocks from Q5_K structure 3046// For eg - First 12 bytes contains 8 scales and 8 mins - each of first sub block from different Q5_K structures 3047uint8_t s [8 ],m [8 ]; 3048 3049for (int i = 0 ;i < 4 ;i ++ ) { 3050for (int j = 0 ;j < 8 ;j ++ ) { 3051s [j ]= in [j ].scales [i ]& 63 ; 3052m [j ]= in [j ].scales [i + 4 ]& 63 ; 3053 } 3054 3055out .scales [i * 12 ]= (s [0 ]& 63 )+ ((s [4 ]& 48 ) <<2 ); 3056out .scales [i * 12 + 1 ]= (s [1 ]& 63 )+ ((s [5 ]& 48 ) <<2 ); 3057out .scales [i * 12 + 2 ]= (s [2 ]& 63 )+ ((s [6 ]& 48 ) <<2 ); 3058out .scales [i * 12 + 3 ]= (s [3 ]& 63 )+ ((s [7 ]& 48 ) <<2 ); 3059out .scales [i * 12 + 4 ]= (m [0 ]& 63 )+ ((m [4 ]& 48 ) <<2 ); 3060out .scales [i * 12 + 5 ]= (m [1 ]& 63 )+ ((m [5 ]& 48 ) <<2 ); 3061out .scales [i * 12 + 6 ]= (m [2 ]& 63 )+ ((m [6 ]& 48 ) <<2 ); 3062out .scales [i * 12 + 7 ]= (m [3 ]& 63 )+ ((m [7 ]& 48 ) <<2 ); 3063out .scales [i * 12 + 8 ]= (s [4 ]& 15 )+ ((m [4 ]& 15 ) <<4 ); 3064out .scales [i * 12 + 9 ]= (s [5 ]& 15 )+ ((m [5 ]& 15 ) <<4 ); 3065out .scales [i * 12 + 10 ]= (s [6 ]& 15 )+ ((m [6 ]& 15 ) <<4 ); 3066out .scales [i * 12 + 11 ]= (s [7 ]& 15 )+ ((m [7 ]& 15 ) <<4 ); 3067 } 3068 3069for (int i = 0 ;i < 4 ;i ++ ) { 3070for (int j = 0 ;j < 8 ;j ++ ) { 3071s [j ]= ((in [j ].scales [i ]& 192 ) >>2 ) | (in [j ].scales [i + 8 ]& 15 ); 3072m [j ]= ((in [j ].scales [i + 4 ]& 192 ) >>2 ) | ((in [j ].scales [i + 8 ]& 240 ) >>4 ); 3073 } 3074 3075out .scales [i * 12 + 48 ]= (s [0 ]& 63 )+ ((s [4 ]& 48 ) <<2 ); 3076out .scales [i * 12 + 49 ]= (s [1 ]& 63 )+ ((s [5 ]& 48 ) <<2 ); 3077out .scales [i * 12 + 50 ]= (s [2 ]& 63 )+ ((s [6 ]& 48 ) <<2 ); 3078out .scales [i * 12 + 51 ]= (s [3 ]& 63 )+ ((s [7 ]& 48 ) <<2 ); 3079out .scales [i * 12 + 52 ]= (m [0 ]& 63 )+ ((m [4 ]& 48 ) <<2 ); 3080out .scales [i * 12 + 53 ]= (m [1 ]& 63 )+ ((m [5 ]& 48 ) <<2 ); 3081out .scales [i * 12 + 54 ]= (m [2 ]& 63 )+ ((m [6 ]& 48 ) <<2 ); 3082out .scales [i * 12 + 55 ]= (m [3 ]& 63 )+ ((m [7 ]& 48 ) <<2 ); 3083out .scales [i * 12 + 56 ]= (s [4 ]& 15 )+ ((m [4 ]& 15 ) <<4 ); 3084out .scales [i * 12 + 57 ]= (s [5 ]& 15 )+ ((m [5 ]& 15 ) <<4 ); 3085out .scales [i * 12 + 58 ]= (s [6 ]& 15 )+ ((m [6 ]& 15 ) <<4 ); 3086out .scales [i * 12 + 59 ]= (s [7 ]& 15 )+ ((m [7 ]& 15 ) <<4 ); 3087 } 3088 3089return out ; 3090} 3091 3092static block_q6_Kx8 make_block_q6_Kx8 (block_q6_K * in ,unsigned int blck_size_interleave ) { 3093block_q6_Kx8 out ; 3094constexpr int n_blocks = 8 ;// Kx8 3095for (int i = 0 ;i < n_blocks ;i ++ ) { 3096out .d [i ]= in [i ].d ; 3097 } 3098 3099const int end_ls = QK_K * 4 /blck_size_interleave ; 3100// Interleave Q6_K quants by taking blck_size_interleave bytes at a time 3101for (int i = 0 ;i < end_ls ;++ i ) { 3102int src_id = i %n_blocks ; 3103int src_offset = (i /n_blocks )* blck_size_interleave ; 3104int dst_offset = i * blck_size_interleave ; 3105 3106uint64_t elem_ls ; 3107memcpy (& elem_ls ,& in [src_id ].ql [src_offset ],blck_size_interleave ); 3108memcpy (& out .ql [dst_offset ],& elem_ls ,blck_size_interleave ); 3109 } 3110 3111// Interleave high bits using same chunk size as low bits 3112const int end_hs = end_ls /2 ; 3113for (int i = 0 ;i < end_hs ;++ i ) { 3114int src_id = i %n_blocks ; 3115int src_offset = (i /n_blocks )* blck_size_interleave ; 3116int dst_offset = i * blck_size_interleave ; 3117 3118uint64_t elem_hs ; 3119memcpy (& elem_hs ,& in [src_id ].qh [src_offset ],blck_size_interleave ); 3120memcpy (& out .qh [dst_offset ],& elem_hs ,blck_size_interleave ); 3121 } 3122 3123// The below logic is designed so as to unpack and rearrange scales in Q6_K 3124// The output Q6_Kx8 structure interleaves the 8 bit scales in the same fashion as the quants 3125// Q6_K structure has an 8-bit scale per 16 elements -> 16 scales 3126// scales: [0 bl0 0 bl1 ... 0 bl7][1 bl0 ... 1 bl7] ... [15 bl0 ... 15 bl7] (bl = block) 3127constexpr int n_scales = QK_K /16 ; 3128 3129for (int i = 0 ;i < n_blocks ;i ++ ) { 3130for (int j = 0 ;j < n_scales ;j ++ ) { 3131out .scales [j * n_blocks + i ]= in [i ].scales [j ]; 3132 } 3133 } 3134 3135return out ; 3136} 3137 3138static block_q2_Kx16 make_block_q2_Kx16 (const block_q2_K * in ,unsigned int blck_size_interleave ) { 3139block_q2_Kx16 out ; 3140constexpr int N_COLS = 16 ; 3141 3142// 1. Copy Super-Scales (d) and Super-Mins (dmin) 3143for (int i = 0 ;i < N_COLS ;i ++ ) { 3144out .d [i ]= in [i ].GGML_COMMON_AGGR_U .GGML_COMMON_AGGR_S .d ; 3145out .dmin [i ]= in [i ].GGML_COMMON_AGGR_U .GGML_COMMON_AGGR_S .dmin ; 3146 } 3147 3148// 2. Interleave Q2_K Data 3149const int bytes_per_col = 64 ; 3150const int total_bytes = N_COLS * bytes_per_col ; 3151const int end = total_bytes /blck_size_interleave ; 3152 3153for (int i = 0 ;i < end ;++ i ) { 3154int src_col_id = i %N_COLS ; 3155int src_offset = (i /N_COLS )* blck_size_interleave ; 3156int dst_offset = i * blck_size_interleave ; 3157memcpy (& out .qs [dst_offset ],& in [src_col_id ].qs [src_offset ],blck_size_interleave ); 3158 } 3159 3160// 3. Repack Scales into the Optimized "Sequential-Parallel" Layout 3161int out_idx = 0 ; 3162 3163// Arrays define the sub-block order for each group 3164const int even_low_sbs []= {0 ,2 ,4 ,6 }; 3165const int odd_low_sbs []= {1 ,3 ,5 ,7 }; 3166const int even_high_sbs []= {8 ,10 ,12 ,14 }; 3167const int odd_high_sbs []= {9 ,11 ,13 ,15 }; 3168 3169// Pack Group 1: Even-Low 3170for (int sb :even_low_sbs ) { 3171for (int col = 0 ;col < N_COLS ;col ++ ) { 3172out .scales [out_idx ++ ]= in [col ].scales [sb ]; 3173 } 3174 } 3175 3176// Pack Group 2: Odd-Low 3177for (int sb :odd_low_sbs ) { 3178for (int col = 0 ;col < N_COLS ;col ++ ) { 3179out .scales [out_idx ++ ]= in [col ].scales [sb ]; 3180 } 3181 } 3182 3183// Pack Group 3: Even-High 3184for (int sb :even_high_sbs ) { 3185for (int col = 0 ;col < N_COLS ;col ++ ) { 3186out .scales [out_idx ++ ]= in [col ].scales [sb ]; 3187 } 3188 } 3189 3190// Pack Group 4: Odd-High 3191for (int sb :odd_high_sbs ) { 3192for (int col = 0 ;col < N_COLS ;col ++ ) { 3193out .scales [out_idx ++ ]= in [col ].scales [sb ]; 3194 } 3195 } 3196 3197return out ; 3198} 3199 3200static int repack_q4_0_to_q4_0_4_bl (struct ggml_tensor * t ,int interleave_block ,const void * GGML_RESTRICT data ,size_t data_size ) { 3201GGML_ASSERT (t -> type == GGML_TYPE_Q4_0 ); 3202GGML_ASSERT (interleave_block == 4 || interleave_block == 8 ); 3203constexpr int nrows_interleaved = 4 ; 3204 3205block_q4_0x4 * dst = (block_q4_0x4 * )t -> data ; 3206const block_q4_0 * src = (const block_q4_0 * )data ; 3207block_q4_0 dst_tmp [4 ]; 3208int nrow = ggml_nrows (t ); 3209int nblocks = t -> ne [0 ] /QK4_0 ; 3210 3211GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_q4_0 )); 3212 3213if (t -> ne [1 ] %nrows_interleaved != 0 || t -> ne [0 ] %8 != 0 ) { 3214return -1 ; 3215 } 3216 3217for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3218for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3219for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3220dst_tmp [i ]= src [x + i * nblocks ]; 3221 } 3222* dst ++ = make_block_q4_0x4 (dst_tmp ,interleave_block ); 3223 } 3224src += nrows_interleaved * nblocks ; 3225 } 3226return 0 ; 3227 3228GGML_UNUSED (data_size ); 3229} 3230 3231static int repack_q4_K_to_q4_K_8_bl (struct ggml_tensor * t ,int interleave_block ,const void * GGML_RESTRICT data ,size_t data_size ) { 3232GGML_ASSERT (t -> type == GGML_TYPE_Q4_K ); 3233GGML_ASSERT (interleave_block == 8 || interleave_block == 4 ); 3234constexpr int nrows_interleaved = 8 ; 3235 3236block_q4_Kx8 * dst = (block_q4_Kx8 * )t -> data ; 3237const block_q4_K * src = (const block_q4_K * )data ; 3238block_q4_K dst_tmp [8 ]; 3239int nrow = ggml_nrows (t ); 3240int nblocks = t -> ne [0 ] /QK_K ; 3241 3242GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_q4_K )); 3243 3244if (t -> ne [1 ] %nrows_interleaved != 0 || t -> ne [0 ] %8 != 0 ) { 3245return -1 ; 3246 } 3247 3248for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3249for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3250for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3251dst_tmp [i ]= src [x + i * nblocks ]; 3252 } 3253* dst ++ = make_block_q4_Kx8 (dst_tmp ,interleave_block ); 3254 } 3255src += nrows_interleaved * nblocks ; 3256 } 3257return 0 ; 3258 3259GGML_UNUSED (data_size ); 3260} 3261 3262static int repack_q4_K_to_q4_K_16_bl (struct ggml_tensor * t ,int interleave_block ,const void * GGML_RESTRICT data ,size_t data_size ) { 3263GGML_ASSERT (t -> type == GGML_TYPE_Q4_K ); 3264constexpr int nrows_interleaved = 16 ; 3265 3266block_q4_Kx16 * dst = (block_q4_Kx16 * )t -> data ; 3267const block_q4_K * src = (const block_q4_K * )data ; 3268block_q4_K dst_tmp [16 ]; 3269int nrow = ggml_nrows (t ); 3270int nblocks = t -> ne [0 ] /QK_K ; 3271 3272GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_q4_K )); 3273 3274if (t -> ne [1 ] %nrows_interleaved != 0 || t -> ne [0 ] %8 != 0 ) { 3275return -1 ; 3276 } 3277 3278for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3279for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3280for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3281dst_tmp [i ]= src [x + i * nblocks ]; 3282 } 3283* dst ++ = make_block_q4_Kx16 (dst_tmp ,interleave_block ); 3284 } 3285src += nrows_interleaved * nblocks ; 3286 } 3287return 0 ; 3288 3289GGML_UNUSED (data_size ); 3290} 3291 3292static int repack_q2_K_to_q2_K_8_bl (struct ggml_tensor * t ,int interleave_block ,const void * GGML_RESTRICT data ,size_t data_size ) { 3293GGML_ASSERT (t -> type == GGML_TYPE_Q2_K ); 3294GGML_ASSERT (interleave_block == 8 ); 3295constexpr int nrows_interleaved = 8 ; 3296 3297block_q2_Kx8 * dst = (block_q2_Kx8 * )t -> data ; 3298const block_q2_K * src = (const block_q2_K * )data ; 3299block_q2_K dst_tmp [8 ]; 3300int nrow = ggml_nrows (t ); 3301int nblocks = t -> ne [0 ] /QK_K ; 3302 3303GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_q2_K )); 3304 3305if (t -> ne [1 ] %nrows_interleaved != 0 || t -> ne [0 ] %8 != 0 ) { 3306return -1 ; 3307 } 3308 3309for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3310for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3311for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3312dst_tmp [i ]= src [x + i * nblocks ]; 3313 } 3314* dst ++ = make_block_q2_Kx8 (dst_tmp ,interleave_block ); 3315 } 3316src += nrows_interleaved * nblocks ; 3317 } 3318return 0 ; 3319 3320GGML_UNUSED (data_size ); 3321} 3322 3323static int repack_q2_K_to_q2_K_16_bl (struct ggml_tensor * t ,int interleave_block ,const void * GGML_RESTRICT data ,size_t data_size ) { 3324GGML_ASSERT (t -> type == GGML_TYPE_Q2_K ); 3325constexpr int nrows_interleaved = 16 ; 3326 3327block_q2_Kx16 * dst = (block_q2_Kx16 * )t -> data ; 3328const block_q2_K * src = (const block_q2_K * )data ; 3329 3330block_q2_K dst_tmp [nrows_interleaved ]; 3331 3332int nrow = ggml_nrows (t ); 3333int nblocks = t -> ne [0 ] /QK_K ; 3334 3335GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_q2_K )); 3336 3337if (t -> ne [1 ] %nrows_interleaved != 0 || t -> ne [0 ] %8 != 0 ) { 3338return -1 ; 3339 } 3340 3341for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3342for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3343// This loop gathers 16 separate blocks (one from each column) 3344// that correspond to the same K-dimension chunk. 3345for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3346dst_tmp [i ]= src [x + i * nblocks ]; 3347 } 3348 3349* dst ++ = make_block_q2_Kx16 (dst_tmp ,interleave_block ); 3350 } 3351src += nrows_interleaved * nblocks ; 3352 } 3353return 0 ; 3354 3355GGML_UNUSED (data_size ); 3356} 3357 3358static int repack_q4_0_to_q4_0_16_bl (struct ggml_tensor * t ,int interleave_block ,const void * GGML_RESTRICT data ,size_t data_size ) { 3359GGML_ASSERT (t -> type == GGML_TYPE_Q4_0 ); 3360constexpr int nrows_interleaved = 16 ; 3361 3362block_q4_0x16 * dst = (block_q4_0x16 * )t -> data ; 3363const block_q4_0 * src = (const block_q4_0 * )data ; 3364block_q4_0 dst_tmp [16 ]; 3365int nrow = ggml_nrows (t ); 3366int nblocks = t -> ne [0 ] /QK4_0 ; 3367 3368GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_q4_0 )); 3369 3370if (t -> ne [1 ] %nrows_interleaved != 0 || t -> ne [0 ] %8 != 0 ) { 3371return -1 ; 3372 } 3373 3374for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3375for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3376for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3377dst_tmp [i ]= src [x + i * nblocks ]; 3378 } 3379* dst ++ = make_block_q4_0x16 (dst_tmp ,interleave_block ); 3380 } 3381src += nrows_interleaved * nblocks ; 3382 } 3383return 0 ; 3384 3385GGML_UNUSED (data_size ); 3386} 3387 3388static int repack_q5_K_to_q5_K_8_bl (struct ggml_tensor * t , 3389int interleave_block , 3390const void * GGML_RESTRICT data , 3391size_t data_size ) { 3392GGML_ASSERT (t -> type == GGML_TYPE_Q5_K ); 3393GGML_ASSERT (interleave_block == 4 || interleave_block == 8 ); 3394constexpr int nrows_interleaved = 8 ; 3395 3396block_q5_Kx8 * dst = (block_q5_Kx8 * )t -> data ; 3397const block_q5_K * src = (const block_q5_K * )data ; 3398block_q5_K dst_tmp [8 ]; 3399int nrow = ggml_nrows (t ); 3400int nblocks = t -> ne [0 ] /QK_K ; 3401 3402GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_q5_K )); 3403 3404if (t -> ne [1 ] %nrows_interleaved != 0 || t -> ne [0 ] %8 != 0 ) { 3405return -1 ; 3406 } 3407 3408for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3409for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3410for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3411dst_tmp [i ]= src [x + i * nblocks ]; 3412 } 3413* dst ++ = make_block_q5_Kx8 (dst_tmp ,interleave_block ); 3414 } 3415src += nrows_interleaved * nblocks ; 3416 } 3417return 0 ; 3418} 3419 3420static int repack_q6_K_to_q6_K_8_bl (struct ggml_tensor * t ,int interleave_block ,const void * GGML_RESTRICT data ,size_t data_size ) { 3421GGML_ASSERT (t -> type == GGML_TYPE_Q6_K ); 3422GGML_ASSERT (interleave_block == 4 || interleave_block == 8 ); 3423constexpr int nrows_interleaved = 8 ; 3424 3425block_q6_Kx8 * dst = (block_q6_Kx8 * )t -> data ; 3426const block_q6_K * src = (const block_q6_K * )data ; 3427block_q6_K dst_tmp [8 ]; 3428int nrow = ggml_nrows (t ); 3429int nblocks = t -> ne [0 ] /QK_K ; 3430 3431GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_q6_K )); 3432 3433if (t -> ne [1 ] %nrows_interleaved != 0 || t -> ne [0 ] %8 != 0 ) { 3434return -1 ; 3435 } 3436 3437for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3438for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3439for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3440dst_tmp [i ]= src [x + i * nblocks ]; 3441 } 3442* dst ++ = make_block_q6_Kx8 (dst_tmp ,interleave_block ); 3443 } 3444src += nrows_interleaved * nblocks ; 3445 } 3446return 0 ; 3447} 3448 3449static int repack_q4_0_to_q4_0_8_bl (struct ggml_tensor * t ,int interleave_block ,const void * GGML_RESTRICT data ,size_t data_size ) { 3450GGML_ASSERT (t -> type == GGML_TYPE_Q4_0 ); 3451GGML_ASSERT (interleave_block == 8 ); 3452constexpr int nrows_interleaved = 8 ; 3453 3454block_q4_0x8 * dst = (block_q4_0x8 * )t -> data ; 3455const block_q4_0 * src = (const block_q4_0 * )data ; 3456block_q4_0 dst_tmp [8 ]; 3457int nrow = ggml_nrows (t ); 3458int nblocks = t -> ne [0 ] /QK4_0 ; 3459 3460GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_q4_0 )); 3461 3462if (t -> ne [1 ] %nrows_interleaved != 0 || t -> ne [0 ] %8 != 0 ) { 3463return -1 ; 3464 } 3465 3466for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3467for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3468for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3469dst_tmp [i ]= src [x + i * nblocks ]; 3470 } 3471* dst ++ = make_block_q4_0x8 (dst_tmp ,interleave_block ); 3472 } 3473src += nrows_interleaved * nblocks ; 3474 } 3475return 0 ; 3476 3477GGML_UNUSED (data_size ); 3478} 3479 3480static int repack_q8_0_to_q8_0_4_bl (struct ggml_tensor * t , 3481int interleave_block , 3482const void * GGML_RESTRICT data , 3483size_t data_size ) { 3484GGML_ASSERT (t -> type == GGML_TYPE_Q8_0 ); 3485GGML_ASSERT (interleave_block == 4 || interleave_block == 8 ); 3486constexpr int nrows_interleaved = 4 ; 3487 3488block_q8_0x4 * dst = (block_q8_0x4 * )t -> data ; 3489const block_q8_0 * src = (const block_q8_0 * )data ; 3490block_q8_0 dst_tmp [4 ]; 3491int nrow = ggml_nrows (t ); 3492int nblocks = t -> ne [0 ] /QK8_0 ; 3493 3494GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_q8_0 )); 3495 3496if (t -> ne [1 ] %nrows_interleaved != 0 || t -> ne [0 ] %8 != 0 ) { 3497return -1 ; 3498 } 3499 3500for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3501for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3502for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3503dst_tmp [i ]= src [x + i * nblocks ]; 3504 } 3505* dst ++ = make_block_q8_0x4 (dst_tmp ,interleave_block ); 3506 } 3507src += nrows_interleaved * nblocks ; 3508 } 3509return 0 ; 3510} 3511 3512static block_q8_0x16 make_block_q8_0x16 (block_q8_0 * in ,unsigned int blck_size_interleave ) { 3513block_q8_0x16 out ; 3514 3515for (int i = 0 ;i < 16 ;i ++ ) { 3516out .d [i ]= in [i ].d ; 3517 } 3518 3519const int end = QK8_0 * 16 /blck_size_interleave ; 3520 3521if (blck_size_interleave == 1 ) { 3522for (int i = 0 ;i < end ;++ i ) { 3523int src_id = i %16 ; 3524int src_offset = i /16 ; 3525int dst_offset = i ; 3526out .qs [dst_offset ]= in [src_id ].qs [src_offset ]; 3527 } 3528 }else { 3529GGML_ASSERT (false); 3530 } 3531 3532return out ; 3533} 3534 3535static int repack_q8_0_to_q8_0_16_bl (struct ggml_tensor * t , 3536int interleave_block , 3537const void * GGML_RESTRICT data , 3538size_t data_size ) { 3539GGML_ASSERT (t -> type == GGML_TYPE_Q8_0 ); 3540constexpr int nrows_interleaved = 16 ; 3541 3542block_q8_0x16 * dst = (block_q8_0x16 * )t -> data ; 3543const block_q8_0 * src = (const block_q8_0 * )data ; 3544block_q8_0 dst_tmp [16 ]; 3545int nrow = ggml_nrows (t ); 3546int nblocks = t -> ne [0 ] /QK8_0 ; 3547 3548GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_q8_0 )); 3549 3550if (t -> ne [1 ] %nrows_interleaved != 0 || t -> ne [0 ] %8 != 0 ) { 3551return -1 ; 3552 } 3553 3554for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3555for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3556for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3557dst_tmp [i ]= src [x + i * nblocks ]; 3558 } 3559* dst ++ = make_block_q8_0x16 (dst_tmp ,interleave_block ); 3560 } 3561src += nrows_interleaved * nblocks ; 3562 } 3563return 0 ; 3564} 3565 3566static block_iq4_nlx4 make_block_iq4_nlx4 (block_iq4_nl * in ,unsigned int blck_size_interleave ) { 3567block_iq4_nlx4 out ; 3568 3569for (int i = 0 ;i < 4 ;i ++ ) { 3570out .d [i ]= in [i ].d ; 3571 } 3572 3573const int end = QK4_NL * 2 /blck_size_interleave ; 3574 3575// TODO: this branch seems wrong 3576//if (blck_size_interleave == 8) { 3577// for (int i = 0; i < end; ++i) { 3578// int src_id = i % 4; 3579// int src_offset = (i / 4) * blck_size_interleave; 3580// int dst_offset = i * blck_size_interleave; 3581 3582// // Using memcpy to avoid unaligned memory accesses 3583// memcpy(&out.qs[dst_offset], &in[src_id].qs[src_offset], sizeof(uint64_t)); 3584// } 3585//} else 3586if (blck_size_interleave == 4 ) { 3587for (int i = 0 ;i < end ;++ i ) { 3588int src_id = i %4 ; 3589int src_offset = (i /4 )* blck_size_interleave ; 3590int dst_offset = i * blck_size_interleave ; 3591 3592memcpy (& out .qs [dst_offset ],& in [src_id ].qs [src_offset ],sizeof (uint32_t )); 3593 } 3594 }else { 3595GGML_ASSERT (false); 3596 } 3597 3598return out ; 3599} 3600 3601static int repack_iq4_nl_to_iq4_nl_4_bl (struct ggml_tensor * t ,int interleave_block ,const void * GGML_RESTRICT data ,size_t data_size ) { 3602GGML_ASSERT (t -> type == GGML_TYPE_IQ4_NL ); 3603GGML_ASSERT (interleave_block == 4 ); 3604 3605const block_iq4_nl * src = (const block_iq4_nl * )data ; 3606block_iq4_nlx4 * dst = (block_iq4_nlx4 * )t -> data ; 3607 3608block_iq4_nl dst_tmp [4 ]; 3609 3610int nrow = ggml_nrows (t ); 3611int nrows_interleaved = 4 ; 3612int nblocks = t -> ne [0 ] /QK4_NL ; 3613 3614GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_iq4_nl )); 3615 3616if (t -> ne [1 ] %nrows_interleaved != 0 || t -> ne [0 ] %8 != 0 ) { 3617return -1 ; 3618 } 3619 3620for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3621for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3622for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3623dst_tmp [i ]= src [x + i * nblocks ]; 3624 } 3625* dst ++ = make_block_iq4_nlx4 (dst_tmp ,interleave_block ); 3626 } 3627src += nrows_interleaved * nblocks ; 3628 } 3629return 0 ; 3630 3631GGML_UNUSED (data_size ); 3632} 3633 3634static block_iq4_nlx8 make_block_iq4_nlx8 (block_iq4_nl * in ,unsigned int blck_size_interleave ) { 3635block_iq4_nlx8 out ; 3636 3637for (int i = 0 ;i < 8 ;i ++ ) { 3638out .d [i ]= in [i ].d ; 3639 } 3640 3641const int end = QK4_NL * 4 /blck_size_interleave ; 3642 3643if (blck_size_interleave == 8 ) { 3644for (int i = 0 ;i < end ;++ i ) { 3645int src_id = i %8 ; 3646int src_offset = (i /8 )* blck_size_interleave ; 3647int dst_offset = i * blck_size_interleave ; 3648 3649memcpy (& out .qs [dst_offset ],& in [src_id ].qs [src_offset ],sizeof (uint64_t )); 3650 } 3651 }else { 3652GGML_ASSERT (false); 3653 } 3654 3655return out ; 3656} 3657 3658static int repack_iq4_nl_to_iq4_nl_8_bl (struct ggml_tensor * t ,int interleave_block ,const void * GGML_RESTRICT data ,size_t data_size ) { 3659GGML_ASSERT (t -> type == GGML_TYPE_IQ4_NL ); 3660GGML_ASSERT (interleave_block == 8 ); 3661 3662const block_iq4_nl * src = (const block_iq4_nl * )data ; 3663block_iq4_nlx8 * dst = (block_iq4_nlx8 * )t -> data ; 3664 3665block_iq4_nl dst_tmp [8 ]; 3666 3667int nrow = ggml_nrows (t ); 3668int nrows_interleaved = 8 ; 3669int nblocks = t -> ne [0 ] /QK4_NL ; 3670 3671GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_iq4_nl )); 3672 3673if (t -> ne [1 ] %nrows_interleaved != 0 ) { 3674return -1 ; 3675 } 3676 3677for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3678for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3679for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3680dst_tmp [i ]= src [x + i * nblocks ]; 3681 } 3682* dst ++ = make_block_iq4_nlx8 (dst_tmp ,interleave_block ); 3683 } 3684src += nrows_interleaved * nblocks ; 3685 } 3686return 0 ; 3687 3688GGML_UNUSED (data_size ); 3689} 3690 3691static block_iq4_nlx16 make_block_iq4_nlx16 (block_iq4_nl * in ,unsigned int blck_size_interleave ) { 3692block_iq4_nlx16 out ; 3693 3694for (int i = 0 ;i < 16 ;i ++ ) { 3695out .d [i ]= in [i ].d ; 3696 } 3697 3698const int end = QK4_NL * 8 /blck_size_interleave ; 3699 3700if (blck_size_interleave == 1 ) { 3701for (int i = 0 ;i < end ;++ i ) { 3702int src_id = i %16 ; 3703int src_offset = i /16 ; 3704int dst_offset = i ; 3705 3706out .qs [dst_offset ]= in [src_id ].qs [src_offset ]; 3707 } 3708 }else { 3709GGML_ASSERT (false); 3710 } 3711 3712return out ; 3713} 3714 3715static int repack_iq4_nl_to_iq4_nl_16_bl (struct ggml_tensor * t ,int interleave_block ,const void * GGML_RESTRICT data ,size_t data_size ) { 3716GGML_ASSERT (t -> type == GGML_TYPE_IQ4_NL ); 3717GGML_ASSERT (interleave_block == 1 ); 3718 3719const block_iq4_nl * src = (const block_iq4_nl * )data ; 3720block_iq4_nlx16 * dst = (block_iq4_nlx16 * )t -> data ; 3721 3722block_iq4_nl dst_tmp [16 ]; 3723 3724int nrow = ggml_nrows (t ); 3725int nrows_interleaved = 16 ; 3726int nblocks = t -> ne [0 ] /QK4_NL ; 3727 3728GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_iq4_nl )); 3729 3730if (t -> ne [1 ] %nrows_interleaved != 0 ) { 3731return -1 ; 3732 } 3733 3734for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3735for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3736for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3737dst_tmp [i ]= src [x + i * nblocks ]; 3738 } 3739* dst ++ = make_block_iq4_nlx16 (dst_tmp ,interleave_block ); 3740 } 3741src += nrows_interleaved * nblocks ; 3742 } 3743return 0 ; 3744 3745GGML_UNUSED (data_size ); 3746} 3747 3748static block_mxfp4x4 make_block_mxfp4x4 (block_mxfp4 * in ,unsigned int blck_size_interleave ) { 3749block_mxfp4x4 out ; 3750 3751for (int i = 0 ;i < 4 ;i ++ ) { 3752out .e [i ]= in [i ].e ; 3753 } 3754 3755const int end = QK_MXFP4 * 2 /blck_size_interleave ; 3756 3757if (blck_size_interleave == 4 ) { 3758for (int i = 0 ;i < end ;++ i ) { 3759int src_id = i %4 ; 3760int src_offset = (i /4 )* blck_size_interleave ; 3761int dst_offset = i * blck_size_interleave ; 3762 3763memcpy (& out .qs [dst_offset ],& in [src_id ].qs [src_offset ],sizeof (uint32_t )); 3764 } 3765 }else { 3766GGML_ASSERT (false); 3767 } 3768 3769return out ; 3770} 3771 3772static int repack_mxfp4_to_mxfp4_4_bl (struct ggml_tensor * t ,int interleave_block ,const void * GGML_RESTRICT data ,size_t data_size ) { 3773GGML_ASSERT (t -> type == GGML_TYPE_MXFP4 ); 3774GGML_ASSERT (interleave_block == 4 ); 3775 3776const block_mxfp4 * src = (const block_mxfp4 * )data ; 3777block_mxfp4x4 * dst = (block_mxfp4x4 * )t -> data ; 3778 3779block_mxfp4 dst_tmp [4 ]; 3780 3781int nrow = ggml_nrows (t ); 3782int nrows_interleaved = 4 ; 3783int nblocks = t -> ne [0 ] /QK_MXFP4 ; 3784 3785GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_mxfp4 )); 3786 3787if (t -> ne [1 ] %nrows_interleaved != 0 || t -> ne [0 ] %8 != 0 ) { 3788return -1 ; 3789 } 3790 3791for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3792for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3793for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3794dst_tmp [i ]= src [x + i * nblocks ]; 3795 } 3796* dst ++ = make_block_mxfp4x4 (dst_tmp ,interleave_block ); 3797 } 3798src += nrows_interleaved * nblocks ; 3799 } 3800return 0 ; 3801 3802GGML_UNUSED (data_size ); 3803} 3804 3805static block_mxfp4x8 make_block_mxfp4x8 (block_mxfp4 * in ,unsigned int blck_size_interleave ) { 3806block_mxfp4x8 out ; 3807 3808for (int i = 0 ;i < 8 ;i ++ ) { 3809out .e [i ]= in [i ].e ; 3810 } 3811 3812const int end = QK_MXFP4 * 4 /blck_size_interleave ; 3813 3814if (blck_size_interleave == 8 ) { 3815for (int i = 0 ;i < end ;++ i ) { 3816int src_id = i %8 ; 3817int src_offset = (i /8 )* blck_size_interleave ; 3818int dst_offset = i * blck_size_interleave ; 3819 3820memcpy (& out .qs [dst_offset ],& in [src_id ].qs [src_offset ],sizeof (uint64_t )); 3821 } 3822 }else { 3823GGML_ASSERT (false); 3824 } 3825 3826return out ; 3827} 3828 3829static int repack_mxfp4_to_mxfp4_8_bl (struct ggml_tensor * t ,int interleave_block ,const void * GGML_RESTRICT data ,size_t data_size ) { 3830GGML_ASSERT (t -> type == GGML_TYPE_MXFP4 ); 3831GGML_ASSERT (interleave_block == 8 ); 3832 3833const block_mxfp4 * src = (const block_mxfp4 * )data ; 3834block_mxfp4x8 * dst = (block_mxfp4x8 * )t -> data ; 3835 3836block_mxfp4 dst_tmp [8 ]; 3837 3838int nrow = ggml_nrows (t ); 3839int nrows_interleaved = 8 ; 3840int nblocks = t -> ne [0 ] /QK_MXFP4 ; 3841 3842GGML_ASSERT (data_size == nrow * nblocks * sizeof (block_mxfp4 )); 3843 3844if (t -> ne [1 ] %nrows_interleaved != 0 ) { 3845return -1 ; 3846 } 3847 3848for (int b = 0 ;b < nrow ;b += nrows_interleaved ) { 3849for (int64_t x = 0 ;x < nblocks ;x ++ ) { 3850for (int i = 0 ;i < nrows_interleaved ;i ++ ) { 3851dst_tmp [i ]= src [x + i * nblocks ]; 3852 } 3853* dst ++ = make_block_mxfp4x8 (dst_tmp ,interleave_block ); 3854 } 3855src += nrows_interleaved * nblocks ; 3856 } 3857return 0 ; 3858 3859GGML_UNUSED (data_size ); 3860} 3861 3862namespace ggml::cpu::repack { 3863// repack 3864template < typename BLOC_TYPE ,int64_t INTER_SIZE ,int64_t NB_COLS > 3865int repack (struct ggml_tensor * ,const void * ,size_t ); 3866 3867// TODO: generalise. 3868template <> int repack < block_q4_0 ,4 ,4 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3869return repack_q4_0_to_q4_0_4_bl (t ,4 ,data ,data_size ); 3870} 3871 3872template <> int repack < block_q4_0 ,8 ,4 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3873return repack_q4_0_to_q4_0_4_bl (t ,8 ,data ,data_size ); 3874} 3875 3876template <> int repack < block_q4_0 ,8 ,8 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3877return repack_q4_0_to_q4_0_8_bl (t ,8 ,data ,data_size ); 3878} 3879 3880template <> int repack < block_q4_K ,8 ,8 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3881return repack_q4_K_to_q4_K_8_bl (t ,8 ,data ,data_size ); 3882} 3883 3884template <> int repack < block_q4_K ,4 ,8 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3885return repack_q4_K_to_q4_K_8_bl (t ,4 ,data ,data_size ); 3886} 3887 3888template <> int repack < block_q2_K ,8 ,8 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3889return repack_q2_K_to_q2_K_8_bl (t ,8 ,data ,data_size ); 3890} 3891 3892template <> int repack < block_q5_K ,4 ,8 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3893return repack_q5_K_to_q5_K_8_bl (t ,4 ,data ,data_size ); 3894} 3895 3896template <> int repack < block_q5_K ,8 ,8 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3897return repack_q5_K_to_q5_K_8_bl (t ,8 ,data ,data_size ); 3898} 3899 3900template <> int repack < block_q6_K ,4 ,8 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3901return repack_q6_K_to_q6_K_8_bl (t ,4 ,data ,data_size ); 3902} 3903 3904template <> int repack < block_q6_K ,8 ,8 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3905return repack_q6_K_to_q6_K_8_bl (t ,8 ,data ,data_size ); 3906} 3907 3908template <> int repack < block_iq4_nl ,4 ,4 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3909return repack_iq4_nl_to_iq4_nl_4_bl (t ,4 ,data ,data_size ); 3910} 3911 3912// TODO: needs to be revisited 3913//template <> int repack<block_iq4_nl, 8, 4>(struct ggml_tensor * t, const void * data, size_t data_size) { 3914// return repack_iq4_nl_to_iq4_nl_4_bl(t, 8, data, data_size); 3915//} 3916 3917template <> int repack < block_iq4_nl ,8 ,8 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3918return repack_iq4_nl_to_iq4_nl_8_bl (t ,8 ,data ,data_size ); 3919} 3920 3921template <> int repack < block_mxfp4 ,4 ,4 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3922return repack_mxfp4_to_mxfp4_4_bl (t ,4 ,data ,data_size ); 3923} 3924 3925template <> int repack < block_mxfp4 ,8 ,8 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3926return repack_mxfp4_to_mxfp4_8_bl (t ,8 ,data ,data_size ); 3927} 3928 3929template <> int repack < block_q8_0 ,4 ,4 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3930return repack_q8_0_to_q8_0_4_bl (t ,4 ,data ,data_size ); 3931} 3932 3933template <> int repack < block_q8_0 ,8 ,4 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3934return repack_q8_0_to_q8_0_4_bl (t ,8 ,data ,data_size ); 3935} 3936 3937#if defined__riscv_zvfh 3938template <> int repack < block_q4_0 ,1 ,16 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3939return repack_q4_0_to_q4_0_16_bl (t ,1 ,data ,data_size ); 3940} 3941 3942template <> int repack < block_q4_K ,1 ,16 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3943return repack_q4_K_to_q4_K_16_bl (t ,1 ,data ,data_size ); 3944} 3945 3946template <> int repack < block_iq4_nl ,1 ,16 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3947return repack_iq4_nl_to_iq4_nl_16_bl (t ,1 ,data ,data_size ); 3948} 3949 3950template <> int repack < block_q8_0 ,1 ,16 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3951return repack_q8_0_to_q8_0_16_bl (t ,1 ,data ,data_size ); 3952} 3953 3954template <> int repack < block_q2_K ,1 ,16 > (struct ggml_tensor * t ,const void * data ,size_t data_size ) { 3955return repack_q2_K_to_q2_K_16_bl (t ,1 ,data ,data_size ); 3956} 3957#endif 3958 3959// gemv 3960template < typename BLOC_TYPE ,int64_t INTER_SIZE ,int64_t NB_COLS ,ggml_type PARAM_TYPE > 3961void gemv (int ,float * ,size_t ,const void * ,const void * ,int ,int ); 3962 3963template <> void gemv < block_q4_0 ,4 ,4 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 3964ggml_gemv_q4_0_4x4_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 3965} 3966 3967template <> void gemv < block_q4_0 ,8 ,4 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 3968ggml_gemv_q4_0_4x8_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 3969} 3970 3971template <> void gemv < block_q4_0 ,8 ,8 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 3972ggml_gemv_q4_0_8x8_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 3973} 3974 3975template <> 3976void gemv < block_q2_K ,8 ,8 ,GGML_TYPE_Q8_K > (int n , 3977float * s , 3978size_t bs , 3979const void * vx , 3980const void * vy , 3981int nr , 3982int nc ) { 3983ggml_gemv_q2_K_8x8_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 3984} 3985 3986template <> void gemv < block_q4_K ,4 ,8 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 3987ggml_gemv_q4_K_8x4_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 3988} 3989 3990template <> void gemv < block_q4_K ,8 ,8 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 3991ggml_gemv_q4_K_8x8_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 3992} 3993 3994template <> void gemv < block_q5_K ,4 ,8 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 3995ggml_gemv_q5_K_8x4_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 3996} 3997 3998template <> void gemv < block_q5_K ,8 ,8 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 3999ggml_gemv_q5_K_8x8_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4000} 4001 4002template <> void gemv < block_q6_K ,4 ,8 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4003ggml_gemv_q6_K_8x4_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4004} 4005 4006template <> void gemv < block_q6_K ,8 ,8 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4007ggml_gemv_q6_K_8x8_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4008} 4009 4010template <> void gemv < block_iq4_nl ,4 ,4 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4011ggml_gemv_iq4_nl_4x4_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4012} 4013 4014template <> void gemv < block_iq4_nl ,8 ,8 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4015ggml_gemv_iq4_nl_8x8_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4016} 4017 4018template <> void gemv < block_mxfp4 ,4 ,4 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4019ggml_gemv_mxfp4_4x4_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4020} 4021 4022template <> void gemv < block_mxfp4 ,8 ,8 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4023ggml_gemv_mxfp4_8x8_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4024} 4025 4026template <> void gemv < block_q8_0 ,4 ,4 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4027ggml_gemv_q8_0_4x4_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4028} 4029 4030template <> void gemv < block_q8_0 ,8 ,4 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4031ggml_gemv_q8_0_4x8_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4032} 4033 4034#if defined__riscv_zvfh 4035template <> void gemv < block_q4_0 ,1 ,16 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4036ggml_gemv_q4_0_16x1_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4037} 4038 4039template <> void gemv < block_q4_K ,1 ,16 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4040ggml_gemv_q4_K_16x1_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4041} 4042 4043template <> void gemv < block_iq4_nl ,1 ,16 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4044ggml_gemv_iq4_nl_16x1_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4045} 4046 4047template <> void gemv < block_q8_0 ,1 ,16 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4048ggml_gemv_q8_0_16x1_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4049} 4050 4051template <> void gemv < block_q2_K ,1 ,16 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4052ggml_gemv_q2_K_16x1_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4053} 4054#endif 4055 4056// gemm 4057template < typename BLOC_TYPE ,int64_t INTER_SIZE ,int64_t NB_COLS ,ggml_type PARAM_TYPE > 4058void gemm (int ,float * ,size_t ,const void * ,const void * ,int ,int ); 4059 4060template <> void gemm < block_q4_0 ,4 ,4 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4061ggml_gemm_q4_0_4x4_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4062} 4063 4064template <> void gemm < block_q4_0 ,8 ,4 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4065ggml_gemm_q4_0_4x8_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4066} 4067 4068template <> 4069void gemm < block_q4_0 ,8 ,8 ,GGML_TYPE_Q8_0 > (int n , 4070float * s , 4071size_t bs , 4072const void * vx , 4073const void * vy , 4074int nr , 4075int nc ) { 4076ggml_gemm_q4_0_8x8_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4077} 4078 4079template <> void gemm < block_q2_K ,8 ,8 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4080ggml_gemm_q2_K_8x8_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4081} 4082 4083template <> void gemm < block_q4_K ,4 ,8 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4084ggml_gemm_q4_K_8x4_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4085} 4086 4087template <> void gemm < block_q4_K ,8 ,8 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4088ggml_gemm_q4_K_8x8_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4089} 4090 4091template <> void gemm < block_q5_K ,4 ,8 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4092ggml_gemm_q5_K_8x4_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4093} 4094 4095template <> void gemm < block_q5_K ,8 ,8 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4096ggml_gemm_q5_K_8x8_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4097} 4098 4099template <> void gemm < block_q6_K ,4 ,8 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4100ggml_gemm_q6_K_8x4_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4101} 4102 4103template <> void gemm < block_q6_K ,8 ,8 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4104ggml_gemm_q6_K_8x8_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4105} 4106 4107template <> void gemm < block_iq4_nl ,4 ,4 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4108ggml_gemm_iq4_nl_4x4_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4109} 4110 4111template <> void gemm < block_iq4_nl ,8 ,8 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4112ggml_gemm_iq4_nl_8x8_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4113} 4114 4115template <> void gemm < block_mxfp4 ,4 ,4 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4116ggml_gemm_mxfp4_4x4_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4117} 4118 4119template <> void gemm < block_mxfp4 ,8 ,8 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4120ggml_gemm_mxfp4_8x8_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4121} 4122 4123template <> void gemm < block_q8_0 ,4 ,4 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4124ggml_gemm_q8_0_4x4_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4125} 4126 4127template <> void gemm < block_q8_0 ,8 ,4 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4128ggml_gemm_q8_0_4x8_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4129} 4130 4131#if defined__riscv_zvfh 4132template <> void gemm < block_q4_0 ,1 ,16 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4133ggml_gemm_q4_0_16x1_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4134} 4135 4136template <> void gemm < block_q4_K ,1 ,16 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4137ggml_gemm_q4_K_16x1_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4138} 4139 4140template <> void gemm < block_iq4_nl ,1 ,16 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4141ggml_gemm_iq4_nl_16x1_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4142} 4143 4144template <> void gemm < block_q8_0 ,1 ,16 ,GGML_TYPE_Q8_0 > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4145ggml_gemm_q8_0_16x1_q8_0 (n ,s ,bs ,vx ,vy ,nr ,nc ); 4146} 4147 4148template <> void gemm < block_q2_K ,1 ,16 ,GGML_TYPE_Q8_K > (int n ,float * s ,size_t bs ,const void * vx ,const void * vy ,int nr ,int nc ) { 4149ggml_gemm_q2_K_16x1_q8_K (n ,s ,bs ,vx ,vy ,nr ,nc ); 4150} 4151#endif 4152 4153class tensor_traits_base :public ggml::cpu::tensor_traits { 4154public : 4155virtual int repack (struct ggml_tensor * t ,const void * data ,size_t data_size )= 0 ; 4156}; 4157 4158template < typename BLOC_TYPE ,int64_t INTER_SIZE ,int64_t NB_COLS ,ggml_type PARAM_TYPE > class tensor_traits :public tensor_traits_base { 4159 4160bool work_size (int /* n_threads */ ,const struct ggml_tensor * op ,size_t & size )override { 4161// not realy a GGML_TYPE_Q8_0 but same size. 4162switch (op -> op ) { 4163case GGML_OP_MUL_MAT : 4164 { 4165size = ggml_row_size (PARAM_TYPE ,ggml_nelements (op -> src [1 ])); 4166return true; 4167 } 4168case GGML_OP_MUL_MAT_ID : 4169 { 4170size = ggml_row_size (PARAM_TYPE ,ggml_nelements (op -> src [1 ])); 4171size = GGML_PAD (size ,sizeof (int64_t ));// + padding for next block. 4172 4173const int64_t ne02 = op -> src [0 ]-> ne [2 ];// n_as, n_expert 4174const int64_t ne12 = op -> src [1 ]-> ne [2 ];// n_tokens 4175 4176const size_t sizeof_mmid_row_mapping = sizeof (int64_t ); 4177 4178size += sizeof_mmid_row_mapping * ne02 * (ne12 + 1 ); 4179 4180return true; 4181 } 4182default : 4183// GGML_ABORT("fatal error"); 4184break ; 4185 } 4186return false; 4187 } 4188 4189bool compute_forward (struct ggml_compute_params * params ,struct ggml_tensor * op )override { 4190switch (op -> op ) { 4191case GGML_OP_MUL_MAT : 4192forward_mul_mat (params ,op ); 4193return true; 4194case GGML_OP_MUL_MAT_ID : 4195forward_mul_mat_id (params ,op ); 4196return true; 4197default : 4198// GGML_ABORT("fatal error"); 4199break ; 4200 } 4201return false; 4202 } 4203 4204void forward_mul_mat_one_chunk (ggml_compute_params * params , 4205ggml_tensor * op , 4206int64_t src0_start , 4207int64_t src0_end , 4208int64_t src1_start , 4209int64_t src1_end ) { 4210const ggml_tensor * src0 = op -> src [0 ]; 4211const ggml_tensor * src1 = op -> src [1 ]; 4212ggml_tensor * dst = op ; 4213 4214GGML_TENSOR_BINARY_OP_LOCALS 4215 4216const size_t src1_col_stride = ggml_row_size (PARAM_TYPE ,ne10 ); 4217 4218GGML_ASSERT (ne03 == 1 && ne13 == 1 ); 4219GGML_ASSERT (ne12 %ne02 == 0 ); 4220const int64_t r2 = ne12 /ne02 ; 4221 4222const int64_t i12 = src1_start /ne1 ; 4223const int64_t i11 = src1_start - i12 * ne1 ; 4224 4225// Determine batch index 4226const int64_t i02 = i12 /r2 ; 4227 4228const int64_t i1 = i11 ; 4229const int64_t i2 = i12 ; 4230 4231const char * src0_ptr = (const char * )src0 -> data + i02 * nb02 ; 4232const char * src1_ptr = (const char * )params -> wdata + (i11 + i12 * ne11 )* src1_col_stride ; 4233char * dst_ptr = ((char * )dst -> data + (i1 * nb1 + i2 * nb2 )); 4234 4235const int64_t nrows = src1_end - src1_start ; 4236const int64_t ncols = src0_end - src0_start ; 4237 4238GGML_ASSERT (src1_ptr + src1_col_stride * nrows <= (const char * )params -> wdata + params -> wsize ); 4239 4240// If there are more than three rows in src1, use gemm; otherwise, use gemv. 4241if (nrows > 3 ) { 4242gemm < BLOC_TYPE ,INTER_SIZE ,NB_COLS ,PARAM_TYPE > (ne00 , (float * ) (dst_ptr )+ src0_start ,nb1 /nb0 , 4243src0_ptr + src0_start * nb01 ,src1_ptr , 4244nrows - (nrows %4 ),ncols ); 4245 } 4246for (int iter = nrows - (nrows %4 );iter < nrows ;iter ++ ) { 4247gemv < BLOC_TYPE ,INTER_SIZE ,NB_COLS ,PARAM_TYPE > (ne00 , (float * ) (dst_ptr + (iter * nb1 ))+ src0_start , 4248ne01 ,src0_ptr + src0_start * nb01 , 4249src1_ptr + (src1_col_stride * iter ),1 /* nrows */ ,ncols ); 4250 } 4251 } 4252 4253void forward_mul_mat (ggml_compute_params * params ,ggml_tensor * op ) { 4254const ggml_tensor * src0 = op -> src [0 ]; 4255const ggml_tensor * src1 = op -> src [1 ]; 4256ggml_tensor * dst = op ; 4257 4258GGML_TENSOR_BINARY_OP_LOCALS 4259 4260const int ith = params -> ith ; 4261const int nth = params -> nth ; 4262 4263GGML_ASSERT (ne0 == ne01 ); 4264GGML_ASSERT (ne1 == ne11 ); 4265GGML_ASSERT (ne2 == ne12 ); 4266GGML_ASSERT (ne3 == ne13 ); 4267 4268// dst cannot be transposed or permuted 4269GGML_ASSERT (nb0 == sizeof (float )); 4270GGML_ASSERT (nb0 <=nb1 ); 4271GGML_ASSERT (nb1 <=nb2 ); 4272GGML_ASSERT (nb2 <=nb3 ); 4273 4274// TODO: General batched mul mat for 4D tensors 4275// Currently only supports 3D tensors 4276GGML_ASSERT (ne03 == 1 ); 4277GGML_ASSERT (ne13 == 1 ); 4278GGML_ASSERT (ne3 == 1 ); 4279 4280GGML_ASSERT (src1 -> type == GGML_TYPE_F32 ); 4281 4282GGML_ASSERT (ggml_n_dims (op -> src [0 ])== 2 ); 4283// GGML_ASSERT(ggml_n_dims(op->src[1]) == 2); 4284 4285char * wdata = static_cast < char *> (params -> wdata ); 4286const size_t nbw1 = ggml_row_size (PARAM_TYPE ,ne10 ); 4287const size_t nbw2 = nbw1 * ne11 ; 4288 4289assert (params -> wsize >=nbw2 * ne12 ); 4290 4291const ggml_from_float_t from_float = ggml_get_type_traits_cpu (PARAM_TYPE )-> from_float ; 4292 4293// INFO: Quantization is done in planes to avoid extra complexity in chunking. 4294// Flattening dimensions not multiple of INTER_SIZE would require extra handling depending on how 4295// the planes are broadcast. 4296for (int64_t i12 = 0 ;i12 < ne12 ;i12 ++ ) { 4297char * data_ptr = (char * )src1 -> data + i12 * nb12 ; 4298char * wdata_ptr = wdata + i12 * nbw2 ; 4299 4300for (int64_t i11 = ith * 4 ;i11 < ne11 - ne11 %4 ;i11 += nth * 4 ) { 4301ggml_quantize_mat_t < INTER_SIZE ,PARAM_TYPE > ((float * ) (data_ptr + i11 * nb11 ), 4302 (void * ) (wdata_ptr + i11 * nbw1 ),4 ,ne10 ); 4303 } 4304 4305const int64_t i11_processed = ne11 - ne11 %4 ; 4306for (int64_t i11 = i11_processed + ith ;i11 < ne11 ;i11 += nth ) { 4307from_float ((float * ) (data_ptr + i11 * nb11 ), (void * ) (wdata_ptr + i11 * nbw1 ),ne10 ); 4308 } 4309 } 4310 4311// disable for NUMA 4312const bool disable_chunking = ggml_is_numa (); 4313 4314// 4x chunks per thread 4315const int64_t nr0 = ggml_nrows (op -> src [0 ]); 4316 4317int nth_scaled = nth * 4 ; 4318int64_t chunk_size0 = (nr0 + nth_scaled - 1 ) /nth_scaled ; 4319int64_t nchunk0 = (nr0 + chunk_size0 - 1 ) /chunk_size0 ; 4320 4321// src1 is chunked only by full planes. 4322// When we flatten we need to address dimensions not multiple of the q8 INTER_SIZE 4323// to route them thorugh GEMV. 4324// nchunk1 = ne12 also avoids messing the chunking for models with no 3d tensors 4325// to avoid affecting their performance 4326int64_t nchunk1 = ne12 ; 4327 4328// Ensure minimum chunk size to avoid alignment issues with high thread counts 4329// Minimum chunk size should be at least NB_COLS to prevent overlapping chunks after alignment 4330const int64_t min_chunk_size = NB_COLS ; 4331if (nchunk0 > 0 && (nr0 /nchunk0 )< min_chunk_size && nr0 >=min_chunk_size ) { 4332nchunk0 = (nr0 + min_chunk_size - 1 ) /min_chunk_size ; 4333 } 4334 4335int64_t dr0 = (nr0 + nchunk0 - 1 ) /nchunk0 ; 4336// Only increase nchunk0 to nth if it won't make chunks too small 4337if (nth == 1 || ((nchunk0 < nth || disable_chunking )&& (nr0 + nth - 1 ) /nth >=min_chunk_size )) { 4338nchunk0 = nth ; 4339dr0 = (nr0 + nchunk0 - 1 ) /nchunk0 ; 4340 } 4341 4342// Ensure nchunk doesn't exceed the number of rows divided by minimum chunk size 4343// This prevents creating too many tiny chunks that could overlap after alignment 4344const int64_t max_nchunk = (nr0 + min_chunk_size - 1 ) /min_chunk_size ; 4345nchunk0 = MIN (nchunk0 ,max_nchunk ); 4346 4347if (ith == 0 ) { 4348// Every thread starts at ith, so the first unprocessed chunk is nth. This save a bit of coordination right at the start. 4349ggml_threadpool_chunk_set (params -> threadpool ,nth ); 4350 } 4351 4352ggml_barrier (params -> threadpool ); 4353 4354// The first chunk comes from our thread_id, the rest will get auto-assigned. 4355int current_chunk = ith ; 4356 4357while (current_chunk < nchunk0 * nchunk1 ) { 4358const int64_t ith0 = current_chunk %nchunk0 ; 4359const int64_t ith1 = current_chunk /nchunk0 ; 4360 4361int64_t src0_start = dr0 * ith0 ; 4362int64_t src0_end = MIN (src0_start + dr0 ,nr0 ); 4363 4364// full-plane range for src1 4365int64_t src1_start = ith1 * ne11 ; 4366int64_t src1_end = (ith1 + 1 )* ne11 ; 4367 4368// Align boundaries to NB_COLS - round up to ensure all data is included 4369// The chunk size limiting above ensures chunks are large enough to prevent overlaps 4370src0_start = (src0_start %NB_COLS ) ?src0_start + NB_COLS - (src0_start %NB_COLS ) :src0_start ; 4371src0_end = (src0_end %NB_COLS ) ?src0_end + NB_COLS - (src0_end %NB_COLS ) :src0_end ; 4372src0_end = MIN (src0_end ,ne01 ); 4373 4374// Make sure current plane is the last one before exiting 4375if (src0_start >=src0_end ) { 4376current_chunk = ggml_threadpool_chunk_add (params -> threadpool ,1 ); 4377continue ; 4378 } 4379 4380forward_mul_mat_one_chunk (params ,dst ,src0_start ,src0_end ,src1_start ,src1_end ); 4381 4382current_chunk = ggml_threadpool_chunk_add (params -> threadpool ,1 ); 4383 } 4384 } 4385 4386void forward_mul_mat_id (ggml_compute_params * params ,ggml_tensor * op ) { 4387const ggml_tensor * src0 = op -> src [0 ]; 4388const ggml_tensor * src1 = op -> src [1 ]; 4389const ggml_tensor * ids = op -> src [2 ]; 4390ggml_tensor * dst = op ; 4391 4392GGML_TENSOR_BINARY_OP_LOCALS 4393 4394const int ith = params -> ith ; 4395const int nth = params -> nth ; 4396 4397const ggml_from_float_t from_float = ggml_get_type_traits_cpu (PARAM_TYPE )-> from_float ; 4398 4399// we don't support permuted src0 or src1 4400GGML_ASSERT (nb00 == ggml_type_size (src0 -> type )); 4401GGML_ASSERT (nb10 == ggml_type_size (src1 -> type )); 4402 4403// dst cannot be transposed or permuted 4404GGML_ASSERT (nb0 == sizeof (float )); 4405GGML_ASSERT (nb0 <=nb1 ); 4406GGML_ASSERT (nb1 <=nb2 ); 4407GGML_ASSERT (nb2 <=nb3 ); 4408 4409GGML_ASSERT (ne03 == 1 ); 4410GGML_ASSERT (ne13 == 1 ); 4411GGML_ASSERT (ne3 == 1 ); 4412 4413GGML_ASSERT (src1 -> type == GGML_TYPE_F32 ); 4414 4415// row groups 4416const int n_ids = ids -> ne [0 ];// n_expert_used 4417const int n_as = ne02 ;// n_expert 4418 4419const size_t nbw1 = ggml_row_size (PARAM_TYPE ,ne10 ); 4420const size_t nbw2 = nbw1 * ne11 ; 4421const size_t nbw3 = nbw2 * ne12 ; 4422 4423struct mmid_row_mapping { 4424int32_t i1 ; 4425int32_t i2 ; 4426 }; 4427 4428GGML_ASSERT (params -> wsize >= 4429 (GGML_PAD (nbw3 ,sizeof (int64_t ))+ 4430n_as * (ne12 + 1 )* sizeof (mmid_row_mapping )) 4431 ); 4432 4433auto * wdata = (char * )params -> wdata ; 4434auto * wdata_src1_end = (char * )wdata + GGML_PAD (nbw3 ,sizeof (int64_t )); 4435 4436// total of [n_as][ne12 + 1] elements of type mmid_row_mapping (2*int32_t = int64_t) 4437auto * matrix_row_counts = (int64_t * ) (wdata_src1_end );// [n_as] 4438struct mmid_row_mapping * matrix_rows = (struct mmid_row_mapping * ) (matrix_row_counts + n_as );// [n_as][ne12] 4439 4440// src1: float32 => param type 4441for (int64_t i12 = 0 ;i12 < ne12 ;++ i12 ) { 4442for (int64_t i11 = ith ;i11 < ne11 ;i11 += nth ) { 4443from_float ((float * )((char * )src1 -> data + i12 * nb12 + i11 * nb11 ), 4444 (void * ) (wdata + i12 * nbw2 + i11 * nbw1 ), 4445ne10 ); 4446 } 4447 } 4448 4449#define MMID_MATRIX_ROW (row_id ,i1 ) matrix_rows[(row_id) * ne12 + (i1)] 4450 4451if (ith == 0 ) { 4452// initialize matrix_row_counts 4453memset (matrix_row_counts ,0 ,n_as * sizeof (int64_t )); 4454 4455// group rows by src0 matrix 4456for (int32_t iid1 = 0 ;iid1 < ids -> ne [1 ];++ iid1 ) { 4457for (int32_t id = 0 ;id < n_ids ;++ id ) { 4458const int32_t i02 = 4459* (const int32_t * ) ((const char * )ids -> data + iid1 * ids -> nb [1 ]+ id * ids -> nb [0 ]); 4460 4461GGML_ASSERT (i02 >=0 && i02 < n_as ); 4462 4463MMID_MATRIX_ROW (i02 ,matrix_row_counts [i02 ])= {id ,iid1 }; 4464matrix_row_counts [i02 ]+= 1 ; 4465 } 4466 } 4467 } 4468 4469ggml_barrier (params -> threadpool ); 4470 4471// compute each matrix multiplication in sequence 4472for (int cur_a = 0 ;cur_a < n_as ;++ cur_a ) { 4473const int64_t cne1 = matrix_row_counts [cur_a ]; 4474 4475if (cne1 == 0 ) { 4476continue ; 4477 } 4478 4479const auto * src0_cur = (const char * )src0 -> data + cur_a * nb02 ; 4480 4481//const int64_t nr0 = ne01; // src0 rows 4482const int64_t nr1 = cne1 ;// src1 rows 4483 4484int64_t src0_cur_start = (ith * ne01 ) /nth ; 4485int64_t src0_cur_end = ((ith + 1 )* ne01 ) /nth ; 4486 4487// Align boundaries to NB_COLS - round up to ensure all data is included 4488src0_cur_start = (src0_cur_start %NB_COLS ) ?src0_cur_start + NB_COLS - (src0_cur_start %NB_COLS ) :src0_cur_start ; 4489src0_cur_end = (src0_cur_end %NB_COLS ) ?src0_cur_end + NB_COLS - (src0_cur_end %NB_COLS ) :src0_cur_end ; 4490if (src0_cur_end > ne01 ) { 4491src0_cur_end = ne01 ; 4492 } 4493 4494if (src0_cur_start >=src0_cur_end ) { 4495return ; 4496 } 4497 4498for (int ir1 = 0 ;ir1 < nr1 ;ir1 ++ ) { 4499struct mmid_row_mapping row_mapping = MMID_MATRIX_ROW (cur_a ,ir1 ); 4500 4501const int id = row_mapping .i1 ;// selected expert index 4502 4503const int64_t i11 = id %ne11 ; 4504const int64_t i12 = row_mapping .i2 ;// row index in src1 4505 4506const int64_t i1 = id ;// selected expert index 4507const int64_t i2 = i12 ;// row 4508 4509const auto * src1_col = (const char * )wdata + (i11 * nbw1 + i12 * nbw2 ); 4510 4511gemv < BLOC_TYPE ,INTER_SIZE ,NB_COLS ,PARAM_TYPE > ( 4512ne00 , (float * ) ((char * )dst -> data + (i1 * nb1 + i2 * nb2 ))+ src0_cur_start ,ne01 , 4513src0_cur + src0_cur_start * nb01 ,src1_col ,1 ,src0_cur_end - src0_cur_start ); 4514 } 4515 } 4516#undef MMID_MATRIX_ROW 4517 } 4518 4519int repack (struct ggml_tensor * t ,const void * data ,size_t data_size )override { 4520GGML_LOG_DEBUG ("%s: repack tensor %s with %s_%dx%d\n" ,__func__ ,t -> name ,ggml_type_name (t -> type ), 4521 (int )NB_COLS , (int )INTER_SIZE ); 4522return ggml::cpu::repack::repack < BLOC_TYPE ,INTER_SIZE ,NB_COLS > (t ,data ,data_size ); 4523 } 4524}; 4525 4526}// namespace ggml::cpu::repack 4527 4528static const ggml::cpu::tensor_traits * ggml_repack_get_optimal_repack_type (const struct ggml_tensor * cur ) { 4529// instance for Q4 4530static const ggml::cpu::repack::tensor_traits < block_q4_0 ,4 ,4 ,GGML_TYPE_Q8_0 > q4_0_4x4_q8_0 ; 4531static const ggml::cpu::repack::tensor_traits < block_q4_0 ,8 ,4 ,GGML_TYPE_Q8_0 > q4_0_4x8_q8_0 ; 4532static const ggml::cpu::repack::tensor_traits < block_q4_0 ,8 ,8 ,GGML_TYPE_Q8_0 > q4_0_8x8_q8_0 ; 4533 4534// instance for Q4_K 4535static const ggml::cpu::repack::tensor_traits < block_q4_K ,4 ,8 ,GGML_TYPE_Q8_K > q4_K_8x4_q8_K ; 4536static const ggml::cpu::repack::tensor_traits < block_q4_K ,8 ,8 ,GGML_TYPE_Q8_K > q4_K_8x8_q8_K ; 4537 4538// instance for Q5_K 4539static const ggml::cpu::repack::tensor_traits < block_q5_K ,4 ,8 ,GGML_TYPE_Q8_K > q5_K_8x4_q8_K ; 4540static const ggml::cpu::repack::tensor_traits < block_q5_K ,8 ,8 ,GGML_TYPE_Q8_K > q5_K_8x8_q8_K ; 4541 4542// instance for Q6_K 4543static const ggml::cpu::repack::tensor_traits < block_q6_K ,4 ,8 ,GGML_TYPE_Q8_K > q6_K_8x4_q8_K ; 4544static const ggml::cpu::repack::tensor_traits < block_q6_K ,8 ,8 ,GGML_TYPE_Q8_K > q6_K_8x8_q8_K ; 4545 4546// instance for Q2 4547static const ggml::cpu::repack::tensor_traits < block_q2_K ,8 ,8 ,GGML_TYPE_Q8_K > q2_K_8x8_q8_K ; 4548 4549// instance for IQ4 4550static const ggml::cpu::repack::tensor_traits < block_iq4_nl ,4 ,4 ,GGML_TYPE_Q8_0 > iq4_nl_4x4_q8_0 ; 4551static const ggml::cpu::repack::tensor_traits < block_iq4_nl ,8 ,8 ,GGML_TYPE_Q8_0 > iq4_nl_8x8_q8_0 ; 4552 4553// instance for MXFP4 4554static const ggml::cpu::repack::tensor_traits < block_mxfp4 ,4 ,4 ,GGML_TYPE_Q8_0 > mxfp4_4x4_q8_0 ; 4555static const ggml::cpu::repack::tensor_traits < block_mxfp4 ,8 ,8 ,GGML_TYPE_Q8_0 > mxfp4_8x8_q8_0 ; 4556 4557// instance for Q8_0 4558static const ggml::cpu::repack::tensor_traits < block_q8_0 ,4 ,4 ,GGML_TYPE_Q8_0 > q8_0_4x4_q8_0 ; 4559static const ggml::cpu::repack::tensor_traits < block_q8_0 ,8 ,4 ,GGML_TYPE_Q8_0 > q8_0_4x8_q8_0 ; 4560 4561// instances for RISC-V 4562// 4563// These implement outer-product style matrix multiplication kernels with 4564// an interleave of 1. 4565#if defined__riscv_zvfh 4566static const ggml::cpu::repack::tensor_traits < block_q4_0 ,1 ,16 ,GGML_TYPE_Q8_0 > q4_0_16x1_q8_0 ; 4567static const ggml::cpu::repack::tensor_traits < block_q4_K ,1 ,16 ,GGML_TYPE_Q8_K > q4_K_16x1_q8_K ; 4568static const ggml::cpu::repack::tensor_traits < block_iq4_nl ,1 ,16 ,GGML_TYPE_Q8_0 > iq4_nl_16x1_q8_0 ; 4569static const ggml::cpu::repack::tensor_traits < block_q8_0 ,1 ,16 ,GGML_TYPE_Q8_0 > q8_0_16x1_q8_0 ; 4570static const ggml::cpu::repack::tensor_traits < block_q2_K ,1 ,16 ,GGML_TYPE_Q8_K > q2_K_16x1_q8_K ; 4571#endif 4572 4573if (cur -> type == GGML_TYPE_Q4_0 ) { 4574if (ggml_cpu_has_avx2 ()|| (ggml_cpu_has_sve ()&& ggml_cpu_has_matmul_int8 ()&& ggml_cpu_get_sve_cnt ()== QK8_0 )) { 4575if (cur -> ne [1 ] %8 == 0 ) { 4576return & q4_0_8x8_q8_0 ; 4577 } 4578 } 4579if (ggml_cpu_has_neon ()&& ggml_cpu_has_matmul_int8 ()) { 4580if (cur -> ne [1 ] %4 == 0 ) { 4581return & q4_0_4x8_q8_0 ; 4582 } 4583 } 4584if (ggml_cpu_has_neon ()&& ggml_cpu_has_dotprod ()) { 4585if (cur -> ne [1 ] %4 == 0 ) { 4586return & q4_0_4x4_q8_0 ; 4587 } 4588 } 4589if (ggml_cpu_has_vxe ()) { 4590if (cur -> ne [1 ] %4 == 0 ) { 4591return & q4_0_4x4_q8_0 ; 4592 } 4593 } 4594if (ggml_cpu_has_riscv_v ()) { 4595#if defined__riscv_zvfh 4596switch (__riscv_vlenb ()* 8 ) { 4597case 128 : {break ; }// TODO 4598case 256 : {if (cur -> ne [1 ] %16 == 0 ) {return & q4_0_16x1_q8_0 ; }break ; } 4599case 512 : {break ; }// TODO 4600case 1024 : {break ; }// TODO 4601default : {return nullptr ; } 4602 } 4603#endif 4604 } 4605 }else if (cur -> type == GGML_TYPE_Q4_K ) { 4606if (ggml_cpu_has_avx2 ()) { 4607if (cur -> ne [1 ] %8 == 0 ) { 4608return & q4_K_8x8_q8_K ; 4609 } 4610 } 4611if (ggml_cpu_has_neon ()&& ggml_cpu_has_matmul_int8 ()) { 4612if (cur -> ne [1 ] %8 == 0 ) { 4613return & q4_K_8x8_q8_K ; 4614 } 4615 } 4616if (ggml_cpu_has_neon ()&& ggml_cpu_has_dotprod ()) { 4617if (cur -> ne [1 ] %8 == 0 ) { 4618return & q4_K_8x4_q8_K ; 4619 } 4620 } 4621if (ggml_cpu_has_riscv_v ()) { 4622#if defined__riscv_zvfh 4623switch (__riscv_vlenb ()* 8 ) { 4624case 128 : {break ; }// TODO 4625case 256 : {if (cur -> ne [1 ] %16 == 0 ) {return & q4_K_16x1_q8_K ; }break ; } 4626case 512 : {break ; }// TODO 4627case 1024 : {break ; }// TODO 4628default : {return nullptr ; } 4629 } 4630#endif 4631 } 4632 }else if (cur -> type == GGML_TYPE_Q2_K ) { 4633if (ggml_cpu_has_avx512 ()) { 4634if (cur -> ne [1 ] %8 == 0 ) { 4635return & q2_K_8x8_q8_K ; 4636 } 4637 } 4638if (ggml_cpu_has_riscv_v ()) { 4639#if defined__riscv_zvfh 4640switch (__riscv_vlenb ()* 8 ) { 4641case 128 : {break ; }// TODO 4642case 256 : {if (cur -> ne [1 ] %16 == 0 ) {return & q2_K_16x1_q8_K ; }break ; } 4643case 512 : {break ; }// TODO 4644case 1024 : {break ; }// TODO 4645default : {return nullptr ; } 4646 } 4647#endif 4648 } 4649 }else if (cur -> type == GGML_TYPE_Q5_K ) { 4650if (ggml_cpu_has_neon ()&& ggml_cpu_has_matmul_int8 ()) { 4651if (cur -> ne [1 ] %8 == 0 ) { 4652return & q5_K_8x8_q8_K ; 4653 } 4654 } 4655if (ggml_cpu_has_neon ()&& ggml_cpu_has_dotprod ()) { 4656if (cur -> ne [1 ] %8 == 0 ) { 4657return & q5_K_8x4_q8_K ; 4658 } 4659 } 4660 }else if (cur -> type == GGML_TYPE_Q6_K ) { 4661if (ggml_cpu_has_neon ()&& ggml_cpu_has_matmul_int8 ()) { 4662if (cur -> ne [1 ] %8 == 0 ) { 4663return & q6_K_8x8_q8_K ; 4664 } 4665 } 4666if (ggml_cpu_has_neon ()&& ggml_cpu_has_dotprod ()) { 4667if (cur -> ne [1 ] %8 == 0 ) { 4668return & q6_K_8x4_q8_K ; 4669 } 4670 } 4671 }else if (cur -> type == GGML_TYPE_IQ4_NL ) { 4672if (ggml_cpu_has_avx2 ()) { 4673if (cur -> ne [1 ] %8 == 0 ) { 4674return & iq4_nl_8x8_q8_0 ; 4675 } 4676 } 4677if (ggml_cpu_has_neon ()&& ggml_cpu_has_dotprod ()) { 4678if (cur -> ne [1 ] %4 == 0 ) { 4679return & iq4_nl_4x4_q8_0 ; 4680 } 4681 } 4682if (ggml_cpu_has_riscv_v ()) { 4683#if defined__riscv_zvfh 4684switch (__riscv_vlenb ()* 8 ) { 4685case 128 : {break ; }// TODO 4686case 256 : {if (cur -> ne [1 ] %16 == 0 ) {return & iq4_nl_16x1_q8_0 ; }break ; } 4687case 512 : {break ; }// TODO 4688case 1024 : {break ; }// TODO 4689default : {return nullptr ; } 4690 } 4691#endif 4692 } 4693 }else if (cur -> type == GGML_TYPE_MXFP4 ) { 4694if (ggml_cpu_has_avx2 ()) { 4695if (cur -> ne [1 ] %8 == 0 ) { 4696return & mxfp4_8x8_q8_0 ; 4697 } 4698 } 4699if (ggml_cpu_has_neon ()&& ggml_cpu_has_dotprod ()) { 4700if (cur -> ne [1 ] %4 == 0 ) { 4701return & mxfp4_4x4_q8_0 ; 4702 } 4703 } 4704 }else if (cur -> type == GGML_TYPE_Q8_0 ) { 4705if (ggml_cpu_has_neon ()&& ggml_cpu_has_matmul_int8 ()) { 4706if (cur -> ne [1 ] %4 == 0 ) { 4707return & q8_0_4x8_q8_0 ; 4708 } 4709 } 4710if (ggml_cpu_has_neon ()&& ggml_cpu_has_dotprod ()) { 4711if (cur -> ne [1 ] %4 == 0 ) { 4712return & q8_0_4x4_q8_0 ; 4713 } 4714 } 4715if (ggml_cpu_has_riscv_v ()) { 4716#if defined__riscv_zvfh 4717switch (__riscv_vlenb ()* 8 ) { 4718case 128 : {break ; }// TODO 4719case 256 : {if (cur -> ne [1 ] %16 == 0 ) {return & q8_0_16x1_q8_0 ; }break ; } 4720case 512 : {break ; }// TODO 4721case 1024 : {break ; }// TODO 4722default : {return nullptr ; } 4723 } 4724#endif 4725 } 4726 } 4727 4728return nullptr ; 4729} 4730 4731static enum ggml_status ggml_backend_cpu_repack_buffer_init_tensor (ggml_backend_buffer_t buffer ,struct ggml_tensor * tensor ) { 4732tensor -> extra = (void * )const_cast < ggml::cpu::tensor_traits *> (ggml_repack_get_optimal_repack_type (tensor )); 4733 4734GGML_UNUSED (buffer ); 4735return GGML_STATUS_SUCCESS ; 4736} 4737 4738static void ggml_backend_cpu_repack_buffer_set_tensor (ggml_backend_buffer_t buffer ,struct ggml_tensor * tensor , 4739const void * data ,size_t offset ,size_t size ) { 4740GGML_ASSERT (offset == 0 ); 4741GGML_ASSERT (size == ggml_nbytes (tensor )); 4742 4743auto tensor_traits = (ggml::cpu::repack::tensor_traits_base * )tensor -> extra ; 4744auto OK = tensor_traits -> repack (tensor ,data ,size ); 4745 4746GGML_ASSERT (OK == 0 ); 4747GGML_UNUSED (buffer ); 4748} 4749 4750static const char * ggml_backend_cpu_repack_buffer_type_get_name (ggml_backend_buffer_type_t buft ) { 4751return "CPU_REPACK" ; 4752 4753GGML_UNUSED (buft ); 4754} 4755 4756static ggml_backend_buffer_t ggml_backend_cpu_repack_buffer_type_alloc_buffer (ggml_backend_buffer_type_t buft ,size_t size ) { 4757ggml_backend_buffer_t buffer = ggml_backend_buft_alloc_buffer (ggml_backend_cpu_buffer_type (),size ); 4758 4759if (buffer == nullptr ) { 4760return nullptr ; 4761 } 4762 4763buffer -> buft = buft ; 4764buffer -> iface .init_tensor = ggml_backend_cpu_repack_buffer_init_tensor ; 4765buffer -> iface .set_tensor = ggml_backend_cpu_repack_buffer_set_tensor ; 4766buffer -> iface .get_tensor = nullptr ; 4767buffer -> iface .cpy_tensor = nullptr ; 4768return buffer ; 4769} 4770 4771static size_t ggml_backend_cpu_repack_buffer_type_get_alignment (ggml_backend_buffer_type_t buft ) { 4772return TENSOR_ALIGNMENT ; 4773 4774GGML_UNUSED (buft ); 4775} 4776 4777namespace ggml::cpu::repack { 4778class extra_buffer_type : ggml::cpu::extra_buffer_type { 4779bool supports_op (ggml_backend_dev_t ,const struct ggml_tensor * op )override { 4780if (op -> op == GGML_OP_MUL_MAT && 4781op -> src [0 ]-> buffer && 4782 (ggml_n_dims (op -> src [0 ])== 2 )&& 4783op -> src [0 ]-> buffer -> buft == ggml_backend_cpu_repack_buffer_type ()&& 4784ggml_repack_get_optimal_repack_type (op -> src [0 ]) 4785 ) { 4786if (op -> src [1 ]-> buffer && !ggml_backend_buft_is_host (op -> src [1 ]-> buffer -> buft )) { 4787return false; 4788 } 4789if (op -> src [1 ]-> type == GGML_TYPE_F32 ) { 4790return true; 4791 } 4792//if (op->src[1]->type == GGML_TYPE_Q8_0) { 4793// return true; 4794//} 4795// may be possible if Q8_0 packed... 4796 }else if (op -> op == GGML_OP_MUL_MAT_ID 4797&& op -> src [0 ]-> buffer 4798&& (ggml_n_dims (op -> src [0 ])== 3 ) 4799&& op -> src [0 ]-> buffer -> buft == ggml_backend_cpu_repack_buffer_type () 4800&& ggml_repack_get_optimal_repack_type (op -> src [0 ]) 4801 ) { 4802if (op -> src [1 ]-> buffer && !ggml_backend_buft_is_host (op -> src [1 ]-> buffer -> buft )) { 4803return false; 4804 } 4805if (op -> src [1 ]-> type == GGML_TYPE_F32 ) { 4806return true; 4807 } 4808//if (op->src[1]->type == GGML_TYPE_Q8_0) { 4809// return true; 4810//} 4811 } 4812return false; 4813 } 4814 4815 ggml::cpu::tensor_traits * get_tensor_traits (const struct ggml_tensor * op )override { 4816if (op -> op == GGML_OP_MUL_MAT || op -> op == GGML_OP_MUL_MAT_ID ) { 4817if (op -> src [0 ]-> buffer && op -> src [0 ]-> buffer -> buft == ggml_backend_cpu_repack_buffer_type ()) { 4818return (ggml::cpu::tensor_traits * )op -> src [0 ]-> extra ; 4819 } 4820 } 4821return nullptr ; 4822 } 4823}; 4824}// namespace ggml::cpu::repack 4825 4826ggml_backend_buffer_type_t ggml_backend_cpu_repack_buffer_type (void ) { 4827static struct ggml_backend_buffer_type ggml_backend_cpu_buffer_type_repack = { 4828/* .iface = */ { 4829/* .get_name = */ ggml_backend_cpu_repack_buffer_type_get_name , 4830/* .alloc_buffer = */ ggml_backend_cpu_repack_buffer_type_alloc_buffer , 4831/* .get_alignment = */ ggml_backend_cpu_repack_buffer_type_get_alignment , 4832/* .get_max_size = */ nullptr ,// defaults to SIZE_MAX 4833/* .get_alloc_size = */ nullptr ,// defaults to ggml_nbytes 4834/* .is_host = */ nullptr , 4835 }, 4836/* .device = */ ggml_backend_reg_dev_get (ggml_backend_cpu_reg (),0 ), 4837/* .context = */ new ggml::cpu::repack::extra_buffer_type (), 4838 }; 4839 4840return & ggml_backend_cpu_buffer_type_repack ; 4841}