← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
swiglu_kernels.c File Reference

SwiGLU activation kernels with SIMD (SSE/AVX/AVX512) More...

#include "bf16_utils.h"
#include "ck_threadpool.h"
#include "ckernel_engine.h"
#include "ckernel_quant.h"
#include <dlfcn.h>
#include <math.h>
#include <pthread.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 

Functions

static void ck_swiglu_dispatch_rows (ck_threadpool_t *pool, int active, int tokens, int dim, ck_range_fn_t fn, void *args, const float *input, float *output)
 
static void ck_swiglu_exact_rows (int begin, int end, void *opaque)
 
const char * ck_swiglu_ggml_provider_name (void)
 
static void ck_swiglu_ggml_rows (int begin, int end, void *opaque)
 
static int ck_swiglu_ranges_overlap (const float *input, const float *output, int tokens, int dim)
 
static float sigmoid_scalar_parity (float x)
 
void swiglu_backward (const float *input, const float *d_output, float *d_input, int tokens, int dim)
 
void swiglu_backward_exact (const float *input, const float *d_output, float *d_input, int tokens, int dim)
 
void swiglu_forward (const float *input, float *output, int tokens, int dim)
 
void swiglu_forward_exact (const float *input, float *output, int tokens, int dim)
 
void swiglu_forward_ggml (const float *input, float *output, int tokens, int dim)
 
void swiglu_forward_ggml_split (const float *gate, const float *up, float *output, int tokens, int dim)
 
void swiglu_forward_pytorch_bf16_storage (const float *input, float *output, int tokens, int dim)
 
void swiglu_forward_q8_k (const float *input, void *output_q8, int tokens, int dim)
 

Detailed Description

SwiGLU activation kernels with SIMD (SSE/AVX/AVX512)

CK-ENGINE KERNEL RULES:

  1. NO malloc/free - memory via bump allocator, pointers passed in
  2. NO OpenMP - parallelization at orchestrator/codegen layer
  3. API must define: inputs, outputs, workspace, and memory layouts
  4. Pure computation - deterministic, no side effects

After changes: make test && make llamacpp-parity-full

SwiGLU: y = silu(gate) * up = (gate * sigmoid(gate)) * up

Definition in file swiglu_kernels.c.

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 18 of file swiglu_kernels.c.

Function Documentation

◆ ck_swiglu_dispatch_rows()

static void ck_swiglu_dispatch_rows ( ck_threadpool_t *  pool,
int  active,
int  tokens,
int  dim,
ck_range_fn_t  fn,
void *  args,
const float *  input,
float *  output 
)
static

Definition at line 581 of file swiglu_kernels.c.

589{
590 const size_t minimum_elements_per_thread = 65536u;
591 const size_t elems = (size_t)tokens * (size_t)dim;
592 if (!pool || active <= 1 || tokens < 2 ||
593 elems < 2u * minimum_elements_per_thread ||
594 ck_threadpool_thread_id(pool) > 0) {
595 fn(0, tokens, args);
596 return;
597 }
598
599 const size_t useful_threads =
600 (elems + minimum_elements_per_thread - 1u) /
601 minimum_elements_per_thread;
602 if ((size_t)active > useful_threads) active = (int)useful_threads;
603 if (active > tokens) active = tokens;
604
605 if (!ck_swiglu_ranges_overlap(input, output, tokens, dim)) {
607 pool, active, 0, tokens, 1, fn, args);
608 return;
609 }
610 if (input != output) {
611 fn(0, tokens, args);
612 return;
613 }
614
615 /*
616 * In-place [T, 2D] -> [T, D] compaction has a binary dependency:
617 * output row t overlaps input row floor(t / 2). Process each parent
618 * wave before its children; rows within a wave remain independent.
619 */
620 fn(0, 1, args);
621 for (int begin = 1; begin < tokens;) {
622 int end = begin > tokens - begin ? tokens : begin * 2;
623 int wave_threads = active;
624 const int wave_rows = end - begin;
625 if (wave_threads > wave_rows) wave_threads = wave_rows;
627 pool, wave_threads, begin, end, 1, fn, args);
628 begin = end;
629 }
630}
void ck_threadpool_parallel_for_n(ck_threadpool_t *pool, int active_threads, int begin, int end, int grain_size, ck_range_fn_t fn, void *args)
int ck_threadpool_thread_id(const ck_threadpool_t *pool)
static int ck_swiglu_ranges_overlap(const float *input, const float *output, int tokens, int dim)
uint32_t end
Definition utf8.c:215

References ck_swiglu_ranges_overlap(), ck_threadpool_parallel_for_n(), ck_threadpool_thread_id(), and end.

Referenced by swiglu_forward_exact(), and swiglu_forward_ggml().

◆ ck_swiglu_exact_rows()

static void ck_swiglu_exact_rows ( int  begin,
int  end,
void *  opaque 
)
static

Definition at line 632 of file swiglu_kernels.c.

633{
634 const ck_swiglu_exact_args_t *args =
635 (const ck_swiglu_exact_args_t *)opaque;
636
637 for (int t = begin; t < end; ++t) {
638 const float *row = args->input +
639 (size_t)t * (size_t)(2 * args->dim);
640 float *out_row = args->output + (size_t)t * (size_t)args->dim;
641
642 for (int d = 0; d < args->dim; ++d) {
643 float a = row[d];
644 float b = row[args->dim + d];
645 float s = sigmoid_scalar_parity(a);
646 float silu = a * s;
647 out_row[d] = silu * b;
648 }
649 }
650}
static float sigmoid_scalar_parity(float x)
static void silu(float *x, int n)

References end, sigmoid_scalar_parity(), and silu().

Referenced by swiglu_forward_exact().

◆ ck_swiglu_ggml_provider_name()

const char * ck_swiglu_ggml_provider_name ( void  )

Definition at line 804 of file swiglu_kernels.c.

805{
806#if defined(__ARM_NEON) && (defined(__aarch64__) || defined(__ARM_FEATURE_FMA))
807 if (ck_swiglu_ggml_ref_forced()) {
808 return "swiglu_ggml_ref";
809 }
810#endif
811#if defined(__AVX512F__) && defined(__AVX512DQ__)
812 return "swiglu_ggml_avx512";
813#elif defined(__AVX2__) && defined(__FMA__)
814 return "swiglu_ggml_avx2";
815#elif defined(__ARM_NEON) && (defined(__aarch64__) || defined(__ARM_FEATURE_FMA))
816 return "swiglu_ggml_neon";
817#else
818 return "swiglu_ggml_ref";
819#endif
820}

