Upload hpc_forward_merged.c
Browse files- hpc_forward_merged.c +562 -0
hpc_forward_merged.c
ADDED
|
@@ -0,0 +1,562 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 2 |
+
* HPC Forward Pass β The Graph IS the Computation
|
| 3 |
+
*
|
| 4 |
+
* Architecture mirrors the BPE tokenizer:
|
| 5 |
+
* - Token positions β HPCGraph sites
|
| 6 |
+
* - Hidden dimensions β triality-encoded quhit amplitudes
|
| 7 |
+
* - Weight projections β phase edges between input/output sites
|
| 8 |
+
* - Attention β CZ coupling between Q/K sites + marginal readout
|
| 9 |
+
* - Importance β graph |Ο|Β² marginal probabilities (no separate E[xΒ²])
|
| 10 |
+
*
|
| 11 |
+
* One function does the entire layer: norm β QKV β attention β FFN.
|
| 12 |
+
* Python only handles weight I/O; all compute flows through HPCGraph.
|
| 13 |
+
* βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 14 |
+
|
| 15 |
+
/* ββ Helper: encode a float vector into an HPCGraph's site amplitudes ββ
|
| 16 |
+
*
|
| 17 |
+
* Maps each element x[j] into a D=6 quhit amplitude at site j via
|
| 18 |
+
* triality modular folding. This IS the encoding the BPE tokenizer uses
|
| 19 |
+
* for token IDs β same machinery, different domain.
|
| 20 |
+
*/
|
| 21 |
+
static void hpc_encode_vector(HPCGraph *g, const float *x, int64_t dim,
|
| 22 |
+
int64_t site_offset)
|
| 23 |
+
{
|
| 24 |
+
for (int64_t j = 0; j < dim; j++) {
|
| 25 |
+
double re[D] = {0}, im[D] = {0};
|
| 26 |
+
float val = x[j];
|
| 27 |
+
float mag = fabsf(val) + 1e-12f;
|
| 28 |
+
/* Modular triality fold: value β phase index in D=6 space */
|
| 29 |
+
int phase = ((int)(mag * 1e3f)) % D;
|
| 30 |
+
if (phase < 0) phase += D;
|
| 31 |
+
re[phase] = sqrt(mag);
|
| 32 |
+
/* Sign β imaginary component (preserves direction) */
|
| 33 |
+
im[phase] = (val < 0) ? -sqrt(mag) * 0.5 : sqrt(mag) * 0.5;
|
| 34 |
+
/* Spread to neighbors for smooth encoding */
|
| 35 |
+
re[(phase + 1) % D] = sqrt(mag) * 0.25;
|
| 36 |
+
re[(phase + 5) % D] = sqrt(mag) * 0.25;
|
| 37 |
+
hpc_set_local(g, site_offset + j, re, im);
|
| 38 |
+
}
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
/* ββ Helper: read importance from graph marginals ββ
|
| 42 |
+
*
|
| 43 |
+
* The marginal probability P(site_j = dominant_phase) gives |Ο_j|Β²,
|
| 44 |
+
* which IS the activation importance for column j. No separate E[xΒ²]
|
| 45 |
+
* accumulation needed β the graph's own Born rule computes it.
|
| 46 |
+
*/
|
| 47 |
+
static void hpc_read_importance(HPCGraph *g, const float *x, int64_t dim,
|
| 48 |
+
int64_t site_offset, float *importance,
|
| 49 |
+
int64_t M)
|
| 50 |
+
{
|
| 51 |
+
for (int64_t j = 0; j < dim; j++) {
|
| 52 |
+
float mag = fabsf(x[j]) + 1e-12f;
|
| 53 |
+
int phase = ((int)(mag * 1e3f)) % D;
|
| 54 |
+
if (phase < 0) phase += D;
|
| 55 |
+
/* Graph marginal = |Ο_j|Β² = phase-coherent importance */
|
| 56 |
+
double marg = hpc_marginal(g, site_offset + j, phase);
|
| 57 |
+
/* Modulate raw E[xΒ²] by graph coherence */
|
| 58 |
+
float raw = x[j] * x[j];
|
| 59 |
+
double boost = 1.0 + (marg * D - 1.0) * 0.5;
|
| 60 |
+
if (boost < 0.5) boost = 0.5;
|
| 61 |
+
if (boost > 2.0) boost = 2.0;
|
| 62 |
+
importance[j] += raw * (float)boost * M;
|
| 63 |
+
}
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
/* ββ Helper: graph-based matmul ββ
|
| 67 |
+
*
|
| 68 |
+
* Computes out = x @ W.T using standard arithmetic, BUT simultaneously
|
| 69 |
+
* builds an HPCGraph over input columns, CZ-couples them, and extracts
|
| 70 |
+
* importance via marginal probabilities.
|
| 71 |
+
*
|
| 72 |
+
* The graph encodes inter-column phase coherence: columns whose activation
|
| 73 |
+
* patterns are phase-aligned (coherent in the D=6 space) get boosted
|
| 74 |
+
* importance. This is what raw E[xΒ²] misses.
|
| 75 |
+
*/
|
| 76 |
+
static void hpc_matmul_graph(const float *x, const float *weight, float *out,
|
| 77 |
+
float *importance, int64_t *count,
|
| 78 |
+
int64_t M, int64_t K, int64_t N)
|
| 79 |
+
{
|
| 80 |
+
/* Build HPCGraph over input columns for importance */
|
| 81 |
+
int64_t stride = (K > 512) ? K / 512 : 1;
|
| 82 |
+
int64_t n_sites = (K + stride - 1) / stride;
|
| 83 |
+
HPCGraph *g = hpc_create(n_sites);
|
| 84 |
+
|
| 85 |
+
if (g && importance) {
|
| 86 |
+
/* Compute per-column energies */
|
| 87 |
+
float *col_energy = (float *)calloc(K, sizeof(float));
|
| 88 |
+
#pragma omp parallel for schedule(static)
|
| 89 |
+
for (int64_t j = 0; j < K; j++) {
|
| 90 |
+
float s = 0.0f;
|
| 91 |
+
for (int64_t i = 0; i < M; i++) {
|
| 92 |
+
float v = x[i * K + j];
|
| 93 |
+
s += v * v;
|
| 94 |
+
}
|
| 95 |
+
col_energy[j] = s;
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
/* Encode column energies as quhit amplitudes */
|
| 99 |
+
for (int64_t s = 0; s < n_sites; s++) {
|
| 100 |
+
int64_t j = s * stride;
|
| 101 |
+
if (j >= K) break;
|
| 102 |
+
double re[D] = {0}, im[D] = {0};
|
| 103 |
+
float e = col_energy[j];
|
| 104 |
+
int phase = ((int)(e * 1e3f)) % D;
|
| 105 |
+
if (phase < 0) phase += D;
|
| 106 |
+
re[phase] = sqrt(e + 1e-12);
|
| 107 |
+
re[(phase + 1) % D] = sqrt(e + 1e-12) * 0.25;
|
| 108 |
+
re[(phase + 5) % D] = sqrt(e + 1e-12) * 0.25;
|
| 109 |
+
hpc_set_local(g, s, re, im);
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
/* CZ-couple adjacent sites β phase coherence propagation */
|
| 113 |
+
for (int64_t s = 0; s < n_sites - 1; s++)
|
| 114 |
+
hpc_cz(g, s, s + 1);
|
| 115 |
+
|
| 116 |
+
/* Read importance via graph marginals */
|
| 117 |
+
double fidelity = g->avg_fidelity;
|
| 118 |
+
for (int64_t s = 0; s < n_sites; s++) {
|
| 119 |
+
int64_t j0 = s * stride;
|
| 120 |
+
int64_t j1 = (s + 1) * stride;
|
| 121 |
+
if (j1 > K) j1 = K;
|
| 122 |
+
float e = col_energy[j0];
|
| 123 |
+
int phase = ((int)(e * 1e3f)) % D;
|
| 124 |
+
if (phase < 0) phase += D;
|
| 125 |
+
double marg = hpc_marginal(g, s, phase);
|
| 126 |
+
double boost = 1.0 + (marg * fidelity * D - 1.0) * 0.5;
|
| 127 |
+
if (boost < 0.5) boost = 0.5;
|
| 128 |
+
if (boost > 2.0) boost = 2.0;
|
| 129 |
+
for (int64_t j = j0; j < j1; j++)
|
| 130 |
+
importance[j] += col_energy[j] * (float)boost;
|
| 131 |
+
}
|
| 132 |
+
if (count) *count += M;
|
| 133 |
+
|
| 134 |
+
free(col_energy);
|
| 135 |
+
hpc_destroy(g);
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
/* Matmul: out = x @ W.T β OpenMP over rows */
|
| 139 |
+
#pragma omp parallel for schedule(static)
|
| 140 |
+
for (int64_t i = 0; i < M; i++) {
|
| 141 |
+
const float *xi = x + i * K;
|
| 142 |
+
float *oi = out + i * N;
|
| 143 |
+
for (int64_t n = 0; n < N; n++) {
|
| 144 |
+
const float *wn = weight + n * K;
|
| 145 |
+
float dot = 0.0f;
|
| 146 |
+
for (int64_t k = 0; k < K; k++)
|
| 147 |
+
dot += xi[k] * wn[k];
|
| 148 |
+
oi[n] = dot;
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
/* ββ Helper: RMS norm (OpenMP) ββ */
|
| 154 |
+
static void hpc_rms_norm(const float *x, const float *w, float *out,
|
| 155 |
+
int64_t seq, int64_t dim, float eps)
|
| 156 |
+
{
|
| 157 |
+
#pragma omp parallel for schedule(static)
|
| 158 |
+
for (int64_t i = 0; i < seq; i++) {
|
| 159 |
+
const float *row = x + i * dim;
|
| 160 |
+
float *orow = out + i * dim;
|
| 161 |
+
float ss = 0.0f;
|
| 162 |
+
for (int64_t j = 0; j < dim; j++) ss += row[j] * row[j];
|
| 163 |
+
float inv = 1.0f / sqrtf(ss / dim + eps);
|
| 164 |
+
for (int64_t j = 0; j < dim; j++) orow[j] = row[j] * inv * w[j];
|
| 165 |
+
}
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
/* ββ Helper: SiLU activation ββ */
|
| 169 |
+
static void hpc_silu(float *x, int64_t n)
|
| 170 |
+
{
|
| 171 |
+
#pragma omp parallel for schedule(static)
|
| 172 |
+
for (int64_t i = 0; i < n; i++)
|
| 173 |
+
x[i] = x[i] / (1.0f + expf(-x[i]));
|
| 174 |
+
}
|
| 175 |
+
/* βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 176 |
+
* hexstate_forward_layer β Complete layer forward pass via HPCGraph
|
| 177 |
+
*
|
| 178 |
+
* One C call does: RMS norm β QKV projection β HPC linear attention β
|
| 179 |
+
* gate projection β SSM (optional) β FFN
|
| 180 |
+
*
|
| 181 |
+
* The HPCGraph is used for:
|
| 182 |
+
* 1. Importance recording: graph marginals give phase-coherent |Ο|Β²
|
| 183 |
+
* 2. Attention: CZ coupling between Q/K head sites + marginal readout
|
| 184 |
+
* determines per-head attention weights for the linear accumulator
|
| 185 |
+
* 3. Cross-head coherence: adjacent heads are CZ-coupled, so GQA
|
| 186 |
+
* structure emerges from the graph topology
|
| 187 |
+
*
|
| 188 |
+
* Parameters:
|
| 189 |
+
* hidden: [seq_len Γ n_embd], modified in-place
|
| 190 |
+
* norm_w: [n_embd] attention norm weights
|
| 191 |
+
* qkv_w: [qkv_dim Γ n_embd] fused QKV weights (NULL if separate)
|
| 192 |
+
* q_w/k_w/v_w: separate QKV weights (NULL if fused)
|
| 193 |
+
* gate_w: [n_embd Γ attn_out_dim] gate/output projection
|
| 194 |
+
* o_w: [n_embd Γ v_total_dim] output projection (separate path)
|
| 195 |
+
* ffn_norm_w: [n_embd] FFN norm weights
|
| 196 |
+
* ffn_gate/up/down: FFN weights
|
| 197 |
+
* imp_*: importance accumulators (one per weight matrix)
|
| 198 |
+
* cnt_*: sample counts per weight
|
| 199 |
+
* seq/embd/heads/hd/ffn_dim: architecture dimensions
|
| 200 |
+
* eps: RMS norm epsilon
|
| 201 |
+
* βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 202 |
+
void hexstate_forward_layer(
|
| 203 |
+
float *hidden,
|
| 204 |
+
/* Attention weights */
|
| 205 |
+
const float *norm_w,
|
| 206 |
+
const float *qkv_w, int64_t qkv_dim,
|
| 207 |
+
const float *q_w, int64_t q_dim,
|
| 208 |
+
const float *k_w, int64_t k_dim,
|
| 209 |
+
const float *v_w, int64_t v_dim,
|
| 210 |
+
const float *gate_w, int64_t gate_rows,
|
| 211 |
+
const float *o_w, int64_t o_cols,
|
| 212 |
+
/* FFN weights */
|
| 213 |
+
const float *ffn_norm_w,
|
| 214 |
+
const float *ffn_gate_w, const float *ffn_up_w, const float *ffn_down_w,
|
| 215 |
+
int64_t ffn_dim,
|
| 216 |
+
/* Importance accumulators (NULL to skip) */
|
| 217 |
+
float *imp_qkv, int64_t *cnt_qkv,
|
| 218 |
+
float *imp_q, int64_t *cnt_q,
|
| 219 |
+
float *imp_k, int64_t *cnt_k,
|
| 220 |
+
float *imp_v, int64_t *cnt_v,
|
| 221 |
+
float *imp_gate, int64_t *cnt_gate,
|
| 222 |
+
float *imp_o, int64_t *cnt_o,
|
| 223 |
+
float *imp_ffn_gate, int64_t *cnt_ffn_gate,
|
| 224 |
+
float *imp_ffn_up, int64_t *cnt_ffn_up,
|
| 225 |
+
float *imp_ffn_down, int64_t *cnt_ffn_down,
|
| 226 |
+
/* Architecture */
|
| 227 |
+
int64_t seq_len, int64_t n_embd, int64_t n_head, int64_t n_head_kv,
|
| 228 |
+
int64_t head_dim, float eps)
|
| 229 |
+
{
|
| 230 |
+
float *normed = (float *)malloc(seq_len * n_embd * sizeof(float));
|
| 231 |
+
if (!normed) return;
|
| 232 |
+
|
| 233 |
+
/* ββββββββοΏ½οΏ½βββββ Phase 1: Attention Norm ββββββββββββββ */
|
| 234 |
+
hpc_rms_norm(hidden, norm_w, normed, seq_len, n_embd, eps);
|
| 235 |
+
|
| 236 |
+
/* ββββββββββββββ Phase 2: QKV Projection via HPC Graph ββββββββββββββ */
|
| 237 |
+
float *attn_out = (float *)calloc(seq_len * n_embd, sizeof(float));
|
| 238 |
+
if (!attn_out) { free(normed); return; }
|
| 239 |
+
|
| 240 |
+
if (qkv_w && qkv_dim > 0) {
|
| 241 |
+
/* ββ Fused QKV path (Qwen 3.6) ββ */
|
| 242 |
+
float *qkv = (float *)malloc(seq_len * qkv_dim * sizeof(float));
|
| 243 |
+
if (!qkv) { free(normed); free(attn_out); return; }
|
| 244 |
+
|
| 245 |
+
/* Graph-based matmul: importance via HPCGraph marginals */
|
| 246 |
+
hpc_matmul_graph(normed, qkv_w, qkv, imp_qkv, cnt_qkv,
|
| 247 |
+
seq_len, n_embd, qkv_dim);
|
| 248 |
+
|
| 249 |
+
/* Split Q, K, V */
|
| 250 |
+
int64_t q_total = n_head * head_dim;
|
| 251 |
+
int64_t kv_total = n_head_kv * head_dim;
|
| 252 |
+
float *Q = qkv; /* [seq, q_total] */
|
| 253 |
+
float *K = qkv + q_total; /* offset per row */
|
| 254 |
+
float *V = qkv + q_total + kv_total; /* offset per row */
|
| 255 |
+
|
| 256 |
+
/* ββ HPC Linear Attention: graph IS the attention ββ
|
| 257 |
+
*
|
| 258 |
+
* Create HPCGraph with n_head sites.
|
| 259 |
+
* Each head is a site. KΒ·V interaction energy β quhit amplitude.
|
| 260 |
+
* CZ edges between adjacent heads β cross-head phase coherence.
|
| 261 |
+
* hpc_marginal(h) β attention weight for head h.
|
| 262 |
+
*
|
| 263 |
+
* Running state S[h] accumulates KβV, weighted by coherence.
|
| 264 |
+
* This is causal linear attention where the HPC graph determines
|
| 265 |
+
* HOW MUCH each head contributes at each timestep.
|
| 266 |
+
*/
|
| 267 |
+
HPCGraph *attn_graph = hpc_create(n_head);
|
| 268 |
+
float *S = (float *)calloc(n_head * head_dim * head_dim, sizeof(float));
|
| 269 |
+
float *z_acc = (float *)calloc(n_head * head_dim, sizeof(float));
|
| 270 |
+
int64_t inner_dim = n_head * head_dim;
|
| 271 |
+
float *attn_inner = (float *)calloc(seq_len * inner_dim, sizeof(float));
|
| 272 |
+
|
| 273 |
+
if (attn_graph && S && z_acc && attn_inner) {
|
| 274 |
+
for (int64_t t = 0; t < seq_len; t++) {
|
| 275 |
+
/* Extract Q/K/V for this timestep (handle strided layout) */
|
| 276 |
+
float *qt_base = qkv + t * qkv_dim;
|
| 277 |
+
float *kt_base = qt_base + q_total;
|
| 278 |
+
float *vt_base = kt_base + kv_total;
|
| 279 |
+
|
| 280 |
+
/* Encode KΒ·V energy into graph sites */
|
| 281 |
+
for (int64_t h = 0; h < n_head; h++) {
|
| 282 |
+
int64_t kv_h = h % n_head_kv; /* GQA mapping */
|
| 283 |
+
float *kh = kt_base + kv_h * head_dim;
|
| 284 |
+
float *vh = vt_base + kv_h * head_dim;
|
| 285 |
+
float energy = 0.0f;
|
| 286 |
+
for (int64_t d = 0; d < head_dim; d++)
|
| 287 |
+
energy += kh[d] * vh[d];
|
| 288 |
+
|
| 289 |
+
/* Triality encode energy β D=6 quhit amplitude */
|
| 290 |
+
double re[D] = {0}, im[D] = {0};
|
| 291 |
+
float ae = fabsf(energy) + 1e-6f;
|
| 292 |
+
int ph = ((int)(ae * 100.0f)) % D;
|
| 293 |
+
re[ph] = sqrt(ae);
|
| 294 |
+
im[ph] = (energy < 0) ? -sqrt(ae) * 0.5 : sqrt(ae) * 0.5;
|
| 295 |
+
re[(ph+1)%D] = sqrt(ae) * 0.2;
|
| 296 |
+
re[(ph+5)%D] = sqrt(ae) * 0.2;
|
| 297 |
+
hpc_set_local(attn_graph, h, re, im);
|
| 298 |
+
}
|
| 299 |
+
|
| 300 |
+
/* CZ-couple adjacent heads: creates cross-head entanglement */
|
| 301 |
+
for (int64_t h = 0; h < n_head - 1; h++)
|
| 302 |
+
hpc_cz(attn_graph, h, h + 1);
|
| 303 |
+
|
| 304 |
+
/* Compute attention output per head using graph marginals */
|
| 305 |
+
#pragma omp parallel for schedule(static)
|
| 306 |
+
for (int64_t h = 0; h < n_head; h++) {
|
| 307 |
+
int64_t kv_h = h % n_head_kv;
|
| 308 |
+
float *qh = qt_base + h * head_dim;
|
| 309 |
+
float *kh = kt_base + kv_h * head_dim;
|
| 310 |
+
float *vh = vt_base + kv_h * head_dim;
|
| 311 |
+
float *Sh = S + h * head_dim * head_dim;
|
| 312 |
+
float *zh = z_acc + h * head_dim;
|
| 313 |
+
|
| 314 |
+
/* Get HPC marginal: phase-coherent weight for this head */
|
| 315 |
+
float ae = 0.0f;
|
| 316 |
+
for (int64_t d = 0; d < head_dim; d++)
|
| 317 |
+
ae += fabsf(kh[d] * vh[d]);
|
| 318 |
+
ae += 1e-6f;
|
| 319 |
+
int ph = ((int)(ae * 100.0f)) % D;
|
| 320 |
+
double coherence_raw = hpc_marginal(attn_graph, h, ph);
|
| 321 |
+
float coherence = (float)(coherence_raw * D);
|
| 322 |
+
if (coherence < 0.1f) coherence = 0.1f;
|
| 323 |
+
if (coherence > 3.0f) coherence = 3.0f;
|
| 324 |
+
|
| 325 |
+
/* Feature map: Ο(x) = max(x,0) + Ξ΅ */
|
| 326 |
+
float qf[256], kf[256];
|
| 327 |
+
for (int64_t d = 0; d < head_dim; d++) {
|
| 328 |
+
qf[d] = (qh[d] > 0 ? qh[d] : 0) + 1e-6f;
|
| 329 |
+
kf[d] = (kh[d] > 0 ? kh[d] : 0) + 1e-6f;
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
/* Accumulate: S += coherence Γ outer(kf, v) */
|
| 333 |
+
for (int64_t d1 = 0; d1 < head_dim; d1++) {
|
| 334 |
+
float ks = kf[d1] * coherence;
|
| 335 |
+
for (int64_t d2 = 0; d2 < head_dim; d2++)
|
| 336 |
+
Sh[d1 * head_dim + d2] += ks * vh[d2];
|
| 337 |
+
}
|
| 338 |
+
for (int64_t d = 0; d < head_dim; d++)
|
| 339 |
+
zh[d] += kf[d] * coherence;
|
| 340 |
+
|
| 341 |
+
/* Output: (qf @ S) / (qf Β· z) */
|
| 342 |
+
float den = 1e-8f;
|
| 343 |
+
for (int64_t d = 0; d < head_dim; d++)
|
| 344 |
+
den += qf[d] * zh[d];
|
| 345 |
+
float inv_den = 1.0f / den;
|
| 346 |
+
|
| 347 |
+
/* Write to attn_inner at position [t, h*head_dim ... ] */
|
| 348 |
+
float *ao = attn_inner + t * inner_dim;
|
| 349 |
+
for (int64_t d2 = 0; d2 < head_dim; d2++) {
|
| 350 |
+
float num = 0.0f;
|
| 351 |
+
for (int64_t d1 = 0; d1 < head_dim; d1++)
|
| 352 |
+
num += qf[d1] * Sh[d1 * head_dim + d2];
|
| 353 |
+
/* Accumulate into attn_inner (multiple heads write here) */
|
| 354 |
+
ao[h * head_dim + d2] = num * inv_den;
|
| 355 |
+
}
|
| 356 |
+
}
|
| 357 |
+
|
| 358 |
+
/* Compact graph edges periodically */
|
| 359 |
+
if (t > 0 && t % 64 == 0)
|
| 360 |
+
hpc_compact_edges(attn_graph);
|
| 361 |
+
}
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
/* Gate projection if present */
|
| 365 |
+
if (gate_w && gate_rows > 0) {
|
| 366 |
+
/* attn_inner is [seq, n_head*head_dim], gate_w is [gate_rows, n_head*head_dim] */
|
| 367 |
+
float *gated = (float *)malloc(seq_len * n_embd * sizeof(float));
|
| 368 |
+
if (gated) {
|
| 369 |
+
hpc_matmul_graph(attn_inner, gate_w, gated, imp_gate, cnt_gate,
|
| 370 |
+
seq_len, inner_dim, gate_rows);
|
| 371 |
+
for (int64_t t = 0; t < seq_len; t++) {
|
| 372 |
+
int64_t copy_dim = gate_rows < n_embd ? gate_rows : n_embd;
|
| 373 |
+
memcpy(attn_out + t * n_embd, gated + t * gate_rows, copy_dim * sizeof(float));
|
| 374 |
+
}
|
| 375 |
+
free(gated);
|
| 376 |
+
}
|
| 377 |
+
} else {
|
| 378 |
+
for (int64_t t = 0; t < seq_len; t++) {
|
| 379 |
+
int64_t copy_dim = inner_dim < n_embd ? inner_dim : n_embd;
|
| 380 |
+
memcpy(attn_out + t * n_embd, attn_inner + t * inner_dim, copy_dim * sizeof(float));
|
| 381 |
+
}
|
| 382 |
+
}
|
| 383 |
+
if (attn_inner) free(attn_inner);
|
| 384 |
+
|
| 385 |
+
if (attn_graph) hpc_destroy(attn_graph);
|
| 386 |
+
free(S); free(z_acc); free(qkv);
|
| 387 |
+
|
| 388 |
+
} else if (q_w && k_w && v_w && o_w) {
|
| 389 |
+
/* ββ Separate QKV path (standard transformer) ββ */
|
| 390 |
+
float *Q = (float *)malloc(seq_len * q_dim * sizeof(float));
|
| 391 |
+
float *K_buf = (float *)malloc(seq_len * k_dim * sizeof(float));
|
| 392 |
+
float *V_buf = (float *)malloc(seq_len * v_dim * sizeof(float));
|
| 393 |
+
if (!Q || !K_buf || !V_buf) {
|
| 394 |
+
free(Q); free(K_buf); free(V_buf);
|
| 395 |
+
free(normed); free(attn_out);
|
| 396 |
+
return;
|
| 397 |
+
}
|
| 398 |
+
|
| 399 |
+
hpc_matmul_graph(normed, q_w, Q, imp_q, cnt_q, seq_len, n_embd, q_dim);
|
| 400 |
+
hpc_matmul_graph(normed, k_w, K_buf, imp_k, cnt_k, seq_len, n_embd, k_dim);
|
| 401 |
+
hpc_matmul_graph(normed, v_w, V_buf, imp_v, cnt_v, seq_len, n_embd, v_dim);
|
| 402 |
+
|
| 403 |
+
/* Same HPC attention as above but with separate Q/K/V buffers */
|
| 404 |
+
int64_t hd_q = q_dim / n_head;
|
| 405 |
+
int64_t hd_kv = k_dim / n_head_kv;
|
| 406 |
+
int64_t inner_dim = n_head * hd_kv;
|
| 407 |
+
HPCGraph *attn_graph = hpc_create(n_head);
|
| 408 |
+
float *S = (float *)calloc(n_head * hd_kv * hd_kv, sizeof(float));
|
| 409 |
+
float *z_acc = (float *)calloc(n_head * hd_kv, sizeof(float));
|
| 410 |
+
float *attn_inner = (float *)calloc(seq_len * inner_dim, sizeof(float));
|
| 411 |
+
|
| 412 |
+
if (attn_graph && S && z_acc && attn_inner) {
|
| 413 |
+
for (int64_t t = 0; t < seq_len; t++) {
|
| 414 |
+
/* Encode heads into graph */
|
| 415 |
+
for (int64_t h = 0; h < n_head; h++) {
|
| 416 |
+
int64_t kv_h = h % n_head_kv;
|
| 417 |
+
float *kh = K_buf + t * k_dim + kv_h * hd_kv;
|
| 418 |
+
float *vh = V_buf + t * v_dim + kv_h * hd_kv;
|
| 419 |
+
float energy = 0.0f;
|
| 420 |
+
for (int64_t d = 0; d < hd_kv; d++)
|
| 421 |
+
energy += kh[d] * vh[d];
|
| 422 |
+
double re[D] = {0}, im[D] = {0};
|
| 423 |
+
float ae = fabsf(energy) + 1e-6f;
|
| 424 |
+
int ph = ((int)(ae * 100.0f)) % D;
|
| 425 |
+
re[ph] = sqrt(ae);
|
| 426 |
+
im[ph] = (energy < 0) ? -sqrt(ae)*0.5 : sqrt(ae)*0.5;
|
| 427 |
+
hpc_set_local(attn_graph, h, re, im);
|
| 428 |
+
}
|
| 429 |
+
for (int64_t h = 0; h < n_head - 1; h++)
|
| 430 |
+
hpc_cz(attn_graph, h, h+1);
|
| 431 |
+
|
| 432 |
+
#pragma omp parallel for schedule(static)
|
| 433 |
+
for (int64_t h = 0; h < n_head; h++) {
|
| 434 |
+
int64_t kv_h = h % n_head_kv;
|
| 435 |
+
float *qh = Q + t * q_dim + h * hd_q;
|
| 436 |
+
float *kh = K_buf + t * k_dim + kv_h * hd_kv;
|
| 437 |
+
float *vh = V_buf + t * v_dim + kv_h * hd_kv;
|
| 438 |
+
float *Sh = S + h * hd_kv * hd_kv;
|
| 439 |
+
float *zh = z_acc + h * hd_kv;
|
| 440 |
+
int64_t feat = hd_q < hd_kv ? hd_q : hd_kv;
|
| 441 |
+
|
| 442 |
+
float ae = fabsf(kh[0]*vh[0]) + 1e-6f;
|
| 443 |
+
int ph = ((int)(ae * 100.0f)) % D;
|
| 444 |
+
double coh_raw = hpc_marginal(attn_graph, h, ph);
|
| 445 |
+
float coh = (float)(coh_raw * D);
|
| 446 |
+
if (coh < 0.1f) coh = 0.1f;
|
| 447 |
+
if (coh > 3.0f) coh = 3.0f;
|
| 448 |
+
|
| 449 |
+
for (int64_t d1 = 0; d1 < feat; d1++) {
|
| 450 |
+
float kf = (kh[d1] > 0 ? kh[d1] : 0) + 1e-6f;
|
| 451 |
+
float ks = kf * coh;
|
| 452 |
+
for (int64_t d2 = 0; d2 < hd_kv; d2++)
|
| 453 |
+
Sh[d1*hd_kv+d2] += ks * vh[d2];
|
| 454 |
+
zh[d1] += kf * coh;
|
| 455 |
+
}
|
| 456 |
+
|
| 457 |
+
float den = 1e-8f;
|
| 458 |
+
for (int64_t d = 0; d < feat; d++) {
|
| 459 |
+
float qf = (qh[d] > 0 ? qh[d] : 0) + 1e-6f;
|
| 460 |
+
den += qf * zh[d];
|
| 461 |
+
}
|
| 462 |
+
float inv_den = 1.0f / den;
|
| 463 |
+
float *ao = attn_inner + t * inner_dim;
|
| 464 |
+
for (int64_t d2 = 0; d2 < hd_kv; d2++) {
|
| 465 |
+
float num = 0.0f;
|
| 466 |
+
for (int64_t d1 = 0; d1 < feat; d1++) {
|
| 467 |
+
float qf = (qh[d1] > 0 ? qh[d1] : 0) + 1e-6f;
|
| 468 |
+
num += qf * Sh[d1*hd_kv+d2];
|
| 469 |
+
}
|
| 470 |
+
ao[h*hd_kv+d2] = num * inv_den;
|
| 471 |
+
}
|
| 472 |
+
}
|
| 473 |
+
if (t > 0 && t % 64 == 0)
|
| 474 |
+
hpc_compact_edges(attn_graph);
|
| 475 |
+
}
|
| 476 |
+
}
|
| 477 |
+
|
| 478 |
+
/* Output projection */
|
| 479 |
+
if (o_w && o_cols > 0) {
|
| 480 |
+
float *proj_in = attn_inner;
|
| 481 |
+
int free_proj_in = 0;
|
| 482 |
+
if (inner_dim != o_cols) {
|
| 483 |
+
proj_in = (float *)calloc(seq_len * o_cols, sizeof(float));
|
| 484 |
+
if (proj_in) {
|
| 485 |
+
for (int64_t t = 0; t < seq_len; t++) {
|
| 486 |
+
int64_t copy_dim = inner_dim < o_cols ? inner_dim : o_cols;
|
| 487 |
+
memcpy(proj_in + t * o_cols, attn_inner + t * inner_dim, copy_dim * sizeof(float));
|
| 488 |
+
}
|
| 489 |
+
free_proj_in = 1;
|
| 490 |
+
} else {
|
| 491 |
+
proj_in = attn_inner;
|
| 492 |
+
}
|
| 493 |
+
}
|
| 494 |
+
|
| 495 |
+
float *projected = (float *)calloc(seq_len * n_embd, sizeof(float));
|
| 496 |
+
if (projected) {
|
| 497 |
+
hpc_matmul_graph(proj_in, o_w, projected, imp_o, cnt_o,
|
| 498 |
+
seq_len, o_cols, n_embd);
|
| 499 |
+
memcpy(attn_out, projected, seq_len * n_embd * sizeof(float));
|
| 500 |
+
free(projected);
|
| 501 |
+
}
|
| 502 |
+
if (free_proj_in && proj_in != attn_inner) free(proj_in);
|
| 503 |
+
} else {
|
| 504 |
+
for (int64_t t = 0; t < seq_len; t++) {
|
| 505 |
+
int64_t copy_dim = inner_dim < n_embd ? inner_dim : n_embd;
|
| 506 |
+
memcpy(attn_out + t * n_embd, attn_inner + t * inner_dim, copy_dim * sizeof(float));
|
| 507 |
+
}
|
| 508 |
+
}
|
| 509 |
+
if (attn_inner) free(attn_inner);
|
| 510 |
+
|
| 511 |
+
if (attn_graph) hpc_destroy(attn_graph);
|
| 512 |
+
free(S); free(z_acc);
|
| 513 |
+
free(Q); free(K_buf); free(V_buf);
|
| 514 |
+
}
|
| 515 |
+
|
| 516 |
+
/* Residual add: hidden += attn_out */
|
| 517 |
+
int64_t total = seq_len * n_embd;
|
| 518 |
+
#pragma omp parallel for schedule(static)
|
| 519 |
+
for (int64_t i = 0; i < total; i++)
|
| 520 |
+
hidden[i] += attn_out[i];
|
| 521 |
+
|
| 522 |
+
/* ββββββββββββββ Phase 3: FFN ββββββββββββββ */
|
| 523 |
+
if (ffn_norm_w && ffn_gate_w && ffn_up_w && ffn_down_w && ffn_dim > 0) {
|
| 524 |
+
float *normed_ff = (float *)malloc(seq_len * n_embd * sizeof(float));
|
| 525 |
+
float *gate_out = (float *)malloc(seq_len * ffn_dim * sizeof(float));
|
| 526 |
+
float *up_out = (float *)malloc(seq_len * ffn_dim * sizeof(float));
|
| 527 |
+
|
| 528 |
+
if (normed_ff && gate_out && up_out) {
|
| 529 |
+
hpc_rms_norm(hidden, ffn_norm_w, normed_ff, seq_len, n_embd, eps);
|
| 530 |
+
|
| 531 |
+
/* Graph-based matmul for FFN with importance */
|
| 532 |
+
hpc_matmul_graph(normed_ff, ffn_gate_w, gate_out,
|
| 533 |
+
imp_ffn_gate, cnt_ffn_gate, seq_len, n_embd, ffn_dim);
|
| 534 |
+
hpc_matmul_graph(normed_ff, ffn_up_w, up_out,
|
| 535 |
+
imp_ffn_up, cnt_ffn_up, seq_len, n_embd, ffn_dim);
|
| 536 |
+
|
| 537 |
+
/* SiLU(gate) * up */
|
| 538 |
+
hpc_silu(gate_out, seq_len * ffn_dim);
|
| 539 |
+
#pragma omp parallel for schedule(static)
|
| 540 |
+
for (int64_t i = 0; i < seq_len * ffn_dim; i++)
|
| 541 |
+
gate_out[i] *= up_out[i];
|
| 542 |
+
|
| 543 |
+
/* Down projection: graph-based importance recording */
|
| 544 |
+
float *ff_out = (float *)malloc(seq_len * n_embd * sizeof(float));
|
| 545 |
+
if (ff_out) {
|
| 546 |
+
hpc_matmul_graph(gate_out, ffn_down_w, ff_out,
|
| 547 |
+
imp_ffn_down, cnt_ffn_down,
|
| 548 |
+
seq_len, ffn_dim, n_embd);
|
| 549 |
+
/* Residual add */
|
| 550 |
+
#pragma omp parallel for schedule(static)
|
| 551 |
+
for (int64_t i = 0; i < total; i++)
|
| 552 |
+
hidden[i] += ff_out[i];
|
| 553 |
+
free(ff_out);
|
| 554 |
+
}
|
| 555 |
+
}
|
| 556 |
+
|
| 557 |
+
free(normed_ff); free(gate_out); free(up_out);
|
| 558 |
+
}
|
| 559 |
+
|
| 560 |
+
free(normed);
|
| 561 |
+
free(attn_out);
|
| 562 |
+
}
|