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

AXPY kernels for FP32: y = y + alpha * x. More...

#include <stdint.h>
#include <stddef.h>
#include <stdatomic.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "ckernel_engine.h"
#include "ckernel_dtype.h"
#include "ck_threadpool.h"
#include "bf16_utils.h"

Go to the source code of this file.

Typedefs

typedef int(* ck_moe_expert_workspace_fn) (const float *, const int *, const float *, const void *, const void *, const void *, float *, int, int, int, int, int, void *, size_t)
 
typedef int(* ck_moe_shared_gated_workspace_fn) (const float *, const float *, const void *, const void *, const void *, const float *, float *, int, int, int, void *, size_t)
 
typedef int(* ck_moe_shared_workspace_fn) (const float *, const float *, const void *, const void *, const void *, float *, int, int, int, void *, size_t)
 

Enumerations

enum  { CK_MOE_Q4K_Q5K_TASK_ROWS = 16 }
 
enum  ck_moe_down_kind_t { CK_MOE_DOWN_Q4_K , CK_MOE_DOWN_Q6_K , CK_MOE_DOWN_Q5_0 , CK_MOE_DOWN_Q8_0 }
 

Functions

void axpy_2d_f32 (float *Y, const float *X, float alpha, int num_tokens, int dim, int y_stride, int x_stride)
 Batched AXPY for 2D tensors: Y[t,:] += alpha * X[t,:].
 
void axpy_f32 (float *y, const float *x, float alpha, int n)
 In-place AXPY: y += alpha * x.
 
void axpy_zero_f32 (float *y, const float *x, float alpha, int n)
 Zero output then accumulate: y = 0; y += alpha * x.
 
static size_t ck_moe_align64 (size_t value)
 
static float ck_moe_bf16_round (float x)
 
static int ck_moe_bucket_expert_for_position (const int *offsets, int n_experts, int position)
 
static int ck_moe_bucket_layout (int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, ck_moe_q4k_q5k_bucket_layout_t *layout)
 
static int ck_moe_debug_enabled (void)
 
static void ck_moe_debug_finite (const char *name, const float *x, size_t n)
 
static size_t ck_moe_down_idx (int e, int h, int i, int hidden_dim, int intermediate_dim)
 
static float ck_moe_dsilu_f32 (float x)
 
static void ck_moe_llama_weighted_accumulate (float *output, const float *expert_output, float route_weight, int n)
 
static void ck_moe_q4k_llama_projection (float *output, const void *weights, const void *input_q8, int output_dim, int input_dim, void *scratch)
 
static size_t ck_moe_q4k_llama_projection_scratch_bytes (int output_dim, int input_dim)
 
static void ck_moe_q4k_mixed_parallel_work (int ith, int nth, void *opaque)
 
static int ck_moe_q4k_mixed_parallel_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes, ck_moe_expert_workspace_fn serial_fn, ck_moe_down_kind_t down_kind)
 
static int ck_moe_q4k_mixed_route_parallel (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes, size_t workspace_stride, ck_threadpool_t *pool, ck_moe_down_kind_t down_kind)
 
static void ck_moe_q4k_mixed_route_work (int ith, int nth, void *opaque)
 
static void ck_moe_q4k_q5k_bucket_work (int ith, int nth, void *opaque)
 
static void ck_moe_q4k_q5k_parallel_work (int ith, int nth, void *opaque)
 
static void ck_moe_q4k_q5k_quantize_work (int ith, int nth, void *opaque)
 
static int ck_moe_q4k_q5k_route_parallel (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes, size_t workspace_stride, ck_threadpool_t *pool)
 
static void ck_moe_q4k_q5k_route_work (int ith, int nth, void *opaque)
 
static int ck_moe_shared_gated_parallel_workspace (const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes, size_t stride, ck_moe_shared_gated_workspace_fn serial_fn)
 
static int ck_moe_shared_q4k_gated_workspace (const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes, void(*down_projection)(float *, const void *, const void *, int, int))
 
static void ck_moe_shared_q4k_parallel_work (int ith, int nth, void *opaque)
 
static int ck_moe_shared_q4k_parallel_workspace (const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes, ck_moe_shared_workspace_fn serial_fn)
 
static void ck_moe_shared_q8_0_parallel_work (int ith, int nth, void *opaque)
 
static float ck_moe_sigmoid_f32 (float x)
 
static float ck_moe_silu_f32 (float x)
 
static int ck_moe_size_add (size_t a, size_t b, size_t *result)
 
static int ck_moe_size_mul (size_t a, size_t b, size_t *result)
 
static int ck_moe_swiglu_expert_forward_q4k_q5k_bucketed_impl (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, const void *expert_gate_packed, const void *expert_up_packed, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
static size_t ck_moe_up_idx (int e, int i, int h, int intermediate_dim, int hidden_dim)
 
void farskip_swiglu_shared_combine_bf16 (const float *hidden, const float *routed, const float *post_attn_residual, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, float *main_output, float *routed_free_output, int rows, int hidden_dim, int intermediate_dim)
 
void farskip_swiglu_shared_combine_bf16_row_range (const float *hidden, const float *routed, const float *post_attn_residual, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, float *main_output, float *routed_free_output, int rows, int hidden_dim, int intermediate_dim, int row_begin, int row_end)
 
void gemm_nt_q4_k_packed_meta_x8_q8_k_gemv_order (const void *input, const void *packed_weight, const float *bias, float *output, int rows, int output_dim, int input_dim)
 
void gemm_nt_q4_k_q8_k_pairwise_split_min_parallel_dispatch (const void *input, const void *weight, const float *bias, float *output, int rows, int output_dim, int input_dim)
 
void gemm_q4_k_q8_k_compact_rows4 (float *output, int output_stride, const void *weights, const void *const input_rows[4], int rows, int output_dim, int input_dim)
 
void gemm_q4_k_q8_k_packed_vnni_x8_compact_order_rows4 (float *output, const void *weights_packed, const void *input_q8, int rows, int output_dim, int input_dim)
 
void gemm_q5_k_q8_k_compact_rows4 (float *output, int output_stride, const void *weights, const void *const input_rows[4], int rows, int output_dim, int input_dim)
 
void moe_accumulate_expert_f32 (float *output, const float *expert_output, float routing_weight, int hidden_dim)
 Accumulate expert output: output += routing_weight * expert_output.
 
void moe_relu2_expert_backward_f32 (const float *d_output, const float *hidden, const int *indices, const float *routing_weights, const float *expert_up, const float *expert_down, float *d_hidden, float *d_routing_weights, float *d_expert_up, float *d_expert_down, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
 
void moe_relu2_expert_forward_f32 (const float *hidden, const int *indices, const float *routing_weights, const float *expert_up, const float *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
 
void moe_relu2_expert_forward_q5_0_q5_0 (const float *hidden, const int *indices, const float *routing_weights, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
 
void moe_relu2_expert_forward_q5_0_q8_0 (const float *hidden, const int *indices, const float *routing_weights, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
 
void moe_relu2_shared_forward_q5_1_q8_0 (const float *hidden, const float *routed, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim)
 
void moe_swiglu_expert_backward_f32 (const float *d_output, const float *hidden, const int *indices, const float *routing_weights, const float *expert_gate, const float *expert_up, const float *expert_down, float *d_hidden, float *d_routing_weights, float *d_expert_gate, float *d_expert_up, float *d_expert_down, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
 
void moe_swiglu_expert_forward_bf16 (const float *hidden, const int *indices, const float *routing_weights, const uint16_t *expert_gate, const uint16_t *expert_up, const uint16_t *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
 
void moe_swiglu_expert_forward_bf16_row_range (const float *hidden, const int *indices, const float *routing_weights, const uint16_t *expert_gate, const uint16_t *expert_up, const uint16_t *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, int row_begin, int row_end)
 
void moe_swiglu_expert_forward_f32 (const float *hidden, const int *indices, const float *routing_weights, const float *expert_gate, const float *expert_up, const float *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
 
int moe_swiglu_expert_forward_q4k_q4k_parallel_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_expert_forward_q4k_q4k_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_expert_forward_q4k_q5_0_parallel_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_expert_forward_q4k_q5_0_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_expert_forward_q4k_q5k_auto_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_expert_forward_q4k_q5k_bucketed_prepared_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, const void *expert_gate_packed, const void *expert_up_packed, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_expert_forward_q4k_q5k_bucketed_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_expert_forward_q4k_q5k_parallel_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_expert_forward_q4k_q5k_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_expert_forward_q4k_q6k_parallel_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_expert_forward_q4k_q6k_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_expert_forward_q4k_q8_0_parallel_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_expert_forward_q4k_q8_0_workspace (const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
 
size_t moe_swiglu_expert_q4k_q5k_bucketed_workspace_bytes (int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
 
size_t moe_swiglu_expert_q4k_q5k_workspace_bytes (int hidden_dim, int intermediate_dim)
 
size_t moe_swiglu_expert_q4k_q8_0_workspace_bytes (int hidden_dim, int intermediate_dim)
 
void moe_swiglu_packed_expert_forward_bf16 (const float *hidden, const int *indices, const float *routing_weights, const uint16_t *expert_gate_up, const uint16_t *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
 
void moe_swiglu_shared_backward_f32 (const float *d_output, const float *hidden, const float *shared_gate, const float *shared_up, const float *shared_down, float *d_hidden, float *d_routed, float *d_shared_gate, float *d_shared_up, float *d_shared_down, int rows, int hidden_dim, int intermediate_dim)
 
void moe_swiglu_shared_forward_bf16 (const float *hidden, const float *routed, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim)
 
void moe_swiglu_shared_forward_bf16_gated (const float *hidden, const float *routed, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, const uint16_t *shared_router, float *output, int rows, int hidden_dim, int intermediate_dim)
 
void moe_swiglu_shared_forward_bf16_gated_row_range (const float *hidden, const float *routed, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, const uint16_t *shared_router, float *output, int rows, int hidden_dim, int intermediate_dim, int row_begin, int row_end)
 
void moe_swiglu_shared_forward_bf16_row_range (const float *hidden, const float *routed, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, int row_begin, int row_end)
 
void moe_swiglu_shared_forward_f32 (const float *hidden, const float *routed, const float *shared_gate, const float *shared_up, const float *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim)
 
int moe_swiglu_shared_forward_q4k_q4k_parallel_workspace (const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_shared_forward_q4k_q4k_workspace (const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_shared_forward_q4k_q5_0_gated_parallel_workspace (const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_shared_forward_q4k_q5_0_gated_workspace (const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_shared_forward_q4k_q6k_parallel_workspace (const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_shared_forward_q4k_q6k_workspace (const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_shared_forward_q4k_q8_0_gated_parallel_workspace (const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_shared_forward_q4k_q8_0_gated_workspace (const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_shared_forward_q8_0_gated_parallel_workspace (const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
 
int moe_swiglu_shared_forward_q8_0_gated_workspace (const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
 
size_t moe_swiglu_shared_q4k_q8_0_gated_workspace_bytes (int hidden_dim, int intermediate_dim)
 
size_t moe_swiglu_shared_q8_0_gated_workspace_bytes (int hidden_dim, int intermediate_dim)
 
void pack_q4_k_to_packed_meta_x8 (const void *source, void *destination, int output_dim, int input_dim)
 
size_t q4_k_packed_meta_x8_block_size (void)
 
size_t q4_k_packed_vnni_x8_block_size (void)
 
void scal_copy_f32 (float *y, const float *x, float alpha, int n)
 Scaled copy: y = alpha * x.
 
void weighted_sum_f32 (float *y, const float **vectors, const float *weights, int k, int n)
 Weighted sum of k vectors: y = sum_i(weights[i] * vectors[i])
 

Detailed Description

AXPY kernels for FP32: y = y + alpha * x.

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

Classic BLAS Level-1 operation used in MoE expert output accumulation. When gathering expert outputs: output += weight[i] * expert_output[i]

Operations:

  • axpy_f32: y += alpha * x (in-place)
  • axpy_strided_f32: strided version for non-contiguous memory
  • weighted_sum_f32: sum multiple vectors with weights

Definition in file axpy_kernels.c.

Typedef Documentation

◆ ck_moe_expert_workspace_fn

typedef int(* ck_moe_expert_workspace_fn) (const float *, const int *, const float *, const void *, const void *, const void *, float *, int, int, int, int, int, void *, size_t)

Definition at line 1541 of file axpy_kernels.c.

◆ ck_moe_shared_gated_workspace_fn

typedef int(* ck_moe_shared_gated_workspace_fn) (const float *, const float *, const void *, const void *, const void *, const float *, float *, int, int, int, void *, size_t)

Definition at line 2848 of file axpy_kernels.c.

◆ ck_moe_shared_workspace_fn

typedef int(* ck_moe_shared_workspace_fn) (const float *, const float *, const void *, const void *, const void *, float *, int, int, int, void *, size_t)

Definition at line 1950 of file axpy_kernels.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
CK_MOE_Q4K_Q5K_TASK_ROWS 

Definition at line 2265 of file axpy_kernels.c.

@ CK_MOE_Q4K_Q5K_TASK_ROWS

◆ ck_moe_down_kind_t

Enumerator
CK_MOE_DOWN_Q4_K 
CK_MOE_DOWN_Q6_K 
CK_MOE_DOWN_Q5_0 
CK_MOE_DOWN_Q8_0 

Definition at line 1545 of file axpy_kernels.c.

1545 {
ck_moe_down_kind_t
@ CK_MOE_DOWN_Q4_K
@ CK_MOE_DOWN_Q5_0
@ CK_MOE_DOWN_Q8_0
@ CK_MOE_DOWN_Q6_K

Function Documentation

◆ axpy_2d_f32()

void axpy_2d_f32 ( float *  Y,
const float *  X,
float  alpha,
int  num_tokens,
int  dim,
int  y_stride,
int  x_stride 
)

Batched AXPY for 2D tensors: Y[t,:] += alpha * X[t,:].

Parameters
YOutput tensor [num_tokens, dim]
XInput tensor [num_tokens, dim]
alphaScalar multiplier
num_tokensNumber of tokens
dimHidden dimension
y_strideStride between Y rows (for alignment)
x_strideStride between X rows

Definition at line 272 of file axpy_kernels.c.

279{
280 if (!Y || !X || num_tokens <= 0 || dim <= 0) {
281 return;
282 }
283
284 /* Default strides if not specified */
285 if (y_stride <= 0) y_stride = dim;
286 if (x_stride <= 0) x_stride = dim;
287
288 for (int t = 0; t < num_tokens; t++) {
289 axpy_f32(Y + t * y_stride, X + t * x_stride, alpha, dim);
290 }
291}
void axpy_f32(float *y, const float *x, float alpha, int n)
In-place AXPY: y += alpha * x.

References axpy_f32().

◆ axpy_f32()

void axpy_f32 ( float *  y,
const float *  x,
float  alpha,
int  n 
)

In-place AXPY: y += alpha * x.

Test:

test_axpy.py::TestAXPY::test_axpy_f32

test_axpy.py::TestAXPY::test_axpy_vs_naive

In-place scaled vector addition: y += alpha * x BLAS-like axpy operation.

After changes: make test

Definition at line 105 of file axpy_kernels.c.

109{
110 if (!y || !x || n <= 0) {
111 return;
112 }
113
114 int i = 0;
115
116#ifdef __AVX512F__
117 __m512 valpha = _mm512_set1_ps(alpha);
118 for (; i + 16 <= n; i += 16) {
119 __m512 vy = _mm512_loadu_ps(&y[i]);
120 __m512 vx = _mm512_loadu_ps(&x[i]);
121 vy = _mm512_fmadd_ps(vx, valpha, vy); /* y = y + alpha * x */
122 _mm512_storeu_ps(&y[i], vy);
123 }
124#endif
125
126#ifdef __AVX2__
127 __m256 valpha256 = _mm256_set1_ps(alpha);
128 for (; i + 8 <= n; i += 8) {
129 __m256 vy = _mm256_loadu_ps(&y[i]);
130 __m256 vx = _mm256_loadu_ps(&x[i]);
131 vy = _mm256_fmadd_ps(vx, valpha256, vy);
132 _mm256_storeu_ps(&y[i], vy);
133 }
134#endif
135
136 /* Scalar remainder */
137 for (; i < n; i++) {
138 y[i] += alpha * x[i];
139 }
140}

Referenced by axpy_2d_f32(), axpy_zero_f32(), ck_moe_q4k_mixed_route_parallel(), ck_moe_q4k_q5k_bucket_work(), ck_moe_q4k_q5k_route_parallel(), moe_accumulate_expert_f32(), moe_swiglu_expert_forward_q4k_q4k_workspace(), moe_swiglu_expert_forward_q4k_q5k_workspace(), moe_swiglu_expert_forward_q4k_q6k_workspace(), and weighted_sum_f32().

◆ axpy_zero_f32()

void axpy_zero_f32 ( float *  y,
const float *  x,
float  alpha,
int  n 
)

Zero output then accumulate: y = 0; y += alpha * x.

Parameters
yOutput vector [n], zeroed then accumulated
xInput vector [n]
alphaScalar multiplier
nVector length

Definition at line 239 of file axpy_kernels.c.

243{
244 if (!y || n <= 0) {
245 return;
246 }
247
248 memset(y, 0, n * sizeof(float));
249
250 if (x) {
251 axpy_f32(y, x, alpha, n);
252 }
253}

References axpy_f32().

◆ ck_moe_align64()

◆ ck_moe_bf16_round()

static float ck_moe_bf16_round ( float  x)
inlinestatic

Definition at line 439 of file axpy_kernels.c.

440{
441 return bf16_to_float(float_to_bf16(x));
442}
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 bf16_to_float(), and float_to_bf16().

Referenced by moe_swiglu_packed_expert_forward_bf16(), and moe_swiglu_shared_forward_bf16_gated_row_range().

◆ ck_moe_bucket_expert_for_position()

static int ck_moe_bucket_expert_for_position ( const int *  offsets,
int  n_experts,
int  position 
)
static

Definition at line 2267 of file axpy_kernels.c.

2270{
2271 int lo = 0;
2272 int hi = n_experts;
2273 while (lo < hi) {
2274 const int mid = lo + (hi - lo) / 2;
2275 if (offsets[mid + 1] <= position) {
2276 lo = mid + 1;
2277 } else {
2278 hi = mid;
2279 }
2280 }
2281 return lo;
2282}
int const int32_t * offsets
Definition true_bpe.h:194

References offsets.

Referenced by ck_moe_q4k_q5k_bucket_work().

◆ ck_moe_bucket_layout()

static int ck_moe_bucket_layout ( int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
ck_moe_q4k_q5k_bucket_layout_t *  layout 
)
static

Definition at line 2116 of file axpy_kernels.c.

2122{
2123 if (!layout || rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 ||
2124 n_experts <= 0 || top_k <= 0 || top_k > n_experts ||
2125 hidden_dim % 256 != 0 || intermediate_dim % 256 != 0) {
2126 return -1;
2127 }
2128
2129 memset(layout, 0, sizeof(*layout));
2130 layout->hidden_q8_row_bytes = ck_moe_align64(
2131 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim));
2132
2133 size_t gate_up_bytes = 0;
2134 size_t worker_bytes = 0;
2135 if (ck_moe_size_mul(8u * sizeof(float), (size_t)intermediate_dim,
2136 &gate_up_bytes) != 0) {
2137 return -1;
2138 }
2139 worker_bytes = ck_moe_align64(gate_up_bytes);
2140 if (ck_moe_size_add(
2141 worker_bytes,
2143 CK_DT_Q8_K, (size_t)hidden_dim)),
2144 &worker_bytes) != 0 ||
2146 worker_bytes,
2148 CK_DT_Q8_K, (size_t)intermediate_dim)),
2149 &worker_bytes) != 0 ||
2151 worker_bytes,
2152 ck_moe_align64(4u * (size_t)hidden_dim * sizeof(float)),
2153 &worker_bytes) != 0) {
2154 return -1;
2155 }
2156 layout->worker_stride = worker_bytes;
2157
2158 size_t cursor = 0;
2159 size_t bytes = 0;
2160 layout->hidden_q8_offset = cursor;
2161 if (ck_moe_size_mul((size_t)rows, layout->hidden_q8_row_bytes, &bytes) != 0 ||
2162 ck_moe_size_add(cursor, ck_moe_align64(bytes), &cursor) != 0) {
2163 return -1;
2164 }
2165
2166 layout->route_rows_offset = cursor;
2167 if (ck_moe_size_mul((size_t)rows, (size_t)top_k, &bytes) != 0 ||
2168 ck_moe_size_mul(bytes, sizeof(int), &bytes) != 0 ||
2169 ck_moe_size_add(cursor, ck_moe_align64(bytes), &cursor) != 0) {
2170 return -1;
2171 }
2172
2173 layout->slot_offsets_offset = cursor;
2174 if (ck_moe_size_mul((size_t)top_k, (size_t)n_experts + 1u, &bytes) != 0 ||
2175 ck_moe_size_mul(bytes, sizeof(int), &bytes) != 0 ||
2176 ck_moe_size_add(cursor, ck_moe_align64(bytes), &cursor) != 0) {
2177 return -1;
2178 }
2179
2180 layout->counts_offset = cursor;
2181 if (ck_moe_size_mul((size_t)n_experts, sizeof(int), &bytes) != 0 ||
2182 ck_moe_size_add(cursor, ck_moe_align64(bytes), &cursor) != 0) {
2183 return -1;
2184 }
2185
2186 layout->cursors_offset = cursor;
2187 if (ck_moe_size_mul((size_t)n_experts, sizeof(int), &bytes) != 0 ||
2188 ck_moe_size_add(cursor, ck_moe_align64(bytes), &cursor) != 0) {
2189 return -1;
2190 }
2191
2192 layout->workers_offset = cursor;
2194 layout->worker_stride, &bytes) != 0 ||
2195 ck_moe_size_add(cursor, ck_moe_align64(bytes), &cursor) != 0) {
2196 return -1;
2197 }
2198 layout->total_bytes = cursor;
2199 return 0;
2200}
static size_t ck_moe_align64(size_t value)
static int ck_moe_size_mul(size_t a, size_t b, size_t *result)
static int ck_moe_size_add(size_t a, size_t b, size_t *result)
#define CK_THREADPOOL_MAX_THREADS
@ CK_DT_Q8_K
static size_t ck_dtype_row_bytes(CKDataType dt, size_t n_elements)
Calculate total bytes for n_elements of given dtype.

References CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), ck_moe_size_add(), ck_moe_size_mul(), and CK_THREADPOOL_MAX_THREADS.

Referenced by ck_moe_swiglu_expert_forward_q4k_q5k_bucketed_impl(), and moe_swiglu_expert_q4k_q5k_bucketed_workspace_bytes().

◆ ck_moe_debug_enabled()

static int ck_moe_debug_enabled ( void  )
static

Definition at line 333 of file axpy_kernels.c.

334{
335 const char *v = getenv("CK_DEBUG_MOE");
336 return v && v[0] && v[0] != '0';
337}

Referenced by ck_moe_debug_finite(), moe_relu2_expert_forward_q5_0_q5_0(), moe_relu2_expert_forward_q5_0_q8_0(), and moe_relu2_shared_forward_q5_1_q8_0().

◆ ck_moe_debug_finite()

static void ck_moe_debug_finite ( const char *  name,
const float *  x,
size_t  n 
)
static

Definition at line 339 of file axpy_kernels.c.

340{
341 if (!ck_moe_debug_enabled() || !x) {
342 return;
343 }
344 size_t finite = 0;
345 size_t nan = 0;
346 size_t inf = 0;
347 float min_v = 0.0f;
348 float max_v = 0.0f;
349 int have = 0;
350 for (size_t i = 0; i < n; ++i) {
351 const float v = x[i];
352 if (isnan(v)) {
353 ++nan;
354 } else if (isinf(v)) {
355 ++inf;
356 } else {
357 ++finite;
358 if (!have || v < min_v) min_v = v;
359 if (!have || v > max_v) max_v = v;
360 have = 1;
361 }
362 }
363 fprintf(stderr,
364 "[CK_DEBUG_MOE] %s finite=%zu/%zu nan=%zu inf=%zu min=%g max=%g\n",
365 name,
366 finite,
367 n,
368 nan,
369 inf,
370 have ? min_v : 0.0f,
371 have ? max_v : 0.0f);
372}
static int ck_moe_debug_enabled(void)

References ck_moe_debug_enabled().

Referenced by moe_relu2_expert_forward_q5_0_q5_0(), moe_relu2_expert_forward_q5_0_q8_0(), and moe_relu2_shared_forward_q5_1_q8_0().

◆ ck_moe_down_idx()

static size_t ck_moe_down_idx ( int  e,
int  h,
int  i,
int  hidden_dim,
int  intermediate_dim 
)
inlinestatic

Definition at line 328 of file axpy_kernels.c.

329{
330 return ((size_t)e * (size_t)hidden_dim + (size_t)h) * (size_t)intermediate_dim + (size_t)i;
331}

Referenced by moe_relu2_expert_backward_f32(), moe_relu2_expert_forward_f32(), moe_swiglu_expert_backward_f32(), moe_swiglu_expert_forward_bf16_row_range(), moe_swiglu_expert_forward_f32(), and moe_swiglu_packed_expert_forward_bf16().

◆ ck_moe_dsilu_f32()

static float ck_moe_dsilu_f32 ( float  x)
inlinestatic

Definition at line 444 of file axpy_kernels.c.

445{
446 const float sig = ck_moe_sigmoid_f32(x);
447 return sig + x * sig * (1.0f - sig);
448}
static float ck_moe_sigmoid_f32(float x)

References ck_moe_sigmoid_f32().

Referenced by moe_swiglu_expert_backward_f32(), and moe_swiglu_shared_backward_f32().

◆ ck_moe_llama_weighted_accumulate()

static void ck_moe_llama_weighted_accumulate ( float *  output,
const float *  expert_output,
float  route_weight,
int  n 
)
static

Definition at line 718 of file axpy_kernels.c.

720{
721 for (int i = 0; i < n; ++i) {
722 volatile float weighted = expert_output[i] * route_weight;
723 output[i] += weighted;
724 }
725}

Referenced by ck_moe_q4k_mixed_route_parallel(), moe_swiglu_expert_forward_q4k_q5_0_workspace(), and moe_swiglu_expert_forward_q4k_q8_0_workspace().

◆ ck_moe_q4k_llama_projection()

static void ck_moe_q4k_llama_projection ( float *  output,
const void *  weights,
const void *  input_q8,
int  output_dim,
int  input_dim,
void *  scratch 
)
static

Definition at line 695 of file axpy_kernels.c.

702{
703#if defined(__AVX512F__) && defined(__AVX512BW__) && defined(__AVX512DQ__)
704 if (scratch && output_dim > 0 && input_dim > 0 &&
705 output_dim % 16 == 0 && input_dim % 256 == 0) {
706 pack_q4_k_to_packed_meta_x8(weights, scratch, output_dim, input_dim);
708 input_q8, scratch, NULL, output, 1, output_dim, input_dim);
709 return;
710 }
711 gemv_q4_k_q8_k(output, weights, input_q8, output_dim, input_dim);
712#else
713 (void)scratch;
714 gemv_q4_k_q8_k(output, weights, input_q8, output_dim, input_dim);
715#endif
716}
void pack_q4_k_to_packed_meta_x8(const void *source, void *destination, int output_dim, int input_dim)
void gemm_nt_q4_k_packed_meta_x8_q8_k_gemv_order(const void *input, const void *packed_weight, const float *bias, float *output, int rows, int output_dim, int input_dim)
void gemv_q4_k_q8_k(float *y, const void *W, const void *x_q8, int M, int K)

References gemm_nt_q4_k_packed_meta_x8_q8_k_gemv_order(), gemv_q4_k_q8_k(), and pack_q4_k_to_packed_meta_x8().

Referenced by ck_moe_q4k_mixed_route_work(), moe_swiglu_expert_forward_q4k_q5_0_workspace(), and moe_swiglu_expert_forward_q4k_q8_0_workspace().

◆ ck_moe_q4k_llama_projection_scratch_bytes()

static size_t ck_moe_q4k_llama_projection_scratch_bytes ( int  output_dim,
int  input_dim 
)
static

Definition at line 677 of file axpy_kernels.c.

679{
680#if defined(__AVX512F__) && defined(__AVX512BW__) && defined(__AVX512DQ__)
681 if (output_dim <= 0 || input_dim <= 0 || output_dim % 16 != 0 ||
682 input_dim % 256 != 0) {
683 return 0;
684 }
685 return ck_moe_align64(
686 (size_t)((output_dim + 7) / 8) * (size_t)(input_dim / 256) *
688#else
689 (void)output_dim;
690 (void)input_dim;
691 return 0;
692#endif
693}
size_t q4_k_packed_meta_x8_block_size(void)

References ck_moe_align64(), and q4_k_packed_meta_x8_block_size().

Referenced by moe_swiglu_expert_q4k_q8_0_workspace_bytes().

◆ ck_moe_q4k_mixed_parallel_work()

static void ck_moe_q4k_mixed_parallel_work ( int  ith,
int  nth,
void *  opaque 
)
static

Definition at line 1571 of file axpy_kernels.c.

1572{
1573 ck_moe_q4k_mixed_parallel_args_t *args =
1574 (ck_moe_q4k_mixed_parallel_args_t *)opaque;
1575 const int begin = (args->rows * ith) / nth;
1576 const int end = (args->rows * (ith + 1)) / nth;
1577 if (begin >= end) {
1578 args->status[ith] = 0;
1579 return;
1580 }
1581 args->status[ith] = args->serial_fn(
1582 args->hidden + (size_t)begin * (size_t)args->hidden_dim,
1583 args->indices + (size_t)begin * (size_t)args->top_k,
1584 args->routing_weights + (size_t)begin * (size_t)args->top_k,
1585 args->expert_gate,
1586 args->expert_up,
1587 args->expert_down,
1588 args->output + (size_t)begin * (size_t)args->hidden_dim,
1589 end - begin,
1590 args->hidden_dim,
1591 args->intermediate_dim,
1592 args->n_experts,
1593 args->top_k,
1594 args->workspace + (size_t)ith * args->workspace_stride,
1595 args->workspace_stride);
1596}
uint32_t end
Definition utf8.c:215

References end.

Referenced by ck_moe_q4k_mixed_parallel_workspace().

◆ ck_moe_q4k_mixed_parallel_workspace()

static int ck_moe_q4k_mixed_parallel_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes,
ck_moe_expert_workspace_fn  serial_fn,
ck_moe_down_kind_t  down_kind 
)
static

Definition at line 1781 of file axpy_kernels.c.

1798{
1799 const int q8_0_activation =
1800 down_kind == CK_MOE_DOWN_Q5_0 || down_kind == CK_MOE_DOWN_Q8_0;
1801 const size_t stride = q8_0_activation
1802 ? moe_swiglu_expert_q4k_q8_0_workspace_bytes(hidden_dim, intermediate_dim)
1803 : moe_swiglu_expert_q4k_q5k_workspace_bytes(hidden_dim, intermediate_dim);
1804 if (!hidden || !indices || !routing_weights || !expert_gate || !expert_up ||
1805 !expert_down || !output || !workspace || !serial_fn || stride == 0 ||
1806 rows <= 0 || n_experts <= 0 || top_k <= 0 || top_k > n_experts) {
1807 return -1;
1808 }
1809
1810 ck_threadpool_t *pool = ck_threadpool_global();
1811 if (rows == 1) {
1812 const int route_status = ck_moe_q4k_mixed_route_parallel(
1813 hidden, indices, routing_weights, expert_gate, expert_up,
1814 expert_down, output, hidden_dim, intermediate_dim, n_experts,
1815 top_k, workspace, workspace_bytes, stride, pool, down_kind);
1816 if (route_status <= 0) return route_status;
1817 }
1818
1819 int active = pool ? ck_threadpool_n_threads(pool) : 1;
1820 if (active > rows) active = rows;
1822 const size_t workspace_workers = workspace_bytes / stride;
1823 if (workspace_workers == 0) return -1;
1824 if ((size_t)active > workspace_workers) active = (int)workspace_workers;
1825 if (active <= 1) {
1826 return serial_fn(
1827 hidden, indices, routing_weights, expert_gate, expert_up,
1828 expert_down, output, rows, hidden_dim, intermediate_dim, n_experts,
1829 top_k, workspace, stride);
1830 }
1831
1832 ck_moe_q4k_mixed_parallel_args_t args = {
1833 .hidden = hidden,
1834 .indices = indices,
1835 .routing_weights = routing_weights,
1836 .expert_gate = expert_gate,
1837 .expert_up = expert_up,
1838 .expert_down = expert_down,
1839 .output = output,
1840 .rows = rows,
1841 .hidden_dim = hidden_dim,
1842 .intermediate_dim = intermediate_dim,
1843 .n_experts = n_experts,
1844 .top_k = top_k,
1845 .workspace = (uint8_t *)workspace,
1846 .workspace_stride = stride,
1847 .serial_fn = serial_fn,
1848 .status = {0},
1849 };
1851 pool, active, ck_moe_q4k_mixed_parallel_work, &args);
1852 for (int ith = 0; ith < active; ++ith) {
1853 if (args.status[ith] != 0) return args.status[ith];
1854 }
1855 return 0;
1856}
size_t moe_swiglu_expert_q4k_q5k_workspace_bytes(int hidden_dim, int intermediate_dim)
static int ck_moe_q4k_mixed_route_parallel(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes, size_t workspace_stride, ck_threadpool_t *pool, ck_moe_down_kind_t down_kind)
static void ck_moe_q4k_mixed_parallel_work(int ith, int nth, void *opaque)
size_t moe_swiglu_expert_q4k_q8_0_workspace_bytes(int hidden_dim, int intermediate_dim)
void ck_threadpool_dispatch_n(ck_threadpool_t *pool, int active_threads, ck_work_fn_t fn, void *args)
ck_threadpool_t * ck_threadpool_global(void)
int ck_threadpool_n_threads(const ck_threadpool_t *pool)

References CK_MOE_DOWN_Q5_0, CK_MOE_DOWN_Q8_0, ck_moe_q4k_mixed_parallel_work(), ck_moe_q4k_mixed_route_parallel(), ck_threadpool_dispatch_n(), ck_threadpool_global(), CK_THREADPOOL_MAX_THREADS, ck_threadpool_n_threads(), moe_swiglu_expert_q4k_q5k_workspace_bytes(), and moe_swiglu_expert_q4k_q8_0_workspace_bytes().

Referenced by moe_swiglu_expert_forward_q4k_q4k_parallel_workspace(), moe_swiglu_expert_forward_q4k_q5_0_parallel_workspace(), moe_swiglu_expert_forward_q4k_q6k_parallel_workspace(), and moe_swiglu_expert_forward_q4k_q8_0_parallel_workspace().

◆ ck_moe_q4k_mixed_route_parallel()

static int ck_moe_q4k_mixed_route_parallel ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes,
size_t  workspace_stride,
ck_threadpool_t *  pool,
ck_moe_down_kind_t  down_kind 
)
static

Definition at line 1713 of file axpy_kernels.c.

1730{
1731 if (!pool || top_k <= 1 || top_k > CK_THREADPOOL_MAX_THREADS ||
1732 ck_threadpool_n_threads(pool) < top_k ||
1733 workspace_bytes < workspace_stride * (size_t)top_k) {
1734 return 1;
1735 }
1736
1737 const size_t hidden_q8_bytes = ck_moe_align64(
1738 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim));
1739 void *hidden_q8 = workspace;
1740 quantize_row_q8_k(hidden, hidden_q8, hidden_dim);
1741
1742 ck_moe_q4k_mixed_route_args_t args = {
1743 .indices = indices,
1744 .expert_gate = expert_gate,
1745 .expert_up = expert_up,
1746 .expert_down = expert_down,
1747 .hidden_q8 = hidden_q8,
1748 .workspace = (uint8_t *)workspace,
1749 .workspace_stride = workspace_stride,
1750 .hidden_q8_bytes = hidden_q8_bytes,
1751 .hidden_dim = hidden_dim,
1752 .intermediate_dim = intermediate_dim,
1753 .n_experts = n_experts,
1754 .top_k = top_k,
1755 .down_kind = down_kind,
1756 .expert_output = {0},
1757 .status = {0},
1758 };
1760 pool, top_k, ck_moe_q4k_mixed_route_work, &args);
1761
1762 memset(output, 0, (size_t)hidden_dim * sizeof(float));
1763 for (int slot = 0; slot < top_k; ++slot) {
1764 if (args.status[slot] != 0 || !args.expert_output[slot]) {
1765 return args.status[slot] != 0 ? args.status[slot] : -1;
1766 }
1767 if (down_kind == CK_MOE_DOWN_Q5_0 ||
1768 down_kind == CK_MOE_DOWN_Q8_0) {
1770 output, args.expert_output[slot], routing_weights[slot],
1771 hidden_dim);
1772 } else {
1773 axpy_f32(
1774 output, args.expert_output[slot], routing_weights[slot],
1775 hidden_dim);
1776 }
1777 }
1778 return 0;
1779}
static void ck_moe_llama_weighted_accumulate(float *output, const float *expert_output, float route_weight, int n)
static void ck_moe_q4k_mixed_route_work(int ith, int nth, void *opaque)
void quantize_row_q8_k(const float *x, void *y, int k)

References axpy_f32(), CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), CK_MOE_DOWN_Q5_0, CK_MOE_DOWN_Q8_0, ck_moe_llama_weighted_accumulate(), ck_moe_q4k_mixed_route_work(), ck_threadpool_dispatch_n(), CK_THREADPOOL_MAX_THREADS, ck_threadpool_n_threads(), and quantize_row_q8_k().

Referenced by ck_moe_q4k_mixed_parallel_workspace().

◆ ck_moe_q4k_mixed_route_work()

static void ck_moe_q4k_mixed_route_work ( int  ith,
int  nth,
void *  opaque 
)
static

Definition at line 1616 of file axpy_kernels.c.

1617{
1618 ck_moe_q4k_mixed_route_args_t *args =
1619 (ck_moe_q4k_mixed_route_args_t *)opaque;
1620 if (ith >= nth || ith >= args->top_k) return;
1621
1622 const int expert = args->indices[ith];
1623 if (expert < 0 || expert >= args->n_experts) {
1624 args->status[ith] = -2;
1625 return;
1626 }
1627
1628 const size_t gate_up_bytes = ck_moe_align64(
1629 2u * (size_t)args->intermediate_dim * sizeof(float));
1630 const int q8_0_activation =
1631 args->down_kind == CK_MOE_DOWN_Q5_0 ||
1632 args->down_kind == CK_MOE_DOWN_Q8_0;
1633 const size_t act_q8_bytes = ck_moe_align64(ck_dtype_row_bytes(
1634 q8_0_activation ? CK_DT_Q8_0 : CK_DT_Q8_K,
1635 (size_t)args->intermediate_dim));
1636 uint8_t *cursor = args->workspace + (size_t)ith * args->workspace_stride;
1637 cursor += args->hidden_q8_bytes;
1638 float *gate_up = (float *)cursor;
1639 cursor += gate_up_bytes;
1640 void *act_q8 = cursor;
1641 cursor += act_q8_bytes;
1642 float *expert_output = (float *)cursor;
1643 args->expert_output[ith] = expert_output;
1644 cursor += ck_moe_align64((size_t)args->hidden_dim * sizeof(float));
1645 void *projection_scratch = cursor;
1646
1647 const size_t gate_row_bytes = ck_dtype_row_bytes(
1648 CK_DT_Q4_K, (size_t)args->hidden_dim);
1649 const size_t gate_offset =
1650 (size_t)expert * (size_t)args->intermediate_dim * gate_row_bytes;
1651 if (q8_0_activation) {
1653 gate_up, (const uint8_t *)args->expert_gate + gate_offset,
1654 args->hidden_q8, args->intermediate_dim, args->hidden_dim,
1655 projection_scratch);
1657 gate_up + args->intermediate_dim,
1658 (const uint8_t *)args->expert_up + gate_offset,
1659 args->hidden_q8, args->intermediate_dim, args->hidden_dim,
1660 projection_scratch);
1661 } else {
1663 gate_up, (const uint8_t *)args->expert_gate + gate_offset,
1664 args->hidden_q8, args->intermediate_dim, args->hidden_dim);
1666 gate_up + args->intermediate_dim,
1667 (const uint8_t *)args->expert_up + gate_offset,
1668 args->hidden_q8, args->intermediate_dim, args->hidden_dim);
1669 }
1670 swiglu_forward_ggml(gate_up, gate_up, 1, args->intermediate_dim);
1671 if (q8_0_activation) {
1672 quantize_row_q8_0(gate_up, act_q8, args->intermediate_dim);
1673 } else {
1674 quantize_row_q8_k(gate_up, act_q8, args->intermediate_dim);
1675 }
1676
1677 if (args->down_kind == CK_MOE_DOWN_Q6_K) {
1678 const size_t row_bytes = ck_dtype_row_bytes(
1679 CK_DT_Q6_K, (size_t)args->intermediate_dim);
1680 const size_t offset =
1681 (size_t)expert * (size_t)args->hidden_dim * row_bytes;
1683 expert_output, (const uint8_t *)args->expert_down + offset,
1684 act_q8, args->hidden_dim, args->intermediate_dim);
1685 } else if (args->down_kind == CK_MOE_DOWN_Q5_0) {
1686 const size_t row_bytes = ck_dtype_row_bytes(
1687 CK_DT_Q5_0, (size_t)args->intermediate_dim);
1688 const size_t offset =
1689 (size_t)expert * (size_t)args->hidden_dim * row_bytes;
1691 expert_output, (const uint8_t *)args->expert_down + offset,
1692 act_q8, args->hidden_dim, args->intermediate_dim);
1693 } else if (args->down_kind == CK_MOE_DOWN_Q8_0) {
1694 const size_t row_bytes = ck_dtype_row_bytes(
1695 CK_DT_Q8_0, (size_t)args->intermediate_dim);
1696 const size_t offset =
1697 (size_t)expert * (size_t)args->hidden_dim * row_bytes;
1699 expert_output, (const uint8_t *)args->expert_down + offset,
1700 act_q8, args->hidden_dim, args->intermediate_dim);
1701 } else {
1702 const size_t row_bytes = ck_dtype_row_bytes(
1703 CK_DT_Q4_K, (size_t)args->intermediate_dim);
1704 const size_t offset =
1705 (size_t)expert * (size_t)args->hidden_dim * row_bytes;
1707 expert_output, (const uint8_t *)args->expert_down + offset,
1708 act_q8, args->hidden_dim, args->intermediate_dim);
1709 }
1710 args->status[ith] = 0;
1711}
static void ck_moe_q4k_llama_projection(float *output, const void *weights, const void *input_q8, int output_dim, int input_dim, void *scratch)
@ CK_DT_Q4_K
@ CK_DT_Q8_0
@ CK_DT_Q5_0
@ CK_DT_Q6_K
void gemv_q5_0_q8_0(float *y, const void *W, const void *x_q8, int M, int K)
Matrix-vector multiply with Q5_0 weights and Q8_0 input.
void gemv_q6_k_q8_k(float *y, const void *W, const void *x_q8, int M, int K)
GEMV: y = W @ x where W is Q6_K and x is Q8_K.
void quantize_row_q8_0(const float *x, void *y, int k)
Quantize FP32 to Q8_0 format (scalar reference)
void gemv_q8_0_q8_0(float *y, const void *W, const void *x_q8, int M, int K)
Matrix-vector multiply with Q8_0 weights and Q8_0 input.
void swiglu_forward_ggml(const float *input, float *output, int tokens, int dim)