◆ ck_swiglu_ggml_rows()

static void ck_swiglu_ggml_rows ( int  begin,
int  end,
void *  opaque 
)
static

Definition at line 674 of file swiglu_kernels.c.

675{
676 const ck_swiglu_ggml_args_t *args =
677 (const ck_swiglu_ggml_args_t *)opaque;
678 const int dim = args->dim;
679#if defined(__ARM_NEON) && (defined(__aarch64__) || defined(__ARM_FEATURE_FMA))
680 const int force_ref = ck_swiglu_ggml_ref_forced();
681#endif
682 for (int t = begin; t < end; ++t) {
683 const float *row = args->input + (size_t)t * (size_t)(2 * dim);
684 float *out_row = args->output + (size_t)t * (size_t)dim;
685 int d = 0;
686
687#if defined(__AVX512F__) && defined(__AVX512DQ__)
688 for (; d + 16 <= dim; d += 16) {
689 const __m512 gate = _mm512_loadu_ps(row + d);
690 const __m512 up = _mm512_loadu_ps(row + dim + d);
691 const __m512 neg_gate = _mm512_sub_ps(_mm512_setzero_ps(), gate);
692 const __m512 denom = _mm512_add_ps(
693 _mm512_set1_ps(1.0f), ck_ggml_expf_avx512(neg_gate));
694 const __m512 silu = _mm512_div_ps(gate, denom);
695 _mm512_storeu_ps(out_row + d, _mm512_mul_ps(silu, up));
696 }
697#elif defined(__AVX2__) && defined(__FMA__)
698 for (; d + 8 <= dim; d += 8) {
699 const __m256 gate = _mm256_loadu_ps(row + d);
700 const __m256 up = _mm256_loadu_ps(row + dim + d);
701 const __m256 neg_gate = _mm256_sub_ps(_mm256_setzero_ps(), gate);
702 const __m256 denom = _mm256_add_ps(
703 _mm256_set1_ps(1.0f), ck_ggml_expf_avx2(neg_gate));
704 const __m256 silu = _mm256_div_ps(gate, denom);
705 _mm256_storeu_ps(out_row + d, _mm256_mul_ps(silu, up));
706 }
707#elif defined(__ARM_NEON) && (defined(__aarch64__) || defined(__ARM_FEATURE_FMA))
708 if (!force_ref) {
709 for (; d + 4 <= dim; d += 4) {
710 const float32x4_t gate = vld1q_f32(row + d);
711 const float32x4_t up = vld1q_f32(row + dim + d);
712 const float32x4_t neg_gate = vsubq_f32(vdupq_n_f32(0.0f), gate);
713 const float32x4_t denom = vaddq_f32(
714 vdupq_n_f32(1.0f), ck_ggml_expf_neon(neg_gate));
715 const float32x4_t silu = vdivq_f32(gate, denom);
716 vst1q_f32(out_row + d, vmulq_f32(silu, up));
717 }
718 }
719#endif
720 for (; d < dim; ++d) {
721 const float gate = row[d];
722 out_row[d] = (gate / (1.0f + expf(-gate))) * row[dim + d];
723 }
724 }
725}

References end, and silu().

Referenced by swiglu_forward_ggml().

◆ ck_swiglu_ranges_overlap()

static int ck_swiglu_ranges_overlap ( const float *  input,
const float *  output,
int  tokens,
int  dim 
)
static

Definition at line 567 of file swiglu_kernels.c.

571{
572 const uintptr_t input_begin = (uintptr_t)input;
573 const uintptr_t input_end = input_begin +
574 (size_t)tokens * (size_t)(2 * dim) * sizeof(float);
575 const uintptr_t output_begin = (uintptr_t)output;
576 const uintptr_t output_end = output_begin +
577 (size_t)tokens * (size_t)dim * sizeof(float);
578 return input_begin < output_end && output_begin < input_end;
579}

Referenced by ck_swiglu_dispatch_rows().

◆ sigmoid_scalar_parity()

static float sigmoid_scalar_parity ( float  x)
inlinestatic

Definition at line 44 of file swiglu_kernels.c.

45{
46 return 1.0f / (1.0f + expf(-x));
47}

Referenced by ck_swiglu_exact_rows(), swiglu_backward_exact(), and swiglu_forward_q8_k().

◆ swiglu_backward()

void swiglu_backward ( const float *  input,
const float *  d_output,
float *  d_input,
int  tokens,
int  dim 
)

SwiGLU backward pass

Test:

test_swiglu.py::TestSwiGLUBackward::test_backward_tokens

test_swiglu.py::TestSwiGLUBackward::test_backward_single

test_parity.py::test_swiglu_backward_parity

Computes dGate and dUp given dY. dGate = dy * b * silu'(a), dUp = dy * silu(a)

After changes: make test && make llamacpp-parity-full

Definition at line 432 of file swiglu_kernels.c.

