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

FP32 Gated DeltaNet kernels for Qwen3.5-style recurrent attention. More...

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

Go to the source code of this file.

Macros

#define CK_DELTANET_LLAMA_CHUNK_MAX_DIM   256
 
#define CK_DELTANET_LLAMA_CHUNK_SIZE   64
 
#define CK_DELTANET_MAX_STACK_DIM   4096
 
#define CK_DELTANET_NOINLINE
 

Typedefs

typedef float(* ck_deltanet_libm_f32_fn) (float)
 
typedef void(* ck_deltanet_mkl_vsexp_fn) (int, const float *, float *)
 

Functions

static void ck_bind_deltanet_llama_libm (void)
 
static void ck_bind_deltanet_pytorch_primitives (void)
 
static int ck_deltanet_ceil_log2 (int value)
 
static int ck_deltanet_force_ref (void)
 
static float ck_deltanet_llama_sigmoidf (float x)
 
static void ck_deltanet_pytorch_gate_values (const float *g, const float *beta, float *gate_values, float *beta_values, int num_heads)
 
static void ck_deltanet_pytorch_outer_sum (const float *matrix, const float *row_weights, float *output, int state_dim)
 
static float ck_deltanet_sigmoidf (float x)
 
void gated_deltanet_autoregressive_backward (const float *d_out, const float *d_state_out, const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, const float *state_out, float *d_q, float *d_k, float *d_v, float *d_g, float *d_beta, float *d_state_in, int num_heads, int state_dim, float norm_eps)
 
void gated_deltanet_autoregressive_backward_ref (const float *d_out, const float *d_state_out, const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, const float *state_out, float *d_q, float *d_k, float *d_v, float *d_g, float *d_beta, float *d_state_in, int num_heads, int state_dim, float norm_eps)
 
void gated_deltanet_autoregressive_forward (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int num_heads, int state_dim, float norm_eps)
 
void gated_deltanet_autoregressive_forward_ref (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int num_heads, int state_dim, float norm_eps)
 
const char * gated_deltanet_impl_name (void)
 
void gated_deltanet_llama_avx2_forward (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int num_heads, int group_count, int state_dim, float norm_eps)
 
void gated_deltanet_llama_avx2_forward_head_range (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int num_heads, int group_count, int state_dim, float norm_eps, int head_begin, int head_end)
 
static void gated_deltanet_llama_avx2_grouped_forward_impl (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int num_heads, int group_count, int state_dim, float norm_eps, int head_begin, int head_end, int pytorch_bf16_boundaries)
 
static void gated_deltanet_llama_avx2_grouped_forward_transposed_impl (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int num_heads, int group_count, int state_dim, float norm_eps, int head_begin, int head_end)
 
void gated_deltanet_llama_avx2_prefill_forward (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int rows, int num_heads, int group_count, int state_dim, float norm_eps)
 
void gated_deltanet_llama_chunk64_head_forward (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int rows, int num_heads, int group_count, int head, int state_dim)
 
void gated_deltanet_llama_chunk64_prefill_forward (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int rows, int num_heads, int group_count, int state_dim, float norm_eps)
 
void gated_deltanet_prefill_forward (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int rows, int num_heads, int state_dim, float norm_eps)
 
void gated_deltanet_pytorch_gate_values_debug (const float *g, const float *beta, float *gate_values, float *beta_values, int num_heads)
 
void gated_deltanet_pytorch_grouped_bf16_forward (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int num_heads, int group_count, int state_dim, float norm_eps)
 
void gated_deltanet_pytorch_grouped_bf16_forward_debug (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, float *decayed_state, float *memory, float *delta, int num_heads, int group_count, int state_dim, float norm_eps)
 
static void gated_deltanet_pytorch_grouped_bf16_forward_impl (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, float *debug_decayed_state, float *debug_memory, float *debug_delta, int num_heads, int group_count, int state_dim, float norm_eps)
 
void gated_deltanet_pytorch_grouped_bf16_prefill_forward (const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int rows, int num_heads, int group_count, int state_dim, float norm_eps)
 

Variables

static void * ck_deltanet_libm_handle = NULL
 
static pthread_once_t ck_deltanet_libm_once = PTHREAD_ONCE_INIT
 
static ck_deltanet_libm_f32_fn ck_deltanet_llama_expf = NULL
 
static void * ck_deltanet_mkl_handle = NULL
 
static pthread_once_t ck_deltanet_pytorch_primitives_once = PTHREAD_ONCE_INIT
 
static ck_deltanet_mkl_vsexp_fn ck_deltanet_pytorch_vsexp = NULL
 

Detailed Description

FP32 Gated DeltaNet kernels for Qwen3.5-style recurrent attention.

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

This file implements the single-token recurrent update used by the qwen3next / Gated DeltaNet path in llama.cpp.

Per head, matching llama.cpp qwen35/qwen3next autoregressive DeltaNet: q_scaled = q / sqrt(state_dim) // q and k arrive pre-normalized k_hat = k beta_s = sigmoid(beta) gate = exp(g) S = gate * S_prev kv_mem = S^T * k_hat delta = (v - kv_mem) * beta_s S_new = S + outer(k_hat, delta) out = S_new^T * q_scaled

Design:

  • *_ref is the scalar reference implementation.
  • *_avx keeps a simple 1-row vector walk.
  • *_avx2 precomputes scaled q rows and unrolls the state sweep in row pairs to reduce loop overhead and layout churn.
  • The public dispatcher selects the best compiled ISA unless strict parity is enabled, in which case it falls back to *_ref.

Definition in file deltanet_kernels.c.

Macro Definition Documentation

◆ CK_DELTANET_LLAMA_CHUNK_MAX_DIM

#define CK_DELTANET_LLAMA_CHUNK_MAX_DIM   256

Definition at line 54 of file deltanet_kernels.c.

◆ CK_DELTANET_LLAMA_CHUNK_SIZE

#define CK_DELTANET_LLAMA_CHUNK_SIZE   64

Definition at line 53 of file deltanet_kernels.c.

◆ CK_DELTANET_MAX_STACK_DIM

#define CK_DELTANET_MAX_STACK_DIM   4096

Definition at line 52 of file deltanet_kernels.c.

◆ CK_DELTANET_NOINLINE

#define CK_DELTANET_NOINLINE

Definition at line 59 of file deltanet_kernels.c.

Typedef Documentation

◆ ck_deltanet_libm_f32_fn

typedef float(* ck_deltanet_libm_f32_fn) (float)

Definition at line 62 of file deltanet_kernels.c.

◆ ck_deltanet_mkl_vsexp_fn

typedef void(* ck_deltanet_mkl_vsexp_fn) (int, const float *, float *)

Definition at line 99 of file deltanet_kernels.c.

Function Documentation

◆ ck_bind_deltanet_llama_libm()

static void ck_bind_deltanet_llama_libm ( void  )
static

Definition at line 67 of file deltanet_kernels.c.

68{
69 ck_deltanet_libm_handle = dlopen("libm.so.6", RTLD_NOW | RTLD_LOCAL);
73 }
75 fprintf(stderr,
76 "HARD KERNEL CONTRACT FAULT: llama.cpp DeltaNet requires "
77 "expf from libm.so.6\n");
78 abort();
79 }
80}
static ck_deltanet_libm_f32_fn ck_deltanet_llama_expf
static void * ck_deltanet_libm_handle
float(* ck_deltanet_libm_f32_fn)(float)