References CK_DT_Q4_K, CK_DT_Q5_0, CK_DT_Q6_K, CK_DT_Q8_0, CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), CK_MOE_DOWN_Q5_0, CK_MOE_DOWN_Q6_K, CK_MOE_DOWN_Q8_0, ck_moe_q4k_llama_projection(), gemv_q4_k_q8_k(), gemv_q5_0_q8_0(), gemv_q6_k_q8_k(), gemv_q8_0_q8_0(), quantize_row_q8_0(), quantize_row_q8_k(), and swiglu_forward_ggml().

Referenced by ck_moe_q4k_mixed_route_parallel().

◆ ck_moe_q4k_q5k_bucket_work()

static void ck_moe_q4k_q5k_bucket_work ( int  ith,
int  nth,
void *  opaque 
)
static

Definition at line 2284 of file axpy_kernels.c.

2285{
2286 (void)nth;
2287 ck_moe_q4k_q5k_bucket_work_t *args =
2288 (ck_moe_q4k_q5k_bucket_work_t *)opaque;
2289 uint8_t *cursor = args->workers + (size_t)ith * args->worker_stride;
2290 float *gate_up = (float *)cursor;
2291 cursor += ck_moe_align64(
2292 8u * (size_t)args->intermediate_dim * sizeof(float));
2293 uint8_t *hidden_q8_batch = cursor;
2294 const size_t hidden_q8_batch_row_bytes = ck_dtype_row_bytes(
2295 CK_DT_Q8_K, (size_t)args->hidden_dim);
2296 cursor += ck_moe_align64(4u * hidden_q8_batch_row_bytes);
2297 void *act_q8 = cursor;
2298 cursor += ck_moe_align64(
2299 4u * ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)args->intermediate_dim));
2300 float *expert_output = (float *)cursor;
2301 const size_t act_q8_row_bytes = ck_dtype_row_bytes(
2302 CK_DT_Q8_K, (size_t)args->intermediate_dim);
2303
2304 for (;;) {
2305 const int task = atomic_fetch_add_explicit(
2306 &args->next_task, 1, memory_order_relaxed);
2307 if (task >= args->total_tasks) break;
2308
2309 int position = task * CK_MOE_Q4K_Q5K_TASK_ROWS;
2310 const int task_end = position + CK_MOE_Q4K_Q5K_TASK_ROWS <
2311 args->bucket_offsets[args->n_experts]
2312 ? position + CK_MOE_Q4K_Q5K_TASK_ROWS
2313 : args->bucket_offsets[args->n_experts];
2315 args->bucket_offsets, args->n_experts, position);
2316
2317 while (position < task_end && expert < args->n_experts) {
2318 const int expert_end = args->bucket_offsets[expert + 1];
2319 const int segment_end = expert_end < task_end
2320 ? expert_end : task_end;
2321 const uint8_t *gate = args->gate_base +
2322 (size_t)expert * args->q4_expert_stride;
2323 const uint8_t *up = args->up_base +
2324 (size_t)expert * args->q4_expert_stride;
2325 const uint8_t *gate_packed = args->gate_packed_base
2326 ? args->gate_packed_base +
2327 (size_t)expert * args->q4_packed_expert_stride
2328 : NULL;
2329 const uint8_t *up_packed = args->up_packed_base
2330 ? args->up_packed_base +
2331 (size_t)expert * args->q4_packed_expert_stride
2332 : NULL;
2333 const uint8_t *down = args->down_base +
2334 (size_t)expert * args->q5_expert_stride;
2335
2336 for (int i = position; i < segment_end; i += 4) {
2337 const int batch_rows = segment_end - i < 4
2338 ? segment_end - i : 4;
2339 const void *hidden_rows[4] = {NULL, NULL, NULL, NULL};
2340 const void *activation_rows[4] = {NULL, NULL, NULL, NULL};
2341 int output_rows[4] = {0, 0, 0, 0};
2342 for (int batch_row = 0; batch_row < batch_rows; ++batch_row) {
2343 const int row = args->bucket_rows[i + batch_row];
2344 output_rows[batch_row] = row;
2345 hidden_rows[batch_row] = args->hidden_q8 +
2346 (size_t)row * args->hidden_q8_row_bytes;
2347 if (gate_packed && up_packed) {
2348 memcpy(
2349 hidden_q8_batch +
2350 (size_t)batch_row * hidden_q8_batch_row_bytes,
2351 hidden_rows[batch_row],
2352 args->hidden_q8_row_bytes);
2353 }
2354 }
2355 for (int batch_row = batch_rows; batch_row < 4; ++batch_row) {
2356 hidden_rows[batch_row] = hidden_rows[0];
2357 }
2358
2359 if (gate_packed && up_packed) {
2360 float *up_rows = gate_up +
2361 4u * (size_t)args->intermediate_dim;
2363 gate_up, gate_packed, hidden_q8_batch,
2364 batch_rows, args->intermediate_dim,
2365 args->hidden_dim);
2367 up_rows, up_packed, hidden_q8_batch,
2368 batch_rows, args->intermediate_dim,
2369 args->hidden_dim);
2371 gate_up, up_rows, gate_up, batch_rows,
2372 args->intermediate_dim);
2373 } else {
2374 const int gate_up_stride = 2 * args->intermediate_dim;
2376 gate_up, gate_up_stride, gate, hidden_rows, batch_rows,
2377 args->intermediate_dim, args->hidden_dim);
2379 gate_up + args->intermediate_dim, gate_up_stride, up,
2380 hidden_rows, batch_rows,
2381 args->intermediate_dim, args->hidden_dim);
2383 gate_up, gate_up, batch_rows, args->intermediate_dim);
2384 }
2385 for (int batch_row = 0; batch_row < batch_rows; ++batch_row) {
2386 void *activation = (uint8_t *)act_q8 +
2387 (size_t)batch_row * act_q8_row_bytes;
2389 gate_up + (size_t)batch_row *
2390 (size_t)args->intermediate_dim,
2391 activation, args->intermediate_dim);
2392 activation_rows[batch_row] = activation;
2393 }
2394 for (int batch_row = batch_rows; batch_row < 4; ++batch_row) {
2395 activation_rows[batch_row] = activation_rows[0];
2396 }
2398 expert_output, args->hidden_dim, down, activation_rows,
2399 batch_rows, args->hidden_dim, args->intermediate_dim);
2400
2401 for (int batch_row = 0; batch_row < batch_rows; ++batch_row) {
2402 const int row = output_rows[batch_row];
2403 const size_t route_index = (size_t)row *
2404 (size_t)args->top_k + (size_t)args->slot;
2405 axpy_f32(
2406 args->output + (size_t)row *
2407 (size_t)args->hidden_dim,
2408 expert_output + (size_t)batch_row *
2409 (size_t)args->hidden_dim,
2410 args->routing_weights[route_index], args->hidden_dim);
2411 }
2412 }
2413 position = segment_end;
2414 ++expert;
2415 }
2416 }
2417}
void gemm_q5_k_q8_k_compact_rows4(float *output, int output_stride, const void *weights, const void *const input_rows[4], int rows, int output_dim, int input_dim)
void gemm_q4_k_q8_k_packed_vnni_x8_compact_order_rows4(float *output, const void *weights_packed, const void *input_q8, int rows, int output_dim, int input_dim)
static int ck_moe_bucket_expert_for_position(const int *offsets, int n_experts, int position)
void gemm_q4_k_q8_k_compact_rows4(float *output, int output_stride, const void *weights, const void *const input_rows[4], int rows, int output_dim, int input_dim)
void swiglu_forward_ggml_split(const float *gate, const float *up, float *output, int tokens, int dim)