437{
439 swiglu_backward_exact(input, d_output, d_input, tokens, dim);
440 return;
441 }
442
443 int T = tokens;
444 int D = dim;
445
446 for (int t = 0; t < T; ++t) {
447 const float *row = input + (size_t)t * (2 * D);
448 const float *dy_row = d_output + (size_t)t * D;
449 float *dx_row = d_input + (size_t)t * (2 * D);
450 int d = 0;
451
452#if defined(__AVX512F__)
453 // AVX-512: Process 16 floats at a time
454 __m512 one = _mm512_set1_ps(1.0f);
455 for (; d + 16 <= D; d += 16) {
456 __m512 a = _mm512_loadu_ps(&row[d]); // gate
457 __m512 b = _mm512_loadu_ps(&row[D + d]); // value
458 __m512 dy = _mm512_loadu_ps(&dy_row[d]);
459
460 __m512 s = sigmoid512_fast(a); // sigmoid(a)
461 __m512 silu = _mm512_mul_ps(a, s); // silu(a) = a * s
462 __m512 one_minus_s = _mm512_sub_ps(one, s);
463 __m512 inner = _mm512_fmadd_ps(a, one_minus_s, one); // 1 + a * (1 - s)
464 __m512 silu_prime = _mm512_mul_ps(s, inner); // s * (1 + a * (1 - s))
465
466 // dA = dy * b * silu_prime
467 __m512 dA = _mm512_mul_ps(dy, _mm512_mul_ps(b, silu_prime));
468 // dB = dy * silu
469 __m512 dB = _mm512_mul_ps(dy, silu);
470
471 _mm512_storeu_ps(&dx_row[d], dA);
472 _mm512_storeu_ps(&dx_row[D + d], dB);
473 }
474#elif defined(__AVX2__)
475 // AVX2: Process 8 floats at a time
476 __m256 one = _mm256_set1_ps(1.0f);
477 for (; d + 8 <= D; d += 8) {
478 __m256 a = _mm256_loadu_ps(&row[d]); // gate
479 __m256 b = _mm256_loadu_ps(&row[D + d]); // value
480 __m256 dy = _mm256_loadu_ps(&dy_row[d]);
481
482 __m256 s = sigmoid256_fast(a); // sigmoid(a)
483 __m256 silu = _mm256_mul_ps(a, s); // silu(a) = a * s
484 __m256 one_minus_s = _mm256_sub_ps(one, s);
485 __m256 inner = _mm256_fmadd_ps(a, one_minus_s, one); // 1 + a * (1 - s)
486 __m256 silu_prime = _mm256_mul_ps(s, inner); // s * (1 + a * (1 - s))
487
488 // dA = dy * b * silu_prime
489 __m256 dA = _mm256_mul_ps(dy, _mm256_mul_ps(b, silu_prime));
490 // dB = dy * silu
491 __m256 dB = _mm256_mul_ps(dy, silu);
492
493 _mm256_storeu_ps(&dx_row[d], dA);
494 _mm256_storeu_ps(&dx_row[D + d], dB);
495 }
496#elif defined(__AVX__)
497 // AVX1: Vectorize arithmetic, use scalar sigmoid
498 __m256 one = _mm256_set1_ps(1.0f);
499 float a_arr[8] __attribute__((aligned(32)));
500 float s_arr[8] __attribute__((aligned(32)));
501
502 for (; d + 8 <= D; d += 8) {
503 __m256 a = _mm256_loadu_ps(&row[d]); // gate
504 __m256 b = _mm256_loadu_ps(&row[D + d]); // value
505 __m256 dy = _mm256_loadu_ps(&dy_row[d]);
506
507 // Compute sigmoid scalarly
508 _mm256_store_ps(a_arr, a);
509 for (int j = 0; j < 8; ++j) {
510 s_arr[j] = sigmoid_scalar(a_arr[j]);
511 }
512 __m256 s = _mm256_load_ps(s_arr);
513
514 __m256 silu = _mm256_mul_ps(a, s); // silu(a) = a * s
515 __m256 one_minus_s = _mm256_sub_ps(one, s);
516 __m256 a_one_minus_s = _mm256_mul_ps(a, one_minus_s);
517 __m256 inner = _mm256_add_ps(one, a_one_minus_s); // 1 + a * (1 - s)
518 __m256 silu_prime = _mm256_mul_ps(s, inner); // s * (1 + a * (1 - s))
519
520 // dA = dy * b * silu_prime
521 __m256 dA = _mm256_mul_ps(dy, _mm256_mul_ps(b, silu_prime));
522 // dB = dy * silu
523 __m256 dB = _mm256_mul_ps(dy, silu);
524
525 _mm256_storeu_ps(&dx_row[d], dA);
526 _mm256_storeu_ps(&dx_row[D + d], dB);
527 }
528#endif
529
530 // Scalar fallback for remaining elements
531 for (; d < D; ++d) {
532 float a = row[d]; // gate
533 float b = row[D + d]; // value
534 float dy = dy_row[d];
535
536 float s = sigmoid_scalar(a); // sigmoid(a)
537 float silu = a * s; // silu(a)
538 float silu_prime = s * (1.0f + a * (1.0f - s)); // silu'(a), PyTorch form
539
540 float dA = dy * b * silu_prime;
541 float dB = dy * silu;
542
543 dx_row[d] = dA;
544 dx_row[D + d] = dB;
545 }
546 }
547}
float sigmoid_scalar(float x)
int ck_strict_parity_enabled(void)
void swiglu_backward_exact(const float *input, const float *d_output, float *d_input, int tokens, int dim)
__attribute__((visibility("default"))) CKTokenizer *ck_tokenizer_create(CKTokenizerType type)

References __attribute__(), ck_strict_parity_enabled(), sigmoid_scalar(), silu(), and swiglu_backward_exact().

Referenced by ck_layer_backward_rmsnorm_swiglu().

◆ swiglu_backward_exact()

void swiglu_backward_exact ( const float *  input,
const float *  d_output,
float *  d_input,
int  tokens,
int  dim 
)

SwiGLU backward pass (exact version using stdlib sigmoid)

Test:

test_swiglu.py::TestSwiGLUBackward::test_exact_vs_fast

test_swiglu.py::TestSwiGLUBackward::test_exact_single

Uses standard library expf for numerical accuracy reference.

After changes: make test

Definition at line 922 of file swiglu_kernels.c.

927{
928 int T = tokens;
929 int D = dim;
930
931 for (int t = 0; t < T; ++t) {
932 const float *row = input + (size_t)t * (2 * D);
933 const float *dy_row = d_output + (size_t)t * D;
934 float *dx_row = d_input + (size_t)t * (2 * D);
935
936 for (int d = 0; d < D; ++d) {
937 float a = row[d]; // gate
938 float b = row[D + d]; // value
939 float dy = dy_row[d];
940
941 float s = sigmoid_scalar_parity(a); // sigmoid(a)
942 float silu = a * s; // silu(a)
943 float silu_prime = s * (1.0f + a * (1.0f - s)); // silu'(a), PyTorch form
944
945 float dA = dy * b * silu_prime;
946 float dB = dy * silu;
947
948 dx_row[d] = dA;
949 dx_row[D + d] = dB;
950 }
951 }
952}

References sigmoid_scalar_parity(), and silu().

Referenced by swiglu_backward().

◆ swiglu_forward()

void swiglu_forward ( const float *  input,
float *  output,
int  tokens,
int  dim 
)

SwiGLU forward pass

Test:

test_swiglu.py::TestSwiGLUForward::test_forward_tokens

test_swiglu.py::TestSwiGLUForward::test_forward_single

test_mlp.py::TestMLPForward::test_swiglu_mlp

test_fused_swiglu_decode.py::TestFusedSwiGLUDecode::test_fused_swiglu_decode