References ck_deltanet_libm_handle, and ck_deltanet_llama_expf.

Referenced by ck_deltanet_llama_sigmoidf(), gated_deltanet_llama_avx2_grouped_forward_impl(), and gated_deltanet_llama_avx2_grouped_forward_transposed_impl().

◆ ck_bind_deltanet_pytorch_primitives()

static void ck_bind_deltanet_pytorch_primitives ( void  )
static

Definition at line 104 of file deltanet_kernels.c.

105{
106 const char *mkl_library = getenv("CK_MKL_LIBRARY");
107 if (mkl_library && *mkl_library) {
108 ck_deltanet_mkl_handle = dlopen(mkl_library, RTLD_NOW | RTLD_LOCAL);
112 ck_deltanet_mkl_handle, "vsExp");
113 }
114 } else {
116 (ck_deltanet_mkl_vsexp_fn)dlsym(RTLD_DEFAULT, "vsExp");
117 }
118
119#if defined(__AVX512F__)
120 const char *library = getenv("CK_SLEEF_LIBRARY");
121 if (library && *library) {
122 ck_deltanet_sleef_handle = dlopen(library, RTLD_NOW | RTLD_LOCAL);
123 if (ck_deltanet_sleef_handle) {
124 ck_deltanet_pytorch_expf16 =
125 (ck_deltanet_sleef_expf16_fn)dlsym(
126 ck_deltanet_sleef_handle, "Sleef_expf16_u10");
127 }
128 } else {
129 ck_deltanet_pytorch_expf16 =
130 (ck_deltanet_sleef_expf16_fn)dlsym(
131 RTLD_DEFAULT, "Sleef_expf16_u10");
132 }
133#endif
134}
#define RTLD_DEFAULT
static ck_deltanet_mkl_vsexp_fn ck_deltanet_pytorch_vsexp
void(* ck_deltanet_mkl_vsexp_fn)(int, const float *, float *)
static void * ck_deltanet_mkl_handle

References ck_deltanet_mkl_handle, ck_deltanet_pytorch_vsexp, and RTLD_DEFAULT.

Referenced by ck_deltanet_pytorch_gate_values().

◆ ck_deltanet_ceil_log2()

static int ck_deltanet_ceil_log2 ( int  value)
static

Definition at line 812 of file deltanet_kernels.c.

813{
814 int result = 0;
815 int power = 1;
816 while (power < value) {
817 power <<= 1;
818 ++result;
819 }
820 return result;
821}

Referenced by ck_deltanet_pytorch_outer_sum().

◆ ck_deltanet_force_ref()

static int ck_deltanet_force_ref ( void  )
static

Definition at line 1884 of file deltanet_kernels.c.

1885{
1886 const char *env = getenv("CK_DELTANET_FORCE_REF");
1887 return env && atoi(env) != 0;
1888}

Referenced by gated_deltanet_autoregressive_forward(), and gated_deltanet_impl_name().

◆ ck_deltanet_llama_sigmoidf()

static float ck_deltanet_llama_sigmoidf ( float  x)
inlinestatic

Definition at line 87 of file deltanet_kernels.c.

88{
90 return 1.0f / (1.0f + ck_deltanet_llama_expf(-x));
91}
static pthread_once_t ck_deltanet_libm_once
static void ck_bind_deltanet_llama_libm(void)

References ck_bind_deltanet_llama_libm(), ck_deltanet_libm_once, and ck_deltanet_llama_expf.

Referenced by gated_deltanet_llama_avx2_grouped_forward_impl(), and gated_deltanet_llama_avx2_grouped_forward_transposed_impl().

◆ ck_deltanet_pytorch_gate_values()

static void ck_deltanet_pytorch_gate_values ( const float *  g,
const float *  beta,
float *  gate_values,
float *  beta_values,
int  num_heads 
)
static

Definition at line 136 of file deltanet_kernels.c.

141{
142 pthread_once(
146 fprintf(stderr,
147 "HARD KERNEL CONTRACT FAULT: PyTorch DeltaNet requires "
148 "MKL vsExp; set CK_MKL_LIBRARY\n");
149 abort();
150 }
151 ck_deltanet_pytorch_vsexp(num_heads, g, gate_values);
152
153 int h = 0;
154#if defined(__AVX512F__)
155 if (ck_deltanet_pytorch_expf16) {
156 const __m512 one = _mm512_set1_ps(1.0f);
157 for (; h + 15 < num_heads; h += 16) {
158 const __m512 bv = _mm512_loadu_ps(beta + h);
159 const __m512 beta_exp = ck_deltanet_pytorch_expf16(
160 _mm512_sub_ps(_mm512_setzero_ps(), bv));
161 const __m512 beta_sigmoid = _mm512_div_ps(
162 one, _mm512_add_ps(one, beta_exp));
163 float beta_lanes[16];
164 _mm512_storeu_ps(beta_lanes, beta_sigmoid);
165 for (int lane = 0; lane < 16; ++lane) {
166 beta_values[h + lane] = bf16_to_float(
167 float_to_bf16(beta_lanes[lane]));
168 }
169 }
170 }
171#endif
172 for (; h < num_heads; ++h) {
173 beta_values[h] = bf16_to_float(float_to_bf16(
174 ck_deltanet_sigmoidf(beta[h])));
175 }
176}
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
static void ck_bind_deltanet_pytorch_primitives(void)
static pthread_once_t ck_deltanet_pytorch_primitives_once
static float ck_deltanet_sigmoidf(float x)

References bf16_to_float(), ck_bind_deltanet_pytorch_primitives(), ck_deltanet_pytorch_primitives_once, ck_deltanet_pytorch_vsexp, ck_deltanet_sigmoidf(), and float_to_bf16().

Referenced by gated_deltanet_pytorch_gate_values_debug(), and gated_deltanet_pytorch_grouped_bf16_forward_impl().

◆ ck_deltanet_pytorch_outer_sum()

static void ck_deltanet_pytorch_outer_sum ( const float *  matrix,
const float *  row_weights,
float *  output,
int  state_dim 
)
static

Definition at line 826 of file deltanet_kernels.c.