References axpy_f32(), CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), ck_moe_bucket_expert_for_position(), CK_MOE_Q4K_Q5K_TASK_ROWS, gemm_q4_k_q8_k_compact_rows4(), gemm_q4_k_q8_k_packed_vnni_x8_compact_order_rows4(), gemm_q5_k_q8_k_compact_rows4(), quantize_row_q8_k(), swiglu_forward_ggml(), and swiglu_forward_ggml_split().

Referenced by ck_moe_swiglu_expert_forward_q4k_q5k_bucketed_impl().

◆ ck_moe_q4k_q5k_parallel_work()

static void ck_moe_q4k_q5k_parallel_work ( int  ith,
int  nth,
void *  opaque 
)
static

Definition at line 1317 of file axpy_kernels.c.

1318{
1319 ck_moe_q4k_q5k_parallel_args_t *args =
1320 (ck_moe_q4k_q5k_parallel_args_t *)opaque;
1321 const int begin = (args->rows * ith) / nth;
1322 const int end = (args->rows * (ith + 1)) / nth;
1323 if (begin >= end) {
1324 args->status[ith] = 0;
1325 return;
1326 }
1328 args->hidden + (size_t)begin * (size_t)args->hidden_dim,
1329 args->indices + (size_t)begin * (size_t)args->top_k,
1330 args->routing_weights + (size_t)begin * (size_t)args->top_k,
1331 args->expert_gate,
1332 args->expert_up,
1333 args->expert_down,
1334 args->output + (size_t)begin * (size_t)args->hidden_dim,
1335 end - begin,
1336 args->hidden_dim,
1337 args->intermediate_dim,
1338 args->n_experts,
1339 args->top_k,
1340 args->workspace + (size_t)ith * args->workspace_stride,
1341 args->workspace_stride);
1342}
int moe_swiglu_expert_forward_q4k_q5k_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)

References end, and moe_swiglu_expert_forward_q4k_q5k_workspace().

Referenced by moe_swiglu_expert_forward_q4k_q5k_parallel_workspace().

◆ ck_moe_q4k_q5k_quantize_work()

static void ck_moe_q4k_q5k_quantize_work ( int  ith,
int  nth,
void *  opaque 
)
static

Definition at line 2225 of file axpy_kernels.c.

2226{
2227 ck_moe_q4k_q5k_quantize_args_t *args =
2228 (ck_moe_q4k_q5k_quantize_args_t *)opaque;
2229 const int begin = (args->rows * ith) / nth;
2230 const int end = (args->rows * (ith + 1)) / nth;
2231 for (int row = begin; row < end; ++row) {
2233 args->hidden + (size_t)row * (size_t)args->hidden_dim,
2234 args->hidden_q8 + (size_t)row * args->hidden_q8_row_bytes,
2235 args->hidden_dim);
2236 }
2237}

References end, and quantize_row_q8_k().

Referenced by ck_moe_swiglu_expert_forward_q4k_q5k_bucketed_impl().

◆ ck_moe_q4k_q5k_route_parallel()

static int ck_moe_q4k_q5k_route_parallel ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes,
size_t  workspace_stride,
ck_threadpool_t *  pool 
)
static

Definition at line 1412 of file axpy_kernels.c.

1428{
1429 if (!pool || top_k <= 1 || top_k > CK_THREADPOOL_MAX_THREADS ||
1430 ck_threadpool_n_threads(pool) < top_k ||
1431 workspace_bytes < workspace_stride * (size_t)top_k) {
1432 return 1;
1433 }
1434
1435 const size_t hidden_q8_bytes = ck_moe_align64(
1436 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim));
1437 void *hidden_q8 = workspace;
1438 quantize_row_q8_k(hidden, hidden_q8, hidden_dim);
1439
1440 ck_moe_q4k_q5k_route_args_t args = {
1441 .indices = indices,
1442 .expert_gate = expert_gate,
1443 .expert_up = expert_up,
1444 .expert_down = expert_down,
1445 .hidden_q8 = hidden_q8,
1446 .workspace = (uint8_t *)workspace,
1447 .workspace_stride = workspace_stride,
1448 .hidden_q8_bytes = hidden_q8_bytes,
1449 .hidden_dim = hidden_dim,
1450 .intermediate_dim = intermediate_dim,
1451 .n_experts = n_experts,
1452 .top_k = top_k,
1453 .expert_output = {0},
1454 .status = {0},
1455 };
1457 pool, top_k, ck_moe_q4k_q5k_route_work, &args);
1458
1459 memset(output, 0, (size_t)hidden_dim * sizeof(float));
1460 for (int slot = 0; slot < top_k; ++slot) {
1461 if (args.status[slot] != 0 || !args.expert_output[slot]) {
1462 return args.status[slot] != 0 ? args.status[slot] : -1;
1463 }
1464 axpy_f32(
1465 output, args.expert_output[slot], routing_weights[slot], hidden_dim);
1466 }
1467 return 0;
1468}
static void ck_moe_q4k_q5k_route_work(int ith, int nth, void *opaque)

References axpy_f32(), CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), ck_moe_q4k_q5k_route_work(), ck_threadpool_dispatch_n(), CK_THREADPOOL_MAX_THREADS, ck_threadpool_n_threads(), and quantize_row_q8_k().

Referenced by moe_swiglu_expert_forward_q4k_q5k_parallel_workspace().

◆ ck_moe_q4k_q5k_route_work()

static void ck_moe_q4k_q5k_route_work ( int  ith,
int  nth,
void *  opaque 
)
static

Definition at line 1361 of file axpy_kernels.c.

1362{
1363 ck_moe_q4k_q5k_route_args_t *args =
1364 (ck_moe_q4k_q5k_route_args_t *)opaque;
1365 if (ith >= nth || ith >= args->top_k) return;
1366
1367 const int expert = args->indices[ith];
1368 if (expert < 0 || expert >= args->n_experts) {
1369 args->status[ith] = -2;
1370 return;
1371 }
1372
1373 const size_t gate_up_bytes = ck_moe_align64(
1374 2u * (size_t)args->intermediate_dim * sizeof(float));
1375 const size_t act_q8_bytes = ck_moe_align64(
1376 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)args->intermediate_dim));
1377 uint8_t *cursor = args->workspace + (size_t)ith * args->workspace_stride;
1378 cursor += args->hidden_q8_bytes;
1379 float *gate_up = (float *)cursor;
1380 cursor += gate_up_bytes;
1381 void *act_q8 = cursor;
1382 cursor += act_q8_bytes;
1383 float *expert_output = (float *)cursor;
1384 args->expert_output[ith] = expert_output;
1385
1386 const size_t q4_row_bytes = ck_dtype_row_bytes(
1387 CK_DT_Q4_K, (size_t)args->hidden_dim);
1388 const size_t q5_row_bytes = ck_dtype_row_bytes(
1389 CK_DT_Q5_K, (size_t)args->intermediate_dim);
1390 const size_t q4_expert_offset =
1391 (size_t)expert * (size_t)args->intermediate_dim * q4_row_bytes;
1392 const size_t q5_expert_offset =
1393 (size_t)expert * (size_t)args->hidden_dim * q5_row_bytes;
1394
1396 gate_up,
1397 (const uint8_t *)args->expert_gate + q4_expert_offset,
1398 args->hidden_q8, args->intermediate_dim, args->hidden_dim);
1400 gate_up + args->intermediate_dim,
1401 (const uint8_t *)args->expert_up + q4_expert_offset,
1402 args->hidden_q8, args->intermediate_dim, args->hidden_dim);
1403 swiglu_forward_ggml(gate_up, gate_up, 1, args->intermediate_dim);
1404 quantize_row_q8_k(gate_up, act_q8, args->intermediate_dim);
1406 expert_output,
1407 (const uint8_t *)args->expert_down + q5_expert_offset,
1408 act_q8, args->hidden_dim, args->intermediate_dim);
1409 args->status[ith] = 0;
1410}
@ CK_DT_Q5_K
void gemv_q5_k_q8_k(float *y, const void *W, const void *x_q8, int M, int K)

References CK_DT_Q4_K, CK_DT_Q5_K, CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), gemv_q4_k_q8_k(), gemv_q5_k_q8_k(), quantize_row_q8_k(), and swiglu_forward_ggml().

Referenced by ck_moe_q4k_q5k_route_parallel().

◆ ck_moe_shared_gated_parallel_workspace()

static int ck_moe_shared_gated_parallel_workspace ( const float *  hidden,
const float *  routed,
const void *  shared_gate,
const void *  shared_up,
const void *  shared_down,
const float *  shared_gate_input,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
void *  workspace,
size_t  workspace_bytes,
size_t  stride,
ck_moe_shared_gated_workspace_fn  serial_fn 
)
static

Definition at line 2897 of file axpy_kernels.c.

2912{
2913 if (!hidden || !shared_gate || !shared_up || !shared_down ||
2914 !shared_gate_input || !output || !workspace || !serial_fn ||
2915 stride == 0 || rows <= 0) {
2916 return -1;
2917 }
2918
2919 ck_threadpool_t *pool = ck_threadpool_global();
2920 int active = pool ? ck_threadpool_n_threads(pool) : 1;
2921 if (active > rows) active = rows;
2923 const size_t workspace_workers = workspace_bytes / stride;
2924 if (workspace_workers == 0) return -1;
2925 if ((size_t)active > workspace_workers) active = (int)workspace_workers;
2926 if (active <= 1) {
2927 return serial_fn(
2928 hidden, routed, shared_gate, shared_up, shared_down,
2929 shared_gate_input, output, rows, hidden_dim, intermediate_dim,
2930 workspace, stride);
2931 }
2932
2933 ck_moe_shared_q8_0_parallel_args_t args = {
2934 .hidden = hidden,
2935 .routed = routed,
2936 .shared_gate = shared_gate,
2937 .shared_up = shared_up,
2938 .shared_down = shared_down,
2939 .shared_gate_input = shared_gate_input,
2940 .output = output,
2941 .rows = rows,
2942 .hidden_dim = hidden_dim,
2943 .intermediate_dim = intermediate_dim,
2944 .workspace = (uint8_t *)workspace,
2945 .workspace_stride = stride,
2946 .serial_fn = serial_fn,
2947 .status = {0},
2948 };
2950 pool, active, ck_moe_shared_q8_0_parallel_work, &args);
2951 for (int ith = 0; ith < active; ++ith) {
2952 if (args.status[ith] != 0) return args.status[ith];
2953 }
2954 return 0;
2955}
static void ck_moe_shared_q8_0_parallel_work(int ith, int nth, void *opaque)

References ck_moe_shared_q8_0_parallel_work(), ck_threadpool_dispatch_n(), ck_threadpool_global(), CK_THREADPOOL_MAX_THREADS, and ck_threadpool_n_threads().

Referenced by moe_swiglu_shared_forward_q8_0_gated_parallel_workspace().

◆ ck_moe_shared_q4k_gated_workspace()

static int ck_moe_shared_q4k_gated_workspace ( const float *  hidden,
const float *  routed,
const void *  shared_gate,
const void *  shared_up,
const void *  shared_down,
const float *  shared_gate_input,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
void *  workspace,
size_t  workspace_bytes,
void(*)(float *, const void *, const void *, int, int)  down_projection 
)
static

Definition at line 2709 of file axpy_kernels.c.

2723{
2725 hidden_dim, intermediate_dim);
2726 if (!hidden || !shared_gate || !shared_up || !shared_down ||
2727 !shared_gate_input || !output || !workspace || required == 0 ||
2728 workspace_bytes < required || rows <= 0) {
2729 return -1;
2730 }
2731
2732 enum { CK_SHARED_Q4K_BATCH_ROWS = 4 };
2733 const size_t hidden_q8_stride =
2734 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim);
2735 const size_t activation_q8_stride =
2736 ck_dtype_row_bytes(CK_DT_Q8_0, (size_t)intermediate_dim);
2737 const size_t hidden_q8_bytes = ck_moe_align64(
2738 CK_SHARED_Q4K_BATCH_ROWS * hidden_q8_stride);
2739 const size_t projection_bytes = ck_moe_align64(
2740 CK_SHARED_Q4K_BATCH_ROWS * (size_t)intermediate_dim * sizeof(float));
2741 const size_t activation_q8_bytes = ck_moe_align64(
2742 CK_SHARED_Q4K_BATCH_ROWS * activation_q8_stride);
2743 uint8_t *cursor = (uint8_t *)workspace;
2744 void *hidden_q8 = cursor;
2745 cursor += hidden_q8_bytes;
2746 float *gate_values = (float *)cursor;
2747 cursor += projection_bytes;
2748 float *up_values = (float *)cursor;
2749 cursor += projection_bytes;
2750 void *activation_q8 = cursor;
2751 cursor += activation_q8_bytes;
2752 float *shared_output = (float *)cursor;
2753
2754 /* llama.cpp evaluates Q4_K prefill projections in complete four-row GEMM
2755 * groups, then uses the GEMV reduction order only for the residual tail.
2756 * Keeping that boundary here matters: tiny per-row reduction differences
2757 * can cross the following Q8_0 activation quantization threshold. */
2758 for (int row0 = 0; row0 < rows; row0 += CK_SHARED_Q4K_BATCH_ROWS) {
2759 int batch_rows = rows - row0;
2760 if (batch_rows > CK_SHARED_Q4K_BATCH_ROWS) {
2761 batch_rows = CK_SHARED_Q4K_BATCH_ROWS;
2762 }
2763 for (int local_row = 0; local_row < batch_rows; ++local_row) {
2764 const float *x = hidden +
2765 (size_t)(row0 + local_row) * (size_t)hidden_dim;
2767 x,
2768 (uint8_t *)hidden_q8 +
2769 (size_t)local_row * hidden_q8_stride,
2770 hidden_dim);
2771 }
2773 hidden_q8, shared_gate, NULL, gate_values,
2774 batch_rows, intermediate_dim, hidden_dim);
2776 hidden_q8, shared_up, NULL, up_values,
2777 batch_rows, intermediate_dim, hidden_dim);
2779 gate_values, up_values, gate_values, batch_rows, intermediate_dim);
2780
2781 for (int local_row = 0; local_row < batch_rows; ++local_row) {
2782 const int row = row0 + local_row;
2783 const float *x = hidden + (size_t)row * (size_t)hidden_dim;
2784 const float *routed_row = routed
2785 ? routed + (size_t)row * (size_t)hidden_dim
2786 : NULL;
2787 float *output_row = output + (size_t)row * (size_t)hidden_dim;
2788 void *activation_q8_row = (uint8_t *)activation_q8 +
2789 (size_t)local_row * activation_q8_stride;
2790 float *shared_output_row = shared_output +
2791 (size_t)local_row * (size_t)hidden_dim;
2792
2794 gate_values + (size_t)local_row * (size_t)intermediate_dim,
2795 activation_q8_row, intermediate_dim);
2796 down_projection(
2797 shared_output_row, shared_down, activation_q8_row,
2798 hidden_dim, intermediate_dim);
2799
2800 float gate_value = 0.0f;
2802 x, shared_gate_input, NULL, &gate_value, 1, 1, hidden_dim);
2803 const float gate_scale = 1.0f / (1.0f + expf(-gate_value));
2804 for (int h = 0; h < hidden_dim; ++h) {
2805 const float routed_value = routed_row ? routed_row[h] : 0.0f;
2806 volatile float gated_shared =
2807 shared_output_row[h] * gate_scale;
2808 output_row[h] = routed_value + gated_shared;
2809 }
2810 }
2811 }
2812 return 0;
2813}
void gemm_nt_q4_k_q8_k_pairwise_split_min_parallel_dispatch(const void *input, const void *weight, const float *bias, float *output, int rows, int output_dim, int input_dim)
size_t moe_swiglu_shared_q4k_q8_0_gated_workspace_bytes(int hidden_dim, int intermediate_dim)
void gemm_nt_f32_llama_production(const float *A, const float *B, const float *bias, float *C, int M, int N, int K)

References CK_DT_Q8_0, CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), gemm_nt_f32_llama_production(), gemm_nt_q4_k_q8_k_pairwise_split_min_parallel_dispatch(), moe_swiglu_shared_q4k_q8_0_gated_workspace_bytes(), quantize_row_q8_0(), quantize_row_q8_k(), and swiglu_forward_ggml_split().

Referenced by moe_swiglu_shared_forward_q4k_q5_0_gated_workspace(), and moe_swiglu_shared_forward_q4k_q8_0_gated_workspace().

◆ ck_moe_shared_q4k_parallel_work()

static void ck_moe_shared_q4k_parallel_work ( int  ith,
int  nth,
void *  opaque 
)
static

Definition at line 1970 of file axpy_kernels.c.

1971{
1972 ck_moe_shared_q4k_parallel_args_t *args =
1973 (ck_moe_shared_q4k_parallel_args_t *)opaque;
1974 const int begin = (args->rows * ith) / nth;
1975 const int end = (args->rows * (ith + 1)) / nth;
1976 if (begin >= end) {
1977 args->status[ith] = 0;
1978 return;
1979 }
1980 args->status[ith] = args->serial_fn(
1981 args->hidden + (size_t)begin * (size_t)args->hidden_dim,
1982 args->routed
1983 ? args->routed + (size_t)begin * (size_t)args->hidden_dim
1984 : NULL,
1985 args->shared_gate,
1986 args->shared_up,
1987 args->shared_down,
1988 args->output + (size_t)begin * (size_t)args->hidden_dim,
1989 end - begin,
1990 args->hidden_dim,
1991 args->intermediate_dim,
1992 args->workspace + (size_t)ith * args->workspace_stride,
1993 args->workspace_stride);
1994}

References end.

Referenced by ck_moe_shared_q4k_parallel_workspace().

◆ ck_moe_shared_q4k_parallel_workspace()

static int ck_moe_shared_q4k_parallel_workspace ( const float *  hidden,
const float *  routed,
const void *  shared_gate,
const void *  shared_up,
const void *  shared_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
void *  workspace,
size_t  workspace_bytes,
ck_moe_shared_workspace_fn  serial_fn 
)
static

Definition at line 1996 of file axpy_kernels.c.

2009{
2010 const size_t stride = moe_swiglu_expert_q4k_q5k_workspace_bytes(
2011 hidden_dim, intermediate_dim);
2012 if (!hidden || !shared_gate || !shared_up || !shared_down || !output ||
2013 !workspace || !serial_fn || stride == 0 || rows <= 0) {
2014 return -1;
2015 }
2016 ck_threadpool_t *pool = ck_threadpool_global();
2017 int active = pool ? ck_threadpool_n_threads(pool) : 1;
2018 if (active > rows) active = rows;
2020 const size_t workspace_workers = workspace_bytes / stride;
2021 if (workspace_workers == 0) return -1;
2022 if ((size_t)active > workspace_workers) active = (int)workspace_workers;
2023 if (active <= 1) {
2024 return serial_fn(
2025 hidden, routed, shared_gate, shared_up, shared_down, output, rows,
2026 hidden_dim, intermediate_dim, workspace, stride);
2027 }
2028
2029 ck_moe_shared_q4k_parallel_args_t args = {
2030 .hidden = hidden,
2031 .routed = routed,
2032 .shared_gate = shared_gate,
2033 .shared_up = shared_up,
2034 .shared_down = shared_down,
2035 .output = output,
2036 .rows = rows,
2037 .hidden_dim = hidden_dim,
2038 .intermediate_dim = intermediate_dim,
2039 .workspace = (uint8_t *)workspace,
2040 .workspace_stride = stride,
2041 .serial_fn = serial_fn,
2042 .status = {0},
2043 };
2045 pool, active, ck_moe_shared_q4k_parallel_work, &args);
2046 for (int ith = 0; ith < active; ++ith) {
2047 if (args.status[ith] != 0) return args.status[ith];
2048 }
2049 return 0;
2050}
static void ck_moe_shared_q4k_parallel_work(int ith, int nth, void *opaque)

References ck_moe_shared_q4k_parallel_work(), ck_threadpool_dispatch_n(), ck_threadpool_global(), CK_THREADPOOL_MAX_THREADS, ck_threadpool_n_threads(), and moe_swiglu_expert_q4k_q5k_workspace_bytes().

Referenced by moe_swiglu_shared_forward_q4k_q4k_parallel_workspace(), and moe_swiglu_shared_forward_q4k_q6k_parallel_workspace().

◆ ck_moe_shared_q8_0_parallel_work()

static void ck_moe_shared_q8_0_parallel_work ( int  ith,
int  nth,
void *  opaque 
)
static

Definition at line 2869 of file axpy_kernels.c.

2870{
2871 ck_moe_shared_q8_0_parallel_args_t *args =
2872 (ck_moe_shared_q8_0_parallel_args_t *)opaque;
2873 const int begin = (args->rows * ith) / nth;
2874 const int end = (args->rows * (ith + 1)) / nth;
2875 if (begin >= end) {
2876 args->status[ith] = 0;
2877 return;
2878 }
2879
2880 args->status[ith] = args->serial_fn(
2881 args->hidden + (size_t)begin * (size_t)args->hidden_dim,
2882 args->routed
2883 ? args->routed + (size_t)begin * (size_t)args->hidden_dim
2884 : NULL,
2885 args->shared_gate,
2886 args->shared_up,
2887 args->shared_down,
2888 args->shared_gate_input,
2889 args->output + (size_t)begin * (size_t)args->hidden_dim,
2890 end - begin,
2891 args->hidden_dim,
2892 args->intermediate_dim,
2893 args->workspace + (size_t)ith * args->workspace_stride,
2894 args->workspace_stride);
2895}