test_parity.py::test_swiglu_parity

SwiGLU: y = silu(gate) * up where silu(x) = x * sigmoid(x)

After changes: make test && make llamacpp-parity-full

Definition at line 283 of file swiglu_kernels.c.

287{
288 const char *fast_env = getenv("CK_SWIGLU_FAST");
289 const char *exact_env = getenv("CK_SWIGLU_EXACT");
291 !(fast_env && atoi(fast_env) != 0) ||
292 (exact_env && atoi(exact_env) != 0)) {
293 swiglu_forward_exact(input, output, tokens, dim);
294 return;
295 }
296
297 int T = tokens;
298 int D = dim;
299
300 for (int t = 0; t < T; ++t) {
301 const float *row = input + (size_t)t * (2 * D);
302 float *out_row = output + (size_t)t * D;
303 int d = 0;
304
305#if defined(__AVX512F__)
306 // AVX-512: Process 16 floats at a time
307 for (; d + 16 <= D; d += 16) {
308 __m512 a = _mm512_loadu_ps(&row[d]); // gate
309 __m512 b = _mm512_loadu_ps(&row[D + d]); // value
310
311 __m512 s = sigmoid512_fast(a); // sigmoid(a)
312 __m512 silu = _mm512_mul_ps(a, s); // silu(a) = a * sigmoid(a)
313 __m512 y = _mm512_mul_ps(silu, b); // y = silu(a) * b
314
315 _mm512_storeu_ps(&out_row[d], y);
316 }
317#elif defined(__AVX2__)
318 // AVX2: Process 8 floats at a time
319 for (; d + 8 <= D; d += 8) {
320 __m256 a = _mm256_loadu_ps(&row[d]); // gate
321 __m256 b = _mm256_loadu_ps(&row[D + d]); // value
322
323 __m256 s = sigmoid256_fast(a); // sigmoid(a)
324 __m256 silu = _mm256_mul_ps(a, s); // silu(a) = a * sigmoid(a)
325 __m256 y = _mm256_mul_ps(silu, b); // y = silu(a) * b
326
327 _mm256_storeu_ps(&out_row[d], y);
328 }
329#elif defined(__AVX__)
330 // AVX1: Vectorize arithmetic, use scalar sigmoid
331 float a_arr[8] __attribute__((aligned(32)));
332 float s_arr[8] __attribute__((aligned(32)));
333
334 for (; d + 8 <= D; d += 8) {
335 __m256 a = _mm256_loadu_ps(&row[d]); // gate
336 __m256 b = _mm256_loadu_ps(&row[D + d]); // value
337
338 // Compute sigmoid scalarly
339 _mm256_store_ps(a_arr, a);
340 for (int j = 0; j < 8; ++j) {
341 s_arr[j] = sigmoid_scalar(a_arr[j]);
342 }
343 __m256 s = _mm256_load_ps(s_arr);
344
345 __m256 silu = _mm256_mul_ps(a, s); // silu(a) = a * sigmoid(a)
346 __m256 y = _mm256_mul_ps(silu, b); // y = silu(a) * b
347
348 _mm256_storeu_ps(&out_row[d], y);
349 }
350#endif
351
352 // Scalar fallback for remaining elements
353 for (; d < D; ++d) {
354 float a = row[d]; // gate
355 float b = row[D + d]; // value
356
357 float s = sigmoid_scalar(a); // sigmoid(a)
358 float silu = a * s; // silu(a) = a * sigmoid(a)
359
360 out_row[d] = silu * b;
361 }
362 }
363}
void swiglu_forward_exact(const float *input, float *output, int tokens, int dim)

References __attribute__(), ck_strict_parity_enabled(), sigmoid_scalar(), silu(), and swiglu_forward_exact().