830{
831 const int num_levels = 4;
832 int level_power = ck_deltanet_ceil_log2(state_dim) / num_levels;
833 if (level_power < 4) {
834 level_power = 4;
835 }
836 const int level_step = 1 << level_power;
837 const int level_mask = level_step - 1;
838 int col = 0;
839
840#if defined(__AVX512F__)
841 /* PyTorch vectorized_outer_sum reduces four adjacent vectors together. */
842 for (; col + 63 < state_dim; col += 64) {
843 __m512 acc[4][4];
844 for (int level = 0; level < num_levels; ++level) {
845 for (int block = 0; block < 4; ++block) {
846 acc[level][block] = _mm512_setzero_ps();
847 }
848 }
849
850 int i = 0;
851 for (; i + level_step <= state_dim;) {
852 for (int j = 0; j < level_step; ++j, ++i) {
853 const float *row = matrix + (size_t)i * (size_t)state_dim + col;
854 const __m512 weight = _mm512_set1_ps(row_weights[i]);
855 for (int block = 0; block < 4; ++block) {
856 const __m512 product = _mm512_mul_ps(
857 _mm512_loadu_ps(row + block * 16), weight);
858 acc[0][block] = _mm512_add_ps(acc[0][block], product);
859 }
860 }
861
862 for (int level = 1; level < num_levels; ++level) {
863 for (int block = 0; block < 4; ++block) {
864 acc[level][block] = _mm512_add_ps(
865 acc[level][block], acc[level - 1][block]);
866 acc[level - 1][block] = _mm512_setzero_ps();
867 }
868 const int mask = level_mask << (level * level_power);
869 if ((i & mask) != 0) {
870 break;
871 }
872 }
873 }
874
875 for (; i < state_dim; ++i) {
876 const float *row = matrix + (size_t)i * (size_t)state_dim + col;
877 const __m512 weight = _mm512_set1_ps(row_weights[i]);
878 for (int block = 0; block < 4; ++block) {
879 const __m512 product = _mm512_mul_ps(
880 _mm512_loadu_ps(row + block * 16), weight);
881 acc[0][block] = _mm512_add_ps(acc[0][block], product);
882 }
883 }
884
885 for (int level = 1; level < num_levels; ++level) {
886 for (int block = 0; block < 4; ++block) {
887 acc[0][block] = _mm512_add_ps(
888 acc[0][block], acc[level][block]);
889 }
890 }
891 for (int block = 0; block < 4; ++block) {
892 _mm512_storeu_ps(output + col + block * 16, acc[0][block]);
893 }
894 }
895#elif defined(__AVX2__)
896 for (; col + 31 < state_dim; col += 32) {
897 __m256 acc[4][4];
898 for (int level = 0; level < num_levels; ++level) {
899 for (int block = 0; block < 4; ++block) {
900 acc[level][block] = _mm256_setzero_ps();
901 }
902 }
903
904 int i = 0;
905 for (; i + level_step <= state_dim;) {
906 for (int j = 0; j < level_step; ++j, ++i) {
907 const float *row = matrix + (size_t)i * (size_t)state_dim + col;
908 const __m256 weight = _mm256_set1_ps(row_weights[i]);
909 for (int block = 0; block < 4; ++block) {
910 const __m256 product = _mm256_mul_ps(
911 _mm256_loadu_ps(row + block * 8), weight);
912 acc[0][block] = _mm256_add_ps(acc[0][block], product);
913 }
914 }
915 for (int level = 1; level < num_levels; ++level) {
916 for (int block = 0; block < 4; ++block) {
917 acc[level][block] = _mm256_add_ps(
918 acc[level][block], acc[level - 1][block]);
919 acc[level - 1][block] = _mm256_setzero_ps();
920 }
921 const int mask = level_mask << (level * level_power);
922 if ((i & mask) != 0) {
923 break;
924 }
925 }
926 }
927 for (; i < state_dim; ++i) {
928 const float *row = matrix + (size_t)i * (size_t)state_dim + col;
929 const __m256 weight = _mm256_set1_ps(row_weights[i]);
930 for (int block = 0; block < 4; ++block) {
931 const __m256 product = _mm256_mul_ps(
932 _mm256_loadu_ps(row + block * 8), weight);
933 acc[0][block] = _mm256_add_ps(acc[0][block], product);
934 }
935 }
936 for (int level = 1; level < num_levels; ++level) {
937 for (int block = 0; block < 4; ++block) {
938 acc[0][block] = _mm256_add_ps(
939 acc[0][block], acc[level][block]);
940 }
941 }
942 for (int block = 0; block < 4; ++block) {
943 _mm256_storeu_ps(output + col + block * 8, acc[0][block]);
944 }
945 }
946#endif
947
948 /* Production Qwen dimensions are covered above. Keep a deterministic
949 * scalar fallback for uncommon tail widths. */
950 for (; col < state_dim; ++col) {
951 float sum = 0.0f;
952 for (int row = 0; row < state_dim; ++row) {
953 sum += matrix[(size_t)row * (size_t)state_dim + col] *
954 row_weights[row];
955 }
956 output[col] = sum;
957 }
958}
static int ck_deltanet_ceil_log2(int value)
int32_t int32_t int32_t int32_t int32_t mask
Definition tokenizer.h:234

References ck_deltanet_ceil_log2(), and mask.

Referenced by gated_deltanet_pytorch_grouped_bf16_forward_impl().

◆ ck_deltanet_sigmoidf()

static float ck_deltanet_sigmoidf ( float  x)
inlinestatic

◆ gated_deltanet_autoregressive_backward()

void gated_deltanet_autoregressive_backward ( const float *  d_out,
const float *  d_state_out,
const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
const float *  state_out,
float *  d_q,
float *  d_k,
float *  d_v,
float *  d_g,
float *  d_beta,
float *  d_state_in,
int  num_heads,
int  state_dim,
float  norm_eps 
)

Definition at line 1988 of file deltanet_kernels.c.

2006{
2007 if (!d_out || !d_state_out || !q || !k || !v || !g || !beta || !state_in || !state_out ||
2008 !d_q || !d_k || !d_v || !d_g || !d_beta || !d_state_in) {
2009 return;
2010 }
2011 if (num_heads <= 0 || state_dim <= 0 || state_dim > CK_DELTANET_MAX_STACK_DIM) {
2012 return;
2013 }
2014
2016 d_out,
2017 d_state_out,
2018 q,
2019 k,
2020 v,
2021 g,
2022 beta,
2023 state_in,
2024 state_out,
2025 d_q,
2026 d_k,
2027 d_v,
2028 d_g,
2029 d_beta,
2030 d_state_in,
2031 num_heads,
2032 state_dim,
2033 norm_eps);
2034}
#define CK_DELTANET_MAX_STACK_DIM
void gated_deltanet_autoregressive_backward_ref(const float *d_out, const float *d_state_out, const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, const float *state_out, float *d_q, float *d_k, float *d_v, float *d_g, float *d_beta, float *d_state_in, int num_heads, int state_dim, float norm_eps)

References CK_DELTANET_MAX_STACK_DIM, and gated_deltanet_autoregressive_backward_ref().

◆ gated_deltanet_autoregressive_backward_ref()

void gated_deltanet_autoregressive_backward_ref ( const float *  d_out,
const float *  d_state_out,
const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
const float *  state_out,
float *  d_q,
float *  d_k,
float *  d_v,
float *  d_g,
float *  d_beta,
float *  d_state_in,
int  num_heads,
int  state_dim,
float  norm_eps 
)

Definition at line 1339 of file deltanet_kernels.c.

