|
7 | 7 | #include "ggml-cpu-impl.h" |
8 | 8 | #include "ggml-impl.h" |
9 | 9 | #include "quants.h" |
| 10 | +#include "ggml-quants.h" |
10 | 11 | #include "ggml-threading.h" |
11 | 12 | #include "unary-ops.h" |
12 | 13 | #include "binary-ops.h" |
@@ -208,6 +209,23 @@ typedef pthread_t ggml_thread_t; |
208 | 209 | #include <TargetConditionals.h> |
209 | 210 | #endif |
210 | 211 |
|
| 212 | +// Forward declarations — defined below, after utility functions |
| 213 | +static void ggml_vec_dot_turbo3_0_f32(int n, float * GGML_RESTRICT s, size_t bs, |
| 214 | + const void * GGML_RESTRICT vx, size_t bx, |
| 215 | + const void * GGML_RESTRICT vy, size_t by, int nrc); |
| 216 | +static void ggml_vec_dot_turbo2_0_f32(int n, float * GGML_RESTRICT s, size_t bs, |
| 217 | + const void * GGML_RESTRICT vx, size_t bx, |
| 218 | + const void * GGML_RESTRICT vy, size_t by, int nrc); |
| 219 | +static void ggml_vec_dot_turbo4_0_f32(int n, float * GGML_RESTRICT s, size_t bs, |
| 220 | + const void * GGML_RESTRICT vx, size_t bx, |
| 221 | + const void * GGML_RESTRICT vy, size_t by, int nrc); |
| 222 | +static void ggml_vec_dot_tq3_1s_q8_0(int n, float * GGML_RESTRICT s, size_t bs, |
| 223 | + const void * GGML_RESTRICT vx, size_t bx, |
| 224 | + const void * GGML_RESTRICT vy, size_t by, int nrc); |
| 225 | +static void ggml_vec_dot_tq4_1s_q8_0(int n, float * GGML_RESTRICT s, size_t bs, |
| 226 | + const void * GGML_RESTRICT vx, size_t bx, |
| 227 | + const void * GGML_RESTRICT vy, size_t by, int nrc); |
| 228 | + |
211 | 229 | static const struct ggml_type_traits_cpu type_traits_cpu[GGML_TYPE_COUNT] = { |
212 | 230 | [GGML_TYPE_F32] = { |
213 | 231 | .from_float = (ggml_from_float_t) ggml_cpu_fp32_to_fp32, |
@@ -403,6 +421,36 @@ static const struct ggml_type_traits_cpu type_traits_cpu[GGML_TYPE_COUNT] = { |
403 | 421 | [GGML_TYPE_I32] = { |
404 | 422 | .from_float = (ggml_from_float_t) ggml_cpu_fp32_to_i32, |
405 | 423 | }, |
| 424 | + [GGML_TYPE_TURBO3_0] = { |
| 425 | + .from_float = (ggml_from_float_t) quantize_row_turbo3_0_ref, |
| 426 | + .vec_dot = (ggml_vec_dot_t) ggml_vec_dot_turbo3_0_f32, |
| 427 | + .vec_dot_type = GGML_TYPE_F32, |
| 428 | + .nrows = 1, |
| 429 | + }, |
| 430 | + [GGML_TYPE_TURBO2_0] = { |
| 431 | + .from_float = (ggml_from_float_t) quantize_row_turbo2_0_ref, |
| 432 | + .vec_dot = (ggml_vec_dot_t) ggml_vec_dot_turbo2_0_f32, |
| 433 | + .vec_dot_type = GGML_TYPE_F32, |
| 434 | + .nrows = 1, |
| 435 | + }, |
| 436 | + [GGML_TYPE_TURBO4_0] = { |
| 437 | + .from_float = (ggml_from_float_t) quantize_row_turbo4_0_ref, |
| 438 | + .vec_dot = (ggml_vec_dot_t) ggml_vec_dot_turbo4_0_f32, |
| 439 | + .vec_dot_type = GGML_TYPE_F32, |
| 440 | + .nrows = 1, |
| 441 | + }, |
| 442 | + [GGML_TYPE_TQ3_1S] = { |
| 443 | + .from_float = (ggml_from_float_t) quantize_row_tq3_1s_ref, |
| 444 | + .vec_dot = (ggml_vec_dot_t) ggml_vec_dot_tq3_1s_q8_0, |
| 445 | + .vec_dot_type = GGML_TYPE_Q8_0, |
| 446 | + .nrows = 1, |
| 447 | + }, |
| 448 | + [GGML_TYPE_TQ4_1S] = { |
| 449 | + .from_float = (ggml_from_float_t) quantize_row_tq4_1s_ref, |
| 450 | + .vec_dot = (ggml_vec_dot_t) ggml_vec_dot_tq4_1s_q8_0, |
| 451 | + .vec_dot_type = GGML_TYPE_Q8_0, |
| 452 | + .nrows = 1, |
| 453 | + }, |
406 | 454 | }; |
407 | 455 |
|
408 | 456 | const struct ggml_type_traits_cpu * ggml_get_type_traits_cpu(enum ggml_type type) { |
@@ -2047,6 +2095,10 @@ static void ggml_compute_forward(struct ggml_compute_params * params, struct ggm |
2047 | 2095 | { |
2048 | 2096 | ggml_compute_forward_gated_delta_net(params, tensor); |
2049 | 2097 | } break; |
| 2098 | + case GGML_OP_TURBO_WHT: |
| 2099 | + { |
| 2100 | + ggml_compute_forward_turbo_wht(params, tensor); |
| 2101 | + } break; |
2050 | 2102 | case GGML_OP_MAP_CUSTOM1: |
2051 | 2103 | { |
2052 | 2104 | ggml_compute_forward_map_custom1(params, tensor); |
@@ -2227,6 +2279,7 @@ static int ggml_get_n_tasks(struct ggml_tensor * node, int n_threads) { |
2227 | 2279 | case GGML_OP_COUNT_EQUAL: |
2228 | 2280 | case GGML_OP_SOLVE_TRI: |
2229 | 2281 | case GGML_OP_GATED_DELTA_NET: |
| 2282 | + case GGML_OP_TURBO_WHT: |
2230 | 2283 | { |
2231 | 2284 | n_tasks = n_threads; |
2232 | 2285 | } break; |
@@ -2947,6 +3000,10 @@ struct ggml_cplan ggml_graph_plan( |
2947 | 3000 | const int64_t per_thread = S_v + (K > 1 ? S_v * S_v : 0); |
2948 | 3001 | cur = per_thread * sizeof(float) * n_tasks; |
2949 | 3002 | } break; |
| 3003 | + case GGML_OP_TURBO_WHT: |
| 3004 | + { |
| 3005 | + cur = 0; // no extra workspace needed |
| 3006 | + } break; |
2950 | 3007 | case GGML_OP_COUNT: |
2951 | 3008 | { |
2952 | 3009 | GGML_ABORT("fatal error"); |
@@ -3385,6 +3442,112 @@ enum ggml_status ggml_graph_compute_with_ctx(struct ggml_context * ctx, struct g |
3385 | 3442 | return ggml_graph_compute(cgraph, &cplan); |
3386 | 3443 | } |
3387 | 3444 |
|
| 3445 | +// TurboQuant3 vec_dot: dequantize turbo3 block to f32, then dot with f32 operand. |
| 3446 | +// Used by CPU flash attention for models with D not supported by CUDA FA (e.g. D=192). |
| 3447 | +static void ggml_vec_dot_turbo3_0_f32(int n, float * GGML_RESTRICT s, size_t bs, |
| 3448 | + const void * GGML_RESTRICT vx, size_t bx, |
| 3449 | + const void * GGML_RESTRICT vy, size_t by, int nrc) { |
| 3450 | + GGML_ASSERT(nrc == 1); |
| 3451 | + GGML_UNUSED(bs); GGML_UNUSED(bx); GGML_UNUSED(by); GGML_UNUSED(nrc); |
| 3452 | + |
| 3453 | + // Dequantize turbo3 to f32 stack scratch, then dot. |
| 3454 | + float * tmp = (float *)alloca((size_t)n * sizeof(float)); |
| 3455 | + GGML_ASSERT(tmp != NULL); |
| 3456 | + ggml_get_type_traits(GGML_TYPE_TURBO3_0)->to_float(vx, tmp, n); |
| 3457 | + |
| 3458 | + const float * y = (const float *)vy; |
| 3459 | + float sum = 0.0f; |
| 3460 | + for (int i = 0; i < n; i++) { |
| 3461 | + sum += tmp[i] * y[i]; |
| 3462 | + } |
| 3463 | + *s = sum; |
| 3464 | +} |
| 3465 | + |
| 3466 | +// TurboQuant2 vec_dot: dequantize turbo2 block to f32, then dot with f32 operand. |
| 3467 | +static void ggml_vec_dot_turbo2_0_f32(int n, float * GGML_RESTRICT s, size_t bs, |
| 3468 | + const void * GGML_RESTRICT vx, size_t bx, |
| 3469 | + const void * GGML_RESTRICT vy, size_t by, int nrc) { |
| 3470 | + GGML_ASSERT(nrc == 1); |
| 3471 | + GGML_UNUSED(bs); GGML_UNUSED(bx); GGML_UNUSED(by); GGML_UNUSED(nrc); |
| 3472 | + |
| 3473 | + float * tmp = (float *)alloca((size_t)n * sizeof(float)); |
| 3474 | + GGML_ASSERT(tmp != NULL); |
| 3475 | + ggml_get_type_traits(GGML_TYPE_TURBO2_0)->to_float(vx, tmp, n); |
| 3476 | + |
| 3477 | + const float * y = (const float *)vy; |
| 3478 | + float sum = 0.0f; |
| 3479 | + for (int i = 0; i < n; i++) { |
| 3480 | + sum += tmp[i] * y[i]; |
| 3481 | + } |
| 3482 | + *s = sum; |
| 3483 | +} |
| 3484 | + |
| 3485 | +// TurboQuant4 vec_dot: dequantize turbo4 block to f32, then dot with f32 operand. |
| 3486 | +static void ggml_vec_dot_turbo4_0_f32(int n, float * GGML_RESTRICT s, size_t bs, |
| 3487 | + const void * GGML_RESTRICT vx, size_t bx, |
| 3488 | + const void * GGML_RESTRICT vy, size_t by, int nrc) { |
| 3489 | + GGML_ASSERT(nrc == 1); |
| 3490 | + GGML_UNUSED(bs); GGML_UNUSED(bx); GGML_UNUSED(by); GGML_UNUSED(nrc); |
| 3491 | + |
| 3492 | + float * tmp = (float *)alloca((size_t)n * sizeof(float)); |
| 3493 | + GGML_ASSERT(tmp != NULL); |
| 3494 | + ggml_get_type_traits(GGML_TYPE_TURBO4_0)->to_float(vx, tmp, n); |
| 3495 | + |
| 3496 | + const float * y = (const float *)vy; |
| 3497 | + float sum = 0.0f; |
| 3498 | + for (int i = 0; i < n; i++) { |
| 3499 | + sum += tmp[i] * y[i]; |
| 3500 | + } |
| 3501 | + *s = sum; |
| 3502 | +} |
| 3503 | + |
| 3504 | +// TQ3_1S vec_dot: dequantize tq3_1s block to f32, then dot with q8_0. |
| 3505 | +// TODO: optimize with SIMD intrinsics for ARM NEON / AVX2 |
| 3506 | +static void ggml_vec_dot_tq3_1s_q8_0(int n, float * GGML_RESTRICT s, size_t bs, |
| 3507 | + const void * GGML_RESTRICT vx, size_t bx, |
| 3508 | + const void * GGML_RESTRICT vy, size_t by, int nrc) { |
| 3509 | + GGML_ASSERT(nrc == 1); |
| 3510 | + GGML_UNUSED(bs); GGML_UNUSED(bx); GGML_UNUSED(by); GGML_UNUSED(nrc); |
| 3511 | + |
| 3512 | + float * tmp = (float *)alloca((size_t)n * sizeof(float)); |
| 3513 | + GGML_ASSERT(tmp != NULL); |
| 3514 | + ggml_get_type_traits(GGML_TYPE_TQ3_1S)->to_float(vx, tmp, n); |
| 3515 | + |
| 3516 | + // Dequantize q8_0 and dot |
| 3517 | + float * tmp2 = (float *)alloca((size_t)n * sizeof(float)); |
| 3518 | + GGML_ASSERT(tmp2 != NULL); |
| 3519 | + ggml_get_type_traits(GGML_TYPE_Q8_0)->to_float(vy, tmp2, n); |
| 3520 | + |
| 3521 | + float sum = 0.0f; |
| 3522 | + for (int i = 0; i < n; i++) { |
| 3523 | + sum += tmp[i] * tmp2[i]; |
| 3524 | + } |
| 3525 | + *s = sum; |
| 3526 | +} |
| 3527 | + |
| 3528 | +// TQ4_1S vec_dot: dequantize tq4_1s block to f32, then dot with q8_0. |
| 3529 | +// TODO: optimize with SIMD intrinsics |
| 3530 | +static void ggml_vec_dot_tq4_1s_q8_0(int n, float * GGML_RESTRICT s, size_t bs, |
| 3531 | + const void * GGML_RESTRICT vx, size_t bx, |
| 3532 | + const void * GGML_RESTRICT vy, size_t by, int nrc) { |
| 3533 | + GGML_ASSERT(nrc == 1); |
| 3534 | + GGML_UNUSED(bs); GGML_UNUSED(bx); GGML_UNUSED(by); GGML_UNUSED(nrc); |
| 3535 | + |
| 3536 | + float * tmp = (float *)alloca((size_t)n * sizeof(float)); |
| 3537 | + GGML_ASSERT(tmp != NULL); |
| 3538 | + ggml_get_type_traits(GGML_TYPE_TQ4_1S)->to_float(vx, tmp, n); |
| 3539 | + |
| 3540 | + float * tmp2 = (float *)alloca((size_t)n * sizeof(float)); |
| 3541 | + GGML_ASSERT(tmp2 != NULL); |
| 3542 | + ggml_get_type_traits(GGML_TYPE_Q8_0)->to_float(vy, tmp2, n); |
| 3543 | + |
| 3544 | + float sum = 0.0f; |
| 3545 | + for (int i = 0; i < n; i++) { |
| 3546 | + sum += tmp[i] * tmp2[i]; |
| 3547 | + } |
| 3548 | + *s = sum; |
| 3549 | +} |
| 3550 | + |
3388 | 3551 | void ggml_cpu_fp32_to_fp32(const float * x, float * y, int64_t n) { |
3389 | 3552 | memcpy(y, x, n * sizeof(float)); |
3390 | 3553 | } |
|
0 commit comments