Referenced by ck_mlp_swiglu_forward(), ck_mlp_swiglu_forward_q4_k(), ck_mlp_swiglu_forward_q4_k_q8_k(), ck_mlp_swiglu_forward_q4_k_q8_k_prefill(), ck_mlp_swiglu_forward_quant(), ck_mlp_swiglu_forward_ref(), ck_test_swiglu(), model_layer_0_decode(), model_layer_0_decode(), model_layer_0_decode(), model_layer_0_decode(), model_layer_0_prefill(), model_layer_0_prefill(), model_layer_0_prefill(), model_layer_0_prefill(), model_layer_10_decode(), model_layer_10_decode(), model_layer_10_decode(), model_layer_10_decode(), model_layer_10_prefill(), model_layer_10_prefill(), model_layer_10_prefill(), model_layer_10_prefill(), model_layer_11_decode(), model_layer_11_decode(), model_layer_11_decode(), model_layer_11_decode(), model_layer_11_prefill(), model_layer_11_prefill(), model_layer_11_prefill(), model_layer_11_prefill(), model_layer_12_decode(), model_layer_12_decode(), model_layer_12_decode(), model_layer_12_decode(), model_layer_12_prefill(), model_layer_12_prefill(), model_layer_12_prefill(), model_layer_12_prefill(), model_layer_13_decode(), model_layer_13_decode(), model_layer_13_decode(), model_layer_13_decode(), model_layer_13_prefill(), model_layer_13_prefill(), model_layer_13_prefill(), model_layer_13_prefill(), model_layer_14_decode(), model_layer_14_decode(), model_layer_14_decode(), model_layer_14_decode(), model_layer_14_prefill(), model_layer_14_prefill(), model_layer_14_prefill(), model_layer_14_prefill(), model_layer_15_decode(), model_layer_15_decode(), model_layer_15_decode(), model_layer_15_decode(), model_layer_15_prefill(), model_layer_15_prefill(), model_layer_15_prefill(), model_layer_15_prefill(), model_layer_16_decode(), model_layer_16_decode(), model_layer_16_decode(), model_layer_16_decode(), model_layer_16_prefill(), model_layer_16_prefill(), model_layer_16_prefill(), model_layer_16_prefill(), model_layer_17_decode(), model_layer_17_decode(), model_layer_17_decode(), model_layer_17_decode(), model_layer_17_prefill(), model_layer_17_prefill(), model_layer_17_prefill(), model_layer_17_prefill(), model_layer_18_decode(), model_layer_18_decode(), model_layer_18_decode(), model_layer_18_decode(), model_layer_18_prefill(), model_layer_18_prefill(), model_layer_18_prefill(), model_layer_18_prefill(), model_layer_19_decode(), model_layer_19_decode(), model_layer_19_decode(), model_layer_19_decode(), model_layer_19_prefill(), model_layer_19_prefill(), model_layer_19_prefill(), model_layer_19_prefill(), model_layer_1_decode(), model_layer_1_decode(), model_layer_1_decode(), model_layer_1_decode(), model_layer_1_prefill(), model_layer_1_prefill(), model_layer_1_prefill(), model_layer_1_prefill(), model_layer_20_decode(), model_layer_20_decode(), model_layer_20_decode(), model_layer_20_decode(), model_layer_20_prefill(), model_layer_20_prefill(), model_layer_20_prefill(), model_layer_20_prefill(), model_layer_21_decode(), model_layer_21_decode(), model_layer_21_decode(), model_layer_21_decode(), model_layer_21_prefill(), model_layer_21_prefill(), model_layer_21_prefill(), model_layer_21_prefill(), model_layer_22_decode(), model_layer_22_decode(), model_layer_22_decode(), model_layer_22_decode(), model_layer_22_prefill(), model_layer_22_prefill(), model_layer_22_prefill(), model_layer_22_prefill(), model_layer_23_decode(), model_layer_23_decode(), model_layer_23_decode(), model_layer_23_decode(), model_layer_23_prefill(), model_layer_23_prefill(), model_layer_23_prefill(), model_layer_23_prefill(), model_layer_2_decode(), model_layer_2_decode(), model_layer_2_decode(), model_layer_2_decode(), model_layer_2_prefill(), model_layer_2_prefill(), model_layer_2_prefill(), model_layer_2_prefill(), model_layer_3_decode(), model_layer_3_decode(), model_layer_3_decode(), model_layer_3_decode(), model_layer_3_prefill(), model_layer_3_prefill(), model_layer_3_prefill(), model_layer_3_prefill(), model_layer_4_decode(), model_layer_4_decode(), model_layer_4_decode(), model_layer_4_decode(), model_layer_4_prefill(), model_layer_4_prefill(), model_layer_4_prefill(), model_layer_4_prefill(), model_layer_5_decode(), model_layer_5_decode(), model_layer_5_decode(), model_layer_5_decode(), model_layer_5_prefill(), model_layer_5_prefill(), model_layer_5_prefill(), model_layer_5_prefill(), model_layer_6_decode(), model_layer_6_decode(), model_layer_6_decode(), model_layer_6_decode(), model_layer_6_prefill(), model_layer_6_prefill(), model_layer_6_prefill(), model_layer_6_prefill(), model_layer_7_decode(), model_layer_7_decode(), model_layer_7_decode(), model_layer_7_decode(), model_layer_7_prefill(), model_layer_7_prefill(), model_layer_7_prefill(), model_layer_7_prefill(), model_layer_8_decode(), model_layer_8_decode(), model_layer_8_decode(), model_layer_8_decode(), model_layer_8_prefill(), model_layer_8_prefill(), model_layer_8_prefill(), model_layer_8_prefill(), model_layer_9_decode(), model_layer_9_decode(), model_layer_9_decode(), model_layer_9_decode(), model_layer_9_prefill(), model_layer_9_prefill(), model_layer_9_prefill(), model_layer_9_prefill(), qwen2_0_5b_decode_layer_0_decode(), qwen2_0_5b_decode_layer_0_decode(), qwen2_0_5b_decode_layer_0_decode(), qwen2_0_5b_decode_layer_0_decode(), qwen2_0_5b_decode_layer_0_decode(), qwen2_0_5b_decode_layer_0_prefill(), qwen2_0_5b_decode_layer_0_prefill(), qwen2_0_5b_decode_layer_0_prefill(), qwen2_0_5b_decode_layer_0_prefill(), qwen2_0_5b_decode_layer_10_decode(), qwen2_0_5b_decode_layer_10_decode(), qwen2_0_5b_decode_layer_10_decode(), qwen2_0_5b_decode_layer_10_decode(), qwen2_0_5b_decode_layer_10_decode(), qwen2_0_5b_decode_layer_10_prefill(), qwen2_0_5b_decode_layer_10_prefill(), qwen2_0_5b_decode_layer_10_prefill(), qwen2_0_5b_decode_layer_10_prefill(), qwen2_0_5b_decode_layer_11_decode(), qwen2_0_5b_decode_layer_11_decode(), qwen2_0_5b_decode_layer_11_decode(), qwen2_0_5b_decode_layer_11_decode(), qwen2_0_5b_decode_layer_11_decode(), qwen2_0_5b_decode_layer_11_prefill(), qwen2_0_5b_decode_layer_11_prefill(), qwen2_0_5b_decode_layer_11_prefill(), qwen2_0_5b_decode_layer_11_prefill(), qwen2_0_5b_decode_layer_12_decode(), qwen2_0_5b_decode_layer_12_decode(), qwen2_0_5b_decode_layer_12_decode(), qwen2_0_5b_decode_layer_12_decode(), qwen2_0_5b_decode_layer_12_decode(), qwen2_0_5b_decode_layer_12_prefill(), qwen2_0_5b_decode_layer_12_prefill(), qwen2_0_5b_decode_layer_12_prefill(), qwen2_0_5b_decode_layer_12_prefill(), qwen2_0_5b_decode_layer_13_decode(), qwen2_0_5b_decode_layer_13_decode(), qwen2_0_5b_decode_layer_13_decode(), qwen2_0_5b_decode_layer_13_decode(), qwen2_0_5b_decode_layer_13_decode(), qwen2_0_5b_decode_layer_13_prefill(), qwen2_0_5b_decode_layer_13_prefill(), qwen2_0_5b_decode_layer_13_prefill(), qwen2_0_5b_decode_layer_13_prefill(), qwen2_0_5b_decode_layer_14_decode(), qwen2_0_5b_decode_layer_14_decode(), qwen2_0_5b_decode_layer_14_decode(), qwen2_0_5b_decode_layer_14_decode(), qwen2_0_5b_decode_layer_14_decode(), qwen2_0_5b_decode_layer_14_prefill(), qwen2_0_5b_decode_layer_14_prefill(), qwen2_0_5b_decode_layer_14_prefill(), qwen2_0_5b_decode_layer_14_prefill(), qwen2_0_5b_decode_layer_15_decode(), qwen2_0_5b_decode_layer_15_decode(), qwen2_0_5b_decode_layer_15_decode(), qwen2_0_5b_decode_layer_15_decode(), qwen2_0_5b_decode_layer_15_decode(), qwen2_0_5b_decode_layer_15_prefill(), qwen2_0_5b_decode_layer_15_prefill(), qwen2_0_5b_decode_layer_15_prefill(), qwen2_0_5b_decode_layer_15_prefill(), qwen2_0_5b_decode_layer_16_decode(), qwen2_0_5b_decode_layer_16_decode(), qwen2_0_5b_decode_layer_16_decode(), qwen2_0_5b_decode_layer_16_decode(), qwen2_0_5b_decode_layer_16_decode(), qwen2_0_5b_decode_layer_16_prefill(), qwen2_0_5b_decode_layer_16_prefill(), qwen2_0_5b_decode_layer_16_prefill(), qwen2_0_5b_decode_layer_16_prefill(), qwen2_0_5b_decode_layer_17_decode(), qwen2_0_5b_decode_layer_17_decode(), qwen2_0_5b_decode_layer_17_decode(), qwen2_0_5b_decode_layer_17_decode(), qwen2_0_5b_decode_layer_17_decode(), qwen2_0_5b_decode_layer_17_prefill(), qwen2_0_5b_decode_layer_17_prefill(), qwen2_0_5b_decode_layer_17_prefill(), qwen2_0_5b_decode_layer_17_prefill(), qwen2_0_5b_decode_layer_18_decode(), qwen2_0_5b_decode_layer_18_decode(), qwen2_0_5b_decode_layer_18_decode(), qwen2_0_5b_decode_layer_18_decode(), qwen2_0_5b_decode_layer_18_decode(), qwen2_0_5b_decode_layer_18_prefill(), qwen2_0_5b_decode_layer_18_prefill(), qwen2_0_5b_decode_layer_18_prefill(), qwen2_0_5b_decode_layer_18_prefill(), qwen2_0_5b_decode_layer_19_decode(), qwen2_0_5b_decode_layer_19_decode(), qwen2_0_5b_decode_layer_19_decode(), qwen2_0_5b_decode_layer_19_decode(), qwen2_0_5b_decode_layer_19_decode(), qwen2_0_5b_decode_layer_19_prefill(), qwen2_0_5b_decode_layer_19_prefill(), qwen2_0_5b_decode_layer_19_prefill(), qwen2_0_5b_decode_layer_19_prefill(), qwen2_0_5b_decode_layer_1_decode(), qwen2_0_5b_decode_layer_1_decode(), qwen2_0_5b_decode_layer_1_decode(), qwen2_0_5b_decode_layer_1_decode(), qwen2_0_5b_decode_layer_1_decode(), qwen2_0_5b_decode_layer_1_prefill(), qwen2_0_5b_decode_layer_1_prefill(), qwen2_0_5b_decode_layer_1_prefill(), qwen2_0_5b_decode_layer_1_prefill(), qwen2_0_5b_decode_layer_20_decode(), qwen2_0_5b_decode_layer_20_decode(), qwen2_0_5b_decode_layer_20_decode(), qwen2_0_5b_decode_layer_20_decode(), qwen2_0_5b_decode_layer_20_decode(), qwen2_0_5b_decode_layer_20_prefill(), qwen2_0_5b_decode_layer_20_prefill(), qwen2_0_5b_decode_layer_20_prefill(), qwen2_0_5b_decode_layer_20_prefill(), qwen2_0_5b_decode_layer_21_decode(), qwen2_0_5b_decode_layer_21_decode(), qwen2_0_5b_decode_layer_21_decode(), qwen2_0_5b_decode_layer_21_decode(), qwen2_0_5b_decode_layer_21_decode(), qwen2_0_5b_decode_layer_21_prefill(), qwen2_0_5b_decode_layer_21_prefill(), qwen2_0_5b_decode_layer_21_prefill(), qwen2_0_5b_decode_layer_21_prefill(), qwen2_0_5b_decode_layer_22_decode(), qwen2_0_5b_decode_layer_22_decode(), qwen2_0_5b_decode_layer_22_decode(), qwen2_0_5b_decode_layer_22_decode(), qwen2_0_5b_decode_layer_22_decode(), qwen2_0_5b_decode_layer_22_prefill(), qwen2_0_5b_decode_layer_22_prefill(), qwen2_0_5b_decode_layer_22_prefill(), qwen2_0_5b_decode_layer_22_prefill(), qwen2_0_5b_decode_layer_23_decode(), qwen2_0_5b_decode_layer_23_decode(), qwen2_0_5b_decode_layer_23_decode(), qwen2_0_5b_decode_layer_23_decode(), qwen2_0_5b_decode_layer_23_decode(), qwen2_0_5b_decode_layer_23_prefill(), qwen2_0_5b_decode_layer_23_prefill(), qwen2_0_5b_decode_layer_23_prefill(), qwen2_0_5b_decode_layer_23_prefill(), qwen2_0_5b_decode_layer_2_decode(), qwen2_0_5b_decode_layer_2_decode(), qwen2_0_5b_decode_layer_2_decode(), qwen2_0_5b_decode_layer_2_decode(), qwen2_0_5b_decode_layer_2_decode(), qwen2_0_5b_decode_layer_2_prefill(), qwen2_0_5b_decode_layer_2_prefill(), qwen2_0_5b_decode_layer_2_prefill(), qwen2_0_5b_decode_layer_2_prefill(), qwen2_0_5b_decode_layer_3_decode(), qwen2_0_5b_decode_layer_3_decode(), qwen2_0_5b_decode_layer_3_decode(), qwen2_0_5b_decode_layer_3_decode(), qwen2_0_5b_decode_layer_3_decode(), qwen2_0_5b_decode_layer_3_prefill(), qwen2_0_5b_decode_layer_3_prefill(), qwen2_0_5b_decode_layer_3_prefill(), qwen2_0_5b_decode_layer_3_prefill(), qwen2_0_5b_decode_layer_4_decode(), qwen2_0_5b_decode_layer_4_decode(), qwen2_0_5b_decode_layer_4_decode(), qwen2_0_5b_decode_layer_4_decode(), qwen2_0_5b_decode_layer_4_decode(), qwen2_0_5b_decode_layer_4_prefill(), qwen2_0_5b_decode_layer_4_prefill(), qwen2_0_5b_decode_layer_4_prefill(), qwen2_0_5b_decode_layer_4_prefill(), qwen2_0_5b_decode_layer_5_decode(), qwen2_0_5b_decode_layer_5_decode(), qwen2_0_5b_decode_layer_5_decode(), qwen2_0_5b_decode_layer_5_decode(), qwen2_0_5b_decode_layer_5_decode(), qwen2_0_5b_decode_layer_5_prefill(), qwen2_0_5b_decode_layer_5_prefill(), qwen2_0_5b_decode_layer_5_prefill(), qwen2_0_5b_decode_layer_5_prefill(), qwen2_0_5b_decode_layer_6_decode(), qwen2_0_5b_decode_layer_6_decode(), qwen2_0_5b_decode_layer_6_decode(), qwen2_0_5b_decode_layer_6_decode(), qwen2_0_5b_decode_layer_6_decode(), qwen2_0_5b_decode_layer_6_prefill(), qwen2_0_5b_decode_layer_6_prefill(), qwen2_0_5b_decode_layer_6_prefill(), qwen2_0_5b_decode_layer_6_prefill(), qwen2_0_5b_decode_layer_7_decode(), qwen2_0_5b_decode_layer_7_decode(), qwen2_0_5b_decode_layer_7_decode(), qwen2_0_5b_decode_layer_7_decode(), qwen2_0_5b_decode_layer_7_decode(), qwen2_0_5b_decode_layer_7_prefill(), qwen2_0_5b_decode_layer_7_prefill(), qwen2_0_5b_decode_layer_7_prefill(), qwen2_0_5b_decode_layer_7_prefill(), qwen2_0_5b_decode_layer_8_decode(), qwen2_0_5b_decode_layer_8_decode(), qwen2_0_5b_decode_layer_8_decode(), qwen2_0_5b_decode_layer_8_decode(), qwen2_0_5b_decode_layer_8_decode(), qwen2_0_5b_decode_layer_8_prefill(), qwen2_0_5b_decode_layer_8_prefill(), qwen2_0_5b_decode_layer_8_prefill(), qwen2_0_5b_decode_layer_8_prefill(), qwen2_0_5b_decode_layer_9_decode(), qwen2_0_5b_decode_layer_9_decode(), qwen2_0_5b_decode_layer_9_decode(), qwen2_0_5b_decode_layer_9_decode(), qwen2_0_5b_decode_layer_9_decode(), qwen2_0_5b_decode_layer_9_prefill(), qwen2_0_5b_decode_layer_9_prefill(), qwen2_0_5b_decode_layer_9_prefill(), and qwen2_0_5b_decode_layer_9_prefill().