References end.

Referenced by ck_moe_shared_gated_parallel_workspace().

◆ ck_moe_sigmoid_f32()

static float ck_moe_sigmoid_f32 ( float  x)
inlinestatic

Definition at line 429 of file axpy_kernels.c.

430{
431 return 1.0f / (1.0f + expf(-x));
432}

Referenced by ck_moe_dsilu_f32(), ck_moe_silu_f32(), and moe_swiglu_shared_forward_bf16_gated_row_range().

◆ ck_moe_silu_f32()

◆ ck_moe_size_add()

static int ck_moe_size_add ( size_t  a,
size_t  b,
size_t *  result 
)
static

Definition at line 2102 of file axpy_kernels.c.

2103{
2104 if (!result || a > SIZE_MAX - b) return -1;
2105 *result = a + b;
2106 return 0;
2107}

Referenced by ck_moe_bucket_layout().

◆ ck_moe_size_mul()

static int ck_moe_size_mul ( size_t  a,
size_t  b,
size_t *  result 
)
static

Definition at line 2109 of file axpy_kernels.c.

2110{
2111 if (!result || (a != 0 && b > SIZE_MAX / a)) return -1;
2112 *result = a * b;
2113 return 0;
2114}

Referenced by ck_moe_bucket_layout().

◆ ck_moe_swiglu_expert_forward_q4k_q5k_bucketed_impl()

static int ck_moe_swiglu_expert_forward_q4k_q5k_bucketed_impl ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
const void *  expert_gate_packed,
const void *  expert_up_packed,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)
static

Definition at line 2419 of file axpy_kernels.c.

2436{
2437 ck_moe_q4k_q5k_bucket_layout_t layout;
2438 if (!hidden || !indices || !routing_weights || !expert_gate || !expert_up ||
2439 !expert_down || !output || !workspace ||
2440 ((expert_gate_packed == NULL) != (expert_up_packed == NULL)) ||
2441 ck_moe_bucket_layout(rows, hidden_dim, intermediate_dim, n_experts,
2442 top_k, &layout) != 0 ||
2443 workspace_bytes < layout.total_bytes) {
2444 return -1;
2445 }
2446
2447 uint8_t *base = (uint8_t *)workspace;
2448 uint8_t *hidden_q8 = base + layout.hidden_q8_offset;
2449 int *route_rows = (int *)(base + layout.route_rows_offset);
2450 int *slot_offsets = (int *)(base + layout.slot_offsets_offset);
2451 int *counts = (int *)(base + layout.counts_offset);
2452 int *cursors = (int *)(base + layout.cursors_offset);
2453 uint8_t *workers = base + layout.workers_offset;
2454
2455 for (int slot = 0; slot < top_k; ++slot) {
2456 memset(counts, 0, (size_t)n_experts * sizeof(*counts));
2457 for (int row = 0; row < rows; ++row) {
2458 const int expert = indices[(size_t)row * (size_t)top_k +
2459 (size_t)slot];
2460 if (expert < 0 || expert >= n_experts) return -2;
2461 counts[expert] += 1;
2462 }
2463
2464 int *offsets = slot_offsets + (size_t)slot * ((size_t)n_experts + 1u);
2465 offsets[0] = 0;
2466 for (int expert = 0; expert < n_experts; ++expert) {
2467 offsets[expert + 1] = offsets[expert] + counts[expert];
2468 cursors[expert] = offsets[expert];
2469 }
2470 int *rows_for_slot = route_rows + (size_t)slot * (size_t)rows;
2471 for (int row = 0; row < rows; ++row) {
2472 const int expert = indices[(size_t)row * (size_t)top_k +
2473 (size_t)slot];
2474 rows_for_slot[cursors[expert]++] = row;
2475 }
2476 }
2477
2478 memset(output, 0, (size_t)rows * (size_t)hidden_dim * sizeof(float));
2479 ck_threadpool_t *pool = ck_threadpool_global();
2480 int active = pool ? ck_threadpool_n_threads(pool) : 1;
2481 if (active > rows) active = rows;
2483 if (active < 1) active = 1;
2484
2485 ck_moe_q4k_q5k_quantize_args_t quantize_args = {
2486 .hidden = hidden,
2487 .hidden_q8 = hidden_q8,
2488 .rows = rows,
2489 .hidden_dim = hidden_dim,
2490 .hidden_q8_row_bytes = layout.hidden_q8_row_bytes,
2491 };
2492 if (active > 1 && pool) {
2494 pool, active, ck_moe_q4k_q5k_quantize_work, &quantize_args);
2495 } else {
2496 ck_moe_q4k_q5k_quantize_work(0, 1, &quantize_args);
2497 }
2498
2499 const size_t q4_expert_stride = (size_t)intermediate_dim *
2500 ck_dtype_row_bytes(CK_DT_Q4_K, (size_t)hidden_dim);
2501 const size_t q4_packed_expert_stride =
2502 (size_t)((intermediate_dim + 7) / 8) *
2503 (size_t)(hidden_dim / 256) * q4_k_packed_vnni_x8_block_size();
2504 const size_t q5_expert_stride = (size_t)hidden_dim *
2505 ck_dtype_row_bytes(CK_DT_Q5_K, (size_t)intermediate_dim);
2506 for (int slot = 0; slot < top_k; ++slot) {
2507 ck_moe_q4k_q5k_bucket_work_t args = {
2508 .bucket_rows = route_rows + (size_t)slot * (size_t)rows,
2509 .bucket_offsets = slot_offsets +
2510 (size_t)slot * ((size_t)n_experts + 1u),
2511 .routing_weights = routing_weights,
2512 .hidden_q8 = hidden_q8,
2513 .gate_base = (const uint8_t *)expert_gate,
2514 .up_base = (const uint8_t *)expert_up,
2515 .gate_packed_base = (const uint8_t *)expert_gate_packed,
2516 .up_packed_base = (const uint8_t *)expert_up_packed,
2517 .down_base = (const uint8_t *)expert_down,
2518 .output = output,
2519 .workers = workers,
2520 .worker_stride = layout.worker_stride,
2521 .hidden_q8_row_bytes = layout.hidden_q8_row_bytes,
2522 .q4_expert_stride = q4_expert_stride,
2523 .q4_packed_expert_stride = q4_packed_expert_stride,
2524 .q5_expert_stride = q5_expert_stride,
2525 .hidden_dim = hidden_dim,
2526 .intermediate_dim = intermediate_dim,
2527 .n_experts = n_experts,
2528 .top_k = top_k,
2529 .slot = slot,
2530 .total_tasks = (rows + CK_MOE_Q4K_Q5K_TASK_ROWS - 1) /
2532 };
2533 atomic_init(&args.next_task, 0);
2534 int task_threads = active;
2535 if (task_threads > args.total_tasks) task_threads = args.total_tasks;
2536 if (active > 1 && pool) {
2538 pool, task_threads, ck_moe_q4k_q5k_bucket_work, &args);
2539 } else {
2540 ck_moe_q4k_q5k_bucket_work(0, 1, &args);
2541 }
2542 }
2543 return 0;
2544}
size_t q4_k_packed_vnni_x8_block_size(void)
static void ck_moe_q4k_q5k_bucket_work(int ith, int nth, void *opaque)
static void ck_moe_q4k_q5k_quantize_work(int ith, int nth, void *opaque)
static int ck_moe_bucket_layout(int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, ck_moe_q4k_q5k_bucket_layout_t *layout)

References CK_DT_Q4_K, CK_DT_Q5_K, ck_dtype_row_bytes(), ck_moe_bucket_layout(), ck_moe_q4k_q5k_bucket_work(), ck_moe_q4k_q5k_quantize_work(), CK_MOE_Q4K_Q5K_TASK_ROWS, ck_threadpool_dispatch_n(), ck_threadpool_global(), CK_THREADPOOL_MAX_THREADS, ck_threadpool_n_threads(), offsets, and q4_k_packed_vnni_x8_block_size().

Referenced by moe_swiglu_expert_forward_q4k_q5k_bucketed_prepared_workspace(), and moe_swiglu_expert_forward_q4k_q5k_bucketed_workspace().

◆ ck_moe_up_idx()

static size_t ck_moe_up_idx ( int  e,
int  i,
int  h,
int  intermediate_dim,
int  hidden_dim 
)
inlinestatic

Definition at line 323 of file axpy_kernels.c.

324{
325 return ((size_t)e * (size_t)intermediate_dim + (size_t)i) * (size_t)hidden_dim + (size_t)h;
326}

Referenced by moe_relu2_expert_backward_f32(), moe_relu2_expert_forward_f32(), moe_swiglu_expert_backward_f32(), moe_swiglu_expert_forward_bf16_row_range(), and moe_swiglu_expert_forward_f32().

◆ farskip_swiglu_shared_combine_bf16()

void farskip_swiglu_shared_combine_bf16 ( const float *  hidden,
const float *  routed,
const float *  post_attn_residual,
const uint16_t *  shared_gate,
const uint16_t *  shared_up,
const uint16_t *  shared_down,
float *  main_output,
float *  routed_free_output,
int  rows,
int  hidden_dim,
int  intermediate_dim 
)

Definition at line 3381 of file axpy_kernels.c.

3392{
3393 if (rows <= 0) return;
3395 hidden, routed, post_attn_residual, shared_gate, shared_up, shared_down,
3396 main_output, routed_free_output, rows, hidden_dim, intermediate_dim,
3397 0, rows);
3398}
void farskip_swiglu_shared_combine_bf16_row_range(const float *hidden, const float *routed, const float *post_attn_residual, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, float *main_output, float *routed_free_output, int rows, int hidden_dim, int intermediate_dim, int row_begin, int row_end)

References farskip_swiglu_shared_combine_bf16_row_range().

◆ farskip_swiglu_shared_combine_bf16_row_range()

void farskip_swiglu_shared_combine_bf16_row_range ( const float *  hidden,
const float *  routed,
const float *  post_attn_residual,
const uint16_t *  shared_gate,
const uint16_t *  shared_up,
const uint16_t *  shared_down,
float *  main_output,
float *  routed_free_output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  row_begin,
int  row_end 
)

Definition at line 3328 of file axpy_kernels.c.

3342{
3343 if (!hidden || !routed || !post_attn_residual || !shared_gate || !shared_up ||
3344 !shared_down || !main_output || !routed_free_output || rows <= 0 ||
3345 hidden_dim <= 0 || intermediate_dim <= 0 || row_begin < 0 ||
3346 row_begin >= row_end || row_end > rows) {
3347 return;
3348 }
3349
3350 float act[intermediate_dim];
3351
3352 for (int r = row_begin; r < row_end; ++r) {
3353 const float *x = hidden + (size_t)r * (size_t)hidden_dim;
3354 const float *route = routed + (size_t)r * (size_t)hidden_dim;
3355 const float *residual = post_attn_residual + (size_t)r * (size_t)hidden_dim;
3356 float *main = main_output + (size_t)r * (size_t)hidden_dim;
3357 float *routed_free = routed_free_output + (size_t)r * (size_t)hidden_dim;
3358
3359 for (int i = 0; i < intermediate_dim; ++i) {
3360 float gv = 0.0f;
3361 float uv = 0.0f;
3362 for (int h = 0; h < hidden_dim; ++h) {
3363 gv += bf16_to_float(shared_gate[(size_t)i * (size_t)hidden_dim + (size_t)h]) * x[h];
3364 uv += bf16_to_float(shared_up[(size_t)i * (size_t)hidden_dim + (size_t)h]) * x[h];
3365 }
3366 act[i] = ck_moe_silu_f32(gv) * uv;
3367 }
3368
3369 for (int h = 0; h < hidden_dim; ++h) {
3370 float shared = 0.0f;
3371 for (int i = 0; i < intermediate_dim; ++i) {
3372 shared += bf16_to_float(shared_down[(size_t)h * (size_t)intermediate_dim + (size_t)i]) * act[i];
3373 }
3374 const float mlp_output = route[h] + shared;
3375 routed_free[h] = residual[h] + shared;
3376 main[h] = residual[h] + mlp_output;
3377 }
3378 }
3379}
static float ck_moe_silu_f32(float x)
int main(int argc, char **argv)
Definition ck_cli_v5.c:110

References bf16_to_float(), ck_moe_silu_f32(), and main().

Referenced by farskip_swiglu_shared_combine_bf16().

◆ gemm_nt_q4_k_packed_meta_x8_q8_k_gemv_order()

void gemm_nt_q4_k_packed_meta_x8_q8_k_gemv_order ( const void *  input,
const void *  packed_weight,
const float *  bias,
float *  output,
int  rows,
int  output_dim,
int  input_dim 
)

Definition at line 2055 of file gemm_kernels_q4k_q8k_vnni.c.

2058{
2059 if (!A_q8 || !B_packed_x8 || !C || M <= 0 || N <= 0 || K <= 0 || (K % QK_K) != 0) {
2060 return;
2061 }
2062 const block_q8_K *A = (const block_q8_K *)A_q8;
2063 const block_q4_K_packed_meta_x8 *W = (const block_q4_K_packed_meta_x8 *)B_packed_x8;
2064 const int blocks_per_row = K / QK_K;
2065 const int groups = (N + 7) / 8;
2066 for (int m = 0; m < M; ++m) {
2067 const block_q8_K *a_row = A + (size_t)m * (size_t)blocks_per_row;
2068 float *c_row = C + (size_t)m * (size_t)N;
2069 for (int g = 0; g < groups; ++g) {
2070 const int n0 = g * 8;
2071 const int active = (n0 + 8 <= N) ? 8 : (N - n0);
2072 float acc[8] = {0};
2073 float acc_min[8] = {0};
2074 for (int b = 0; b < blocks_per_row; ++b) {
2075 const block_q4_K_packed_meta_x8 *w_group =
2076 W + (size_t)g * (size_t)blocks_per_row + (size_t)b;
2078 acc, acc_min, w_group, active, &a_row[b]);
2079 }
2080 float values[8];
2081#if defined(__AVX2__)
2082 _mm256_storeu_ps(values, _mm256_sub_ps(
2083 _mm256_loadu_ps(acc), _mm256_loadu_ps(acc_min)));
2084#else
2085 for (int lane = 0; lane < active; ++lane) values[lane] = acc[lane] - acc_min[lane];
2086#endif
2087 for (int lane = 0; lane < active; ++lane) {
2088 c_row[n0 + lane] = values[lane] + (bias ? bias[n0 + lane] : 0.0f);
2089 }
2090 }
2091 }
2092}
#define QK_K
static void accum_q4_k_packed_meta_x8_q8_k_gemv_block(float acc[8], float acc_min[8], const block_q4_K_packed_meta_x8 *w, int active, const block_q8_K *x)
#define C(color)
Definition show_config.c:39

References accum_q4_k_packed_meta_x8_q8_k_gemv_block(), C, and QK_K.

Referenced by ck_moe_q4k_llama_projection().

◆ gemm_nt_q4_k_q8_k_pairwise_split_min_parallel_dispatch()

void gemm_nt_q4_k_q8_k_pairwise_split_min_parallel_dispatch ( const void *  input,
const void *  weight,
const float *  bias,
float *  output,
int  rows,
int  output_dim,
int  input_dim 
)

◆ gemm_q4_k_q8_k_compact_rows4()

void gemm_q4_k_q8_k_compact_rows4 ( float *  output,
int  output_stride,
const void *  weights,
const void *const  input_rows[4],
int  rows,
int  output_dim,
int  input_dim 
)

Definition at line 3615 of file gemm_kernels_q4k_q8k_vnni.c.

3622{
3623 if (!output || !weights || !input_rows || rows <= 0 || rows > 4 ||
3624 output_stride < output_dim || output_dim <= 0 || input_dim <= 0 ||
3625 (input_dim % QK_K) != 0) {
3626 return;
3627 }
3628 for (int row = 0; row < rows; ++row) {
3629 if (!input_rows[row]) return;
3630 }
3631
3632#if defined(__AVX512VNNI__) && defined(__AVX512VL__)
3633 const block_q4_K *blocks = (const block_q4_K *)weights;
3634 const int blocks_per_row = input_dim / QK_K;
3635 const block_q8_K *inputs[4] = {
3636 (const block_q8_K *)input_rows[0],
3637 (const block_q8_K *)input_rows[rows > 1 ? 1 : 0],
3638 (const block_q8_K *)input_rows[rows > 2 ? 2 : 0],
3639 (const block_q8_K *)input_rows[rows > 3 ? 3 : 0],
3640 };
3641 for (int n = 0; n < output_dim; ++n) {
3642 const block_q4_K *weight_row =
3643 blocks + (size_t)n * (size_t)blocks_per_row;
3644 float sums[4] = {0.0f, 0.0f, 0.0f, 0.0f};
3645 for (int block = 0; block < blocks_per_row; ++block) {
3646 const block_q8_K *block_rows[4] = {
3647 &inputs[0][block], &inputs[1][block],
3648 &inputs[2][block], &inputs[3][block],
3649 };
3650 float block_sums[4];
3651 dot_q4_k_q8_k_vnni_block_rows4(
3652 &weight_row[block], block_rows, rows, block_sums);
3653 for (int row = 0; row < rows; ++row) {
3654 sums[row] += block_sums[row];
3655 }
3656 }
3657 for (int row = 0; row < rows; ++row) {
3658 output[(size_t)row * (size_t)output_stride + (size_t)n] = sums[row];
3659 }
3660 }
3661#else
3662 for (int row = 0; row < rows; ++row) {
3664 output + (size_t)row * (size_t)output_stride,
3665 weights, input_rows[row], output_dim, input_dim);
3666 }
3667#endif
3668}

References gemv_q4_k_q8_k(), and QK_K.

Referenced by ck_moe_q4k_q5k_bucket_work().

◆ gemm_q4_k_q8_k_packed_vnni_x8_compact_order_rows4()

void gemm_q4_k_q8_k_packed_vnni_x8_compact_order_rows4 ( float *  output,
const void *  weights_packed,
const void *  input_q8,
int  rows,
int  output_dim,
int  input_dim 
)

Definition at line 1123 of file gemm_kernels_q4k_q8k_vnni.c.

1130{
1131 if (!output || !weights_packed || !input_q8 || rows <= 0 || rows > 4 ||
1132 output_dim <= 0 || input_dim <= 0 || (input_dim % QK_K) != 0) {
1133 return;
1134 }
1135#if defined(CK_HAS_AVX_VNNI_256)
1136 const block_q8_K *input = (const block_q8_K *)input_q8;
1137 const block_q4_K_packed_vnni_x8 *weights =
1138 (const block_q4_K_packed_vnni_x8 *)weights_packed;
1139 const int blocks_per_row = input_dim / QK_K;
1140 const int groups = (output_dim + 7) / 8;
1141 for (int group = 0; group < groups; ++group) {
1142 const int n0 = group * 8;
1143 const int active = n0 + 8 <= output_dim ? 8 : output_dim - n0;
1144 float acc[4][8] = {{0}};
1145 for (int block = 0; block < blocks_per_row; ++block) {
1146 float block_sums[4][8] = {{0}};
1147 const block_q8_K *input_rows[4] = {NULL, NULL, NULL, NULL};
1148 for (int row = 0; row < rows; ++row) {
1149 input_rows[row] = input +
1150 (size_t)row * (size_t)blocks_per_row + (size_t)block;
1151 }
1153 block_sums,
1154 weights + (size_t)group * (size_t)blocks_per_row +
1155 (size_t)block,
1156 input_rows,
1157 rows);
1158 for (int row = 0; row < rows; ++row) {
1159 const __m256 prior = _mm256_loadu_ps(acc[row]);
1160 const __m256 current = _mm256_loadu_ps(block_sums[row]);
1161 _mm256_storeu_ps(acc[row], _mm256_add_ps(prior, current));
1162 }
1163 }
1164 for (int row = 0; row < rows; ++row) {
1165 for (int lane = 0; lane < active; ++lane) {
1166 output[(size_t)row * (size_t)output_dim +
1167 (size_t)n0 + (size_t)lane] = acc[row][lane];
1168 }
1169 }
1170 }
1171#else
1172 (void)rows;
1173 (void)output_dim;
1174 (void)input_dim;
1175#endif
1176}
static void dot_q4_k_packed_vnni_x8_q8_k_compact_order(float block_sums[4][8], const block_q4_K_packed_vnni_x8 *w, const block_q8_K *x[4], int rows)

References dot_q4_k_packed_vnni_x8_q8_k_compact_order(), and QK_K.

Referenced by ck_moe_q4k_q5k_bucket_work().

◆ gemm_q5_k_q8_k_compact_rows4()

void gemm_q5_k_q8_k_compact_rows4 ( float *  output,
int  output_stride,
const void *  weights,
const void *const  input_rows[4],
int  rows,
int  output_dim,
int  input_dim 
)

Definition at line 937 of file gemm_kernels_q5_k.c.

944{
945 if (!output || !weights || !input_rows || rows <= 0 || rows > 4 ||
946 output_stride < output_dim || output_dim <= 0 || input_dim <= 0 ||
947 (input_dim % QK_K) != 0) {
948 return;
949 }
950 for (int row = 0; row < rows; ++row) {
951 if (!input_rows[row]) return;
952 }
953
954#if defined(__AVX2__)
955 const block_q5_K *blocks = (const block_q5_K *)weights;
956 const int blocks_per_row = input_dim / QK_K;
957 const block_q8_K *inputs[4] = {
958 (const block_q8_K *)input_rows[0],
959 (const block_q8_K *)input_rows[rows > 1 ? 1 : 0],
960 (const block_q8_K *)input_rows[rows > 2 ? 2 : 0],
961 (const block_q8_K *)input_rows[rows > 3 ? 3 : 0],
962 };
963 for (int n = 0; n < output_dim; ++n) {
964 float values[4];
965 dot_q5_k_q8_k_rows4_avx2(
966 blocks + (size_t)n * (size_t)blocks_per_row,
967 inputs, rows, blocks_per_row, values);
968 for (int row = 0; row < rows; ++row) {
969 output[(size_t)row * (size_t)output_stride + (size_t)n] =
970 values[row];
971 }
972 }
973#else
974 for (int row = 0; row < rows; ++row) {
976 output + (size_t)row * (size_t)output_stride,
977 weights, input_rows[row], output_dim, input_dim);
978 }
979#endif
980}
void gemv_q5_k_q8_k(float *y, const void *W, const void *x_q8, int M, int K)
#define QK_K

References gemv_q5_k_q8_k(), and QK_K.

Referenced by ck_moe_q4k_q5k_bucket_work().

◆ moe_accumulate_expert_f32()

void moe_accumulate_expert_f32 ( float *  output,
const float *  expert_output,
float  routing_weight,
int  hidden_dim 
)

Accumulate expert output: output += routing_weight * expert_output.

Parameters
outputToken output buffer [hidden_dim], accumulated in place
expert_outputExpert's output for this token [hidden_dim]
routing_weightSoftmax routing weight for this expert
hidden_dimHidden dimension

Definition at line 307 of file axpy_kernels.c.

311{
312 axpy_f32(output, expert_output, routing_weight, hidden_dim);
313}

References axpy_f32().

◆ moe_relu2_expert_backward_f32()

void moe_relu2_expert_backward_f32 ( const float *  d_output,
const float *  hidden,
const int *  indices,
const float *  routing_weights,
const float *  expert_up,
const float *  expert_down,
float *  d_hidden,
float *  d_routing_weights,
float *  d_expert_up,
float *  d_expert_down,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k 
)

Definition at line 3706 of file axpy_kernels.c.