1357{
1358 const float q_scale = 1.0f / sqrtf((float)state_dim);
1359 const size_t vec_stride = (size_t)state_dim;
1360 const size_t state_stride = (size_t)state_dim * (size_t)state_dim;
1361
1362 float q_hat[CK_DELTANET_MAX_STACK_DIM];
1363 float k_hat[CK_DELTANET_MAX_STACK_DIM];
1364 float kv_mem[CK_DELTANET_MAX_STACK_DIM];
1365 float delta[CK_DELTANET_MAX_STACK_DIM];
1366 float d_q_hat[CK_DELTANET_MAX_STACK_DIM];
1367 float d_k_hat[CK_DELTANET_MAX_STACK_DIM];
1368 float d_mem[CK_DELTANET_MAX_STACK_DIM];
1369
1370 for (int h = 0; h < num_heads; ++h) {
1371 const float *d_out_head = d_out + (size_t)h * vec_stride;
1372 const float *d_state_out_head = d_state_out + (size_t)h * state_stride;
1373 const float *q_head = q + (size_t)h * vec_stride;
1374 const float *k_head = k + (size_t)h * vec_stride;
1375 const float *v_head = v + (size_t)h * vec_stride;
1376 const float *state_prev = state_in + (size_t)h * state_stride;
1377 const float *state_cur = state_out + (size_t)h * state_stride;
1378 float *d_q_head = d_q + (size_t)h * vec_stride;
1379 float *d_k_head = d_k + (size_t)h * vec_stride;
1380 float *d_v_head = d_v + (size_t)h * vec_stride;
1381 float *d_state_prev = d_state_in + (size_t)h * state_stride;
1382
1383 const float beta_s = ck_deltanet_sigmoidf(beta[h]);
1384 const float gate = expf(g[h]);
1385
1386 float qk_dot = 0.0f;
1387 float out_delta_dot = 0.0f;
1388 float beta_acc = 0.0f;
1389 float gate_acc = 0.0f;
1390
1391 for (int i = 0; i < state_dim; ++i) {
1392 q_hat[i] = q_head[i] * q_scale;
1393 k_hat[i] = k_head[i];
1394 kv_mem[i] = 0.0f;
1395 d_q_hat[i] = 0.0f;
1396 d_k_hat[i] = 0.0f;
1397 d_mem[i] = 0.0f;
1398 d_v_head[i] = 0.0f;
1399 qk_dot += q_hat[i] * k_hat[i];
1400 }
1401
1402 for (int col = 0; col < state_dim; ++col) {
1403 float mem = 0.0f;
1404 for (int row = 0; row < state_dim; ++row) {
1405 mem += (state_prev[(size_t)row * (size_t)state_dim + (size_t)col] * gate) * k_hat[row];
1406 }
1407 kv_mem[col] = mem;
1408 delta[col] = (v_head[col] - mem) * beta_s;
1409 out_delta_dot += d_out_head[col] * delta[col];
1410 }
1411
1412 for (int row = 0; row < state_dim; ++row) {
1413 const size_t row_off = (size_t)row * (size_t)state_dim;
1414 float dq_acc = 0.0f;
1415 float dk_acc = q_hat[row] * out_delta_dot;
1416 for (int col = 0; col < state_dim; ++col) {
1417 const float d_state_direct = d_state_out_head[row_off + (size_t)col];
1418 dq_acc += state_cur[row_off + (size_t)col] * d_out_head[col];
1419 dk_acc += d_state_direct * delta[col];
1420 }
1421 d_q_hat[row] = dq_acc;
1422 d_k_hat[row] = dk_acc;
1423 }
1424
1425 for (int col = 0; col < state_dim; ++col) {
1426 float d_delta_acc = d_out_head[col] * qk_dot;
1427 for (int row = 0; row < state_dim; ++row) {
1428 d_delta_acc += d_state_out_head[(size_t)row * (size_t)state_dim + (size_t)col] * k_hat[row];
1429 }
1430
1431 d_v_head[col] = beta_s * d_delta_acc;
1432 d_mem[col] = -beta_s * d_delta_acc;
1433 beta_acc += d_delta_acc * (v_head[col] - kv_mem[col]);
1434 }
1435
1436 for (int row = 0; row < state_dim; ++row) {
1437 const size_t row_off = (size_t)row * (size_t)state_dim;
1438 float s_dm_acc = 0.0f;
1439 for (int col = 0; col < state_dim; ++col) {
1440 s_dm_acc += (state_prev[row_off + (size_t)col] * gate) * d_mem[col];
1441 }
1442 d_k_hat[row] += s_dm_acc;
1443 }
1444
1445 for (int row = 0; row < state_dim; ++row) {
1446 const size_t row_off = (size_t)row * (size_t)state_dim;
1447 for (int col = 0; col < state_dim; ++col) {
1448 const float d_state_total = d_state_out_head[row_off + (size_t)col]
1449 + q_hat[row] * d_out_head[col]
1450 + k_hat[row] * d_mem[col];
1451 d_state_prev[row_off + (size_t)col] = gate * d_state_total;
1452 gate_acc += d_state_total * state_prev[row_off + (size_t)col];
1453 }
1454 }
1455
1456 for (int i = 0; i < state_dim; ++i) {
1457 d_q_head[i] = d_q_hat[i] * q_scale;
1458 d_k_head[i] = d_k_hat[i];
1459 }
1460
1461 d_g[h] = gate_acc * gate;
1462 d_beta[h] = beta_acc * beta_s * (1.0f - beta_s);
1463 }
1464}

References CK_DELTANET_MAX_STACK_DIM, and ck_deltanet_sigmoidf().

Referenced by gated_deltanet_autoregressive_backward().

◆ gated_deltanet_autoregressive_forward()

void gated_deltanet_autoregressive_forward ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
int  num_heads,
int  state_dim,
float  norm_eps 
)

Definition at line 1906 of file deltanet_kernels.c.

1917{
1918 if (!q || !k || !v || !g || !beta || !state_in || !state_out || !out) {
1919 return;
1920 }
1921 if (num_heads <= 0 || state_dim <= 0) {
1922 return;
1923 }
1924
1925 /*
1926 * q and k arrive pre-normalized by recurrent_qk_l2_norm, so the
1927 * ISA-specialized kernels can follow the same contract as the scalar ref.
1928 */
1931 q, k, v, g, beta, state_in, state_out, out, num_heads, state_dim, norm_eps);
1932 return;
1933 }
1934#if defined(__AVX512F__)
1935 gated_deltanet_autoregressive_forward_avx512(
1936 q, k, v, g, beta, state_in, state_out, out, num_heads, state_dim, norm_eps);
1937#elif defined(__AVX2__)
1938 gated_deltanet_autoregressive_forward_avx2(
1939 q, k, v, g, beta, state_in, state_out, out, num_heads, state_dim, norm_eps);
1940#elif defined(__AVX__)
1941 gated_deltanet_autoregressive_forward_avx(
1942 q, k, v, g, beta, state_in, state_out, out, num_heads, state_dim, norm_eps);
1943#else
1945 q, k, v, g, beta, state_in, state_out, out, num_heads, state_dim, norm_eps);
1946#endif
1947}
int ck_strict_parity_enabled(void)
void gated_deltanet_autoregressive_forward_ref(const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int num_heads, int state_dim, float norm_eps)
static int ck_deltanet_force_ref(void)

References ck_deltanet_force_ref(), ck_strict_parity_enabled(), and gated_deltanet_autoregressive_forward_ref().

Referenced by ck_test_gated_deltanet_autoregressive(), and gated_deltanet_prefill_forward().

◆ gated_deltanet_autoregressive_forward_ref()

void gated_deltanet_autoregressive_forward_ref ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
int  num_heads,
int  state_dim,
float  norm_eps 
)