◆ swiglu_forward_exact()

void swiglu_forward_exact ( const float *  input,
float *  output,
int  tokens,
int  dim 
)

Definition at line 652 of file swiglu_kernels.c.

656{
657 if (!input || !output || tokens <= 0 || dim <= 0) {
658 return;
659 }
660
661 ck_swiglu_exact_args_t args = {input, output, dim};
662 ck_threadpool_t *pool = ck_threadpool_global();
663 int active = pool ? ck_threadpool_n_threads(pool) : 1;
664 ck_swiglu_dispatch_rows(pool, active, tokens, dim,
665 ck_swiglu_exact_rows, &args, input, output);
666}
ck_threadpool_t * ck_threadpool_global(void)
int ck_threadpool_n_threads(const ck_threadpool_t *pool)
static void ck_swiglu_dispatch_rows(ck_threadpool_t *pool, int active, int tokens, int dim, ck_range_fn_t fn, void *args, const float *input, float *output)
static void ck_swiglu_exact_rows(int begin, int end, void *opaque)

References ck_swiglu_dispatch_rows(), ck_swiglu_exact_rows(), ck_threadpool_global(), and ck_threadpool_n_threads().

Referenced by ck_mlp_swiglu_forward(), ck_mlp_swiglu_forward_ref(), and swiglu_forward().

