| 3471 | |
| 3472 | int isum = 0; |
| 3473 | int is = 0; |
| 3474 | for (int k = 0; k < QK_K / 128; k++) { |
| 3475 | int shift = 0; |
| 3476 | for (int j = 0; j < 4; j++) { |
| 3477 | int d = sc[is++] & 0x0f; |
| 3478 | int isuml = dot_q2_16(q2, q8, shift); |
| 3479 | isum += d * isuml; |
| 3480 | |
| 3481 | d = sc[is++] & 0x0f; |
| 3482 | isuml = dot_q2_16(q2 + 16, q8 + 16, shift); |
| 3483 | isum += d * isuml; |
| 3484 | |
| 3485 | shift += 2; |
| 3486 | q8 += 32; |
| 3487 | } |
| 3488 | q2 += 32; |
| 3489 | } |
| 3490 | sumf += dall * (float)isum - dmin * (float)summs; |
| 3491 | } |
| 3492 | *s = sumf; |
| 3493 | #endif |
| 3494 | } |
| 3495 | |
| 3496 | static inline float q2_k_value_f32(const block_q2_K *blocks, uint32_t k) { |
| 3497 | const uint32_t block = k / QK_K; |
| 3498 | const uint32_t idx = k - block * QK_K; |
| 3499 | const block_q2_K *xb = blocks + block; |
| 3500 | const uint32_t group = idx / 16u; |
| 3501 | const uint32_t l = idx - group * 16u; |
| 3502 | const uint32_t q_base = 32u * (group / 8u) + 16u * (group & 1u); |
| 3503 | const uint32_t shift = ((group / 2u) & 3u) * 2u; |
| 3504 | const uint32_t q = ((uint32_t)xb->qs[q_base + l] >> shift) & 0x03u; |
| 3505 | const uint32_t sc = xb->scales[group]; |
| 3506 | return f16_to_f32(xb->d) * (float)(sc & 0x0fu) * (float)q - |
| 3507 | f16_to_f32(xb->dmin) * (float)(sc >> 4u); |
| 3508 | } |
| 3509 | |
| 3510 | static float ds4_vec_dot_q2_K_f32(int n, const block_q2_K *x, const float *y) { |
| 3511 | float sum = 0.0f; |
| 3512 | for (int k = 0; k < n; k++) { |
| 3513 | sum += q2_k_value_f32(x, (uint32_t)k) * y[k]; |
| 3514 | } |
| 3515 | return sum; |
| 3516 | } |
| 3517 | |
| 3518 | static inline void q4_k_get_scale_min(int j, const uint8_t *q, uint8_t *sc, uint8_t *m) { |
| 3519 | if (j < 4) { |
| 3520 | *sc = q[j] & 63; |
| 3521 | *m = q[j + 4] & 63; |
| 3522 | } else { |
| 3523 | *sc = (q[j + 4] & 0xF) | ((q[j - 4] >> 6) << 4); |
| 3524 | *m = (q[j + 4] >> 4) | ((q[j - 0] >> 6) << 4); |
| 3525 | } |
| 3526 | } |
no test coverage detected