3721{
3722 if (!d_output || !hidden || !indices || !routing_weights || !expert_up || !expert_down ||
3723 !d_hidden || !d_routing_weights || !d_expert_up || !d_expert_down ||
3724 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
3725 return;
3726 }
3727
3728 for (size_t p = 0; p < (size_t)rows * (size_t)hidden_dim; ++p) d_hidden[p] = 0.0f;
3729 for (size_t p = 0; p < (size_t)rows * (size_t)top_k; ++p) d_routing_weights[p] = 0.0f;
3730 for (size_t p = 0; p < (size_t)n_experts * (size_t)intermediate_dim * (size_t)hidden_dim; ++p) d_expert_up[p] = 0.0f;
3731 for (size_t p = 0; p < (size_t)n_experts * (size_t)hidden_dim * (size_t)intermediate_dim; ++p) d_expert_down[p] = 0.0f;
3732
3733 float pre[intermediate_dim];
3734 float act[intermediate_dim];
3735 float d_act[intermediate_dim];
3736 float d_pre[intermediate_dim];
3737 float expert_out[hidden_dim];
3738
3739 for (int r = 0; r < rows; ++r) {
3740 const float *x = hidden + (size_t)r * (size_t)hidden_dim;
3741 const float *dy = d_output + (size_t)r * (size_t)hidden_dim;
3742 float *dx = d_hidden + (size_t)r * (size_t)hidden_dim;
3743
3744 for (int slot = 0; slot < top_k; ++slot) {
3745 const int e = indices[(size_t)r * (size_t)top_k + (size_t)slot];
3746 if (e < 0 || e >= n_experts) continue;
3747 const float route_w = routing_weights[(size_t)r * (size_t)top_k + (size_t)slot];
3748
3749 for (int i = 0; i < intermediate_dim; ++i) {
3750 float v = 0.0f;
3751 for (int h = 0; h < hidden_dim; ++h) {
3752 v += expert_up[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] * x[h];
3753 }
3754 pre[i] = v;
3755 act[i] = (v > 0.0f) ? v * v : 0.0f;
3756 d_act[i] = 0.0f;
3757 }
3758
3759 for (int h = 0; h < hidden_dim; ++h) {
3760 float v = 0.0f;
3761 for (int i = 0; i < intermediate_dim; ++i) {
3762 v += expert_down[ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)] * act[i];
3763 }
3764 expert_out[h] = v;
3765 }
3766
3767 float d_route = 0.0f;
3768 for (int h = 0; h < hidden_dim; ++h) {
3769 const float d_expert_out = dy[h] * route_w;
3770 d_route += dy[h] * expert_out[h];
3771 for (int i = 0; i < intermediate_dim; ++i) {
3772 d_expert_down[ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)] += d_expert_out * act[i];
3773 d_act[i] += d_expert_out * expert_down[ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)];
3774 }
3775 }
3776 d_routing_weights[(size_t)r * (size_t)top_k + (size_t)slot] += d_route;
3777
3778 for (int i = 0; i < intermediate_dim; ++i) {
3779 d_pre[i] = (pre[i] > 0.0f) ? d_act[i] * 2.0f * pre[i] : 0.0f;
3780 }
3781
3782 for (int i = 0; i < intermediate_dim; ++i) {
3783 const float dpi = d_pre[i];
3784 for (int h = 0; h < hidden_dim; ++h) {
3785 d_expert_up[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] += dpi * x[h];
3786 dx[h] += dpi * expert_up[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)];
3787 }
3788 }
3789 }
3790 }
3791}
static size_t ck_moe_up_idx(int e, int i, int h, int intermediate_dim, int hidden_dim)
static size_t ck_moe_down_idx(int e, int h, int i, int hidden_dim, int intermediate_dim)

References ck_moe_down_idx(), and ck_moe_up_idx().

◆ moe_relu2_expert_forward_f32()

void moe_relu2_expert_forward_f32 ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const float *  expert_up,
const float *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k 
)

Definition at line 374 of file axpy_kernels.c.

385{
386 if (!hidden || !indices || !routing_weights || !expert_up || !expert_down || !output ||
387 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
388 return;
389 }
390
391 const size_t out_count = (size_t)rows * (size_t)hidden_dim;
392 for (size_t p = 0; p < out_count; ++p) output[p] = 0.0f;
393
394 float pre[intermediate_dim];
395 float gate[intermediate_dim];
396 float up[intermediate_dim];
397 float act[intermediate_dim];
398
399 for (int r = 0; r < rows; ++r) {
400 const float *x = hidden + (size_t)r * (size_t)hidden_dim;
401 float *y = output + (size_t)r * (size_t)hidden_dim;
402 for (int slot = 0; slot < top_k; ++slot) {
403 const int e = indices[(size_t)r * (size_t)top_k + (size_t)slot];
404 if (e < 0 || e >= n_experts) continue;
405 const float route_w = routing_weights[(size_t)r * (size_t)top_k + (size_t)slot];
406
407 for (int i = 0; i < intermediate_dim; ++i) {
408 float v = 0.0f;
409 for (int h = 0; h < hidden_dim; ++h) {
410 v += expert_up[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] * x[h];
411 }
412 pre[i] = v;
413 act[i] = (v > 0.0f) ? v * v : 0.0f;
414 }
415
416 for (int h = 0; h < hidden_dim; ++h) {
417 float v = 0.0f;
418 for (int i = 0; i < intermediate_dim; ++i) {
419 v += expert_down[ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)] * act[i];
420 }
421 y[h] += route_w * v;
422 }
423 }
424 }
425}

References ck_moe_down_idx(), and ck_moe_up_idx().

◆ moe_relu2_expert_forward_q5_0_q5_0()

void moe_relu2_expert_forward_q5_0_q5_0 ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k 
)

Definition at line 3557 of file axpy_kernels.c.

3568{
3569 if (!hidden || !indices || !routing_weights || !expert_up || !expert_down || !output ||
3570 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
3571 return;
3572 }
3573
3574 const size_t out_count = (size_t)rows * (size_t)hidden_dim;
3575 for (size_t p = 0; p < out_count; ++p) output[p] = 0.0f;
3576
3577 const size_t up_row_bytes = ck_dtype_row_bytes(CK_DT_Q5_0, (size_t)hidden_dim);
3578 const size_t down_row_bytes = ck_dtype_row_bytes(CK_DT_Q5_0, (size_t)intermediate_dim);
3579 const uint8_t *up_base = (const uint8_t *)expert_up;
3580 const uint8_t *down_base = (const uint8_t *)expert_down;
3581
3582 float up_row[hidden_dim];
3583 float down_row[intermediate_dim];
3584 float act[intermediate_dim];
3585
3586 for (int r = 0; r < rows; ++r) {
3587 const float *x = hidden + (size_t)r * (size_t)hidden_dim;
3588 float *y = output + (size_t)r * (size_t)hidden_dim;
3589 if (ck_moe_debug_enabled() && r == 0) {
3590 fprintf(stderr,
3591 "[CK_DEBUG_MOE] routed_q5q5 rows=%d hidden=%d intermediate=%d experts=%d top_k=%d up_row_bytes=%zu down_row_bytes=%zu\n",
3592 rows,
3593 hidden_dim,
3594 intermediate_dim,
3595 n_experts,
3596 top_k,
3597 up_row_bytes,
3598 down_row_bytes);
3599 fprintf(stderr, "[CK_DEBUG_MOE] routed slots:");
3600 for (int dbg_slot = 0; dbg_slot < top_k; ++dbg_slot) {
3601 fprintf(stderr,
3602 " (%d,%g)",
3603 indices[(size_t)r * (size_t)top_k + (size_t)dbg_slot],
3604 routing_weights[(size_t)r * (size_t)top_k + (size_t)dbg_slot]);
3605 }
3606 fprintf(stderr, "\n");
3607 ck_moe_debug_finite("routed.hidden[0]", x, (size_t)hidden_dim);
3608 ck_moe_debug_finite("routed.hidden_all", hidden, (size_t)rows * (size_t)hidden_dim);
3609 }
3610 for (int slot = 0; slot < top_k; ++slot) {
3611 const int e = indices[(size_t)r * (size_t)top_k + (size_t)slot];
3612 if (e < 0 || e >= n_experts) continue;
3613 const float route_w = routing_weights[(size_t)r * (size_t)top_k + (size_t)slot];
3614 const uint8_t *expert_up_base = up_base + (size_t)e * (size_t)intermediate_dim * up_row_bytes;
3615 const uint8_t *expert_down_base = down_base + (size_t)e * (size_t)hidden_dim * down_row_bytes;
3616
3617 for (int i = 0; i < intermediate_dim; ++i) {
3618 dequant_q5_0_row(expert_up_base + (size_t)i * up_row_bytes, up_row, (size_t)hidden_dim);
3619 float v = 0.0f;
3620 for (int h = 0; h < hidden_dim; ++h) v += up_row[h] * x[h];
3621 act[i] = (v > 0.0f) ? v * v : 0.0f;
3622 }
3623
3624 for (int h = 0; h < hidden_dim; ++h) {
3625 dequant_q5_0_row(expert_down_base + (size_t)h * down_row_bytes, down_row, (size_t)intermediate_dim);
3626 float v = 0.0f;
3627 for (int i = 0; i < intermediate_dim; ++i) v += down_row[i] * act[i];
3628 y[h] += route_w * v;
3629 }
3630 }
3631 if (ck_moe_debug_enabled() && r == 0) {
3632 ck_moe_debug_finite("routed.output[0]", y, (size_t)hidden_dim);
3633 ck_moe_debug_finite("routed.output_all", output, (size_t)rows * (size_t)hidden_dim);
3634 }
3635 }
3636}
static void ck_moe_debug_finite(const char *name, const float *x, size_t n)
void dequant_q5_0_row(const void *src, float *dst, size_t n_elements)
Dequantize Q5_0 row (multiple blocks)

References CK_DT_Q5_0, ck_dtype_row_bytes(), ck_moe_debug_enabled(), ck_moe_debug_finite(), and dequant_q5_0_row().

◆ moe_relu2_expert_forward_q5_0_q8_0()

void moe_relu2_expert_forward_q5_0_q8_0 ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k 
)

Definition at line 3475 of file axpy_kernels.c.

3486{
3487 if (!hidden || !indices || !routing_weights || !expert_up || !expert_down || !output ||
3488 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
3489 return;
3490 }
3491
3492 const size_t out_count = (size_t)rows * (size_t)hidden_dim;
3493 for (size_t p = 0; p < out_count; ++p) output[p] = 0.0f;
3494
3495 const size_t up_row_bytes = ck_dtype_row_bytes(CK_DT_Q5_0, (size_t)hidden_dim);
3496 const size_t down_row_bytes = ck_dtype_row_bytes(CK_DT_Q8_0, (size_t)intermediate_dim);
3497 const uint8_t *up_base = (const uint8_t *)expert_up;
3498 const uint8_t *down_base = (const uint8_t *)expert_down;
3499
3500 float up_row[hidden_dim];
3501 float down_row[intermediate_dim];
3502 float act[intermediate_dim];
3503
3504 for (int r = 0; r < rows; ++r) {
3505 const float *x = hidden + (size_t)r * (size_t)hidden_dim;
3506 float *y = output + (size_t)r * (size_t)hidden_dim;
3507 if (ck_moe_debug_enabled() && r == 0) {
3508 fprintf(stderr,
3509 "[CK_DEBUG_MOE] routed_q5q8 rows=%d hidden=%d intermediate=%d experts=%d top_k=%d up_row_bytes=%zu down_row_bytes=%zu\n",
3510 rows,
3511 hidden_dim,
3512 intermediate_dim,
3513 n_experts,
3514 top_k,
3515 up_row_bytes,
3516 down_row_bytes);
3517 fprintf(stderr, "[CK_DEBUG_MOE] routed slots:");
3518 for (int dbg_slot = 0; dbg_slot < top_k; ++dbg_slot) {
3519 fprintf(stderr,
3520 " (%d,%g)",
3521 indices[(size_t)r * (size_t)top_k + (size_t)dbg_slot],
3522 routing_weights[(size_t)r * (size_t)top_k + (size_t)dbg_slot]);
3523 }
3524 fprintf(stderr, "\n");
3525 ck_moe_debug_finite("routed.hidden[0]", x, (size_t)hidden_dim);
3526 ck_moe_debug_finite("routed.hidden_all", hidden, (size_t)rows * (size_t)hidden_dim);
3527 }
3528 for (int slot = 0; slot < top_k; ++slot) {
3529 const int e = indices[(size_t)r * (size_t)top_k + (size_t)slot];
3530 if (e < 0 || e >= n_experts) continue;
3531 const float route_w = routing_weights[(size_t)r * (size_t)top_k + (size_t)slot];
3532 const uint8_t *expert_up_base = up_base + (size_t)e * (size_t)intermediate_dim * up_row_bytes;
3533 const uint8_t *expert_down_base = down_base + (size_t)e * (size_t)hidden_dim * down_row_bytes;
3534
3535 for (int i = 0; i < intermediate_dim; ++i) {
3536 dequant_q5_0_row(expert_up_base + (size_t)i * up_row_bytes, up_row, (size_t)hidden_dim);
3537 float v = 0.0f;
3538 for (int h = 0; h < hidden_dim; ++h) v += up_row[h] * x[h];
3539 act[i] = (v > 0.0f) ? v * v : 0.0f;
3540 }
3541
3542 for (int h = 0; h < hidden_dim; ++h) {
3543 dequant_q8_0_row(expert_down_base + (size_t)h * down_row_bytes, down_row, (size_t)intermediate_dim);
3544 float v = 0.0f;
3545 for (int i = 0; i < intermediate_dim; ++i) v += down_row[i] * act[i];
3546 y[h] += route_w * v;
3547 }
3548 }
3549 if (ck_moe_debug_enabled() && r == 0) {
3550 ck_moe_debug_finite("routed.output[0]", y, (size_t)hidden_dim);
3551 ck_moe_debug_finite("routed.output_all", output, (size_t)rows * (size_t)hidden_dim);
3552 }
3553 }
3554}
void dequant_q8_0_row(const void *src, float *dst, size_t n_elements)
Dequantize Q8_0 row (multiple blocks)

References CK_DT_Q5_0, CK_DT_Q8_0, ck_dtype_row_bytes(), ck_moe_debug_enabled(), ck_moe_debug_finite(), dequant_q5_0_row(), and dequant_q8_0_row().

◆ moe_relu2_shared_forward_q5_1_q8_0()

void moe_relu2_shared_forward_q5_1_q8_0 ( const float *  hidden,
const float *  routed,
const void *  shared_up,
const void *  shared_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim 
)

Definition at line 3638 of file axpy_kernels.c.

3646{
3647 if (!hidden || !shared_up || !shared_down || !output || rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0) {
3648 return;
3649 }
3650
3651 const size_t up_row_bytes = ck_dtype_row_bytes(CK_DT_Q5_1, (size_t)hidden_dim);
3652 const size_t down_row_bytes = ck_dtype_row_bytes(CK_DT_Q8_0, (size_t)intermediate_dim);
3653 const uint8_t *up_base = (const uint8_t *)shared_up;
3654 const uint8_t *down_base = (const uint8_t *)shared_down;
3655
3656 float up_row[hidden_dim];
3657 float down_row[intermediate_dim];
3658 float act[intermediate_dim];
3659
3660 for (int r = 0; r < rows; ++r) {
3661 const float *x = hidden + (size_t)r * (size_t)hidden_dim;
3662 const float *route = routed ? (routed + (size_t)r * (size_t)hidden_dim) : NULL;
3663 float *y = output + (size_t)r * (size_t)hidden_dim;
3664 float x_alias[hidden_dim];
3665 if (output == hidden) {
3666 memcpy(x_alias, x, (size_t)hidden_dim * sizeof(float));
3667 x = x_alias;
3668 }
3669
3670 if (ck_moe_debug_enabled() && r == 0) {
3671 fprintf(stderr,
3672 "[CK_DEBUG_MOE] shared_q5q8 rows=%d hidden=%d intermediate=%d up_row_bytes=%zu down_row_bytes=%zu alias=%d\n",
3673 rows,
3674 hidden_dim,
3675 intermediate_dim,
3676 up_row_bytes,
3677 down_row_bytes,
3678 output == hidden);
3679 ck_moe_debug_finite("shared.hidden[0]", x, (size_t)hidden_dim);
3680 ck_moe_debug_finite("shared.hidden_all", hidden, (size_t)rows * (size_t)hidden_dim);
3681 ck_moe_debug_finite("shared.routed[0]", route, (size_t)hidden_dim);
3682 if (routed) ck_moe_debug_finite("shared.routed_all", routed, (size_t)rows * (size_t)hidden_dim);
3683 }
3684
3685 for (int i = 0; i < intermediate_dim; ++i) {
3686 dequant_q5_1_row(up_base + (size_t)i * up_row_bytes, up_row, (size_t)hidden_dim);
3687 float v = 0.0f;
3688 for (int h = 0; h < hidden_dim; ++h) v += up_row[h] * x[h];
3689 act[i] = (v > 0.0f) ? v * v : 0.0f;
3690 }
3691
3692 for (int h = 0; h < hidden_dim; ++h) {
3693 dequant_q8_0_row(down_base + (size_t)h * down_row_bytes, down_row, (size_t)intermediate_dim);
3694 float v = route ? route[h] : 0.0f;
3695 for (int i = 0; i < intermediate_dim; ++i) v += down_row[i] * act[i];
3696 y[h] = v;
3697 }
3698
3699 if (ck_moe_debug_enabled() && r == 0) {
3700 ck_moe_debug_finite("shared.output[0]", y, (size_t)hidden_dim);
3701 ck_moe_debug_finite("shared.output_all", output, (size_t)rows * (size_t)hidden_dim);
3702 }
3703 }
3704}
@ CK_DT_Q5_1
void dequant_q5_1_row(const void *src, float *dst, size_t n_elements)
Dequantize Q5_1 row (multiple blocks)

References CK_DT_Q5_1, CK_DT_Q8_0, ck_dtype_row_bytes(), ck_moe_debug_enabled(), ck_moe_debug_finite(), dequant_q5_1_row(), and dequant_q8_0_row().

◆ moe_swiglu_expert_backward_f32()

void moe_swiglu_expert_backward_f32 ( const float *  d_output,
const float *  hidden,
const int *  indices,
const float *  routing_weights,
const float *  expert_gate,
const float *  expert_up,
const float *  expert_down,
float *  d_hidden,
float *  d_routing_weights,
float *  d_expert_gate,
float *  d_expert_up,
float *  d_expert_down,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k 
)

Definition at line 3020 of file axpy_kernels.c.

3037{
3038 if (!d_output || !hidden || !indices || !routing_weights || !expert_gate || !expert_up || !expert_down ||
3039 !d_hidden || !d_routing_weights || !d_expert_gate || !d_expert_up || !d_expert_down ||
3040 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
3041 return;
3042 }
3043
3044 for (size_t p = 0; p < (size_t)rows * (size_t)hidden_dim; ++p) d_hidden[p] = 0.0f;
3045 for (size_t p = 0; p < (size_t)rows * (size_t)top_k; ++p) d_routing_weights[p] = 0.0f;
3046 for (size_t p = 0; p < (size_t)n_experts * (size_t)intermediate_dim * (size_t)hidden_dim; ++p) {
3047 d_expert_gate[p] = 0.0f;
3048 d_expert_up[p] = 0.0f;
3049 }
3050 for (size_t p = 0; p < (size_t)n_experts * (size_t)hidden_dim * (size_t)intermediate_dim; ++p) d_expert_down[p] = 0.0f;
3051
3052 float gate[intermediate_dim];
3053 float up[intermediate_dim];
3054 float silu_gate[intermediate_dim];
3055 float act[intermediate_dim];
3056 float d_act[intermediate_dim];
3057 float expert_out[hidden_dim];
3058
3059 for (int r = 0; r < rows; ++r) {
3060 const float *x = hidden + (size_t)r * (size_t)hidden_dim;
3061 const float *dy = d_output + (size_t)r * (size_t)hidden_dim;
3062 float *dx = d_hidden + (size_t)r * (size_t)hidden_dim;
3063
3064 for (int slot = 0; slot < top_k; ++slot) {
3065 const int e = indices[(size_t)r * (size_t)top_k + (size_t)slot];
3066 if (e < 0 || e >= n_experts) continue;
3067 const float route_w = routing_weights[(size_t)r * (size_t)top_k + (size_t)slot];
3068
3069 for (int i = 0; i < intermediate_dim; ++i) {
3070 float gv = 0.0f;
3071 float uv = 0.0f;
3072 for (int h = 0; h < hidden_dim; ++h) {
3073 gv += expert_gate[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] * x[h];
3074 uv += expert_up[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] * x[h];
3075 }
3076 gate[i] = gv;
3077 up[i] = uv;
3078 silu_gate[i] = ck_moe_silu_f32(gv);
3079 act[i] = silu_gate[i] * uv;
3080 d_act[i] = 0.0f;
3081 }
3082
3083 for (int h = 0; h < hidden_dim; ++h) {
3084 float v = 0.0f;
3085 for (int i = 0; i < intermediate_dim; ++i) {
3086 v += expert_down[ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)] * act[i];
3087 }
3088 expert_out[h] = v;
3089 }
3090
3091 float d_route = 0.0f;
3092 for (int h = 0; h < hidden_dim; ++h) {
3093 const float d_expert_out = dy[h] * route_w;
3094 d_route += dy[h] * expert_out[h];
3095 for (int i = 0; i < intermediate_dim; ++i) {
3096 d_expert_down[ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)] += d_expert_out * act[i];
3097 d_act[i] += d_expert_out * expert_down[ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)];
3098 }
3099 }
3100 d_routing_weights[(size_t)r * (size_t)top_k + (size_t)slot] += d_route;
3101
3102 for (int i = 0; i < intermediate_dim; ++i) {
3103 const float d_up = d_act[i] * silu_gate[i];
3104 const float d_gate = d_act[i] * up[i] * ck_moe_dsilu_f32(gate[i]);
3105 for (int h = 0; h < hidden_dim; ++h) {
3106 d_expert_up[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] += d_up * x[h];
3107 d_expert_gate[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] += d_gate * x[h];
3108 dx[h] += d_up * expert_up[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] +
3109 d_gate * expert_gate[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)];
3110 }
3111 }
3112 }
3113 }
3114}
static float ck_moe_dsilu_f32(float x)

References ck_moe_down_idx(), ck_moe_dsilu_f32(), ck_moe_silu_f32(), and ck_moe_up_idx().

◆ moe_swiglu_expert_forward_bf16()

void moe_swiglu_expert_forward_bf16 ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const uint16_t *  expert_gate,
const uint16_t *  expert_up,
const uint16_t *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k 
)

Definition at line 563 of file axpy_kernels.c.

575{
576 if (rows <= 0) return;
578 hidden, indices, routing_weights, expert_gate, expert_up, expert_down,
579 output, rows, hidden_dim, intermediate_dim, n_experts, top_k, 0, rows);
580}
void moe_swiglu_expert_forward_bf16_row_range(const float *hidden, const int *indices, const float *routing_weights, const uint16_t *expert_gate, const uint16_t *expert_up, const uint16_t *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, int row_begin, int row_end)

References moe_swiglu_expert_forward_bf16_row_range().

◆ moe_swiglu_expert_forward_bf16_row_range()

void moe_swiglu_expert_forward_bf16_row_range ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const uint16_t *  expert_gate,
const uint16_t *  expert_up,
const uint16_t *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
int  row_begin,
int  row_end 
)

Definition at line 505 of file axpy_kernels.c.

520{
521 if (!hidden || !indices || !routing_weights || !expert_gate || !expert_up || !expert_down || !output ||
522 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0 ||
523 row_begin < 0 || row_begin >= row_end || row_end > rows) {
524 return;
525 }
526
527 float gate[intermediate_dim];
528 float up[intermediate_dim];
529 float act[intermediate_dim];
530
531 for (int r = row_begin; r < row_end; ++r) {
532 const float *x = hidden + (size_t)r * (size_t)hidden_dim;
533 float *y = output + (size_t)r * (size_t)hidden_dim;
534 for (int h = 0; h < hidden_dim; ++h) y[h] = 0.0f;
535 for (int slot = 0; slot < top_k; ++slot) {
536 const int e = indices[(size_t)r * (size_t)top_k + (size_t)slot];
537 if (e < 0 || e >= n_experts) continue;
538 const float route_w = routing_weights[(size_t)r * (size_t)top_k + (size_t)slot];
539
540 for (int i = 0; i < intermediate_dim; ++i) {
541 float gv = 0.0f;
542 float uv = 0.0f;
543 for (int h = 0; h < hidden_dim; ++h) {
544 gv += bf16_to_float(expert_gate[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)]) * x[h];
545 uv += bf16_to_float(expert_up[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)]) * x[h];
546 }
547 gate[i] = gv;
548 up[i] = uv;
549 act[i] = ck_moe_silu_f32(gv) * uv;
550 }
551
552 for (int h = 0; h < hidden_dim; ++h) {
553 float v = 0.0f;
554 for (int i = 0; i < intermediate_dim; ++i) {
555 v += bf16_to_float(expert_down[ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)]) * act[i];
556 }
557 y[h] += route_w * v;
558 }
559 }
560 }
561}