◆ swiglu_forward_ggml()

void swiglu_forward_ggml ( const float *  input,
float *  output,
int  tokens,
int  dim 
)

◆ swiglu_forward_ggml_split()

void swiglu_forward_ggml_split ( const float *  gate,
const float *  up,
float *  output,
int  tokens,
int  dim 
)

Definition at line 743 of file swiglu_kernels.c.

748{
749 if (!gate || !up || !output || tokens <= 0 || dim <= 0) {
750 return;
751 }
752#if defined(__ARM_NEON) && (defined(__aarch64__) || defined(__ARM_FEATURE_FMA))
753 const int force_ref = ck_swiglu_ggml_ref_forced();
754#endif
755 for (int t = 0; t < tokens; ++t) {
756 const float *gate_row = gate + (size_t)t * (size_t)dim;
757 const float *up_row = up + (size_t)t * (size_t)dim;
758 float *out_row = output + (size_t)t * (size_t)dim;
759 int d = 0;
760
761#if defined(__AVX512F__) && defined(__AVX512DQ__)
762 for (; d + 16 <= dim; d += 16) {
763 const __m512 gate_v = _mm512_loadu_ps(gate_row + d);
764 const __m512 up_v = _mm512_loadu_ps(up_row + d);
765 const __m512 neg_gate = _mm512_sub_ps(_mm512_setzero_ps(), gate_v);
766 const __m512 denom = _mm512_add_ps(
767 _mm512_set1_ps(1.0f), ck_ggml_expf_avx512(neg_gate));
768 const __m512 silu = _mm512_div_ps(gate_v, denom);
769 _mm512_storeu_ps(out_row + d, _mm512_mul_ps(silu, up_v));
770 }
771#elif defined(__AVX2__) && defined(__FMA__)
772 for (; d + 8 <= dim; d += 8) {
773 const __m256 gate_v = _mm256_loadu_ps(gate_row + d);
774 const __m256 up_v = _mm256_loadu_ps(up_row + d);
775 const __m256 neg_gate = _mm256_sub_ps(_mm256_setzero_ps(), gate_v);
776 const __m256 denom = _mm256_add_ps(
777 _mm256_set1_ps(1.0f), ck_ggml_expf_avx2(neg_gate));
778 const __m256 silu = _mm256_div_ps(gate_v, denom);
779 _mm256_storeu_ps(out_row + d, _mm256_mul_ps(silu, up_v));
780 }
781#elif defined(__ARM_NEON) && (defined(__aarch64__) || defined(__ARM_FEATURE_FMA))
782 if (!force_ref) {
783 for (; d + 4 <= dim; d += 4) {
784 const float32x4_t gate_v = vld1q_f32(gate_row + d);
785 const float32x4_t up_v = vld1q_f32(up_row + d);
786 const float32x4_t neg_gate = vsubq_f32(vdupq_n_f32(0.0f), gate_v);
787 const float32x4_t denom = vaddq_f32(
788 vdupq_n_f32(1.0f), ck_ggml_expf_neon(neg_gate));
789 const float32x4_t silu = vdivq_f32(gate_v, denom);
790 vst1q_f32(out_row + d, vmulq_f32(silu, up_v));
791 }
792 }
793#endif
794 for (; d < dim; ++d) {
795 const float gate_v = gate_row[d];
796 out_row[d] = (gate_v / (1.0f + expf(-gate_v))) * up_row[d];
797 }
798 }
799}