Definition at line 1280 of file deltanet_kernels.c.

1291{
1292 const float q_scale = 1.0f / sqrtf((float)state_dim);
1293 const size_t vec_stride = (size_t)state_dim;
1294 const size_t state_stride = (size_t)state_dim * (size_t)state_dim;
1295
1296 for (int h = 0; h < num_heads; ++h) {
1297 const float *q_head = q + (size_t)h * vec_stride;
1298 const float *k_head = k + (size_t)h * vec_stride;
1299 const float *v_head = v + (size_t)h * vec_stride;
1300 const float *state_prev = state_in + (size_t)h * state_stride;
1301 float *state_cur = state_out + (size_t)h * state_stride;
1302 float *out_head = out + (size_t)h * vec_stride;
1303
1304 const float beta_s = ck_deltanet_sigmoidf(beta[h]);
1305 const float gate = expf(g[h]);
1306
1307 for (int row = 0; row < state_dim; ++row) {
1308 const size_t row_off = (size_t)row * (size_t)state_dim;
1309 for (int col = 0; col < state_dim; ++col) {
1310 state_cur[row_off + (size_t)col] = state_prev[row_off + (size_t)col] * gate;
1311 }
1312 }
1313
1314 for (int col = 0; col < state_dim; ++col) {
1315 float kv_mem = 0.0f;
1316 for (int row = 0; row < state_dim; ++row) {
1317 const float k_hat = k_head[row];
1318 kv_mem += state_cur[(size_t)row * (size_t)state_dim + (size_t)col] * k_hat;
1319 }
1320
1321 const float delta = (v_head[col] - kv_mem) * beta_s;
1322 for (int row = 0; row < state_dim; ++row) {
1323 const float k_hat = k_head[row];
1324 state_cur[(size_t)row * (size_t)state_dim + (size_t)col] += k_hat * delta;
1325 }
1326 }
1327
1328 for (int col = 0; col < state_dim; ++col) {
1329 float acc = 0.0f;
1330 for (int row = 0; row < state_dim; ++row) {
1331 const float q_hat = q_head[row] * q_scale;
1332 acc += state_cur[(size_t)row * (size_t)state_dim + (size_t)col] * q_hat;
1333 }
1334 out_head[col] = acc;
1335 }
1336 }
1337}

References ck_deltanet_sigmoidf().

Referenced by gated_deltanet_autoregressive_forward(), and gated_deltanet_llama_avx2_grouped_forward_impl().

◆ gated_deltanet_impl_name()

const char * gated_deltanet_impl_name ( void  )

Definition at line 1890 of file deltanet_kernels.c.

1891{
1893 return "REF";
1894 }
1895#if defined(__AVX512F__)
1896 return "AVX512";
1897#elif defined(__AVX2__)
1898 return "AVX2";
1899#elif defined(__AVX__)
1900 return "AVX";
1901#else
1902 return "REF";
1903#endif
1904}

References ck_deltanet_force_ref(), and ck_strict_parity_enabled().

◆ gated_deltanet_llama_avx2_forward()

void gated_deltanet_llama_avx2_forward ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
int  num_heads,
int  group_count,
int  state_dim,
float  norm_eps 
)

Definition at line 767 of file deltanet_kernels.c.

779{
781 q, k, v, g, beta, state_in, state_out, out,
782 num_heads, group_count, state_dim, norm_eps, 0, num_heads);
783}
static void gated_deltanet_llama_avx2_grouped_forward_transposed_impl(const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int num_heads, int group_count, int state_dim, float norm_eps, int head_begin, int head_end)

References gated_deltanet_llama_avx2_grouped_forward_transposed_impl().

Referenced by gated_deltanet_llama_avx2_prefill_forward().

◆ gated_deltanet_llama_avx2_forward_head_range()

void gated_deltanet_llama_avx2_forward_head_range ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
int  num_heads,
int  group_count,
int  state_dim,
float  norm_eps,
int  head_begin,
int  head_end 
)

Definition at line 790 of file deltanet_kernels.c.

805{
807 q, k, v, g, beta, state_in, state_out, out,
808 num_heads, group_count, state_dim, norm_eps,
809 head_begin, head_end);
810}

References gated_deltanet_llama_avx2_grouped_forward_transposed_impl().

◆ gated_deltanet_llama_avx2_grouped_forward_impl()

static void gated_deltanet_llama_avx2_grouped_forward_impl ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
int  num_heads,
int  group_count,
int  state_dim,
float  norm_eps,
int  head_begin,
int  head_end,
int  pytorch_bf16_boundaries 
)
static

Definition at line 574 of file deltanet_kernels.c.

590{
591#if defined(__AVX2__)
592 (void) norm_eps;
593 if (!q || !k || !v || !g || !beta || !state_in || !state_out || !out ||
594 num_heads <= 0 || num_heads > CK_DELTANET_MAX_STACK_DIM ||
595 group_count <= 0 || num_heads % group_count != 0 ||
596 state_dim <= 0 || state_dim > CK_DELTANET_MAX_STACK_DIM ||
597 head_begin < 0 || head_end < head_begin || head_end > num_heads) {
598 return;
599 }
600 const float scale = ck_deltanet_llama_scale(state_dim);
601 const size_t vector_stride = (size_t) state_dim;
602 const size_t state_stride = (size_t) state_dim * (size_t) state_dim;
603 float column[CK_DELTANET_MAX_STACK_DIM];
604 float q_scaled[CK_DELTANET_MAX_STACK_DIM];
605
606 for (int h = head_begin; h < head_end; ++h) {
607 /* llama.cpp ggml_repeat_4d tiles compact Q/K heads (0..G-1 repeated),
608 * while the PyTorch Qwen3-Next reference uses repeat_interleave so
609 * each compact head owns H/G adjacent value heads. These layouts
610 * are distinct numerical contracts even though their buffer shapes
611 * are identical. */
612 const int group = pytorch_bf16_boundaries
613 ? h / (num_heads / group_count)
614 : h % group_count;
615 const float *q_head = q + (size_t) group * vector_stride;
616 const float *k_head = k + (size_t) group * vector_stride;
617 const float *v_head = v + (size_t) h * vector_stride;
618 const float *state_prev = state_in + (size_t) h * state_stride;
619 float *state_cur = state_out + (size_t) h * state_stride;
620 float *out_head = out + (size_t) h * vector_stride;
621 float gate;
622 float beta_s;
623 if (pytorch_bf16_boundaries) {
624 gate = expf(g[h]);
625 beta_s = ck_deltanet_sigmoidf(beta[h]);
626 } else {
628 gate = ck_deltanet_llama_expf(g[h]);
629 beta_s = ck_deltanet_llama_sigmoidf(beta[h]);
630 }
631 if (pytorch_bf16_boundaries) {
632 beta_s = bf16_to_float(float_to_bf16(beta_s));
633 for (int row = 0; row < state_dim; ++row) {
634 q_scaled[row] = q_head[row] * scale;
635 }
636 }
637
638 for (int row = 0; row < state_dim; ++row) {
639 const size_t row_offset = (size_t) row * (size_t) state_dim;
640 for (int col = 0; col < state_dim; ++col) {
641 state_cur[row_offset + (size_t) col] =
642 state_prev[row_offset + (size_t) col] * gate;
643 }
644 }
645
646 for (int col = 0; col < state_dim; ++col) {
647 for (int row = 0; row < state_dim; ++row) {
648 column[row] = state_cur[(size_t) row * (size_t) state_dim + (size_t) col];
649 }
650 const float memory = ck_deltanet_llama_avx2_dot(column, k_head, state_dim);
651 const float delta = (v_head[col] - memory) * beta_s;
652 for (int row = 0; row < state_dim; ++row) {
653 const size_t offset = (size_t) row * (size_t) state_dim + (size_t) col;
654#if defined(__FMA__)
655 const float updated = fmaf(k_head[row], delta, state_cur[offset]);
656#else
657 const float updated = state_cur[offset] + k_head[row] * delta;
658#endif
659 state_cur[offset] = updated;
660 column[row] = updated;
661 }
662 if (pytorch_bf16_boundaries) {
663 out_head[col] =
664 ck_deltanet_llama_avx2_dot(column, q_scaled, state_dim);
665 } else {
666 out_head[col] =
667 ck_deltanet_llama_avx2_dot(column, q_head, state_dim) * scale;
668 }
669 }
670 }
671#else
672 if (group_count != num_heads) {
673 return;
674 }
676 q, k, v, g, beta, state_in, state_out, out,
677 num_heads, state_dim, norm_eps);
678#endif
679}
static float ck_deltanet_llama_sigmoidf(float x)