References bf16_to_float(), ck_moe_down_idx(), ck_moe_silu_f32(), and ck_moe_up_idx().

Referenced by moe_swiglu_expert_forward_bf16().

◆ moe_swiglu_expert_forward_f32()

void moe_swiglu_expert_forward_f32 ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const float *  expert_gate,
const float *  expert_up,
const float *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k 
)

Definition at line 450 of file axpy_kernels.c.

462{
463 if (!hidden || !indices || !routing_weights || !expert_gate || !expert_up || !expert_down || !output ||
464 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
465 return;
466 }
467
468 for (size_t p = 0; p < (size_t)rows * (size_t)hidden_dim; ++p) output[p] = 0.0f;
469
470 float gate[intermediate_dim];
471 float up[intermediate_dim];
472 float act[intermediate_dim];
473
474 for (int r = 0; r < rows; ++r) {
475 const float *x = hidden + (size_t)r * (size_t)hidden_dim;
476 float *y = output + (size_t)r * (size_t)hidden_dim;
477 for (int slot = 0; slot < top_k; ++slot) {
478 const int e = indices[(size_t)r * (size_t)top_k + (size_t)slot];
479 if (e < 0 || e >= n_experts) continue;
480 const float route_w = routing_weights[(size_t)r * (size_t)top_k + (size_t)slot];
481
482 for (int i = 0; i < intermediate_dim; ++i) {
483 float gv = 0.0f;
484 float uv = 0.0f;
485 for (int h = 0; h < hidden_dim; ++h) {
486 gv += expert_gate[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] * x[h];
487 uv += expert_up[ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] * x[h];
488 }
489 gate[i] = gv;
490 up[i] = uv;
491 act[i] = ck_moe_silu_f32(gv) * uv;
492 }
493
494 for (int h = 0; h < hidden_dim; ++h) {
495 float v = 0.0f;
496 for (int i = 0; i < intermediate_dim; ++i) {
497 v += expert_down[ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)] * act[i];
498 }
499 y[h] += route_w * v;
500 }
501 }
502 }
503}

References ck_moe_down_idx(), ck_moe_silu_f32(), and ck_moe_up_idx().

◆ moe_swiglu_expert_forward_q4k_q4k_parallel_workspace()

int moe_swiglu_expert_forward_q4k_q4k_parallel_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 1881 of file axpy_kernels.c.

1896{
1898 hidden, indices, routing_weights, expert_gate, expert_up, expert_down,
1899 output, rows, hidden_dim, intermediate_dim, n_experts, top_k,
1900 workspace, workspace_bytes,
1902}
int moe_swiglu_expert_forward_q4k_q4k_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
static int ck_moe_q4k_mixed_parallel_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes, ck_moe_expert_workspace_fn serial_fn, ck_moe_down_kind_t down_kind)

References CK_MOE_DOWN_Q4_K, ck_moe_q4k_mixed_parallel_workspace(), and moe_swiglu_expert_forward_q4k_q4k_workspace().

◆ moe_swiglu_expert_forward_q4k_q4k_workspace()

int moe_swiglu_expert_forward_q4k_q4k_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 1108 of file axpy_kernels.c.

1123{
1124 const size_t required = moe_swiglu_expert_q4k_q5k_workspace_bytes(
1125 hidden_dim, intermediate_dim);
1126 if (!hidden || !indices || !routing_weights || !expert_gate ||
1127 !expert_up || !expert_down || !output || !workspace || required == 0 ||
1128 workspace_bytes < required || rows <= 0 || n_experts <= 0 ||
1129 top_k <= 0 || top_k > n_experts) {
1130 return -1;
1131 }
1132
1133 const size_t hidden_q8_bytes = ck_moe_align64(
1134 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim));
1135 const size_t gate_up_bytes = ck_moe_align64(
1136 2u * (size_t)intermediate_dim * sizeof(float));
1137 const size_t act_q8_bytes = ck_moe_align64(
1138 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)intermediate_dim));
1139 uint8_t *cursor = (uint8_t *)workspace;
1140 void *hidden_q8 = cursor;
1141 cursor += hidden_q8_bytes;
1142 float *gate_up = (float *)cursor;
1143 cursor += gate_up_bytes;
1144 void *act_q8 = cursor;
1145 cursor += act_q8_bytes;
1146 float *expert_output = (float *)cursor;
1147
1148 const size_t gate_row_bytes = ck_dtype_row_bytes(
1149 CK_DT_Q4_K, (size_t)hidden_dim);
1150 const size_t down_row_bytes = ck_dtype_row_bytes(
1151 CK_DT_Q4_K, (size_t)intermediate_dim);
1152 const uint8_t *gate_base = (const uint8_t *)expert_gate;
1153 const uint8_t *up_base = (const uint8_t *)expert_up;
1154 const uint8_t *down_base = (const uint8_t *)expert_down;
1155
1156 memset(output, 0, (size_t)rows * (size_t)hidden_dim * sizeof(float));
1157 for (int row = 0; row < rows; ++row) {
1158 const float *x = hidden + (size_t)row * (size_t)hidden_dim;
1159 float *y = output + (size_t)row * (size_t)hidden_dim;
1160 quantize_row_q8_k(x, hidden_q8, hidden_dim);
1161 for (int slot = 0; slot < top_k; ++slot) {
1162 const size_t route_index =
1163 (size_t)row * (size_t)top_k + (size_t)slot;
1164 const int expert = indices[route_index];
1165 if (expert < 0 || expert >= n_experts) return -2;
1166 const size_t up_offset =
1167 (size_t)expert * (size_t)intermediate_dim * gate_row_bytes;
1168 const size_t down_offset =
1169 (size_t)expert * (size_t)hidden_dim * down_row_bytes;
1170 gemv_q4_k_q8_k(gate_up, gate_base + up_offset, hidden_q8,
1171 intermediate_dim, hidden_dim);
1172 gemv_q4_k_q8_k(gate_up + intermediate_dim,
1173 up_base + up_offset, hidden_q8,
1174 intermediate_dim, hidden_dim);
1175 swiglu_forward_ggml(gate_up, gate_up, 1, intermediate_dim);
1176 quantize_row_q8_k(gate_up, act_q8, intermediate_dim);
1177 gemv_q4_k_q8_k(expert_output, down_base + down_offset, act_q8,
1178 hidden_dim, intermediate_dim);
1179 axpy_f32(y, expert_output, routing_weights[route_index], hidden_dim);
1180 }
1181 }
1182 return 0;
1183}

References axpy_f32(), CK_DT_Q4_K, CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), gemv_q4_k_q8_k(), moe_swiglu_expert_q4k_q5k_workspace_bytes(), quantize_row_q8_k(), and swiglu_forward_ggml().

Referenced by moe_swiglu_expert_forward_q4k_q4k_parallel_workspace().

◆ moe_swiglu_expert_forward_q4k_q5_0_parallel_workspace()

int moe_swiglu_expert_forward_q4k_q5_0_parallel_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 1927 of file axpy_kernels.c.

1942{
1944 hidden, indices, routing_weights, expert_gate, expert_up, expert_down,
1945 output, rows, hidden_dim, intermediate_dim, n_experts, top_k,
1946 workspace, workspace_bytes,
1948}
int moe_swiglu_expert_forward_q4k_q5_0_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)

References CK_MOE_DOWN_Q5_0, ck_moe_q4k_mixed_parallel_workspace(), and moe_swiglu_expert_forward_q4k_q5_0_workspace().

◆ moe_swiglu_expert_forward_q4k_q5_0_workspace()

int moe_swiglu_expert_forward_q4k_q5_0_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 1027 of file axpy_kernels.c.

1042{
1043 const size_t required = moe_swiglu_expert_q4k_q8_0_workspace_bytes(
1044 hidden_dim, intermediate_dim);
1045 if (!hidden || !indices || !routing_weights || !expert_gate ||
1046 !expert_up || !expert_down || !output || !workspace || required == 0 ||
1047 workspace_bytes < required || rows <= 0 || n_experts <= 0 ||
1048 top_k <= 0 || top_k > n_experts) {
1049 return -1;
1050 }
1051
1052 const size_t hidden_q8_bytes = ck_moe_align64(
1053 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim));
1054 const size_t gate_up_bytes = ck_moe_align64(
1055 2u * (size_t)intermediate_dim * sizeof(float));
1056 const size_t act_q8_bytes = ck_moe_align64(
1057 ck_dtype_row_bytes(CK_DT_Q8_0, (size_t)intermediate_dim));
1058 uint8_t *cursor = (uint8_t *)workspace;
1059 void *hidden_q8 = cursor;
1060 cursor += hidden_q8_bytes;
1061 float *gate_up = (float *)cursor;
1062 cursor += gate_up_bytes;
1063 void *act_q8 = cursor;
1064 cursor += act_q8_bytes;
1065 float *expert_output = (float *)cursor;
1066 cursor += ck_moe_align64((size_t)hidden_dim * sizeof(float));
1067 void *projection_scratch = cursor;
1068
1069 const size_t gate_row_bytes = ck_dtype_row_bytes(
1070 CK_DT_Q4_K, (size_t)hidden_dim);
1071 const size_t down_row_bytes = ck_dtype_row_bytes(
1072 CK_DT_Q5_0, (size_t)intermediate_dim);
1073 const uint8_t *gate_base = (const uint8_t *)expert_gate;
1074 const uint8_t *up_base = (const uint8_t *)expert_up;
1075 const uint8_t *down_base = (const uint8_t *)expert_down;
1076
1077 memset(output, 0, (size_t)rows * (size_t)hidden_dim * sizeof(float));
1078 for (int row = 0; row < rows; ++row) {
1079 const float *x = hidden + (size_t)row * (size_t)hidden_dim;
1080 float *y = output + (size_t)row * (size_t)hidden_dim;
1081 quantize_row_q8_k(x, hidden_q8, hidden_dim);
1082 for (int slot = 0; slot < top_k; ++slot) {
1083 const size_t route_index =
1084 (size_t)row * (size_t)top_k + (size_t)slot;
1085 const int expert = indices[route_index];
1086 if (expert < 0 || expert >= n_experts) return -2;
1087 const size_t gate_offset =
1088 (size_t)expert * (size_t)intermediate_dim * gate_row_bytes;
1089 const size_t down_offset =
1090 (size_t)expert * (size_t)hidden_dim * down_row_bytes;
1092 gate_up, gate_base + gate_offset, hidden_q8,
1093 intermediate_dim, hidden_dim, projection_scratch);
1095 gate_up + intermediate_dim, up_base + gate_offset, hidden_q8,
1096 intermediate_dim, hidden_dim, projection_scratch);
1097 swiglu_forward_ggml(gate_up, gate_up, 1, intermediate_dim);
1098 quantize_row_q8_0(gate_up, act_q8, intermediate_dim);
1099 gemv_q5_0_q8_0(expert_output, down_base + down_offset, act_q8,
1100 hidden_dim, intermediate_dim);
1102 y, expert_output, routing_weights[route_index], hidden_dim);
1103 }
1104 }
1105 return 0;
1106}

References CK_DT_Q4_K, CK_DT_Q5_0, CK_DT_Q8_0, CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), ck_moe_llama_weighted_accumulate(), ck_moe_q4k_llama_projection(), gemv_q5_0_q8_0(), moe_swiglu_expert_q4k_q8_0_workspace_bytes(), quantize_row_q8_0(), quantize_row_q8_k(), and swiglu_forward_ggml().

Referenced by moe_swiglu_expert_forward_q4k_q5_0_parallel_workspace().

◆ moe_swiglu_expert_forward_q4k_q5k_auto_workspace()

int moe_swiglu_expert_forward_q4k_q5k_auto_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 2595 of file axpy_kernels.c.

2610{
2611 if (rows < 512) {
2613 hidden, indices, routing_weights,
2614 expert_gate, expert_up, expert_down, output,
2615 rows, hidden_dim, intermediate_dim, n_experts, top_k,
2616 workspace, workspace_bytes);
2617 }
2619 hidden, indices, routing_weights,
2620 expert_gate, expert_up, expert_down, output,
2621 rows, hidden_dim, intermediate_dim, n_experts, top_k,
2622 workspace, workspace_bytes);
2623}
int moe_swiglu_expert_forward_q4k_q5k_parallel_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
int moe_swiglu_expert_forward_q4k_q5k_bucketed_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)

References moe_swiglu_expert_forward_q4k_q5k_bucketed_workspace(), and moe_swiglu_expert_forward_q4k_q5k_parallel_workspace().

◆ moe_swiglu_expert_forward_q4k_q5k_bucketed_prepared_workspace()

int moe_swiglu_expert_forward_q4k_q5k_bucketed_prepared_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
const void *  expert_gate_packed,
const void *  expert_up_packed,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 2569 of file axpy_kernels.c.

2586{
2588 hidden, indices, routing_weights,
2589 expert_gate, expert_up, expert_down,
2590 expert_gate_packed, expert_up_packed, output,
2591 rows, hidden_dim, intermediate_dim, n_experts, top_k,
2592 workspace, workspace_bytes);
2593}
static int ck_moe_swiglu_expert_forward_q4k_q5k_bucketed_impl(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, const void *expert_gate_packed, const void *expert_up_packed, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)

References ck_moe_swiglu_expert_forward_q4k_q5k_bucketed_impl().

◆ moe_swiglu_expert_forward_q4k_q5k_bucketed_workspace()

int moe_swiglu_expert_forward_q4k_q5k_bucketed_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 2546 of file axpy_kernels.c.

2561{
2563 hidden, indices, routing_weights,
2564 expert_gate, expert_up, expert_down, NULL, NULL, output,
2565 rows, hidden_dim, intermediate_dim, n_experts, top_k,
2566 workspace, workspace_bytes);
2567}

References ck_moe_swiglu_expert_forward_q4k_q5k_bucketed_impl().

Referenced by moe_swiglu_expert_forward_q4k_q5k_auto_workspace().

◆ moe_swiglu_expert_forward_q4k_q5k_parallel_workspace()

int moe_swiglu_expert_forward_q4k_q5k_parallel_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 1470 of file axpy_kernels.c.

1485{
1486 const size_t stride = moe_swiglu_expert_q4k_q5k_workspace_bytes(
1487 hidden_dim, intermediate_dim);
1488 if (!hidden || !indices || !routing_weights || !expert_gate || !expert_up ||
1489 !expert_down || !output || !workspace || stride == 0 || rows <= 0 ||
1490 n_experts <= 0 || top_k <= 0 || top_k > n_experts) {
1491 return -1;
1492 }
1493
1494 ck_threadpool_t *pool = ck_threadpool_global();
1495 if (rows == 1) {
1496 const int route_status = ck_moe_q4k_q5k_route_parallel(
1497 hidden, indices, routing_weights,
1498 expert_gate, expert_up, expert_down, output,
1499 hidden_dim, intermediate_dim, n_experts, top_k,
1500 workspace, workspace_bytes, stride, pool);
1501 if (route_status <= 0) return route_status;
1502 }
1503
1504 int active = pool ? ck_threadpool_n_threads(pool) : 1;
1505 if (active > rows) active = rows;
1507 const size_t workspace_workers = workspace_bytes / stride;
1508 if (workspace_workers == 0) return -1;
1509 if ((size_t)active > workspace_workers) active = (int)workspace_workers;
1510 if (active <= 1) {
1512 hidden, indices, routing_weights, expert_gate, expert_up, expert_down,
1513 output, rows, hidden_dim, intermediate_dim, n_experts, top_k,
1514 workspace, stride);
1515 }
1516
1517 ck_moe_q4k_q5k_parallel_args_t args = {
1518 .hidden = hidden,
1519 .indices = indices,
1520 .routing_weights = routing_weights,
1521 .expert_gate = expert_gate,
1522 .expert_up = expert_up,
1523 .expert_down = expert_down,
1524 .output = output,
1525 .rows = rows,
1526 .hidden_dim = hidden_dim,
1527 .intermediate_dim = intermediate_dim,
1528 .n_experts = n_experts,
1529 .top_k = top_k,
1530 .workspace = (uint8_t *)workspace,
1531 .workspace_stride = stride,
1532 .status = {0},
1533 };
1535 for (int ith = 0; ith < active; ++ith) {
1536 if (args.status[ith] != 0) return args.status[ith];
1537 }
1538 return 0;
1539}
static void ck_moe_q4k_q5k_parallel_work(int ith, int nth, void *opaque)
static int ck_moe_q4k_q5k_route_parallel(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes, size_t workspace_stride, ck_threadpool_t *pool)

References ck_moe_q4k_q5k_parallel_work(), ck_moe_q4k_q5k_route_parallel(), ck_threadpool_dispatch_n(), ck_threadpool_global(), CK_THREADPOOL_MAX_THREADS, ck_threadpool_n_threads(), moe_swiglu_expert_forward_q4k_q5k_workspace(), and moe_swiglu_expert_q4k_q5k_workspace_bytes().

Referenced by moe_swiglu_expert_forward_q4k_q5k_auto_workspace().

◆ moe_swiglu_expert_forward_q4k_q5k_workspace()

int moe_swiglu_expert_forward_q4k_q5k_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 781 of file axpy_kernels.c.

796{
797 const size_t required = moe_swiglu_expert_q4k_q5k_workspace_bytes(
798 hidden_dim, intermediate_dim);
799 if (!hidden || !indices || !routing_weights || !expert_gate || !expert_up ||
800 !expert_down || !output || !workspace || required == 0 ||
801 workspace_bytes < required || rows <= 0 || n_experts <= 0 ||
802 top_k <= 0 || top_k > n_experts) {
803 return -1;
804 }
805
806 const size_t hidden_q8_bytes = ck_moe_align64(
807 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim));
808 const size_t gate_up_bytes = ck_moe_align64(
809 2u * (size_t)intermediate_dim * sizeof(float));
810 const size_t act_q8_bytes = ck_moe_align64(
811 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)intermediate_dim));
812 uint8_t *cursor = (uint8_t *)workspace;
813 void *hidden_q8 = cursor;
814 cursor += hidden_q8_bytes;
815 float *gate_up = (float *)cursor;
816 cursor += gate_up_bytes;
817 void *act_q8 = cursor;
818 cursor += act_q8_bytes;
819 float *expert_output = (float *)cursor;
820
821 const size_t q4_row_bytes = ck_dtype_row_bytes(CK_DT_Q4_K, (size_t)hidden_dim);
822 const size_t q5_row_bytes = ck_dtype_row_bytes(CK_DT_Q5_K, (size_t)intermediate_dim);
823 const uint8_t *gate_base = (const uint8_t *)expert_gate;
824 const uint8_t *up_base = (const uint8_t *)expert_up;
825 const uint8_t *down_base = (const uint8_t *)expert_down;
826
827 memset(output, 0, (size_t)rows * (size_t)hidden_dim * sizeof(float));
828 for (int row = 0; row < rows; ++row) {
829 const float *x = hidden + (size_t)row * (size_t)hidden_dim;
830 float *y = output + (size_t)row * (size_t)hidden_dim;
831 quantize_row_q8_k(x, hidden_q8, hidden_dim);
832
833 for (int slot = 0; slot < top_k; ++slot) {
834 const size_t route_index = (size_t)row * (size_t)top_k + (size_t)slot;
835 const int expert = indices[route_index];
836 if (expert < 0 || expert >= n_experts) {
837 return -2;
838 }
839
840 const size_t up_expert_offset =
841 (size_t)expert * (size_t)intermediate_dim * q4_row_bytes;
842 const size_t down_expert_offset =
843 (size_t)expert * (size_t)hidden_dim * q5_row_bytes;
844 gemv_q4_k_q8_k(gate_up,
845 gate_base + up_expert_offset,
846 hidden_q8,
847 intermediate_dim,
848 hidden_dim);
849 gemv_q4_k_q8_k(gate_up + intermediate_dim,
850 up_base + up_expert_offset,
851 hidden_q8,
852 intermediate_dim,
853 hidden_dim);
854 swiglu_forward_ggml(gate_up, gate_up, 1, intermediate_dim);
855 quantize_row_q8_k(gate_up, act_q8, intermediate_dim);
856 gemv_q5_k_q8_k(expert_output,
857 down_base + down_expert_offset,
858 act_q8,
859 hidden_dim,
860 intermediate_dim);
861
862 const float route_weight = routing_weights[route_index];
863 axpy_f32(y, expert_output, route_weight, hidden_dim);
864 }
865 }
866 return 0;
867}

References axpy_f32(), CK_DT_Q4_K, CK_DT_Q5_K, CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), gemv_q4_k_q8_k(), gemv_q5_k_q8_k(), moe_swiglu_expert_q4k_q5k_workspace_bytes(), quantize_row_q8_k(), and swiglu_forward_ggml().

Referenced by ck_moe_q4k_q5k_parallel_work(), and moe_swiglu_expert_forward_q4k_q5k_parallel_workspace().

◆ moe_swiglu_expert_forward_q4k_q6k_parallel_workspace()

int moe_swiglu_expert_forward_q4k_q6k_parallel_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 1858 of file axpy_kernels.c.

1873{
1875 hidden, indices, routing_weights, expert_gate, expert_up, expert_down,
1876 output, rows, hidden_dim, intermediate_dim, n_experts, top_k,
1877 workspace, workspace_bytes,
1879}
int moe_swiglu_expert_forward_q4k_q6k_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)

References CK_MOE_DOWN_Q6_K, ck_moe_q4k_mixed_parallel_workspace(), and moe_swiglu_expert_forward_q4k_q6k_workspace().

◆ moe_swiglu_expert_forward_q4k_q6k_workspace()

int moe_swiglu_expert_forward_q4k_q6k_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 869 of file axpy_kernels.c.

884{
885 const size_t required = moe_swiglu_expert_q4k_q5k_workspace_bytes(
886 hidden_dim, intermediate_dim);
887 if (!hidden || !indices || !routing_weights || !expert_gate ||
888 !expert_up || !expert_down || !output || !workspace || required == 0 ||
889 workspace_bytes < required || rows <= 0 || n_experts <= 0 ||
890 top_k <= 0 || top_k > n_experts) {
891 return -1;
892 }
893
894 const size_t hidden_q8_bytes = ck_moe_align64(
895 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim));
896 const size_t gate_up_bytes = ck_moe_align64(
897 2u * (size_t)intermediate_dim * sizeof(float));
898 const size_t act_q8_bytes = ck_moe_align64(
899 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)intermediate_dim));
900 uint8_t *cursor = (uint8_t *)workspace;
901 void *hidden_q8 = cursor;
902 cursor += hidden_q8_bytes;
903 float *gate_up = (float *)cursor;
904 cursor += gate_up_bytes;
905 void *act_q8 = cursor;
906 cursor += act_q8_bytes;
907 float *expert_output = (float *)cursor;
908
909 const size_t q4_row_bytes = ck_dtype_row_bytes(
910 CK_DT_Q4_K, (size_t)hidden_dim);
911 const size_t q6_row_bytes = ck_dtype_row_bytes(
912 CK_DT_Q6_K, (size_t)intermediate_dim);
913 const uint8_t *gate_base = (const uint8_t *)expert_gate;
914 const uint8_t *up_base = (const uint8_t *)expert_up;
915 const uint8_t *down_base = (const uint8_t *)expert_down;
916
917 memset(output, 0, (size_t)rows * (size_t)hidden_dim * sizeof(float));
918 for (int row = 0; row < rows; ++row) {
919 const float *x = hidden + (size_t)row * (size_t)hidden_dim;
920 float *y = output + (size_t)row * (size_t)hidden_dim;
921 quantize_row_q8_k(x, hidden_q8, hidden_dim);
922 for (int slot = 0; slot < top_k; ++slot) {
923 const size_t route_index =
924 (size_t)row * (size_t)top_k + (size_t)slot;
925 const int expert = indices[route_index];
926 if (expert < 0 || expert >= n_experts) return -2;
927 const size_t up_offset =
928 (size_t)expert * (size_t)intermediate_dim * q4_row_bytes;
929 const size_t down_offset =
930 (size_t)expert * (size_t)hidden_dim * q6_row_bytes;
931 gemv_q4_k_q8_k(gate_up, gate_base + up_offset, hidden_q8,
932 intermediate_dim, hidden_dim);
933 gemv_q4_k_q8_k(gate_up + intermediate_dim,
934 up_base + up_offset, hidden_q8,
935 intermediate_dim, hidden_dim);
936 swiglu_forward_ggml(gate_up, gate_up, 1, intermediate_dim);
937 quantize_row_q8_k(gate_up, act_q8, intermediate_dim);
938 gemv_q6_k_q8_k(expert_output, down_base + down_offset, act_q8,
939 hidden_dim, intermediate_dim);
940 axpy_f32(y, expert_output, routing_weights[route_index], hidden_dim);
941 }
942 }
943 return 0;
944}