References silu().

Referenced by ck_moe_q4k_q5k_bucket_work(), and ck_moe_shared_q4k_gated_workspace().

◆ swiglu_forward_pytorch_bf16_storage()

void swiglu_forward_pytorch_bf16_storage ( const float *  input,
float *  output,
int  tokens,
int  dim 
)

Definition at line 861 of file swiglu_kernels.c.

865{
866 if (!input || !output || tokens < 0 || dim < 0) {
867 fprintf(stderr, "HARD KERNEL CONTRACT FAULT: invalid PyTorch BF16 SwiGLU arguments\n");
868 abort();
869 }
870
871#if defined(__AVX512F__)
872 pthread_once(&ck_pytorch_swiglu_once, ck_bind_pytorch_swiglu_sleef);
873 if (!ck_pytorch_swiglu_expf16) {
874 fprintf(stderr,
875 "HARD KERNEL CONTRACT FAULT: PyTorch BF16 SwiGLU requires "
876 "SLEEF Sleef_expf16_u10; set CK_SLEEF_LIBRARY\n");
877 abort();
878 }
879#endif
880
881 for (int t = 0; t < tokens; ++t) {
882 const float *row = input + (size_t)t * (size_t)(2 * dim);
883 float *out_row = output + (size_t)t * (size_t)dim;
884 int d = 0;
885
886#if defined(__AVX512F__)
887 for (; d + 16 <= dim; d += 16) {
888 const __m512 gate = _mm512_loadu_ps(row + d);
889 const __m512 denominator = _mm512_add_ps(
890 _mm512_set1_ps(1.0f),
891 ck_pytorch_swiglu_expf16(_mm512_sub_ps(_mm512_setzero_ps(), gate)));
892 const __m512 silu = _mm512_div_ps(gate, denominator);
893 float silu_lanes[16] __attribute__((aligned(64)));
894 _mm512_store_ps(silu_lanes, silu);
895 for (int lane = 0; lane < 16; ++lane) {
896 const float silu_bf16 = bf16_to_float(float_to_bf16(silu_lanes[lane]));
897 const float up_bf16 = bf16_to_float(float_to_bf16(row[dim + d + lane]));
898 out_row[d + lane] = bf16_to_float(
899 float_to_bf16(silu_bf16 * up_bf16));
900 }
901 }
902#endif
903 for (; d < dim; ++d) {
904 const float gate_bf16 = bf16_to_float(float_to_bf16(row[d]));
905 const float up_bf16 = bf16_to_float(float_to_bf16(row[dim + d]));
906 const float silu = gate_bf16 / (1.0f + expf(-gate_bf16));
907 const float silu_bf16 = bf16_to_float(float_to_bf16(silu));
908 out_row[d] = bf16_to_float(float_to_bf16(silu_bf16 * up_bf16));
909 }
910 }
911}
static uint16_t float_to_bf16(float f)
Definition bf16_utils.h:90
static float bf16_to_float(uint16_t v)
Definition bf16_utils.h:38

References __attribute__(), bf16_to_float(), float_to_bf16(), and silu().

Referenced by moe_swiglu_packed_expert_forward_bf16().

◆ swiglu_forward_q8_k()

void swiglu_forward_q8_k ( const float *  input,
void *  output_q8,
int  tokens,
int  dim 
)

Definition at line 365 of file swiglu_kernels.c.

369{
370 if (!input || !output_q8 || tokens <= 0 || dim <= 0) {
371 return;
372 }
373 if ((dim % QK_K) != 0) {
374 return;
375 }
376
377 const char *fast_env = getenv("CK_SWIGLU_FAST");
378 const char *exact_env = getenv("CK_SWIGLU_EXACT");
379 const int use_fast = !ck_strict_parity_enabled() &&
380 (fast_env && atoi(fast_env) != 0) &&
381 !(exact_env && atoi(exact_env) != 0);
382
383 const int blocks_per_row = dim / QK_K;
384 block_q8_K *q8 = (block_q8_K *)output_q8;
385 float tmp[QK_K];
386
387 for (int t = 0; t < tokens; ++t) {
388 const float *row = input + (size_t)t * (size_t)(2 * dim);
389 block_q8_K *q8_row = q8 + (size_t)t * (size_t)blocks_per_row;
390
391 for (int block = 0; block < blocks_per_row; ++block) {
392 const int base = block * QK_K;
393 int d = 0;
394
395#if defined(__AVX2__)
396 if (use_fast) {
397 for (; d + 8 <= QK_K; d += 8) {
398 const __m256 a = _mm256_loadu_ps(row + base + d);
399 const __m256 b = _mm256_loadu_ps(row + dim + base + d);
400 const __m256 s = sigmoid256_fast(a);
401 const __m256 y = _mm256_mul_ps(_mm256_mul_ps(a, s), b);
402 _mm256_storeu_ps(tmp + d, y);
403 }
404 }
405#else
406 (void)use_fast;
407#endif
408
409 for (; d < QK_K; ++d) {
410 const float a = row[base + d];
411 const float b = row[dim + base + d];
412 const float s = use_fast ? sigmoid_scalar(a) : sigmoid_scalar_parity(a);
413 tmp[d] = (a * s) * b;
414 }
415
416 quantize_row_q8_k(tmp, (void *)&q8_row[block], QK_K);
417 }
418 }
419}
void quantize_row_q8_k(const float *x, void *y, int k)
#define QK_K

References ck_strict_parity_enabled(), QK_K, quantize_row_q8_k(), sigmoid_scalar(), and sigmoid_scalar_parity().