References bf16_to_float(), ck_bind_deltanet_llama_libm(), ck_deltanet_libm_once, ck_deltanet_llama_expf, ck_deltanet_llama_sigmoidf(), CK_DELTANET_MAX_STACK_DIM, ck_deltanet_sigmoidf(), float_to_bf16(), and gated_deltanet_autoregressive_forward_ref().

◆ gated_deltanet_llama_avx2_grouped_forward_transposed_impl()

static void gated_deltanet_llama_avx2_grouped_forward_transposed_impl ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
int  num_heads,
int  group_count,
int  state_dim,
float  norm_eps,
int  head_begin,
int  head_end 
)
static

Definition at line 687 of file deltanet_kernels.c.

702{
703#if defined(__AVX2__)
704 (void) norm_eps;
705 if (!q || !k || !v || !g || !beta || !state_in || !state_out || !out ||
706 num_heads <= 0 || group_count <= 0 || num_heads % group_count != 0 ||
707 state_dim <= 0 || state_dim > CK_DELTANET_MAX_STACK_DIM ||
708 head_begin < 0 || head_end < head_begin || head_end > num_heads) {
709 return;
710 }
711 const float scale = ck_deltanet_llama_scale(state_dim);
712 const size_t vector_stride = (size_t) state_dim;
713 const size_t state_stride = (size_t) state_dim * (size_t) state_dim;
714
716 for (int h = head_begin; h < head_end; ++h) {
717 const int group = h % group_count;
718 const float *q_head = q + (size_t) group * vector_stride;
719 const float *k_head = k + (size_t) group * vector_stride;
720 const float *v_head = v + (size_t) h * vector_stride;
721 const float *state_prev = state_in + (size_t) h * state_stride;
722 float *state_cur = state_out + (size_t) h * state_stride;
723 float *out_head = out + (size_t) h * vector_stride;
724 const float gate = ck_deltanet_llama_expf(g[h]);
725 const float beta_s = ck_deltanet_llama_sigmoidf(beta[h]);
726
727 for (int col = 0; col < state_dim; ++col) {
728 const float *prev_col = state_prev + (size_t) col * vector_stride;
729 float *cur_col = state_cur + (size_t) col * vector_stride;
730 int row = 0;
731 const __m256 gate8 = _mm256_set1_ps(gate);
732 for (; row + 7 < state_dim; row += 8) {
733 const __m256 scaled = _mm256_mul_ps(
734 _mm256_loadu_ps(prev_col + row), gate8);
735 _mm256_storeu_ps(cur_col + row, scaled);
736 }
737 for (; row < state_dim; ++row) {
738 cur_col[row] = prev_col[row] * gate;
739 }
740
741 const float memory =
742 ck_deltanet_llama_avx2_dot(cur_col, k_head, state_dim);
743 const float delta = (v_head[col] - memory) * beta_s;
744 row = 0;
745 const __m256 delta8 = _mm256_set1_ps(delta);
746 for (; row + 7 < state_dim; row += 8) {
747 const __m256 updated = _mm256_fmadd_ps(
748 _mm256_loadu_ps(k_head + row), delta8,
749 _mm256_loadu_ps(cur_col + row));
750 _mm256_storeu_ps(cur_col + row, updated);
751 }
752 for (; row < state_dim; ++row) {
753 cur_col[row] = fmaf(k_head[row], delta, cur_col[row]);
754 }
755 out_head[col] =
756 ck_deltanet_llama_avx2_dot(cur_col, q_head, state_dim) * scale;
757 }
758 }
759#else
760 (void)q; (void)k; (void)v; (void)g; (void)beta;
761 (void)state_in; (void)state_out; (void)out;
762 (void)num_heads; (void)group_count; (void)state_dim; (void)norm_eps;
763 (void)head_begin; (void)head_end;
764#endif
765}

References ck_bind_deltanet_llama_libm(), ck_deltanet_libm_once, ck_deltanet_llama_expf, ck_deltanet_llama_sigmoidf(), and CK_DELTANET_MAX_STACK_DIM.

Referenced by gated_deltanet_llama_avx2_forward(), and gated_deltanet_llama_avx2_forward_head_range().

◆ gated_deltanet_llama_avx2_prefill_forward()

void gated_deltanet_llama_avx2_prefill_forward ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
int  rows,
int  num_heads,
int  group_count,
int  state_dim,
float  norm_eps 
)

Definition at line 1131 of file deltanet_kernels.c.

1144{
1145 if (!q || !k || !v || !g || !beta || !state_in || !state_out || !out ||
1146 rows <= 0 || num_heads <= 0 || group_count <= 0 ||
1147 num_heads % group_count != 0 || state_dim <= 0) {
1148 return;
1149 }
1150 const size_t qk_stride = (size_t) group_count * (size_t) state_dim;
1151 const size_t value_stride = (size_t) num_heads * (size_t) state_dim;
1152 const size_t gate_stride = (size_t) num_heads;
1153 for (int row = 0; row < rows; ++row) {
1155 q + (size_t) row * qk_stride,
1156 k + (size_t) row * qk_stride,
1157 v + (size_t) row * value_stride,
1158 g + (size_t) row * gate_stride,
1159 beta + (size_t) row * gate_stride,
1160 row == 0 ? state_in : state_out,
1161 state_out,
1162 out + (size_t) row * value_stride,
1163 num_heads, group_count, state_dim, norm_eps);
1164 }
1165}
void gated_deltanet_llama_avx2_forward(const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int num_heads, int group_count, int state_dim, float norm_eps)

References gated_deltanet_llama_avx2_forward().

Referenced by gated_deltanet_llama_chunk64_prefill_forward().

◆ gated_deltanet_llama_chunk64_head_forward()

void gated_deltanet_llama_chunk64_head_forward ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
int  rows,
int  num_heads,
int  group_count,
int  head,
int  state_dim 
)