References axpy_f32(), CK_DT_Q4_K, CK_DT_Q6_K, CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), gemv_q4_k_q8_k(), gemv_q6_k_q8_k(), moe_swiglu_expert_q4k_q5k_workspace_bytes(), quantize_row_q8_k(), and swiglu_forward_ggml().

Referenced by moe_swiglu_expert_forward_q4k_q6k_parallel_workspace().

◆ moe_swiglu_expert_forward_q4k_q8_0_parallel_workspace()

int moe_swiglu_expert_forward_q4k_q8_0_parallel_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 1904 of file axpy_kernels.c.

1919{
1921 hidden, indices, routing_weights, expert_gate, expert_up, expert_down,
1922 output, rows, hidden_dim, intermediate_dim, n_experts, top_k,
1923 workspace, workspace_bytes,
1925}
int moe_swiglu_expert_forward_q4k_q8_0_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)

References CK_MOE_DOWN_Q8_0, ck_moe_q4k_mixed_parallel_workspace(), and moe_swiglu_expert_forward_q4k_q8_0_workspace().

◆ moe_swiglu_expert_forward_q4k_q8_0_workspace()

int moe_swiglu_expert_forward_q4k_q8_0_workspace ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const void *  expert_gate,
const void *  expert_up,
const void *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 946 of file axpy_kernels.c.

961{
962 const size_t required = moe_swiglu_expert_q4k_q8_0_workspace_bytes(
963 hidden_dim, intermediate_dim);
964 if (!hidden || !indices || !routing_weights || !expert_gate ||
965 !expert_up || !expert_down || !output || !workspace || required == 0 ||
966 workspace_bytes < required || rows <= 0 || n_experts <= 0 ||
967 top_k <= 0 || top_k > n_experts) {
968 return -1;
969 }
970
971 const size_t hidden_q8_bytes = ck_moe_align64(
972 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim));
973 const size_t gate_up_bytes = ck_moe_align64(
974 2u * (size_t)intermediate_dim * sizeof(float));
975 const size_t act_q8_bytes = ck_moe_align64(
976 ck_dtype_row_bytes(CK_DT_Q8_0, (size_t)intermediate_dim));
977 uint8_t *cursor = (uint8_t *)workspace;
978 void *hidden_q8 = cursor;
979 cursor += hidden_q8_bytes;
980 float *gate_up = (float *)cursor;
981 cursor += gate_up_bytes;
982 void *act_q8 = cursor;
983 cursor += act_q8_bytes;
984 float *expert_output = (float *)cursor;
985 cursor += ck_moe_align64((size_t)hidden_dim * sizeof(float));
986 void *projection_scratch = cursor;
987
988 const size_t gate_row_bytes = ck_dtype_row_bytes(
989 CK_DT_Q4_K, (size_t)hidden_dim);
990 const size_t down_row_bytes = ck_dtype_row_bytes(
991 CK_DT_Q8_0, (size_t)intermediate_dim);
992 const uint8_t *gate_base = (const uint8_t *)expert_gate;
993 const uint8_t *up_base = (const uint8_t *)expert_up;
994 const uint8_t *down_base = (const uint8_t *)expert_down;
995
996 memset(output, 0, (size_t)rows * (size_t)hidden_dim * sizeof(float));
997 for (int row = 0; row < rows; ++row) {
998 const float *x = hidden + (size_t)row * (size_t)hidden_dim;
999 float *y = output + (size_t)row * (size_t)hidden_dim;
1000 quantize_row_q8_k(x, hidden_q8, hidden_dim);
1001 for (int slot = 0; slot < top_k; ++slot) {
1002 const size_t route_index =
1003 (size_t)row * (size_t)top_k + (size_t)slot;
1004 const int expert = indices[route_index];
1005 if (expert < 0 || expert >= n_experts) return -2;
1006 const size_t gate_offset =
1007 (size_t)expert * (size_t)intermediate_dim * gate_row_bytes;
1008 const size_t down_offset =
1009 (size_t)expert * (size_t)hidden_dim * down_row_bytes;
1011 gate_up, gate_base + gate_offset, hidden_q8,
1012 intermediate_dim, hidden_dim, projection_scratch);
1014 gate_up + intermediate_dim, up_base + gate_offset, hidden_q8,
1015 intermediate_dim, hidden_dim, projection_scratch);
1016 swiglu_forward_ggml(gate_up, gate_up, 1, intermediate_dim);
1017 quantize_row_q8_0(gate_up, act_q8, intermediate_dim);
1018 gemv_q8_0_q8_0(expert_output, down_base + down_offset, act_q8,
1019 hidden_dim, intermediate_dim);
1021 y, expert_output, routing_weights[route_index], hidden_dim);
1022 }
1023 }
1024 return 0;
1025}

References CK_DT_Q4_K, CK_DT_Q8_0, CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), ck_moe_llama_weighted_accumulate(), ck_moe_q4k_llama_projection(), gemv_q8_0_q8_0(), moe_swiglu_expert_q4k_q8_0_workspace_bytes(), quantize_row_q8_0(), quantize_row_q8_k(), and swiglu_forward_ggml().

Referenced by moe_swiglu_expert_forward_q4k_q8_0_parallel_workspace().

◆ moe_swiglu_expert_q4k_q5k_bucketed_workspace_bytes()

size_t moe_swiglu_expert_q4k_q5k_bucketed_workspace_bytes ( int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k 
)

Definition at line 2202 of file axpy_kernels.c.

2208{
2209 ck_moe_q4k_q5k_bucket_layout_t layout;
2210 if (ck_moe_bucket_layout(rows, hidden_dim, intermediate_dim, n_experts,
2211 top_k, &layout) != 0) {
2212 return 0;
2213 }
2214 return layout.total_bytes;
2215}

References ck_moe_bucket_layout().

◆ moe_swiglu_expert_q4k_q5k_workspace_bytes()

size_t moe_swiglu_expert_q4k_q5k_workspace_bytes ( int  hidden_dim,
int  intermediate_dim 
)

Definition at line 727 of file axpy_kernels.c.

729{
730 if (hidden_dim <= 0 || intermediate_dim <= 0 ||
731 hidden_dim % 256 != 0 || intermediate_dim % 256 != 0) {
732 return 0;
733 }
734
735 size_t bytes = ck_moe_align64(ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim));
736 bytes += ck_moe_align64(2u * (size_t)intermediate_dim * sizeof(float));
737 bytes += ck_moe_align64(ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)intermediate_dim));
738 bytes += ck_moe_align64((size_t)hidden_dim * sizeof(float));
739 return bytes;
740}

References CK_DT_Q8_K, ck_dtype_row_bytes(), and ck_moe_align64().

Referenced by ck_moe_q4k_mixed_parallel_workspace(), ck_moe_shared_q4k_parallel_workspace(), moe_swiglu_expert_forward_q4k_q4k_workspace(), moe_swiglu_expert_forward_q4k_q5k_parallel_workspace(), moe_swiglu_expert_forward_q4k_q5k_workspace(), moe_swiglu_expert_forward_q4k_q6k_workspace(), moe_swiglu_shared_forward_q4k_q4k_workspace(), and moe_swiglu_shared_forward_q4k_q6k_workspace().

◆ moe_swiglu_expert_q4k_q8_0_workspace_bytes()

size_t moe_swiglu_expert_q4k_q8_0_workspace_bytes ( int  hidden_dim,
int  intermediate_dim 
)

Definition at line 742 of file axpy_kernels.c.

744{
745 if (hidden_dim <= 0 || intermediate_dim <= 0 ||
746 hidden_dim % 256 != 0 || intermediate_dim % QK8_0 != 0) {
747 return 0;
748 }
749
750 size_t bytes = ck_moe_align64(
751 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim));
752 bytes += ck_moe_align64(2u * (size_t)intermediate_dim * sizeof(float));
753 bytes += ck_moe_align64(
754 ck_dtype_row_bytes(CK_DT_Q8_0, (size_t)intermediate_dim));
755 bytes += ck_moe_align64((size_t)hidden_dim * sizeof(float));
757 intermediate_dim, hidden_dim);
758 return bytes;
759}
static size_t ck_moe_q4k_llama_projection_scratch_bytes(int output_dim, int input_dim)
#define QK8_0

References CK_DT_Q8_0, CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), ck_moe_q4k_llama_projection_scratch_bytes(), and QK8_0.

Referenced by ck_moe_q4k_mixed_parallel_workspace(), moe_swiglu_expert_forward_q4k_q5_0_workspace(), and moe_swiglu_expert_forward_q4k_q8_0_workspace().

◆ moe_swiglu_packed_expert_forward_bf16()

void moe_swiglu_packed_expert_forward_bf16 ( const float *  hidden,
const int *  indices,
const float *  routing_weights,
const uint16_t *  expert_gate_up,
const uint16_t *  expert_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  n_experts,
int  top_k 
)

Definition at line 582 of file axpy_kernels.c.

594{
595 if (!hidden || !indices || !routing_weights || !expert_gate_up ||
596 !expert_down || !output || rows <= 0 || hidden_dim <= 0 ||
597 intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
598 return;
599 }
600
601 float projection[2 * intermediate_dim];
602 float activation[intermediate_dim];
603 const size_t packed_expert_stride =
604 (size_t)2 * (size_t)intermediate_dim * (size_t)hidden_dim;
605 const size_t packed_up_offset =
606 (size_t)intermediate_dim * (size_t)hidden_dim;
607 for (int row = 0; row < rows; ++row) {
608 float *y = output + (size_t)row * (size_t)hidden_dim;
609 for (int hidden_col = 0; hidden_col < hidden_dim; ++hidden_col) {
610 y[hidden_col] = 0.0f;
611 }
612 }
613 for (int row = 0; row < rows; ++row) {
614 const float *x = hidden + (size_t)row * (size_t)hidden_dim;
615 float *y = output + (size_t)row * (size_t)hidden_dim;
616 for (int slot = 0; slot < top_k; ++slot) {
617 const size_t route_index =
618 (size_t)row * (size_t)top_k + (size_t)slot;
619 const int expert = indices[route_index];
620 if (expert < 0 || expert >= n_experts) continue;
621 const uint16_t *packed =
622 expert_gate_up + (size_t)expert * packed_expert_stride;
623 const uint16_t *gate = packed;
624 const uint16_t *up = packed + packed_up_offset;
625 for (int intermediate = 0; intermediate < intermediate_dim;
626 ++intermediate) {
627 float gate_value = 0.0f;
628 float up_value = 0.0f;
629 const size_t row_offset =
630 (size_t)intermediate * (size_t)hidden_dim;
631 for (int hidden_col = 0; hidden_col < hidden_dim;
632 ++hidden_col) {
633 const float input =
634 ck_moe_bf16_round(x[hidden_col]);
635 gate_value +=
636 bf16_to_float(gate[row_offset + hidden_col]) * input;
637 up_value +=
638 bf16_to_float(up[row_offset + hidden_col]) * input;
639 }
640 projection[intermediate] =
641 ck_moe_bf16_round(gate_value);
642 projection[intermediate_dim + intermediate] =
643 ck_moe_bf16_round(up_value);
644 }
646 projection, activation, 1, intermediate_dim);
647
648 const float route_weight =
649 ck_moe_bf16_round(routing_weights[route_index]);
650 for (int hidden_col = 0; hidden_col < hidden_dim;
651 ++hidden_col) {
652 float value = 0.0f;
653 for (int intermediate = 0;
654 intermediate < intermediate_dim; ++intermediate) {
655 value += bf16_to_float(expert_down[
656 ck_moe_down_idx(expert, hidden_col, intermediate,
657 hidden_dim, intermediate_dim)]) *
658 activation[intermediate];
659 }
660 const float down_stored = ck_moe_bf16_round(value);
661 const float weighted = ck_moe_bf16_round(
662 down_stored * route_weight);
663 y[hidden_col] += weighted;
664 }
665 }
666 for (int hidden_col = 0; hidden_col < hidden_dim; ++hidden_col) {
667 y[hidden_col] = ck_moe_bf16_round(y[hidden_col]);
668 }
669 }
670}
static float ck_moe_bf16_round(float x)
void swiglu_forward_pytorch_bf16_storage(const float *input, float *output, int tokens, int dim)

References bf16_to_float(), ck_moe_bf16_round(), ck_moe_down_idx(), and swiglu_forward_pytorch_bf16_storage().

◆ moe_swiglu_shared_backward_f32()

void moe_swiglu_shared_backward_f32 ( const float *  d_output,
const float *  hidden,
const float *  shared_gate,
const float *  shared_up,
const float *  shared_down,
float *  d_hidden,
float *  d_routed,
float *  d_shared_gate,
float *  d_shared_up,
float *  d_shared_down,
int  rows,
int  hidden_dim,
int  intermediate_dim 
)

Definition at line 3400 of file axpy_kernels.c.

3413{
3414 if (!d_output || !hidden || !shared_gate || !shared_up || !shared_down ||
3415 !d_hidden || !d_routed || !d_shared_gate || !d_shared_up || !d_shared_down ||
3416 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0) {
3417 return;
3418 }
3419
3420 for (size_t p = 0; p < (size_t)rows * (size_t)hidden_dim; ++p) {
3421 d_hidden[p] = 0.0f;
3422 d_routed[p] = d_output[p];
3423 }
3424 for (size_t p = 0; p < (size_t)intermediate_dim * (size_t)hidden_dim; ++p) {
3425 d_shared_gate[p] = 0.0f;
3426 d_shared_up[p] = 0.0f;
3427 }
3428 for (size_t p = 0; p < (size_t)hidden_dim * (size_t)intermediate_dim; ++p) d_shared_down[p] = 0.0f;
3429
3430 float gate[intermediate_dim];
3431 float up[intermediate_dim];
3432 float silu_gate[intermediate_dim];
3433 float act[intermediate_dim];
3434 float d_act[intermediate_dim];
3435
3436 for (int r = 0; r < rows; ++r) {
3437 const float *x = hidden + (size_t)r * (size_t)hidden_dim;
3438 const float *dy = d_output + (size_t)r * (size_t)hidden_dim;
3439 float *dx = d_hidden + (size_t)r * (size_t)hidden_dim;
3440
3441 for (int i = 0; i < intermediate_dim; ++i) {
3442 float gv = 0.0f;
3443 float uv = 0.0f;
3444 for (int h = 0; h < hidden_dim; ++h) {
3445 gv += shared_gate[(size_t)i * (size_t)hidden_dim + (size_t)h] * x[h];
3446 uv += shared_up[(size_t)i * (size_t)hidden_dim + (size_t)h] * x[h];
3447 }
3448 gate[i] = gv;
3449 up[i] = uv;
3450 silu_gate[i] = ck_moe_silu_f32(gv);
3451 act[i] = silu_gate[i] * uv;
3452 d_act[i] = 0.0f;
3453 }
3454
3455 for (int h = 0; h < hidden_dim; ++h) {
3456 for (int i = 0; i < intermediate_dim; ++i) {
3457 d_shared_down[(size_t)h * (size_t)intermediate_dim + (size_t)i] += dy[h] * act[i];
3458 d_act[i] += dy[h] * shared_down[(size_t)h * (size_t)intermediate_dim + (size_t)i];
3459 }
3460 }
3461
3462 for (int i = 0; i < intermediate_dim; ++i) {
3463 const float d_up = d_act[i] * silu_gate[i];
3464 const float d_gate = d_act[i] * up[i] * ck_moe_dsilu_f32(gate[i]);
3465 for (int h = 0; h < hidden_dim; ++h) {
3466 d_shared_up[(size_t)i * (size_t)hidden_dim + (size_t)h] += d_up * x[h];
3467 d_shared_gate[(size_t)i * (size_t)hidden_dim + (size_t)h] += d_gate * x[h];
3468 dx[h] += d_up * shared_up[(size_t)i * (size_t)hidden_dim + (size_t)h] +
3469 d_gate * shared_gate[(size_t)i * (size_t)hidden_dim + (size_t)h];
3470 }
3471 }
3472 }
3473}

References ck_moe_dsilu_f32(), and ck_moe_silu_f32().

◆ moe_swiglu_shared_forward_bf16()

void moe_swiglu_shared_forward_bf16 ( const float *  hidden,
const float *  routed,
const uint16_t *  shared_gate,
const uint16_t *  shared_up,
const uint16_t *  shared_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim 
)

Definition at line 3205 of file axpy_kernels.c.

3214{
3215 if (rows <= 0) return;
3217 hidden, routed, shared_gate, shared_up, shared_down, output,
3218 rows, hidden_dim, intermediate_dim, 0, rows);
3219}
void moe_swiglu_shared_forward_bf16_row_range(const float *hidden, const float *routed, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, int row_begin, int row_end)

References moe_swiglu_shared_forward_bf16_row_range().

◆ moe_swiglu_shared_forward_bf16_gated()

void moe_swiglu_shared_forward_bf16_gated ( const float *  hidden,
const float *  routed,
const uint16_t *  shared_gate,
const uint16_t *  shared_up,
const uint16_t *  shared_down,
const uint16_t *  shared_router,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim 
)

Definition at line 3298 of file axpy_kernels.c.

3309{
3310 if (rows <= 0) return;
3312 hidden, routed, shared_gate, shared_up, shared_down, shared_router,
3313 output, rows, hidden_dim, intermediate_dim, 0, rows);
3314}
void moe_swiglu_shared_forward_bf16_gated_row_range(const float *hidden, const float *routed, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, const uint16_t *shared_router, float *output, int rows, int hidden_dim, int intermediate_dim, int row_begin, int row_end)

References moe_swiglu_shared_forward_bf16_gated_row_range().

◆ moe_swiglu_shared_forward_bf16_gated_row_range()

void moe_swiglu_shared_forward_bf16_gated_row_range ( const float *  hidden,
const float *  routed,
const uint16_t *  shared_gate,
const uint16_t *  shared_up,
const uint16_t *  shared_down,
const uint16_t *  shared_router,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  row_begin,
int  row_end 
)

Definition at line 3221 of file axpy_kernels.c.

3234{
3235 if (!hidden || !shared_gate || !shared_up || !shared_down ||
3236 !shared_router || !output || rows <= 0 || hidden_dim <= 0 ||
3237 intermediate_dim <= 0 || row_begin < 0 || row_begin >= row_end ||
3238 row_end > rows) {
3239 return;
3240 }
3241
3242 float activation[intermediate_dim];
3243 for (int row = row_begin; row < row_end; ++row) {
3244 const float *x = hidden + (size_t)row * (size_t)hidden_dim;
3245 const float *route = routed
3246 ? routed + (size_t)row * (size_t)hidden_dim
3247 : NULL;
3248 float *y = output + (size_t)row * (size_t)hidden_dim;
3249
3250 for (int intermediate = 0; intermediate < intermediate_dim;
3251 ++intermediate) {
3252 float gate_sum = 0.0f;
3253 float up_sum = 0.0f;
3254 const size_t weight_base =
3255 (size_t)intermediate * (size_t)hidden_dim;
3256 for (int hidden_col = 0; hidden_col < hidden_dim; ++hidden_col) {
3257 const float value = ck_moe_bf16_round(x[hidden_col]);
3258 gate_sum += bf16_to_float(
3259 shared_gate[weight_base + (size_t)hidden_col]) * value;
3260 up_sum += bf16_to_float(
3261 shared_up[weight_base + (size_t)hidden_col]) * value;
3262 }
3263 const float gate_value = ck_moe_bf16_round(gate_sum);
3264 const float up_value = ck_moe_bf16_round(up_sum);
3265 const float silu = ck_moe_bf16_round(
3266 ck_moe_silu_f32(gate_value));
3267 activation[intermediate] = ck_moe_bf16_round(silu * up_value);
3268 }
3269
3270 float router_sum = 0.0f;
3271 for (int hidden_col = 0; hidden_col < hidden_dim; ++hidden_col) {
3272 router_sum += bf16_to_float(shared_router[hidden_col]) *
3273 ck_moe_bf16_round(x[hidden_col]);
3274 }
3275 const float shared_scale = ck_moe_bf16_round(
3277
3278 for (int hidden_col = 0; hidden_col < hidden_dim; ++hidden_col) {
3279 float down_sum = 0.0f;
3280 const size_t weight_base =
3281 (size_t)hidden_col * (size_t)intermediate_dim;
3282 for (int intermediate = 0; intermediate < intermediate_dim;
3283 ++intermediate) {
3284 down_sum += bf16_to_float(
3285 shared_down[weight_base + (size_t)intermediate]) *
3286 activation[intermediate];
3287 }
3288 const float shared = ck_moe_bf16_round(down_sum);
3289 const float gated_shared = ck_moe_bf16_round(shared * shared_scale);
3290 const float routed_value = route
3291 ? ck_moe_bf16_round(route[hidden_col])
3292 : 0.0f;
3293 y[hidden_col] = ck_moe_bf16_round(routed_value + gated_shared);
3294 }
3295 }
3296}
static void silu(float *x, int n)

References bf16_to_float(), ck_moe_bf16_round(), ck_moe_sigmoid_f32(), ck_moe_silu_f32(), and silu().

Referenced by moe_swiglu_shared_forward_bf16_gated().

◆ moe_swiglu_shared_forward_bf16_row_range()

void moe_swiglu_shared_forward_bf16_row_range ( const float *  hidden,
const float *  routed,
const uint16_t *  shared_gate,
const uint16_t *  shared_up,
const uint16_t *  shared_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
int  row_begin,
int  row_end 
)

Definition at line 3157 of file axpy_kernels.c.

3169{
3170 if (!hidden || !shared_gate || !shared_up || !shared_down || !output ||
3171 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 ||
3172 row_begin < 0 || row_begin >= row_end || row_end > rows) {
3173 return;
3174 }
3175
3176 float gate[intermediate_dim];
3177 float up[intermediate_dim];
3178 float act[intermediate_dim];
3179
3180 for (int r = row_begin; r < row_end; ++r) {
3181 const float *x = hidden + (size_t)r * (size_t)hidden_dim;
3182 const float *route = routed ? (routed + (size_t)r * (size_t)hidden_dim) : NULL;
3183 float *y = output + (size_t)r * (size_t)hidden_dim;
3184 for (int i = 0; i < intermediate_dim; ++i) {
3185 float gv = 0.0f;
3186 float uv = 0.0f;
3187 for (int h = 0; h < hidden_dim; ++h) {
3188 gv += bf16_to_float(shared_gate[(size_t)i * (size_t)hidden_dim + (size_t)h]) * x[h];
3189 uv += bf16_to_float(shared_up[(size_t)i * (size_t)hidden_dim + (size_t)h]) * x[h];
3190 }
3191 gate[i] = gv;
3192 up[i] = uv;
3193 act[i] = ck_moe_silu_f32(gv) * uv;
3194 }
3195 for (int h = 0; h < hidden_dim; ++h) {
3196 float v = route ? route[h] : 0.0f;
3197 for (int i = 0; i < intermediate_dim; ++i) {
3198 v += bf16_to_float(shared_down[(size_t)h * (size_t)intermediate_dim + (size_t)i]) * act[i];
3199 }
3200 y[h] = v;
3201 }
3202 }
3203}

References bf16_to_float(), and ck_moe_silu_f32().

Referenced by moe_swiglu_shared_forward_bf16().

◆ moe_swiglu_shared_forward_f32()

void moe_swiglu_shared_forward_f32 ( const float *  hidden,
const float *  routed,
const float *  shared_gate,
const float *  shared_up,
const float *  shared_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim 
)

Definition at line 3116 of file axpy_kernels.c.

3125{
3126 if (!hidden || !shared_gate || !shared_up || !shared_down || !output || rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0) {
3127 return;
3128 }
3129
3130 float gate[intermediate_dim];
3131 float up[intermediate_dim];
3132 float act[intermediate_dim];
3133
3134 for (int r = 0; r < rows; ++r) {
3135 const float *x = hidden + (size_t)r * (size_t)hidden_dim;
3136 const float *route = routed ? (routed + (size_t)r * (size_t)hidden_dim) : NULL;
3137 float *y = output + (size_t)r * (size_t)hidden_dim;
3138 for (int i = 0; i < intermediate_dim; ++i) {
3139 float gv = 0.0f;
3140 float uv = 0.0f;
3141 for (int h = 0; h < hidden_dim; ++h) {
3142 gv += shared_gate[(size_t)i * (size_t)hidden_dim + (size_t)h] * x[h];
3143 uv += shared_up[(size_t)i * (size_t)hidden_dim + (size_t)h] * x[h];
3144 }
3145 act[i] = ck_moe_silu_f32(gv) * uv;
3146 }
3147 for (int h = 0; h < hidden_dim; ++h) {
3148 float v = route ? route[h] : 0.0f;
3149 for (int i = 0; i < intermediate_dim; ++i) {
3150 v += shared_down[(size_t)h * (size_t)intermediate_dim + (size_t)i] * act[i];
3151 }
3152 y[h] = v;
3153 }
3154 }
3155}

References ck_moe_silu_f32().

◆ moe_swiglu_shared_forward_q4k_q4k_parallel_workspace()

int moe_swiglu_shared_forward_q4k_q4k_parallel_workspace ( const float *  hidden,
const float *  routed,
const void *  shared_gate,
const void *  shared_up,
const void *  shared_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 2071 of file axpy_kernels.c.

2083{
2085 hidden, routed, shared_gate, shared_up, shared_down, output, rows,
2086 hidden_dim, intermediate_dim, workspace, workspace_bytes,
2088}
static int ck_moe_shared_q4k_parallel_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes, ck_moe_shared_workspace_fn serial_fn)
int moe_swiglu_shared_forward_q4k_q4k_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)

