| 1456 | //========================- 2-bit (de)-quantization |
| 1457 | |
| 1458 | void quantize_row_q2_K_reference(const float * restrict x, block_q2_K * restrict y, int k) { |
| 1459 | assert(k % QK_K == 0); |
| 1460 | const int nb = k / QK_K; |
| 1461 | |
| 1462 | uint8_t L[QK_K]; |
| 1463 | uint8_t Laux[16]; |
| 1464 | float weights[16]; |
| 1465 | float mins[QK_K/16]; |
| 1466 | float scales[QK_K/16]; |
| 1467 | |
| 1468 | const float q4scale = 15.f; |
| 1469 | |
| 1470 | for (int i = 0; i < nb; i++) { |
| 1471 | float max_scale = 0; // as we are deducting the min, scales are always positive |
| 1472 | float max_min = 0; |
| 1473 | for (int j = 0; j < QK_K/16; ++j) { |
| 1474 | for (int l = 0; l < 16; ++l) weights[l] = fabsf(x[16*j + l]); |
| 1475 | scales[j] = make_qkx2_quants(16, 3, x + 16*j, weights, L + 16*j, &mins[j], Laux, -0.5f, 0.1f, 15, true); |
| 1476 | float scale = scales[j]; |
| 1477 | if (scale > max_scale) { |
| 1478 | max_scale = scale; |
| 1479 | } |
| 1480 | float min = mins[j]; |
| 1481 | if (min > max_min) { |
| 1482 | max_min = min; |
| 1483 | } |
| 1484 | } |
| 1485 | |
| 1486 | if (max_scale > 0) { |
| 1487 | float iscale = q4scale/max_scale; |
| 1488 | for (int j = 0; j < QK_K/16; ++j) { |
| 1489 | int l = nearest_int(iscale*scales[j]); |
| 1490 | y[i].scales[j] = l; |
| 1491 | } |
| 1492 | y[i].d = GGML_FP32_TO_FP16(max_scale/q4scale); |
| 1493 | } else { |
| 1494 | for (int j = 0; j < QK_K/16; ++j) y[i].scales[j] = 0; |
| 1495 | y[i].d = GGML_FP32_TO_FP16(0.f); |
| 1496 | } |
| 1497 | if (max_min > 0) { |
| 1498 | float iscale = q4scale/max_min; |
| 1499 | for (int j = 0; j < QK_K/16; ++j) { |
| 1500 | int l = nearest_int(iscale*mins[j]); |
| 1501 | y[i].scales[j] |= (l << 4); |
| 1502 | } |
| 1503 | y[i].dmin = GGML_FP32_TO_FP16(max_min/q4scale); |
| 1504 | } else { |
| 1505 | y[i].dmin = GGML_FP32_TO_FP16(0.f); |
| 1506 | } |
| 1507 | for (int j = 0; j < QK_K/16; ++j) { |
| 1508 | const float d = GGML_FP16_TO_FP32(y[i].d) * (y[i].scales[j] & 0xF); |
| 1509 | if (!d) continue; |
| 1510 | const float dm = GGML_FP16_TO_FP32(y[i].dmin) * (y[i].scales[j] >> 4); |
| 1511 | for (int ii = 0; ii < 16; ++ii) { |
| 1512 | int l = nearest_int((x[16*j + ii] + dm)/d); |
| 1513 | l = MAX(0, MIN(3, l)); |
| 1514 | L[16*j + ii] = l; |
| 1515 | } |
no test coverage detected