Definition at line 1202 of file deltanet_kernels.c.

1215{
1216#if defined(__AVX2__)
1217 if (!q || !k || !v || !g || !beta || !state_in || !state_out || !out ||
1218 rows <= 0 || num_heads <= 0 || group_count <= 0 ||
1219 num_heads % group_count != 0 || head < 0 || head >= num_heads ||
1220 state_dim <= 0 || state_dim > CK_DELTANET_LLAMA_CHUNK_MAX_DIM) {
1221 return;
1222 }
1223 gated_deltanet_llama_chunk64_head(
1224 q, k, v, g, beta, state_in, state_out, out,
1225 rows, num_heads, group_count, head, state_dim);
1226#else
1227 (void)q;
1228 (void)k;
1229 (void)v;
1230 (void)g;
1231 (void)beta;
1232 (void)state_in;
1233 (void)state_out;
1234 (void)out;
1235 (void)rows;
1236 (void)num_heads;
1237 (void)group_count;
1238 (void)head;
1239 (void)state_dim;
1240#endif
1241}
#define CK_DELTANET_LLAMA_CHUNK_MAX_DIM

References CK_DELTANET_LLAMA_CHUNK_MAX_DIM.

◆ gated_deltanet_llama_chunk64_prefill_forward()

void gated_deltanet_llama_chunk64_prefill_forward ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
int  rows,
int  num_heads,
int  group_count,
int  state_dim,
float  norm_eps 
)

Definition at line 1167 of file deltanet_kernels.c.

1180{
1181 if (!q || !k || !v || !g || !beta || !state_in || !state_out || !out ||
1182 rows <= 0 || num_heads <= 0 || group_count <= 0 ||
1183 num_heads % group_count != 0 || state_dim <= 0) {
1184 return;
1185 }
1186#if defined(__AVX2__)
1187 (void)norm_eps;
1188 if (state_dim <= CK_DELTANET_LLAMA_CHUNK_MAX_DIM) {
1189 for (int head = 0; head < num_heads; ++head) {
1190 gated_deltanet_llama_chunk64_head(
1191 q, k, v, g, beta, state_in, state_out, out,
1192 rows, num_heads, group_count, head, state_dim);
1193 }
1194 return;
1195 }
1196#endif
1198 q, k, v, g, beta, state_in, state_out, out,
1199 rows, num_heads, group_count, state_dim, norm_eps);
1200}
void gated_deltanet_llama_avx2_prefill_forward(const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int rows, int num_heads, int group_count, int state_dim, float norm_eps)

References CK_DELTANET_LLAMA_CHUNK_MAX_DIM, and gated_deltanet_llama_avx2_prefill_forward().

◆ gated_deltanet_prefill_forward()

void gated_deltanet_prefill_forward ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
int  rows,
int  num_heads,
int  state_dim,
float  norm_eps 
)

Definition at line 1949 of file deltanet_kernels.c.

1961{
1962 if (!q || !k || !v || !g || !beta || !state_in || !state_out || !out) {
1963 return;
1964 }
1965 if (rows <= 0 || num_heads <= 0 || state_dim <= 0) {
1966 return;
1967 }
1968
1969 const size_t vector_stride = (size_t)num_heads * (size_t)state_dim;
1970 const size_t gate_stride = (size_t)num_heads;
1971 for (int row = 0; row < rows; ++row) {
1972 const float *row_state_in = row == 0 ? state_in : state_out;
1974 q + (size_t)row * vector_stride,
1975 k + (size_t)row * vector_stride,
1976 v + (size_t)row * vector_stride,
1977 g + (size_t)row * gate_stride,
1978 beta + (size_t)row * gate_stride,
1979 row_state_in,
1980 state_out,
1981 out + (size_t)row * vector_stride,
1982 num_heads,
1983 state_dim,
1984 norm_eps);
1985 }
1986}
void gated_deltanet_autoregressive_forward(const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int num_heads, int state_dim, float norm_eps)

References gated_deltanet_autoregressive_forward().

◆ gated_deltanet_pytorch_gate_values_debug()

void gated_deltanet_pytorch_gate_values_debug ( const float *  g,
const float *  beta,
float *  gate_values,
float *  beta_values,
int  num_heads 
)

Definition at line 178 of file deltanet_kernels.c.

183{
184 if (!g || !beta || !gate_values || !beta_values || num_heads <= 0 ||
185 num_heads > CK_DELTANET_MAX_STACK_DIM) {
186 return;
187 }
189 g, beta, gate_values, beta_values, num_heads);
190}
static void ck_deltanet_pytorch_gate_values(const float *g, const float *beta, float *gate_values, float *beta_values, int num_heads)

References CK_DELTANET_MAX_STACK_DIM, and ck_deltanet_pytorch_gate_values().

◆ gated_deltanet_pytorch_grouped_bf16_forward()

void gated_deltanet_pytorch_grouped_bf16_forward ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
int  num_heads,
int  group_count,
int  state_dim,
float  norm_eps 
)

Definition at line 1089 of file deltanet_kernels.c.

1101{
1103 q, k, v, g, beta, state_in, state_out, out,
1104 NULL, NULL, NULL,
1105 num_heads, group_count, state_dim, norm_eps);
1106}
static void gated_deltanet_pytorch_grouped_bf16_forward_impl(const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, float *debug_decayed_state, float *debug_memory, float *debug_delta, int num_heads, int group_count, int state_dim, float norm_eps)

References gated_deltanet_pytorch_grouped_bf16_forward_impl().

Referenced by gated_deltanet_pytorch_grouped_bf16_prefill_forward().

◆ gated_deltanet_pytorch_grouped_bf16_forward_debug()

void gated_deltanet_pytorch_grouped_bf16_forward_debug ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
float *  decayed_state,
float *  memory,
float *  delta,
int  num_heads,
int  group_count,
int  state_dim,
float  norm_eps 
)

Definition at line 1108 of file deltanet_kernels.c.

1124{
1126 q, k, v, g, beta, state_in, state_out, out,
1127 decayed_state, memory, delta,
1128 num_heads, group_count, state_dim, norm_eps);
1129}

References gated_deltanet_pytorch_grouped_bf16_forward_impl().

◆ gated_deltanet_pytorch_grouped_bf16_forward_impl()

static void gated_deltanet_pytorch_grouped_bf16_forward_impl ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
float *  debug_decayed_state,
float *  debug_memory,
float *  debug_delta,
int  num_heads,
int  group_count,
int  state_dim,
float  norm_eps 
)
static

Definition at line 963 of file deltanet_kernels.c.