References ck_moe_shared_q4k_parallel_workspace(), and moe_swiglu_shared_forward_q4k_q4k_workspace().

◆ moe_swiglu_shared_forward_q4k_q4k_workspace()

int moe_swiglu_shared_forward_q4k_q4k_workspace ( const float *  hidden,
const float *  routed,
const void *  shared_gate,
const void *  shared_up,
const void *  shared_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 1242 of file axpy_kernels.c.

1254{
1255 const size_t required = moe_swiglu_expert_q4k_q5k_workspace_bytes(
1256 hidden_dim, intermediate_dim);
1257 if (!hidden || !shared_gate || !shared_up || !shared_down || !output ||
1258 !workspace || required == 0 || workspace_bytes < required || rows <= 0) {
1259 return -1;
1260 }
1261
1262 const size_t hidden_q8_bytes = ck_moe_align64(
1263 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim));
1264 const size_t gate_up_bytes = ck_moe_align64(
1265 2u * (size_t)intermediate_dim * sizeof(float));
1266 const size_t act_q8_bytes = ck_moe_align64(
1267 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)intermediate_dim));
1268 uint8_t *cursor = (uint8_t *)workspace;
1269 void *hidden_q8 = cursor;
1270 cursor += hidden_q8_bytes;
1271 float *gate_up = (float *)cursor;
1272 cursor += gate_up_bytes;
1273 void *act_q8 = cursor;
1274 cursor += act_q8_bytes;
1275 float *shared_output = (float *)cursor;
1276
1277 for (int row = 0; row < rows; ++row) {
1278 const float *x = hidden + (size_t)row * (size_t)hidden_dim;
1279 float *y = output + (size_t)row * (size_t)hidden_dim;
1280 quantize_row_q8_k(x, hidden_q8, hidden_dim);
1281 gemv_q4_k_q8_k(gate_up, shared_gate, hidden_q8,
1282 intermediate_dim, hidden_dim);
1283 gemv_q4_k_q8_k(gate_up + intermediate_dim, shared_up, hidden_q8,
1284 intermediate_dim, hidden_dim);
1285 swiglu_forward_ggml(gate_up, gate_up, 1, intermediate_dim);
1286 quantize_row_q8_k(gate_up, act_q8, intermediate_dim);
1287 gemv_q4_k_q8_k(shared_output, shared_down, act_q8,
1288 hidden_dim, intermediate_dim);
1289 const float *route = routed
1290 ? routed + (size_t)row * (size_t)hidden_dim
1291 : NULL;
1292 for (int col = 0; col < hidden_dim; ++col) {
1293 y[col] = shared_output[col] + (route ? route[col] : 0.0f);
1294 }
1295 }
1296 return 0;
1297}

References CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), gemv_q4_k_q8_k(), moe_swiglu_expert_q4k_q5k_workspace_bytes(), quantize_row_q8_k(), and swiglu_forward_ggml().

Referenced by moe_swiglu_shared_forward_q4k_q4k_parallel_workspace().

◆ moe_swiglu_shared_forward_q4k_q5_0_gated_parallel_workspace()

int moe_swiglu_shared_forward_q4k_q5_0_gated_parallel_workspace ( const float *  hidden,
const float *  routed,
const void *  shared_gate,
const void *  shared_up,
const void *  shared_down,
const float *  shared_gate_input,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 2999 of file axpy_kernels.c.

3012{
3013 /* See the Q8_0-down variant above: inner projection dispatch owns the
3014 * pool so nested row dispatch would deadlock. */
3016 hidden, routed, shared_gate, shared_up, shared_down, shared_gate_input,
3017 output, rows, hidden_dim, intermediate_dim, workspace, workspace_bytes);
3018}
int moe_swiglu_shared_forward_q4k_q5_0_gated_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)

References moe_swiglu_shared_forward_q4k_q5_0_gated_workspace().

◆ moe_swiglu_shared_forward_q4k_q5_0_gated_workspace()

int moe_swiglu_shared_forward_q4k_q5_0_gated_workspace ( const float *  hidden,
const float *  routed,
const void *  shared_gate,
const void *  shared_up,
const void *  shared_down,
const float *  shared_gate_input,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 2828 of file axpy_kernels.c.

2841{
2843 hidden, routed, shared_gate, shared_up, shared_down, shared_gate_input,
2844 output, rows, hidden_dim, intermediate_dim, workspace, workspace_bytes,
2846}
static int ck_moe_shared_q4k_gated_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes, void(*down_projection)(float *, const void *, const void *, int, int))

References ck_moe_shared_q4k_gated_workspace(), and gemv_q5_0_q8_0().

Referenced by moe_swiglu_shared_forward_q4k_q5_0_gated_parallel_workspace().

◆ moe_swiglu_shared_forward_q4k_q6k_parallel_workspace()

int moe_swiglu_shared_forward_q4k_q6k_parallel_workspace ( const float *  hidden,
const float *  routed,
const void *  shared_gate,
const void *  shared_up,
const void *  shared_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 2052 of file axpy_kernels.c.

2064{
2066 hidden, routed, shared_gate, shared_up, shared_down, output, rows,
2067 hidden_dim, intermediate_dim, workspace, workspace_bytes,
2069}
int moe_swiglu_shared_forward_q4k_q6k_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)

References ck_moe_shared_q4k_parallel_workspace(), and moe_swiglu_shared_forward_q4k_q6k_workspace().

◆ moe_swiglu_shared_forward_q4k_q6k_workspace()

int moe_swiglu_shared_forward_q4k_q6k_workspace ( const float *  hidden,
const float *  routed,
const void *  shared_gate,
const void *  shared_up,
const void *  shared_down,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 1185 of file axpy_kernels.c.

1197{
1198 const size_t required = moe_swiglu_expert_q4k_q5k_workspace_bytes(
1199 hidden_dim, intermediate_dim);
1200 if (!hidden || !shared_gate || !shared_up || !shared_down || !output ||
1201 !workspace || required == 0 || workspace_bytes < required || rows <= 0) {
1202 return -1;
1203 }
1204
1205 const size_t hidden_q8_bytes = ck_moe_align64(
1206 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim));
1207 const size_t gate_up_bytes = ck_moe_align64(
1208 2u * (size_t)intermediate_dim * sizeof(float));
1209 const size_t act_q8_bytes = ck_moe_align64(
1210 ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)intermediate_dim));
1211 uint8_t *cursor = (uint8_t *)workspace;
1212 void *hidden_q8 = cursor;
1213 cursor += hidden_q8_bytes;
1214 float *gate_up = (float *)cursor;
1215 cursor += gate_up_bytes;
1216 void *act_q8 = cursor;
1217 cursor += act_q8_bytes;
1218 float *shared_output = (float *)cursor;
1219
1220 for (int row = 0; row < rows; ++row) {
1221 const float *x = hidden + (size_t)row * (size_t)hidden_dim;
1222 float *y = output + (size_t)row * (size_t)hidden_dim;
1223 quantize_row_q8_k(x, hidden_q8, hidden_dim);
1224 gemv_q4_k_q8_k(gate_up, shared_gate, hidden_q8,
1225 intermediate_dim, hidden_dim);
1226 gemv_q4_k_q8_k(gate_up + intermediate_dim, shared_up, hidden_q8,
1227 intermediate_dim, hidden_dim);
1228 swiglu_forward_ggml(gate_up, gate_up, 1, intermediate_dim);
1229 quantize_row_q8_k(gate_up, act_q8, intermediate_dim);
1230 gemv_q6_k_q8_k(shared_output, shared_down, act_q8,
1231 hidden_dim, intermediate_dim);
1232 const float *route = routed
1233 ? routed + (size_t)row * (size_t)hidden_dim
1234 : NULL;
1235 for (int col = 0; col < hidden_dim; ++col) {
1236 y[col] = shared_output[col] + (route ? route[col] : 0.0f);
1237 }
1238 }
1239 return 0;
1240}

References CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), gemv_q4_k_q8_k(), gemv_q6_k_q8_k(), moe_swiglu_expert_q4k_q5k_workspace_bytes(), quantize_row_q8_k(), and swiglu_forward_ggml().

Referenced by moe_swiglu_shared_forward_q4k_q6k_parallel_workspace().

◆ moe_swiglu_shared_forward_q4k_q8_0_gated_parallel_workspace()

int moe_swiglu_shared_forward_q4k_q8_0_gated_parallel_workspace ( const float *  hidden,
const float *  routed,
const void *  shared_gate,
const void *  shared_up,
const void *  shared_down,
const float *  shared_gate_input,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 2978 of file axpy_kernels.c.

2991{
2992 /* Gate/up use the output-parallel pairwise Q4_K provider. Do not wrap
2993 * that provider in a second dispatch on the same persistent pool. */
2995 hidden, routed, shared_gate, shared_up, shared_down, shared_gate_input,
2996 output, rows, hidden_dim, intermediate_dim, workspace, workspace_bytes);
2997}
int moe_swiglu_shared_forward_q4k_q8_0_gated_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)

References moe_swiglu_shared_forward_q4k_q8_0_gated_workspace().

◆ moe_swiglu_shared_forward_q4k_q8_0_gated_workspace()

int moe_swiglu_shared_forward_q4k_q8_0_gated_workspace ( const float *  hidden,
const float *  routed,
const void *  shared_gate,
const void *  shared_up,
const void *  shared_down,
const float *  shared_gate_input,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 2815 of file axpy_kernels.c.

2821{
2823 hidden, routed, shared_gate, shared_up, shared_down, shared_gate_input,
2824 output, rows, hidden_dim, intermediate_dim, workspace, workspace_bytes,
2826}

References ck_moe_shared_q4k_gated_workspace(), and gemv_q8_0_q8_0().

Referenced by moe_swiglu_shared_forward_q4k_q8_0_gated_parallel_workspace().

◆ moe_swiglu_shared_forward_q8_0_gated_parallel_workspace()

int moe_swiglu_shared_forward_q8_0_gated_parallel_workspace ( const float *  hidden,
const float *  routed,
const void *  shared_gate,
const void *  shared_up,
const void *  shared_down,
const float *  shared_gate_input,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 2957 of file axpy_kernels.c.

2970{
2972 hidden, routed, shared_gate, shared_up, shared_down, shared_gate_input,
2973 output, rows, hidden_dim, intermediate_dim, workspace, workspace_bytes,
2974 moe_swiglu_shared_q8_0_gated_workspace_bytes(hidden_dim, intermediate_dim),
2976}
int moe_swiglu_shared_forward_q8_0_gated_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
static int ck_moe_shared_gated_parallel_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes, size_t stride, ck_moe_shared_gated_workspace_fn serial_fn)
size_t moe_swiglu_shared_q8_0_gated_workspace_bytes(int hidden_dim, int intermediate_dim)

References ck_moe_shared_gated_parallel_workspace(), moe_swiglu_shared_forward_q8_0_gated_workspace(), and moe_swiglu_shared_q8_0_gated_workspace_bytes().

◆ moe_swiglu_shared_forward_q8_0_gated_workspace()

int moe_swiglu_shared_forward_q8_0_gated_workspace ( const float *  hidden,
const float *  routed,
const void *  shared_gate,
const void *  shared_up,
const void *  shared_down,
const float *  shared_gate_input,
float *  output,
int  rows,
int  hidden_dim,
int  intermediate_dim,
void *  workspace,
size_t  workspace_bytes 
)

Definition at line 2642 of file axpy_kernels.c.

2655{
2656 const size_t required = moe_swiglu_shared_q8_0_gated_workspace_bytes(
2657 hidden_dim, intermediate_dim);
2658 if (!hidden || !shared_gate || !shared_up || !shared_down ||
2659 !shared_gate_input || !output || !workspace || required == 0 ||
2660 workspace_bytes < required || rows <= 0) {
2661 return -1;
2662 }
2663
2664 const size_t hidden_q8_bytes = ck_moe_align64(
2665 ck_dtype_row_bytes(CK_DT_Q8_0, (size_t)hidden_dim));
2666 const size_t gate_up_bytes = ck_moe_align64(
2667 2u * (size_t)intermediate_dim * sizeof(float));
2668 const size_t activation_q8_bytes = ck_moe_align64(
2669 ck_dtype_row_bytes(CK_DT_Q8_0, (size_t)intermediate_dim));
2670 uint8_t *cursor = (uint8_t *)workspace;
2671 void *hidden_q8 = cursor;
2672 cursor += hidden_q8_bytes;
2673 float *gate_up = (float *)cursor;
2674 cursor += gate_up_bytes;
2675 void *activation_q8 = cursor;
2676 cursor += activation_q8_bytes;
2677 float *shared_output = (float *)cursor;
2678
2679 for (int row = 0; row < rows; ++row) {
2680 const float *x = hidden + (size_t)row * (size_t)hidden_dim;
2681 const float *routed_row = routed
2682 ? routed + (size_t)row * (size_t)hidden_dim
2683 : NULL;
2684 float *output_row = output + (size_t)row * (size_t)hidden_dim;
2685
2686 quantize_row_q8_0(x, hidden_q8, hidden_dim);
2687 gemv_q8_0_q8_0(gate_up, shared_gate, hidden_q8,
2688 intermediate_dim, hidden_dim);
2689 gemv_q8_0_q8_0(gate_up + intermediate_dim, shared_up, hidden_q8,
2690 intermediate_dim, hidden_dim);
2691 swiglu_forward_ggml(gate_up, gate_up, 1, intermediate_dim);
2692 quantize_row_q8_0(gate_up, activation_q8, intermediate_dim);
2693 gemv_q8_0_q8_0(shared_output, shared_down, activation_q8,
2694 hidden_dim, intermediate_dim);
2695
2696 float gate_value = 0.0f;
2698 x, shared_gate_input, NULL, &gate_value, 1, 1, hidden_dim);
2699 const float gate_scale = 1.0f / (1.0f + expf(-gate_value));
2700 for (int h = 0; h < hidden_dim; ++h) {
2701 const float routed_value = routed_row ? routed_row[h] : 0.0f;
2702 volatile float gated_shared = shared_output[h] * gate_scale;
2703 output_row[h] = routed_value + gated_shared;
2704 }
2705 }
2706 return 0;
2707}

References CK_DT_Q8_0, ck_dtype_row_bytes(), ck_moe_align64(), gemm_nt_f32_llama_production(), gemv_q8_0_q8_0(), moe_swiglu_shared_q8_0_gated_workspace_bytes(), quantize_row_q8_0(), and swiglu_forward_ggml().

Referenced by moe_swiglu_shared_forward_q8_0_gated_parallel_workspace().

◆ moe_swiglu_shared_q4k_q8_0_gated_workspace_bytes()

size_t moe_swiglu_shared_q4k_q8_0_gated_workspace_bytes ( int  hidden_dim,
int  intermediate_dim 
)

Definition at line 761 of file axpy_kernels.c.

763{
764 enum { batch_rows = 4 };
765 if (hidden_dim <= 0 || intermediate_dim <= 0 ||
766 hidden_dim % 256 != 0 || intermediate_dim % QK8_0 != 0) {
767 return 0;
768 }
769
770 size_t bytes = ck_moe_align64(
771 batch_rows * ck_dtype_row_bytes(CK_DT_Q8_K, (size_t)hidden_dim));
772 bytes += 2u * ck_moe_align64(
773 batch_rows * (size_t)intermediate_dim * sizeof(float));
774 bytes += ck_moe_align64(
775 batch_rows * ck_dtype_row_bytes(CK_DT_Q8_0, (size_t)intermediate_dim));
776 bytes += ck_moe_align64(
777 batch_rows * (size_t)hidden_dim * sizeof(float));
778 return bytes;
779}

References CK_DT_Q8_0, CK_DT_Q8_K, ck_dtype_row_bytes(), ck_moe_align64(), and QK8_0.

Referenced by ck_moe_shared_q4k_gated_workspace().

◆ moe_swiglu_shared_q8_0_gated_workspace_bytes()

size_t moe_swiglu_shared_q8_0_gated_workspace_bytes ( int  hidden_dim,
int  intermediate_dim 
)

Definition at line 2625 of file axpy_kernels.c.

2627{
2628 if (hidden_dim <= 0 || intermediate_dim <= 0 ||
2629 hidden_dim % 32 != 0 || intermediate_dim % 32 != 0) {
2630 return 0;
2631 }
2632
2633 size_t bytes = ck_moe_align64(
2634 ck_dtype_row_bytes(CK_DT_Q8_0, (size_t)hidden_dim));
2635 bytes += ck_moe_align64(2u * (size_t)intermediate_dim * sizeof(float));
2636 bytes += ck_moe_align64(
2637 ck_dtype_row_bytes(CK_DT_Q8_0, (size_t)intermediate_dim));
2638 bytes += ck_moe_align64((size_t)hidden_dim * sizeof(float));
2639 return bytes;
2640}

References CK_DT_Q8_0, ck_dtype_row_bytes(), and ck_moe_align64().

Referenced by moe_swiglu_shared_forward_q8_0_gated_parallel_workspace(), and moe_swiglu_shared_forward_q8_0_gated_workspace().

◆ pack_q4_k_to_packed_meta_x8()

void pack_q4_k_to_packed_meta_x8 ( const void *  source,
void *  destination,
int  output_dim,
int  input_dim 
)

Definition at line 525 of file gemm_kernels_q4k_q8k_vnni.c.

526{
527 if (!src || !dst || N <= 0 || K <= 0 || (K % QK_K) != 0) {
528 return;
529 }
530 const block_q4_K *in = (const block_q4_K *)src;
531 block_q4_K_packed_meta_x8 *out = (block_q4_K_packed_meta_x8 *)dst;
532 const int blocks_per_row = K / QK_K;
533 const int groups = (N + 7) / 8;
534 memset(out, 0, (size_t)groups * (size_t)blocks_per_row * sizeof(*out));
535
536 for (int g = 0; g < groups; ++g) {
537 const int n0 = g * 8;
538 const int active = (n0 + 8 <= N) ? 8 : (N - n0);
539 for (int b = 0; b < blocks_per_row; ++b) {
540 block_q4_K_packed_meta_x8 *pb = out + (size_t)g * (size_t)blocks_per_row + (size_t)b;
541 pb->active = (uint8_t)active;
542 for (int lane = 0; lane < active; ++lane) {
543 const block_q4_K *sb = in + (size_t)(n0 + lane) * (size_t)blocks_per_row + (size_t)b;
544 pb->d[lane] = sb->d;
545 pb->dmin[lane] = sb->dmin;
546 unpack_q4_k_scales(sb->scales, pb->sc[lane], pb->m[lane]);
547 memcpy(pb->qs[lane], sb->qs, sizeof(pb->qs[lane]));
548 }
549 }
550 }
551}
static void unpack_q4_k_scales(const uint8_t *scales, uint8_t *sc, uint8_t *m)
Unpack Q4_K sub-block scales and mins.
uint8_t scales[12]
uint8_t qs[256/2]

References block_q4_K::d, block_q4_K::dmin, QK_K, block_q4_K::qs, block_q4_K::scales, and unpack_q4_k_scales().

Referenced by ck_moe_q4k_llama_projection().

◆ q4_k_packed_meta_x8_block_size()

size_t q4_k_packed_meta_x8_block_size ( void  )

Definition at line 464 of file gemm_kernels_q4k_q8k_vnni.c.

465{
466 return sizeof(block_q4_K_packed_meta_x8);
467}

Referenced by ck_moe_q4k_llama_projection_scratch_bytes().

◆ q4_k_packed_vnni_x8_block_size()

size_t q4_k_packed_vnni_x8_block_size ( void  )

Definition at line 267 of file gemm_kernels_q4k_q8k_vnni.c.

268{
269 return sizeof(block_q4_K_packed_vnni_x8);
270}

Referenced by ck_moe_swiglu_expert_forward_q4k_q5k_bucketed_impl().

◆ scal_copy_f32()

void scal_copy_f32 ( float *  y,
const float *  x,
float  alpha,
int  n 
)

Scaled copy: y = alpha * x.

Parameters
yOutput vector [n]
xInput vector [n]
alphaScalar multiplier
nVector length

Definition at line 156 of file axpy_kernels.c.

160{
161 if (!y || !x || n <= 0) {
162 return;
163 }
164
165 int i = 0;
166
167#ifdef __AVX512F__
168 __m512 valpha = _mm512_set1_ps(alpha);
169 for (; i + 16 <= n; i += 16) {
170 __m512 vx = _mm512_loadu_ps(&x[i]);
171 __m512 vy = _mm512_mul_ps(vx, valpha);
172 _mm512_storeu_ps(&y[i], vy);
173 }
174#endif
175
176#ifdef __AVX2__
177 __m256 valpha256 = _mm256_set1_ps(alpha);
178 for (; i + 8 <= n; i += 8) {
179 __m256 vx = _mm256_loadu_ps(&x[i]);
180 __m256 vy = _mm256_mul_ps(vx, valpha256);
181 _mm256_storeu_ps(&y[i], vy);
182 }
183#endif
184
185 for (; i < n; i++) {
186 y[i] = alpha * x[i];
187 }
188}

Referenced by weighted_sum_f32().

◆ weighted_sum_f32()

void weighted_sum_f32 ( float *  y,
const float **  vectors,
const float *  weights,
int  k,
int  n 
)

Weighted sum of k vectors: y = sum_i(weights[i] * vectors[i])

Parameters
yOutput vector [n]
vectorsArray of k input vector pointers, each [n]
weightsArray of k scalar weights
kNumber of vectors to combine
nVector length

Definition at line 206 of file axpy_kernels.c.

211{
212 if (!y || !vectors || !weights || k <= 0 || n <= 0) {
213 return;
214 }
215
216 /* Initialize with first vector */
217 scal_copy_f32(y, vectors[0], weights[0], n);
218
219 /* Accumulate rest */
220 for (int i = 1; i < k; i++) {
221 axpy_f32(y, vectors[i], weights[i], n);
222 }
223}
void scal_copy_f32(float *y, const float *x, float alpha, int n)
Scaled copy: y = alpha * x.

References axpy_f32(), and scal_copy_f32().