979{
980 (void)norm_eps;
981 if (!q || !k || !v || !g || !beta || !state_in || !state_out || !out ||
982 num_heads <= 0 || group_count <= 0 || num_heads % group_count != 0 ||
983 state_dim <= 0 || state_dim > CK_DELTANET_MAX_STACK_DIM) {
984 return;
985 }
986
987 const size_t vector_stride = (size_t)state_dim;
988 const size_t state_stride = vector_stride * vector_stride;
989 const int heads_per_group = num_heads / group_count;
990 const float sqrt_dim = sqrtf((float)state_dim);
991 float gate_values[CK_DELTANET_MAX_STACK_DIM];
992 float beta_values[CK_DELTANET_MAX_STACK_DIM];
993 float memory[CK_DELTANET_MAX_STACK_DIM];
994 float delta[CK_DELTANET_MAX_STACK_DIM];
995 float q_scaled[CK_DELTANET_MAX_STACK_DIM];
997 g, beta, gate_values, beta_values, num_heads);
998
999 for (int h = 0; h < num_heads; ++h) {
1000 const int group = h / heads_per_group;
1001 const float *q_head = q + (size_t)group * vector_stride;
1002 const float *k_head = k + (size_t)group * vector_stride;
1003 const float *v_head = v + (size_t)h * vector_stride;
1004 const float *state_prev = state_in + (size_t)h * state_stride;
1005 float *state_cur = state_out + (size_t)h * state_stride;
1006 float *out_head = out + (size_t)h * vector_stride;
1007
1008 for (int col = 0; col < state_dim; ++col) {
1009 q_scaled[col] = q_head[col] / sqrt_dim;
1010 }
1011
1012 /* Materialize the decayed state before the separately ordered sum. */
1013 for (int row = 0; row < state_dim; ++row) {
1014 const size_t row_offset = (size_t)row * vector_stride;
1015 int col = 0;
1016#if defined(__AVX2__)
1017 const __m256 gate8 = _mm256_set1_ps(gate_values[h]);
1018 for (; col + 7 < state_dim; col += 8) {
1019 const __m256 state = _mm256_mul_ps(
1020 _mm256_loadu_ps(state_prev + row_offset + (size_t)col),
1021 gate8);
1022 _mm256_storeu_ps(state_cur + row_offset + (size_t)col, state);
1023 }
1024#endif
1025 for (; col < state_dim; ++col) {
1026 const size_t offset = row_offset + (size_t)col;
1027 const float state = state_prev[offset] * gate_values[h];
1028 state_cur[offset] = state;
1029 }
1030 }
1031
1033 state_cur, k_head, memory, state_dim);
1034
1035 if (debug_decayed_state) {
1036 memcpy(
1037 debug_decayed_state + (size_t)h * state_stride,
1038 state_cur,
1039 state_stride * sizeof(float));
1040 }
1041 if (debug_memory) {
1042 memcpy(
1043 debug_memory + (size_t)h * vector_stride,
1044 memory,
1045 vector_stride * sizeof(float));
1046 }
1047
1048 for (int col = 0; col < state_dim; ++col) {
1049 delta[col] = (v_head[col] - memory[col]) * beta_values[h];
1050 }
1051 if (debug_delta) {
1052 memcpy(
1053 debug_delta + (size_t)h * vector_stride,
1054 delta,
1055 vector_stride * sizeof(float));
1056 }
1057
1058 for (int row = 0; row < state_dim; ++row) {
1059 const size_t row_offset = (size_t)row * vector_stride;
1060 const float key = k_head[row];
1061 int col = 0;
1062#if defined(__AVX2__)
1063 const __m256 key8 = _mm256_set1_ps(key);
1064 for (; col + 7 < state_dim; col += 8) {
1065 const __m256 update = _mm256_mul_ps(
1066 key8, _mm256_loadu_ps(delta + col));
1067 const __m256 state = _mm256_add_ps(
1068 _mm256_loadu_ps(state_cur + row_offset + (size_t)col),
1069 update);
1070 _mm256_storeu_ps(state_cur + row_offset + (size_t)col, state);
1071 }
1072#endif
1073 for (; col < state_dim; ++col) {
1074 const size_t offset = row_offset + (size_t)col;
1075 const float state = state_cur[offset] + key * delta[col];
1076 state_cur[offset] = state;
1077 }
1078 }
1079
1081 state_cur, q_scaled, out_head, state_dim);
1082
1083 for (int col = 0; col < state_dim; ++col) {
1084 out_head[col] = bf16_to_float(float_to_bf16(out_head[col]));
1085 }
1086 }
1087}
static void ck_deltanet_pytorch_outer_sum(const float *matrix, const float *row_weights, float *output, int state_dim)

References bf16_to_float(), CK_DELTANET_MAX_STACK_DIM, ck_deltanet_pytorch_gate_values(), ck_deltanet_pytorch_outer_sum(), and float_to_bf16().

Referenced by gated_deltanet_pytorch_grouped_bf16_forward(), and gated_deltanet_pytorch_grouped_bf16_forward_debug().

◆ gated_deltanet_pytorch_grouped_bf16_prefill_forward()

void gated_deltanet_pytorch_grouped_bf16_prefill_forward ( const float *  q,
const float *  k,
const float *  v,
const float *  g,
const float *  beta,
const float *  state_in,
float *  state_out,
float *  out,
int  rows,
int  num_heads,
int  group_count,
int  state_dim,
float  norm_eps 
)

Definition at line 1243 of file deltanet_kernels.c.

1257{
1258 if (!q || !k || !v || !g || !beta || !state_in || !state_out || !out ||
1259 rows <= 0 || num_heads <= 0 || group_count <= 0 ||
1260 num_heads % group_count != 0 || state_dim <= 0) {
1261 return;
1262 }
1263 const size_t qk_stride = (size_t)group_count * (size_t)state_dim;
1264 const size_t value_stride = (size_t)num_heads * (size_t)state_dim;
1265 const size_t gate_stride = (size_t)num_heads;
1266 for (int row = 0; row < rows; ++row) {
1268 q + (size_t)row * qk_stride,
1269 k + (size_t)row * qk_stride,
1270 v + (size_t)row * value_stride,
1271 g + (size_t)row * gate_stride,
1272 beta + (size_t)row * gate_stride,
1273 row == 0 ? state_in : state_out,
1274 state_out,
1275 out + (size_t)row * value_stride,
1276 num_heads, group_count, state_dim, norm_eps);
1277 }
1278}
void gated_deltanet_pytorch_grouped_bf16_forward(const float *q, const float *k, const float *v, const float *g, const float *beta, const float *state_in, float *state_out, float *out, int num_heads, int group_count, int state_dim, float norm_eps)

References gated_deltanet_pytorch_grouped_bf16_forward().

Variable Documentation

◆ ck_deltanet_libm_handle

void* ck_deltanet_libm_handle = NULL
static

Definition at line 64 of file deltanet_kernels.c.

Referenced by ck_bind_deltanet_llama_libm().

◆ ck_deltanet_libm_once

pthread_once_t ck_deltanet_libm_once = PTHREAD_ONCE_INIT
static

◆ ck_deltanet_llama_expf

◆ ck_deltanet_mkl_handle

void* ck_deltanet_mkl_handle = NULL
static

Definition at line 101 of file deltanet_kernels.c.

Referenced by ck_bind_deltanet_pytorch_primitives().

◆ ck_deltanet_pytorch_primitives_once

pthread_once_t ck_deltanet_pytorch_primitives_once = PTHREAD_ONCE_INIT
static

Definition at line 102 of file deltanet_kernels.c.

Referenced by ck_deltanet_pytorch_gate_values().

◆ ck_deltanet_pytorch_vsexp

ck_deltanet_mkl_vsexp_fn ck_deltanet_pytorch_vsexp = NULL
static