emerging.systems / phoenix_brain.c
Nicholas Bumgarner
Convert to Gradio: Phox wave-rider inference engine
a2124e2
Raw
History Blame Contribute Delete
116 kB
/* phoenix_brain.c — Pure BQSM inference: 1 settle = 1 forward pass.
*
* The ring IS the computation. No matmul. Weights are encoded as
* oscillator lens profiles, activations as phases. The 4 mode coupling
* channels (c₁×c₁→c₂, c₂×c₂→c₄, c₂×c₄→c₆, direct) compute
* products through wave interference. One settle of the ring =
* one complete forward pass through all layers.
*
* Build: cc -O3 -std=c11 -march=native -fopenmp phoenix_brain.c -o /tmp/phoenix -lm
* Run: /tmp/phoenix [model.bqsm]
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <math.h>
#include <time.h>
#include <omp.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* ── Ring geometry ── */
#define N_OSC 16
#define N_HARM 8
#define MAX_VQPUS 4096
#define MAX_CONNS (MAX_VQPUS * 8)
/* ── Settle budget ── */
#define SETTLE_STEPS 2 /* Transient capture: 2 steps, not 60 */
#define SETTLE_DT 0.01
/* ── Product channels — the 4 wave interference paths ── */
#define CH_FUND 1 /* c₁ — fundamental */
#define CH_PROD2 2 /* c₁×c₁ → c₂ (4.0× lens) */
#define CH_PROD4 4 /* c₂×c₂ → c₄ (24.38× lens, the money channel) */
#define CH_PROD6 6 /* c₂×c₄ → c₆ (10.0× lens) */
/* ── State persistence ── */
#define STATE_MAGIC 0x434D5142 /* "BQMC" */
#define STATE_VERSION 2 /* v2: vqpu_t gained train_gain (per-tendril trainable) */
/* ── 4-Ring Macro Core ── */
#define MACRO_RINGS 4
#define RING_INTAKE 0 /* activation intake — distributes to compute */
#define RING_PROC_A 1 /* primary processing hub */
#define RING_PROC_B 2 /* secondary processing hub */
#define RING_COLLECT 3 /* product aggregation + ouroboros feedback */
/* ── Checkpoint confirm windows ── */
#define CONFIRM_FAST 3
#define CONFIRM_MEDIUM 10
#define CONFIRM_SLOW 20
/* ── Roles ── */
enum role { ROLE_DORMANT, ROLE_INPUT, ROLE_PROJ, ROLE_GATE, ROLE_OUTPUT, ROLE_RESERVE };
enum tune_phase { TUNE_IDLE, TUNE_PERTURB, TUNE_EVAL, TUNE_COMMIT, TUNE_REVERT };
/* ── Self-tuning state ── */
typedef struct {
int phase;
double best_score;
double perturb_lr;
int perturb_count;
int batch_size;
int improve_count;
int revert_count;
int *train_tokens;
int n_train;
int train_pos;
double last_accuracy; /* next-token argmax accuracy of last eval batch */
/* Backup of the per-tendril gains perturbed this round, for revert */
int perturb_idx[128];
double perturb_old[128];
int n_perturbed;
} self_tune_t;
static const char *role_str[] = {"dormant","input","proj","gate","output","reserve"};
/* ── Scheduling modes ── */
enum mode { IDLE, ACTIVATE, ESCALATE, CRYSTALLIZE, MAINTAIN };
static const char *mode_str[] = {"IDLE","ACTIVATE","ESCALATE","CRYSTALLIZE","MAINTAIN"};
/* ── Modification types ── */
enum mod_type {
MOD_NONE, MOD_ADD_VQPUS, MOD_ADD_CONN, MOD_PRUNE_CONN,
MOD_ADJ_WEIGHT, MOD_RESHAPE
};
static const char *mod_str[] = {
"NONE","ADD_VQPUS","ADD_CONN","PRUNE_CONN","ADJ_WEIGHT","RESHAPE"
};
/* ═══════════════════════════════════════════════════════════════════
* SINGLE vQPU — 16 Kuramoto oscillators
* ═══════════════════════════════════════════════════════════════════ */
typedef struct {
double theta[N_OSC]; /* oscillator phases */
double omega[N_OSC]; /* lens profile = encoded weights */
double c_re[N_HARM]; /* harmonic coefficients (real) */
double c_im[N_HARM]; /* harmonic coefficients (imag) */
double c_mag[N_HARM]; /* harmonic magnitudes */
double K; /* coupling strength */
double coherence; /* |c₁| */
int active;
int age;
int role;
int layer_id; /* transformer layer assignment */
int proj_id; /* which projection (0=Wq,1=Wk,...6=Wdown) */
int col_start; /* which output column range this vQPU handles */
double utilization;
double train_gain; /* trainable per-tendril output gain (1.0 = neutral) */
} vqpu_t;
/* ── Connection ── */
typedef struct {
int src, dst;
int src_harm, dst_harm;
double weight;
double traffic;
int alive;
} conn_t;
/* ── Checkpoint ── */
typedef struct {
vqpu_t *vqpus;
conn_t *fabric;
int n_vqpus, n_connections;
double coherence;
int deadline, pending;
enum mod_type mod;
} checkpoint_t;
/* ═══════════════════════════════════════════════════════════════════
* MACRO CORE — 4 rings × 16 oscillators = 64 fixed oscillators.
* Everything else grows outward as tentacles during weight ingestion.
* The topology IS the model — discovered, not prescribed.
* ═══════════════════════════════════════════════════════════════════ */
typedef struct {
int ring_id[MACRO_RINGS]; /* vQPU index for each core ring */
/* Tendrils grown during ingestion */
int input_start, n_inputs; /* activation-holding tendrils (off INTAKE) */
int compute_start, n_compute; /* weight-processing tendrils (off PROC_A/B) */
int output_start, n_outputs; /* product-collecting tendrils (off COLLECT) */
/* Ingestion stats */
int ingestion_rounds;
int tendrils_pruned;
int tendrils_strengthened;
int ready;
} macro_core_t;
/* ── Phoenix Brain ── */
typedef struct {
vqpu_t *vqpus;
int n_vqpus;
int capacity;
conn_t *fabric;
int n_connections;
int capacity_conns;
int alive_conns;
double g_coupling[N_HARM][N_HARM];
double lens_enhance[N_HARM];
/* Backup of the trainable physics gains, for tune perturb/revert */
double g_coupling_bak[N_HARM][N_HARM];
double lens_enhance_bak[N_HARM];
enum mode mode;
int *hot_set;
int n_hot;
int cycle_count;
int total_cycles;
double ring_coherence;
double convergence_rate;
checkpoint_t ckpt;
int mod_attempts, mod_confirms, mod_reverts;
/* Model (mmap'd) */
const uint8_t *weights;
const uint8_t *weight_base;
size_t weights_size;
int D, FFN, q_dim, kv_dim, V, n_layers;
int qw, kw, vw, ow, gw, uw, dw;
int layer_bytes;
int model_loaded;
/* RMSNorm weights (loaded from end of .bqsm if present) */
float *norm_output, *norm_attn, *norm_q, *norm_k, *norm_ffn;
int has_norms;
/* Pipeline mapping: layer → vQPU groups */
int *layer_base; /* first vQPU index for each layer */
int vqpus_per_layer;
/* 4-Ring Macro Core */
macro_core_t core;
/* Output readout buffer */
double *readout;
int readout_dim;
/* Self-tuning */
self_tune_t tune;
/* Timing */
double last_settle_ms;
double last_cycle_ms;
} phoenix_t;
/* ═══════════════════════════════════════════════════════════════════
* CORE PHYSICS
* ═══════════════════════════════════════════════════════════════════ */
static double now_ms(void) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec * 1000.0 + ts.tv_nsec / 1e6;
}
static void init_coupling(phoenix_t *p) {
for (int i = 0; i < N_HARM; i++)
for (int j = 0; j < N_HARM; j++) {
double ri = 1.0 - cos(2*M_PI*i/N_OSC);
double ii = -sin(2*M_PI*i/N_OSC);
double rj = 1.0 - cos(2*M_PI*j/N_OSC);
double ij = -sin(2*M_PI*j/N_OSC);
p->g_coupling[i][j] = 0.5 * sqrt(
(ri*rj - ii*ij)*(ri*rj - ii*ij) +
(ri*ij + ii*rj)*(ri*ij + ii*rj));
}
for (int k = 0; k < N_HARM; k++) p->lens_enhance[k] = 1.0;
p->lens_enhance[CH_PROD4] = 24.38; /* (2,2)→4 channel */
p->lens_enhance[CH_PROD2] = 4.0; /* (1,1)→2 channel */
p->lens_enhance[CH_PROD6] = 10.0; /* (2,4)→6 channel */
}
/* ── Kuramoto step ── */
static void vqpu_step(vqpu_t *v) {
double dth[N_OSC];
for (int i = 0; i < N_OSC; i++) {
double c = 0;
for (int j = 0; j < N_OSC; j++)
c += sin(v->theta[j] - v->theta[i]);
dth[i] = v->omega[i] + (v->K / N_OSC) * c;
}
for (int i = 0; i < N_OSC; i++)
v->theta[i] += SETTLE_DT * dth[i];
}
/* ── DFT: extract harmonic coefficients from phases ── */
static void vqpu_dft(vqpu_t *v) {
for (int k = 0; k < N_HARM; k++) {
double re = 0, im = 0;
for (int n = 0; n < N_OSC; n++) {
double a = 2.0 * M_PI * k * n / N_OSC;
re += cos(v->theta[n] - a);
im += sin(v->theta[n] - a);
}
v->c_re[k] = re / N_OSC;
v->c_im[k] = im / N_OSC;
v->c_mag[k] = sqrt(re*re + im*im) / N_OSC;
}
v->coherence = v->c_mag[CH_FUND];
}
/* ── Mode coupling product: the wave interference computation ── */
static double vqpu_product(const vqpu_t *v, int p, int q,
const double g[N_HARM][N_HARM],
const double enh[N_HARM]) {
double prod_re = v->c_re[p] * v->c_re[q] - v->c_im[p] * v->c_im[q];
int k = (p + q) % N_HARM;
return prod_re * g[p][q] * enh[k];
}
/* ── Read all 4 product channels from a settled vQPU ── */
static double vqpu_read_products(const vqpu_t *v,
const double g[N_HARM][N_HARM],
const double enh[N_HARM]) {
double sum = 0;
/* Channel 1: c₁×c₁ → c₂ (fundamental self-product, 4× lens) */
sum += vqpu_product(v, 1, 1, g, enh);
/* Channel 2: c₂×c₂ → c₄ (24.38× lens, highest gain) */
sum += vqpu_product(v, 2, 2, g, enh);
/* Channel 3: c₂×c₄ → c₆ (10× lens, cross-product) */
sum += vqpu_product(v, 2, 4, g, enh);
/* Channel 4: c₁×c₂ → c₃ (direct, 1× lens) */
sum += vqpu_product(v, 1, 2, g, enh);
return sum;
}
/* ═══════════════════════════════════════════════════════════════════
* WEIGHT ENCODING — ternary weights → oscillator lens profiles
*
* Each ternary value {-1, 0, +1} becomes an oscillator frequency:
* -1 → ω = -0.5 (counter-rotating)
* 0 → ω = 0.0 (stationary, vanishes from dynamics)
* +1 → ω = +0.5 (co-rotating)
*
* Site-0 bias: ω[0] += 0.5 for the lens enhancement effect.
* The zero weights naturally drop out — they don't oscillate,
* don't contribute to harmonics, don't consume energy. This is
* the same sparsity that makes v5 fast, but expressed as physics.
* ═══════════════════════════════════════════════════════════════════ */
static void decode_ternary_to_lens(const uint8_t *packed, int col,
int stride, double *omega) {
memset(omega, 0, N_OSC * sizeof(double));
const uint8_t *w = packed + (size_t)col * stride;
for (int i = 0; i < N_OSC; i++) {
int byte_idx = i / 4;
int bit_idx = (i % 4) * 2;
if (byte_idx >= stride) break;
int val = (w[byte_idx] >> bit_idx) & 0x03;
if (val == 0) omega[i] = -0.5;
else if (val == 2) omega[i] = 0.5;
/* val=1 or val=3 → 0.0 (zero weight, drops out) */
}
/* Gradient lens: linear frequency ramp creates traveling wave drive.
* The wave propagates because each oscillator has a different omega.
* Weight values modulate the wave speed at each position. */
for (int i = 0; i < N_OSC; i++)
omega[i] += (i - N_OSC / 2.0) * 0.1;
}
/* ── Token embedding: extract column from LM head ──
* The LM head is [D × V] packed 2-bit. Token t's embedding = column t.
* Each row contributes one ternary value per token. */
static void embed_token(phoenix_t *p, int token_id, double *emb) {
size_t lm_offset = (size_t)p->layer_bytes * p->n_layers;
const uint8_t *lm_head = p->weights + lm_offset;
int stride = p->V / 4;
int byte_idx = token_id / 4;
int bit_shift = (token_id % 4) * 2;
memset(emb, 0, p->D * sizeof(double));
for (int d = 0; d < p->D; d++) {
int val = (lm_head[d * stride + byte_idx] >> bit_shift) & 0x03;
if (val == 0) emb[d] = -1.0;
else if (val == 2) emb[d] = 1.0;
}
}
/* ── Project to vocab: x[D] × LM_head[D × V] → logits[V], argmax ── */
static int project_to_vocab(phoenix_t *p, const double *x) {
size_t lm_offset = (size_t)p->layer_bytes * p->n_layers;
const uint8_t *lm_head = p->weights + lm_offset;
int stride = p->V / 4;
double best_logit = -1e30;
int best_id = 0;
#pragma omp parallel
{
double local_best = -1e30;
int local_id = 0;
#pragma omp for schedule(static)
for (int v = 0; v < p->V; v++) {
int byte_idx = v / 4;
int bit_shift = (v % 4) * 2;
double logit = 0;
for (int d = 0; d < p->D; d++) {
int bits = (lm_head[d * stride + byte_idx] >> bit_shift) & 0x03;
if (bits == 0) logit -= x[d];
else if (bits == 2) logit += x[d];
}
if (logit > local_best) { local_best = logit; local_id = v; }
}
#pragma omp critical
if (local_best > best_logit) { best_logit = local_best; best_id = local_id; }
}
return best_id;
}
/* ── Wave-rider activation: token rides traveling wave ──
* Instead of static theta = x * pi/4 (converges to fixed point),
* we create a traveling wave baseline and modulate it with the token.
* The wave keeps information in motion — no fixed point to collapse to.
*
* theta[i] = 2*pi*i/N + x[i] * pi/4
* The traveling wave creates linear phase ramp; the token perturbs it.
*/
static void encode_activation(vqpu_t *v, const double *act, int n) {
for (int i = 0; i < N_OSC; i++) {
double wave = 2.0 * M_PI * i / N_OSC;
double perturb = (i < n) ? act[i] * M_PI / 4.0 : 0.0;
v->theta[i] = wave + perturb;
}
}
/* ═══════════════════════════════════════════════════════════════════
* FABRIC — neuromorphic connections between vQPUs
* ═══════════════════════════════════════════════════════════════════ */
static int fabric_add(phoenix_t *p, int src, int dst,
int sh, int dh, double w) {
for (int i = 0; i < p->n_connections; i++)
if (!p->fabric[i].alive) {
p->fabric[i] = (conn_t){src, dst, sh, dh, w, 0, 1};
p->alive_conns++;
return i;
}
if (p->n_connections >= p->capacity_conns) return -1;
p->fabric[p->n_connections] = (conn_t){src, dst, sh, dh, w, 0, 1};
p->alive_conns++;
return p->n_connections++;
}
/* ── Propagate harmonic data through fabric ── */
static void fabric_propagate(phoenix_t *p) {
for (int i = 0; i < p->n_connections; i++) {
conn_t *c = &p->fabric[i];
if (!c->alive || !p->vqpus[c->src].active) continue;
vqpu_t *src = &p->vqpus[c->src];
vqpu_t *dst = &p->vqpus[c->dst];
double flow = c->weight * src->c_re[c->src_harm];
dst->c_re[c->dst_harm] += flow;
dst->c_im[c->dst_harm] += c->weight * src->c_im[c->src_harm];
c->traffic = c->traffic * 0.95 + fabs(flow) * 0.05;
}
}
/* ═══════════════════════════════════════════════════════════════════
* CHECKPOINT / ROLLBACK — "Keep these changes?"
* ═══════════════════════════════════════════════════════════════════ */
static void ckpt_save(phoenix_t *p) {
checkpoint_t *c = &p->ckpt;
c->vqpus = realloc(c->vqpus, p->n_vqpus * sizeof(vqpu_t));
c->fabric = realloc(c->fabric, p->n_connections * sizeof(conn_t));
memcpy(c->vqpus, p->vqpus, p->n_vqpus * sizeof(vqpu_t));
memcpy(c->fabric, p->fabric, p->n_connections * sizeof(conn_t));
c->n_vqpus = p->n_vqpus;
c->n_connections = p->n_connections;
c->coherence = p->ring_coherence;
}
static void ckpt_revert(phoenix_t *p) {
checkpoint_t *c = &p->ckpt;
if (!c->pending) return;
if (c->n_vqpus <= p->capacity)
memcpy(p->vqpus, c->vqpus, c->n_vqpus * sizeof(vqpu_t));
p->n_vqpus = c->n_vqpus;
if (c->n_connections <= p->capacity_conns)
memcpy(p->fabric, c->fabric, c->n_connections * sizeof(conn_t));
p->n_connections = c->n_connections;
p->alive_conns = 0;
for (int i = 0; i < p->n_connections; i++)
if (p->fabric[i].alive) p->alive_conns++;
c->pending = 0;
p->mod_reverts++;
printf(" ** REVERTED %s **\n", mod_str[c->mod]);
}
static void ckpt_confirm(phoenix_t *p) {
p->ckpt.pending = 0;
p->mod_confirms++;
printf(" ** CONFIRMED %s — ring stable **\n", mod_str[p->ckpt.mod]);
}
static void ckpt_check(phoenix_t *p) {
checkpoint_t *c = &p->ckpt;
if (!c->pending) return;
if (p->total_cycles >= c->deadline) {
double threshold = c->coherence * 0.7;
if (threshold < 0.005) threshold = 0.005;
if (p->ring_coherence >= threshold)
ckpt_confirm(p);
else
ckpt_revert(p);
}
}
/* ═══════════════════════════════════════════════════════════════════
* SELF-MODIFICATION PROPOSALS
* ═══════════════════════════════════════════════════════════════════ */
static void propose_grow(phoenix_t *p, int count) {
if (p->ckpt.pending || p->n_vqpus + count > p->capacity) return;
ckpt_save(p);
p->ckpt.mod = MOD_ADD_VQPUS;
p->ckpt.deadline = p->total_cycles + CONFIRM_SLOW;
p->ckpt.pending = 1;
int start = p->n_vqpus;
p->n_vqpus += count;
for (int i = start; i < p->n_vqpus; i++) {
memset(&p->vqpus[i], 0, sizeof(vqpu_t));
p->vqpus[i].K = 1.0;
for (int o = 0; o < N_OSC; o++)
p->vqpus[i].theta[o] = ((double)rand()/RAND_MAX) * 2*M_PI;
p->vqpus[i].omega[0] = 0.5;
fabric_add(p, (start-1) % start, i, CH_FUND, CH_FUND, 0.1);
fabric_add(p, i, (start-1) % start, CH_FUND, CH_FUND, 0.1);
}
p->mod_attempts++;
printf(" >> PROPOSED: grow +%d vQPUs (%d → %d)\n", count, start, p->n_vqpus);
}
static void propose_prune(phoenix_t *p) {
if (p->ckpt.pending) return;
ckpt_save(p);
p->ckpt.mod = MOD_PRUNE_CONN;
p->ckpt.deadline = p->total_cycles + CONFIRM_MEDIUM;
p->ckpt.pending = 1;
int pruned = 0;
for (int i = 0; i < p->n_connections; i++) {
if (!p->fabric[i].alive) continue;
if (p->fabric[i].traffic < 0.001 && p->total_cycles > 50) {
p->fabric[i].alive = 0;
p->alive_conns--;
pruned++;
}
}
p->mod_attempts++;
printf(" >> PROPOSED: prune %d dead connections\n", pruned);
}
static void propose_strengthen(phoenix_t *p) {
if (p->ckpt.pending) return;
ckpt_save(p);
p->ckpt.mod = MOD_ADJ_WEIGHT;
p->ckpt.deadline = p->total_cycles + CONFIRM_FAST;
p->ckpt.pending = 1;
double mx = 0;
for (int i = 0; i < p->n_connections; i++)
if (p->fabric[i].alive && p->fabric[i].traffic > mx)
mx = p->fabric[i].traffic;
if (mx < 0.001) { p->ckpt.pending = 0; return; }
for (int i = 0; i < p->n_connections; i++) {
if (!p->fabric[i].alive) continue;
double norm = p->fabric[i].traffic / mx;
if (norm > 0.5) p->fabric[i].weight *= 1.05;
else if (norm < 0.1) p->fabric[i].weight *= 0.95;
}
p->mod_attempts++;
}
/* ═══════════════════════════════════════════════════════════════════
* SETTLE — THE COMPUTATIONAL PRIMITIVE
*
* One settle = Kuramoto dynamics evolve until coherence.
* During settle, mode coupling computes products through
* wave interference. Fabric propagates results between vQPUs.
* At the end, harmonic coefficients hold the computation output.
* ═══════════════════════════════════════════════════════════════════ */
static void settle_ring(phoenix_t *p, int steps) {
double t0 = now_ms();
for (int s = 0; s < steps; s++) {
/* Evolve all active vQPUs */
#pragma omp parallel for schedule(static) if(p->n_hot > 80)
for (int i = 0; i < p->n_hot; i++)
vqpu_step(&p->vqpus[p->hot_set[i]]);
/* Every 5 steps: DFT + fabric propagation */
if (s % 5 == 0) {
#pragma omp parallel for schedule(static) if(p->n_hot > 80)
for (int i = 0; i < p->n_hot; i++)
vqpu_dft(&p->vqpus[p->hot_set[i]]);
fabric_propagate(p);
}
}
/* Final DFT to extract products */
#pragma omp parallel for schedule(static) if(p->n_hot > 80)
for (int i = 0; i < p->n_hot; i++)
vqpu_dft(&p->vqpus[p->hot_set[i]]);
p->last_settle_ms = now_ms() - t0;
}
/* ═══════════════════════════════════════════════════════════════════
* MODEL INGESTION — decipher shape, encode weights into lenses
* ═══════════════════════════════════════════════════════════════════ */
static void phoenix_init(phoenix_t *p) {
memset(p, 0, sizeof(*p));
init_coupling(p);
p->capacity = MAX_VQPUS;
p->vqpus = calloc(MAX_VQPUS, sizeof(vqpu_t));
p->capacity_conns = MAX_CONNS;
p->fabric = calloc(MAX_CONNS, sizeof(conn_t));
p->hot_set = calloc(MAX_VQPUS, sizeof(int));
p->layer_base = calloc(256, sizeof(int));
p->mode = IDLE;
}
static void phoenix_ingest(phoenix_t *p, const char *path) {
int fd = open(path, O_RDONLY);
if (fd < 0) { fprintf(stderr, "Cannot open %s\n", path); return; }
struct stat st; fstat(fd, &st);
p->weight_base = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
p->weights_size = st.st_size;
close(fd);
if (p->weight_base == MAP_FAILED) { p->weight_base = NULL; return; }
/* ── Parse header ── */
const uint32_t *h = (const uint32_t *)(p->weight_base + 4);
int version = h[0];
p->D = h[1]; p->FFN = h[2]; p->n_layers = h[3];
if (version >= 5) {
p->q_dim = h[4]; p->kv_dim = h[5]; p->V = h[6];
} else {
int n_qh = h[4], n_kvh = h[5]; p->V = h[6];
int hd = p->D / n_qh;
p->q_dim = n_qh * hd; p->kv_dim = n_kvh * hd;
}
p->weights = p->weight_base + 36; /* 32-byte header + 4-byte n_layers_blocks */
p->qw = (p->D * p->q_dim + 3) / 4;
p->kw = (p->D * p->kv_dim + 3) / 4;
p->vw = (p->D * p->kv_dim + 3) / 4;
p->ow = (p->q_dim * p->D + 3) / 4;
p->gw = (p->D * p->FFN + 3) / 4;
p->uw = (p->D * p->FFN + 3) / 4;
p->dw = (p->FFN * p->D + 3) / 4;
p->layer_bytes = p->qw + p->kw + p->vw + p->ow + p->gw + p->uw + p->dw;
/* Load RMSNorm from end of .bqsm if present (401152 floats + 4-byte count) */
if (p->weights_size > 1600000) {
size_t norm_start = p->weights_size - (size_t)401152 * 4 - 4;
uint32_t n_floats;
memcpy(&n_floats, p->weight_base + norm_start, 4);
if (n_floats == 401152) {
const float *ndat = (const float *)(p->weight_base + norm_start + 4);
p->norm_output = malloc(p->D * sizeof(float));
p->norm_attn = malloc(p->n_layers * p->D * sizeof(float));
p->norm_q = malloc(p->n_layers * (p->q_dim/16) * sizeof(float));
p->norm_k = malloc(p->n_layers * (p->kv_dim/8) * sizeof(float));
p->norm_ffn = malloc(p->n_layers * p->D * sizeof(float));
if (p->norm_output && p->norm_attn && p->norm_ffn) {
memcpy(p->norm_output, ndat, p->D * sizeof(float));
int off = p->D;
for (int l = 0; l < p->n_layers; l++) {
memcpy(p->norm_attn + l * p->D, ndat + off, p->D * sizeof(float)); off += p->D;
off += p->q_dim / 16; /* skip q_norm */
off += p->kv_dim / 8; /* skip k_norm */
memcpy(p->norm_ffn + l * p->D, ndat + off, p->D * sizeof(float)); off += p->D;
}
p->has_norms = 1;
fprintf(stderr, " Loaded RMSNorm: 401K floats, %d layers\n", p->n_layers);
}
}
}
printf(" Model shape:\n");
printf(" BQSM v%d | D=%d FFN=%d layers=%d\n", version, p->D, p->FFN, p->n_layers);
printf(" q_dim=%d kv_dim=%d vocab=%d\n", p->q_dim, p->kv_dim, p->V);
printf(" %.2f GB ternary (mmap'd, page-fault on demand)\n\n", st.st_size / 1e9);
/* ═══════════════════════════════════════════════════════════════
* 4-RING MACRO CORE — self-organizing topology
*
* Instead of fixed pools, we grow the network as we ingest weights.
* 4 core rings (64 osc) form the backbone. Tendrils grow outward,
* wired by traffic-driven Hebbian learning. The structure that
* emerges IS the model — different models → different topologies.
* ═══════════════════════════════════════════════════════════════ */
macro_core_t *mc = &p->core;
memset(mc, 0, sizeof(*mc));
printf(" 4-Ring Macro Core — self-organizing topology\n");
printf(" ─────────────────────────────────────────────\n");
/* ── Phase 0: Initialize 4 core rings ── */
for (int r = 0; r < MACRO_RINGS; r++) {
int id = p->n_vqpus++;
mc->ring_id[r] = id;
vqpu_t *v = &p->vqpus[id];
memset(v, 0, sizeof(*v));
v->K = 0.8; /* moderate coupling — stay responsive to tendrils */
v->role = ROLE_RESERVE;
for (int i = 0; i < N_OSC; i++) {
v->theta[i] = 2.0 * M_PI * i / N_OSC + r * M_PI / 2.0;
/* Each core ring gets a distinct gradient lens */
v->omega[i] = (i - N_OSC / 2.0) * 0.1 * (1.0 + r * 0.3);
}
}
/* Wire backbone: the core rings' fixed inter-connections */
int RI = mc->ring_id[RING_INTAKE];
int RA = mc->ring_id[RING_PROC_A];
int RB = mc->ring_id[RING_PROC_B];
int RC = mc->ring_id[RING_COLLECT];
/* INTAKE → processors (activation flows through c₂, c₄) */
fabric_add(p, RI, RA, CH_PROD2, CH_FUND, 0.30);
fabric_add(p, RI, RA, CH_PROD4, CH_PROD4, 0.40);
fabric_add(p, RI, RB, CH_PROD2, CH_FUND, 0.30);
fabric_add(p, RI, RB, CH_PROD4, CH_PROD4, 0.40);
/* Processors → COLLECT (products flow through c₄, c₆) */
fabric_add(p, RA, RC, CH_PROD4, CH_FUND, 0.40);
fabric_add(p, RA, RC, CH_PROD6, CH_FUND, 0.30);
fabric_add(p, RB, RC, CH_PROD4, CH_FUND, 0.40);
fabric_add(p, RB, RC, CH_PROD6, CH_FUND, 0.30);
/* COLLECT → INTAKE (ouroboros: output feeds next layer) */
fabric_add(p, RC, RI, CH_FUND, CH_FUND, 0.25);
/* Processor cross-talk (c₃ channel) */
fabric_add(p, RA, RB, CH_PROD2, CH_PROD2, 0.15);
fabric_add(p, RB, RA, CH_PROD2, CH_PROD2, 0.15);
printf(" Core: 4 rings (%d osc), %d backbone conns\n",
MACRO_RINGS * N_OSC, p->alive_conns);
/* ── Phase 1: Grow input tendrils (activation → phases) ── */
int n_input = (p->D + N_OSC - 1) / N_OSC;
mc->input_start = p->n_vqpus;
mc->n_inputs = n_input;
for (int i = 0; i < n_input && p->n_vqpus < p->capacity; i++) {
int id = p->n_vqpus++;
vqpu_t *v = &p->vqpus[id];
memset(v, 0, sizeof(*v));
v->K = 1.0;
v->role = ROLE_INPUT;
v->col_start = i * N_OSC;
for (int o = 0; o < N_OSC; o++)
v->theta[o] = 2.0 * M_PI * o / N_OSC;
/* Wire: INTAKE hub ↔ each input tendril */
fabric_add(p, RI, id, CH_FUND, CH_FUND, 0.15);
fabric_add(p, id, RI, CH_PROD2, CH_PROD2, 0.10);
/* Neighbor chain for wave propagation along input */
if (i > 0)
fabric_add(p, id - 1, id, CH_FUND, CH_FUND, 0.05);
}
printf(" Input tendrils: %d (D=%d)\n", mc->n_inputs, p->D);
/* ── Phase 2: Grow compute tendrils (weight processors) ── */
int budget = p->capacity - p->n_vqpus - 40; /* leave reserve */
int compute_n = budget > 512 ? 512 : (budget > 0 ? budget : 16);
mc->compute_start = p->n_vqpus;
mc->n_compute = compute_n;
for (int i = 0; i < compute_n && p->n_vqpus < p->capacity; i++) {
int id = p->n_vqpus++;
vqpu_t *v = &p->vqpus[id];
memset(v, 0, sizeof(*v));
v->K = 1.0;
v->role = ROLE_GATE;
for (int o = 0; o < N_OSC; o++)
v->theta[o] = 2.0 * M_PI * o / N_OSC;
/* Wire to processors — alternate A/B for load distribution */
int hub = (i % 2 == 0) ? RA : RB;
fabric_add(p, hub, id, CH_FUND, CH_FUND, 0.20);
fabric_add(p, id, hub, CH_PROD4, CH_PROD4, 0.30);
fabric_add(p, id, hub, CH_PROD6, CH_PROD6, 0.20);
/* Also wire input tendrils → compute tendrils for direct coupling */
int in_id = mc->input_start + (i % mc->n_inputs);
fabric_add(p, in_id, id, CH_PROD2, CH_PROD2, 0.15);
}
printf(" Compute tendrils: %d (weight processors)\n", compute_n);
/* ── Phase 3: Grow output tendrils (product collectors) ── */
int output_n = 32;
mc->output_start = p->n_vqpus;
mc->n_outputs = output_n;
for (int i = 0; i < output_n && p->n_vqpus < p->capacity; i++) {
int id = p->n_vqpus++;
vqpu_t *v = &p->vqpus[id];
memset(v, 0, sizeof(*v));
v->K = 1.0;
v->role = ROLE_OUTPUT;
for (int o = 0; o < N_OSC; o++)
v->theta[o] = 2.0 * M_PI * o / N_OSC;
/* Wire: COLLECT hub ↔ output tendrils */
fabric_add(p, RC, id, CH_PROD4, CH_FUND, 0.30);
fabric_add(p, id, RC, CH_FUND, CH_FUND, 0.20);
/* Output → input feedback (ouroboros at tendril level) */
int in_id = mc->input_start + (i % mc->n_inputs);
fabric_add(p, id, in_id, CH_FUND, CH_FUND, 0.10);
}
printf(" Output tendrils: %d (product collectors)\n", output_n);
/* ── Phase 4: Self-organization — ingest weight patterns, adapt ── */
printf(" Self-organizing...\n");
int sample_layers = p->n_layers < 3 ? p->n_layers : 3;
for (int layer = 0; layer < sample_layers; layer++) {
const uint8_t *wp = p->weights + (size_t)layer * p->layer_bytes;
int stride = (p->D * p->FFN + 3) / 4 / p->FFN;
/* Load sample weight columns into compute tendrils */
for (int t = 0; t < mc->n_compute; t++) {
vqpu_t *v = &p->vqpus[mc->compute_start + t];
decode_ternary_to_lens(wp, t % (p->FFN > 0 ? p->FFN : 1),
stride > 0 ? stride : 1, v->omega);
v->active = 1;
}
/* Seed input tendrils with random activation */
for (int i = 0; i < mc->n_inputs; i++) {
vqpu_t *v = &p->vqpus[mc->input_start + i];
double seed[N_OSC];
for (int o = 0; o < N_OSC; o++)
seed[o] = ((double)rand() / RAND_MAX) * 0.5;
encode_activation(v, seed, N_OSC);
v->active = 1;
}
/* Activate core + outputs */
for (int r = 0; r < MACRO_RINGS; r++)
p->vqpus[mc->ring_id[r]].active = 1;
for (int i = 0; i < mc->n_outputs; i++)
p->vqpus[mc->output_start + i].active = 1;
/* Build hot set */
p->n_hot = 0;
for (int i = 0; i < p->n_vqpus; i++)
if (p->vqpus[i].active)
p->hot_set[p->n_hot++] = i;
/* Longer settle during ingestion — let traffic accumulate */
settle_ring(p, 10);
/* Measure traffic */
double total_traffic = 0;
int active_conns = 0;
for (int c = 0; c < p->n_connections; c++) {
if (!p->fabric[c].alive) continue;
total_traffic += p->fabric[c].traffic;
if (p->fabric[c].traffic > 0.001) active_conns++;
}
printf(" Layer %d: traffic=%.4f active=%d/%d conns\n",
layer, total_traffic, active_conns, p->alive_conns);
/* Deactivate */
for (int i = 0; i < p->n_vqpus; i++)
p->vqpus[i].active = 0;
}
/* Hebbian adaptation: strengthen high-traffic, prune dead */
double max_traffic = 0;
for (int i = 0; i < p->n_connections; i++)
if (p->fabric[i].alive && p->fabric[i].traffic > max_traffic)
max_traffic = p->fabric[i].traffic;
if (max_traffic > 0.0001) {
int pruned = 0, strengthened = 0;
for (int i = 0; i < p->n_connections; i++) {
if (!p->fabric[i].alive) continue;
double norm = p->fabric[i].traffic / max_traffic;
if (norm > 0.3) {
p->fabric[i].weight *= 1.10;
strengthened++;
} else if (norm < 0.01 && p->fabric[i].traffic < 0.0001) {
p->fabric[i].alive = 0;
p->alive_conns--;
pruned++;
}
}
mc->tendrils_pruned = pruned;
mc->tendrils_strengthened = strengthened;
printf(" Hebbian: strengthened %d, pruned %d connections\n",
strengthened, pruned);
}
mc->ready = 1;
int total_osc = p->n_vqpus * N_OSC;
printf(" Topology: %d vQPUs (%d osc), %d connections\n",
p->n_vqpus, total_osc, p->alive_conns);
printf(" Core: %d osc fixed | Tendrils: %d grown\n",
MACRO_RINGS * N_OSC,
mc->n_inputs + mc->n_compute + mc->n_outputs);
printf(" Connections: %d\n", p->alive_conns);
/* Readout buffer */
p->readout_dim = p->D;
p->readout = calloc(p->D, sizeof(double));
p->model_loaded = 1;
p->vqpus_per_layer = mc->n_inputs;
}
/* ═══════════════════════════════════════════════════════════════════
* FORWARD PASS — one settle = one layer, ring propagates all layers
*
* For each layer:
* 1. Load weights into gate vQPU lenses
* 2. Load activation into input vQPU phases
* 3. Settle → mode coupling computes weight × activation
* 4. Read products from all 4 channels
* 5. Fabric carries result to next layer's input
* ═══════════════════════════════════════════════════════════════════ */
static void phoenix_forward_layer(phoenix_t *p, int layer,
double *x, double *x_out) {
int input_n = (p->D + N_OSC - 1) / N_OSC;
const uint8_t *wp = p->weights + (size_t)layer * p->layer_bytes;
int stride_q = p->q_dim / 4;
/* ── Apply RMSNorm before this layer ── */
if (p->has_norms && p->norm_attn) {
double ss = 0;
for (int i = 0; i < p->D; i++) ss += x[i] * x[i];
double rms = sqrt(ss / p->D + 1e-5);
double inv = 1.0 / rms;
for (int i = 0; i < p->D; i++)
x[i] = x[i] * inv * (double)p->norm_attn[layer * p->D + i];
}
/* ── Load activation into input vQPU phases (wave-rider) ── */
for (int i = 0; i < input_n; i++) {
vqpu_t *v = &p->vqpus[i];
encode_activation(v, x + i * N_OSC,
(i * N_OSC + N_OSC <= p->D) ? N_OSC : (p->D - i * N_OSC));
v->active = 1;
}
/* ── Load weight columns into gate vQPU lenses ── */
int gate_start = input_n;
int gate_n = 0;
for (int i = 0; i < p->n_vqpus; i++)
if (p->vqpus[i].role == ROLE_GATE) { gate_start = i; break; }
for (int i = gate_start; i < p->n_vqpus; i++) {
if (p->vqpus[i].role != ROLE_GATE) break;
/* Encode weight column into lens profile */
decode_ternary_to_lens(wp, gate_n, stride_q, p->vqpus[i].omega);
p->vqpus[i].active = 1;
gate_n++;
}
/* ── Activate output vQPUs ── */
int output_start = gate_start + gate_n;
for (int i = output_start; i < p->n_vqpus; i++) {
if (p->vqpus[i].role == ROLE_OUTPUT) {
p->vqpus[i].active = 1;
memset(p->vqpus[i].c_re, 0, sizeof(p->vqpus[i].c_re));
memset(p->vqpus[i].c_im, 0, sizeof(p->vqpus[i].c_im));
}
}
/* ── Build hot set ── */
p->n_hot = 0;
for (int i = 0; i < p->n_vqpus; i++)
if (p->vqpus[i].active)
p->hot_set[p->n_hot++] = i;
/* ── SETTLE — this is where the computation happens ── */
settle_ring(p, SETTLE_STEPS);
/* ── Read products from all 4 interference channels ── */
memset(x_out, 0, p->D * sizeof(double));
/* Read from gate vQPUs (products of weight × activation) */
for (int g = 0; g < gate_n; g++) {
vqpu_t *gv = &p->vqpus[gate_start + g];
double product = vqpu_read_products(gv, p->g_coupling, p->lens_enhance);
if (g < p->D) x_out[g] += product;
}
/* Read from output vQPUs (accumulated fabric products) */
for (int i = output_start; i < p->n_vqpus; i++) {
if (p->vqpus[i].role != ROLE_OUTPUT) continue;
int o = i - output_start;
if (o < p->D) x_out[o] += p->vqpus[i].c_re[CH_FUND] * 10.0;
}
/* Residual connection */
for (int i = 0; i < p->D; i++)
x_out[i] += x[i];
/* Apply output RMSNorm if this is the last layer */
if (layer == p->n_layers - 1 && p->has_norms && p->norm_output) {
double ss = 0;
for (int i = 0; i < p->D; i++) ss += x_out[i] * x_out[i];
double rms = sqrt(ss / p->D + 1e-5);
double inv = 1.0 / rms;
for (int i = 0; i < p->D; i++)
x_out[i] = x_out[i] * inv * (double)p->norm_output[i];
}
/* Deactivate */
for (int i = 0; i < p->n_vqpus; i++)
p->vqpus[i].active = 0;
}
static void phoenix_forward(phoenix_t *p, int token) {
if (!p->model_loaded) return;
/* Tokenize: simple one-hot into activation space */
double *x = calloc(p->D, sizeof(double));
double *x_out = calloc(p->D, sizeof(double));
x[token % p->D] = 1.0;
double t0 = now_ms();
/* Run all layers — each one is a settle */
for (int layer = 0; layer < p->n_layers; layer++) {
phoenix_forward_layer(p, layer, x, x_out);
memcpy(x, x_out, p->D * sizeof(double));
}
double elapsed = now_ms() - t0;
/* Readout: copy final activation */
memcpy(p->readout, x, p->D * sizeof(double));
/* Sample (argmax over activation) */
int best = 0;
double best_val = x[0];
for (int i = 1; i < p->D; i++)
if (fabs(x[i]) > fabs(best_val)) { best_val = x[i]; best = i; }
/* Layer energy profile */
double max_energy = 0;
for (int i = 0; i < p->D; i++) max_energy += fabs(x[i]);
printf(" tok=%d → sample=%d energy=%.2f "
"settle=%.1fms/layer total=%.1fms (%.2f tok/s)\n",
token, best, max_energy,
elapsed / p->n_layers, elapsed,
elapsed > 0 ? 1000.0 / elapsed : 0);
free(x);
free(x_out);
}
/* ═══════════════════════════════════════════════════════════════════
* MACRO FORWARD PASS — 4-ring core + tentacle topology
*
* The core rings coordinate. The tendrils compute.
* Activation enters through input tendrils → core INTAKE distributes
* to PROC_A/B → compute tendrils process weight×activation →
* products aggregate at COLLECT → output tendrils produce result.
* Ouroboros: COLLECT feeds back to INTAKE for next layer.
* ═══════════════════════════════════════════════════════════════════ */
static void macro_forward_layer(phoenix_t *p, int layer,
double *x, double *x_out) {
macro_core_t *mc = &p->core;
const uint8_t *wp = p->weights + (size_t)layer * p->layer_bytes;
int stride_gate = (p->D * p->FFN + 3) / 4 / (p->FFN > 0 ? p->FFN : 1);
/* ── RMSNorm ── */
if (p->has_norms && p->norm_attn) {
double ss = 0;
for (int i = 0; i < p->D; i++) ss += x[i] * x[i];
double rms = sqrt(ss / p->D + 1e-5);
double inv = 1.0 / rms;
for (int i = 0; i < p->D; i++)
x[i] = x[i] * inv * (double)p->norm_attn[layer * p->D + i];
}
/* ── Perturb core rings with layer-specific signal ── */
/* INTAKE ring absorbs activation summary */
{
vqpu_t *vi = &p->vqpus[mc->ring_id[RING_INTAKE]];
for (int i = 0; i < N_OSC; i++) {
double sum = 0;
int stride = p->D / N_OSC;
for (int j = 0; j < stride && i * stride + j < p->D; j++)
sum += x[i * stride + j];
vi->theta[i] = 2.0 * M_PI * i / N_OSC + sum * M_PI / 4.0;
}
}
/* PROC rings: encode layer signature into phases and omega */
for (int r = RING_PROC_A; r <= RING_PROC_B; r++) {
vqpu_t *vr = &p->vqpus[mc->ring_id[r]];
vr->K = 0.3; /* low coupling — stay responsive */
double phase_offset = layer * 2.0 * M_PI / p->n_layers;
double act_sum = 0;
for (int i = 0; i < p->D; i++) act_sum += x[i] * x[i];
double act_rms = sqrt(act_sum / p->D + 1e-8);
for (int i = 0; i < N_OSC; i++) {
/* Traveling wave + layer offset + activation modulation */
vr->theta[i] = 2.0 * M_PI * i / N_OSC + phase_offset
+ act_rms * sin(i * 0.39 + r * 1.7) * M_PI / 8.0;
/* Strong gradient + layer-dependent wobble */
vr->omega[i] = (i - N_OSC / 2.0) * 0.2 * (1.0 + r * 0.5)
+ 0.15 * sin(layer * 0.27 + i * 1.1 + r * 0.8);
}
}
/* COLLECT ring: activation-modulated gradient, absorbs from PROC */
{
vqpu_t *vc = &p->vqpus[mc->ring_id[RING_COLLECT]];
vc->K = 0.3;
double act_energy = 0;
for (int i = 0; i < p->D; i++) act_energy += fabs(x[i]);
act_energy /= p->D;
for (int i = 0; i < N_OSC; i++) {
int stride = p->D / N_OSC;
double local_act = 0;
for (int j = 0; j < stride && i * stride + j < p->D; j++)
local_act += x[i * stride + j];
vc->theta[i] = 2.0 * M_PI * i / N_OSC
+ local_act * M_PI / 8.0;
vc->omega[i] = (i - N_OSC / 2.0) * 0.2
+ act_energy * sin(i * 0.8 + layer * 0.17);
}
memset(vc->c_re, 0, sizeof(vc->c_re));
memset(vc->c_im, 0, sizeof(vc->c_im));
}
/* ── Load activation into input tendrils (wave-rider) ── */
for (int i = 0; i < mc->n_inputs; i++) {
vqpu_t *v = &p->vqpus[mc->input_start + i];
int chunk = (i * N_OSC + N_OSC <= p->D) ? N_OSC : (p->D - i * N_OSC);
if (chunk <= 0) break;
encode_activation(v, x + i * N_OSC, chunk);
v->active = 1;
}
/* ── Load weights into compute tendrils — wave-rider style ── */
/* Skip past q,k,v,o matrices to reach gate matrix */
const uint8_t *gate_wp = wp + p->qw + p->kw + p->vw + p->ow;
for (int t = 0; t < mc->n_compute; t++) {
vqpu_t *v = &p->vqpus[mc->compute_start + t];
/* Omega = weight lens (same every token) */
decode_ternary_to_lens(gate_wp, t, stride_gate, v->omega);
/* Theta = traveling wave + activation perturbation (varies per token) */
int act_base = (t * N_OSC) % p->D;
for (int i = 0; i < N_OSC; i++) {
double wave = 2.0 * M_PI * i / N_OSC;
double perturb = x[(act_base + i) % p->D] * M_PI / 4.0;
v->theta[i] = wave + perturb;
}
v->active = 1;
}
/* ── Activate core rings ── */
for (int r = 0; r < MACRO_RINGS; r++)
p->vqpus[mc->ring_id[r]].active = 1;
/* ── Clear and activate output tendrils ── */
for (int i = 0; i < mc->n_outputs; i++) {
vqpu_t *v = &p->vqpus[mc->output_start + i];
v->active = 1;
memset(v->c_re, 0, sizeof(v->c_re));
memset(v->c_im, 0, sizeof(v->c_im));
}
/* ── Build hot set ── */
p->n_hot = 0;
for (int i = 0; i < p->n_vqpus; i++)
if (p->vqpus[i].active)
p->hot_set[p->n_hot++] = i;
/* ── SETTLE — the computation happens here ── */
settle_ring(p, SETTLE_STEPS);
/* ── Read products from all channels ── */
memset(x_out, 0, p->D * sizeof(double));
/* From compute tendrils — scatter products across full D dimension.
* Each tendril's harmonics determine WHERE in the output space
* its product lands. This is the demodulation step. */
for (int t = 0; t < mc->n_compute; t++) {
vqpu_t *v = &p->vqpus[mc->compute_start + t];
/* Per-tendril trainable output gain (0 == uninitialized → neutral 1.0) */
double gain = (v->train_gain != 0.0) ? v->train_gain : 1.0;
double product = vqpu_read_products(v, p->g_coupling, p->lens_enhance) * gain;
/* Scatter using harmonic phase as address */
for (int k = 1; k < N_HARM; k++) {
if (v->c_mag[k] < 0.001) continue;
double phase_addr = fmod(fabs(v->c_re[k] * 1000.0), (double)p->D);
int idx = (int)phase_addr;
if (idx >= 0 && idx < p->D)
x_out[idx] += product * v->c_mag[k];
}
/* Also direct map for primary channel */
int direct_idx = t * (p->D / mc->n_compute);
if (direct_idx < p->D)
x_out[direct_idx] += product * 0.5;
}
/* From core PROC rings — broadcast their interference pattern */
for (int r = RING_PROC_A; r <= RING_PROC_B; r++) {
vqpu_t *v = &p->vqpus[mc->ring_id[r]];
double gain = (v->train_gain != 0.0) ? v->train_gain : 1.0;
for (int k = 1; k < N_HARM; k++) {
if (v->c_mag[k] < 0.001) continue;
double product = vqpu_product(v, k, k, p->g_coupling, p->lens_enhance);
/* Broadcast across D using oscillator phases as addresses */
for (int i = 0; i < N_OSC; i++) {
int idx = (int)(fmod(fabs(v->theta[i]) * p->D / (2.0 * M_PI), p->D));
if (idx >= 0 && idx < p->D)
x_out[idx] += product * cos(v->theta[i]) * 0.1 * gain;
}
}
}
/* From COLLECT ring — harmonic summary into output */
{
vqpu_t *vc = &p->vqpus[mc->ring_id[RING_COLLECT]];
double gain = (vc->train_gain != 0.0) ? vc->train_gain : 1.0;
for (int i = 0; i < p->D; i++) {
double acc = 0;
for (int k = 1; k < N_HARM; k++)
acc += vc->c_re[k] * cos(2.0 * M_PI * k * i / p->D)
+ vc->c_im[k] * sin(2.0 * M_PI * k * i / p->D);
x_out[i] += acc * 5.0 * gain;
}
}
/* From output tendrils (fabric-accumulated products) */
for (int i = 0; i < mc->n_outputs; i++) {
vqpu_t *v = &p->vqpus[mc->output_start + i];
double gain = (v->train_gain != 0.0) ? v->train_gain : 1.0;
int base = i * (p->D / mc->n_outputs);
int span = p->D / mc->n_outputs;
double val = v->c_re[CH_FUND] * 10.0 * gain;
for (int j = 0; j < span && base + j < p->D; j++)
x_out[base + j] += val;
}
/* ── Residual connection ── */
for (int i = 0; i < p->D; i++)
x_out[i] += x[i];
/* ── Output RMSNorm on last layer ── */
if (layer == p->n_layers - 1 && p->has_norms && p->norm_output) {
double ss = 0;
for (int i = 0; i < p->D; i++) ss += x_out[i] * x_out[i];
double rms = sqrt(ss / p->D + 1e-5);
double inv = 1.0 / rms;
for (int i = 0; i < p->D; i++)
x_out[i] = x_out[i] * inv * (double)p->norm_output[i];
}
/* Deactivate everything */
for (int i = 0; i < p->n_vqpus; i++)
p->vqpus[i].active = 0;
}
static void macro_forward(phoenix_t *p, int token) {
if (!p->model_loaded || !p->core.ready) return;
double *x = calloc(p->D, sizeof(double));
double *x_out = calloc(p->D, sizeof(double));
x[token % p->D] = 1.0;
double t0 = now_ms();
for (int layer = 0; layer < p->n_layers; layer++) {
macro_forward_layer(p, layer, x, x_out);
/* Track signal propagation for first 3 layers */
if (layer < 3) {
double dot = 0, nx = 0, no = 0;
for (int i = 0; i < p->D; i++) {
dot += x[i] * x_out[i];
nx += x[i] * x[i];
no += x_out[i] * x_out[i];
}
double cos_sim = (nx > 0 && no > 0)
? dot / sqrt(nx * no) : 0;
printf(" L%d cos(x,out)=%.4f\n", layer, cos_sim);
}
memcpy(x, x_out, p->D * sizeof(double));
}
double elapsed = now_ms() - t0;
memcpy(p->readout, x, p->D * sizeof(double));
int best = 0;
double best_val = x[0];
for (int i = 1; i < p->D; i++)
if (fabs(x[i]) > fabs(best_val)) { best_val = x[i]; best = i; }
double energy = 0;
for (int i = 0; i < p->D; i++) energy += fabs(x[i]);
/* Core ring coherence */
double core_coh = 0;
for (int r = 0; r < MACRO_RINGS; r++)
core_coh += p->vqpus[p->core.ring_id[r]].coherence;
core_coh /= MACRO_RINGS;
printf(" tok=%d → sample=%d energy=%.2f core_coh=%.3f "
"%.1fms/layer %.1fms (%.2f tok/s)\n",
token, best, energy, core_coh,
elapsed / p->n_layers, elapsed,
elapsed > 0 ? 1000.0 / elapsed : 0);
free(x);
free(x_out);
}
/* ═══════════════════════════════════════════════════════════════════
* DYNAMIC RING LIFECYCLE — spawn, reclaim, sweep
*
* Rings are biological: they grow when needed, retract when idle.
* Core rings (4) are permanent. Everything else is a tendril that
* can appear or disappear based on demand and utilization.
* ═══════════════════════════════════════════════════════════════════ */
static int spawn_tendril(phoenix_t *p, int parent_id, int role,
int src_ch, int dst_ch, double weight) {
/* Try to reuse a dormant slot first */
int id = -1;
for (int i = 0; i < p->n_vqpus; i++) {
if (p->vqpus[i].role == ROLE_DORMANT) { id = i; break; }
}
/* No dormant slot — grow if capacity allows */
if (id < 0) {
if (p->n_vqpus >= p->capacity) return -1;
id = p->n_vqpus++;
}
vqpu_t *v = &p->vqpus[id];
memset(v, 0, sizeof(*v));
v->K = 1.0;
v->role = role;
v->age = 0;
v->utilization = 1.0;
for (int i = 0; i < N_OSC; i++)
v->theta[i] = 2.0 * M_PI * i / N_OSC;
/* Wire to parent */
fabric_add(p, parent_id, id, src_ch, CH_FUND, weight);
fabric_add(p, id, parent_id, CH_PROD4, dst_ch, weight);
return id;
}
static void reclaim_tendril(phoenix_t *p, int id) {
/* Never reclaim core rings */
for (int r = 0; r < MACRO_RINGS; r++)
if (p->core.ring_id[r] == id) return;
/* Kill all connections to/from this ring */
for (int i = 0; i < p->n_connections; i++) {
if (!p->fabric[i].alive) continue;
if (p->fabric[i].src == id || p->fabric[i].dst == id) {
p->fabric[i].alive = 0;
p->alive_conns--;
}
}
/* Reset to dormant */
memset(&p->vqpus[id], 0, sizeof(vqpu_t));
p->vqpus[id].role = ROLE_DORMANT;
}
static int sweep_dormant(phoenix_t *p, double util_threshold) {
int reclaimed = 0;
for (int i = 0; i < p->n_vqpus; i++) {
if (p->vqpus[i].role == ROLE_DORMANT) continue;
/* Never touch core rings */
int is_core = 0;
for (int r = 0; r < MACRO_RINGS; r++)
if (p->core.ring_id[r] == i) { is_core = 1; break; }
if (is_core) continue;
if (p->vqpus[i].utilization < util_threshold && p->vqpus[i].age > 50) {
reclaim_tendril(p, i);
reclaimed++;
}
}
return reclaimed;
}
/* Count active (non-dormant, non-core) rings */
static int count_active_tendrils(phoenix_t *p) {
int count = 0;
for (int i = 0; i < p->n_vqpus; i++) {
if (p->vqpus[i].role == ROLE_DORMANT) continue;
int is_core = 0;
for (int r = 0; r < MACRO_RINGS; r++)
if (p->core.ring_id[r] == i) { is_core = 1; break; }
if (!is_core) count++;
}
return count;
}
/* ═══════════════════════════════════════════════════════════════════
* STATE PERSISTENCE — save/load the living topology
*
* The .bqmc file holds the entire macro core state: vQPU phases,
* fabric connections, traffic history, core ring assignments.
* Model weights are NOT saved (they come from the .bqsm file).
* On restart, load .bqmc to resume the evolved topology.
* ═══════════════════════════════════════════════════════════════════ */
static int state_save(phoenix_t *p, const char *path) {
FILE *f = fopen(path, "wb");
if (!f) { fprintf(stderr, "Cannot write state: %s\n", path); return -1; }
/* Header */
uint32_t magic = STATE_MAGIC;
uint32_t version = STATE_VERSION;
uint32_t nv = p->n_vqpus;
uint32_t nc = p->n_connections;
uint32_t ac = p->alive_conns;
uint32_t tc = p->total_cycles;
fwrite(&magic, 4, 1, f);
fwrite(&version, 4, 1, f);
fwrite(&nv, 4, 1, f);
fwrite(&nc, 4, 1, f);
fwrite(&ac, 4, 1, f);
fwrite(&tc, 4, 1, f);
/* Macro core metadata */
fwrite(&p->core, sizeof(macro_core_t), 1, f);
/* Physics constants */
fwrite(p->g_coupling, sizeof(p->g_coupling), 1, f);
fwrite(p->lens_enhance, sizeof(p->lens_enhance), 1, f);
/* Model dimensions (needed to verify on reload) */
uint32_t dims[6] = { p->D, p->FFN, p->n_layers, p->q_dim, p->kv_dim, p->V };
fwrite(dims, sizeof(dims), 1, f);
/* All vQPU state — phases, omegas, harmonics, everything */
fwrite(p->vqpus, sizeof(vqpu_t), nv, f);
/* All fabric connections */
fwrite(p->fabric, sizeof(conn_t), nc, f);
long size = ftell(f);
fclose(f);
printf(" [STATE] Saved %d vQPUs, %d conns → %s (%.1f KB)\n",
nv, ac, path, size / 1024.0);
return 0;
}
static int state_load(phoenix_t *p, const char *path) {
FILE *f = fopen(path, "rb");
if (!f) return -1; /* no state file — fresh start */
uint32_t magic, version, nv, nc, ac, tc;
if (fread(&magic, 4, 1, f) != 1 || magic != STATE_MAGIC) {
fprintf(stderr, " [STATE] Bad magic in %s\n", path);
fclose(f); return -1;
}
fread(&version, 4, 1, f);
fread(&nv, 4, 1, f);
fread(&nc, 4, 1, f);
fread(&ac, 4, 1, f);
fread(&tc, 4, 1, f);
if (version != STATE_VERSION) {
fprintf(stderr, " [STATE] Version mismatch (got %d, want %d)\n",
version, STATE_VERSION);
fclose(f); return -1;
}
/* Macro core metadata */
fread(&p->core, sizeof(macro_core_t), 1, f);
/* Physics constants */
fread(p->g_coupling, sizeof(p->g_coupling), 1, f);
fread(p->lens_enhance, sizeof(p->lens_enhance), 1, f);
/* Verify model dimensions match */
uint32_t dims[6];
fread(dims, sizeof(dims), 1, f);
if ((int)dims[0] != p->D || (int)dims[2] != p->n_layers) {
fprintf(stderr, " [STATE] Model mismatch: state D=%d vs model D=%d\n",
dims[0], p->D);
fclose(f); return -1;
}
/* Load vQPU state */
if (nv > (uint32_t)p->capacity) nv = p->capacity;
fread(p->vqpus, sizeof(vqpu_t), nv, f);
p->n_vqpus = nv;
/* Load fabric */
if (nc > (uint32_t)p->capacity_conns) nc = p->capacity_conns;
fread(p->fabric, sizeof(conn_t), nc, f);
p->n_connections = nc;
p->alive_conns = 0;
for (int i = 0; i < (int)nc; i++)
if (p->fabric[i].alive) p->alive_conns++;
p->total_cycles = tc;
fclose(f);
printf(" [STATE] Loaded %d vQPUs, %d conns, %d cycles from %s\n",
p->n_vqpus, p->alive_conns, p->total_cycles, path);
return 0;
}
/* ── Self-verification: check (and optionally repair) structural coherence ──
*
* A self-restructuring topology can evolve into an inconsistent state: a
* connection left pointing at a reclaimed vQPU, counts drifting out of sync
* with the real population, or an oscillator phase gone NaN. Any of those
* makes the next forward pass dereference garbage and crash. The optimizer
* chases a score, not its own integrity — so this is the guard that keeps
* "self-modifying" from meaning "self-destructing."
*
* With repair=1 it fixes what it can:
* - drops connections whose src/dst are out of range or dormant
* - drops connections with invalid harmonic channels
* - recomputes alive_conns to match reality
* - clamps n_vqpus / n_connections to capacity
* - resets any non-finite phase / frequency / harmonic to a safe value
* If a load-bearing core ring is invalid the damage is unrepairable and it
* returns INTEGRITY_FATAL so the caller can discard the state and re-ingest.
*
* Returns the number of problems found (0 == clean). */
#define INTEGRITY_FATAL 1000000
static int verify_integrity(phoenix_t *p, int repair) {
int problems = 0;
/* Population counts within bounds */
if (p->n_vqpus < 0 || p->n_vqpus > p->capacity) {
problems++;
if (repair) p->n_vqpus = p->n_vqpus < 0 ? 0 :
(p->n_vqpus > p->capacity ? p->capacity : p->n_vqpus);
}
if (p->n_connections < 0 || p->n_connections > p->capacity_conns) {
problems++;
if (repair) p->n_connections = p->n_connections < 0 ? 0 :
(p->n_connections > p->capacity_conns ? p->capacity_conns : p->n_connections);
}
/* Core rings are load-bearing — if any is invalid the state is unusable */
for (int r = 0; r < MACRO_RINGS; r++) {
int id = p->core.ring_id[r];
if (id < 0 || id >= p->n_vqpus || p->vqpus[id].role == ROLE_DORMANT)
return INTEGRITY_FATAL + problems;
}
/* Every alive connection must reference in-range, non-dormant vQPUs
* through valid harmonic channels */
int alive = 0;
for (int i = 0; i < p->n_connections; i++) {
conn_t *c = &p->fabric[i];
if (!c->alive) continue;
int bad = (c->src < 0 || c->src >= p->n_vqpus ||
c->dst < 0 || c->dst >= p->n_vqpus ||
c->src_harm < 0 || c->src_harm >= N_HARM ||
c->dst_harm < 0 || c->dst_harm >= N_HARM);
if (!bad && (p->vqpus[c->src].role == ROLE_DORMANT ||
p->vqpus[c->dst].role == ROLE_DORMANT))
bad = 1;
if (bad) {
problems++;
if (repair) { c->alive = 0; continue; }
}
alive++;
}
if (repair) p->alive_conns = alive;
else if (alive != p->alive_conns) problems++;
/* Sanitize oscillator state — a single NaN phase silently poisons the
* Kuramoto step for the whole ring */
for (int i = 0; i < p->n_vqpus; i++) {
vqpu_t *v = &p->vqpus[i];
for (int o = 0; o < N_OSC; o++) {
if (!isfinite(v->theta[o])) { problems++; if (repair) v->theta[o] = 2.0 * M_PI * o / N_OSC; }
if (!isfinite(v->omega[o])) { problems++; if (repair) v->omega[o] = 0.0; }
}
for (int k = 0; k < N_HARM; k++) {
if (!isfinite(v->c_re[k])) { problems++; if (repair) v->c_re[k] = 0.0; }
if (!isfinite(v->c_im[k])) { problems++; if (repair) v->c_im[k] = 0.0; }
}
}
return problems;
}
/* ═══════════════════════════════════════════════════════════════════
* CONTINUOUS FORWARD — living inference with demand-driven growth
*
* Phase state carries between tokens. Rings spawn when compute
* demand saturates existing tendrils. Idle rings get reclaimed.
* The topology continuously evolves.
* ═══════════════════════════════════════════════════════════════════ */
static void continuous_forward_layer(phoenix_t *p, int layer,
double *x, double *x_out) {
macro_core_t *mc = &p->core;
const uint8_t *wp = p->weights + (size_t)layer * p->layer_bytes;
int stride_gate = (p->D * p->FFN + 3) / 4 / (p->FFN > 0 ? p->FFN : 1);
/* ── RMSNorm ── */
if (p->has_norms && p->norm_attn) {
double ss = 0;
for (int i = 0; i < p->D; i++) ss += x[i] * x[i];
double rms = sqrt(ss / p->D + 1e-5);
double inv = 1.0 / rms;
for (int i = 0; i < p->D; i++)
x[i] = x[i] * inv * (double)p->norm_attn[layer * p->D + i];
}
/* ── Core ring perturbation ── */
/* INTAKE: blend activation into existing phase state */
{
vqpu_t *vi = &p->vqpus[mc->ring_id[RING_INTAKE]];
vi->K = 0.3;
for (int i = 0; i < N_OSC; i++) {
double sum = 0;
int stride = p->D / N_OSC;
for (int j = 0; j < stride && i * stride + j < p->D; j++)
sum += x[i * stride + j];
/* BLEND — don't replace. Continuous state. */
vi->theta[i] = vi->theta[i] * 0.6
+ (2.0 * M_PI * i / N_OSC + sum * M_PI / 4.0) * 0.4;
}
vi->utilization += 1.0;
}
/* PROC rings: blend layer signature into existing state */
for (int r = RING_PROC_A; r <= RING_PROC_B; r++) {
vqpu_t *vr = &p->vqpus[mc->ring_id[r]];
vr->K = 0.3;
double phase_offset = layer * 2.0 * M_PI / p->n_layers;
double act_sum = 0;
for (int i = 0; i < p->D; i++) act_sum += x[i] * x[i];
double act_rms = sqrt(act_sum / p->D + 1e-8);
for (int i = 0; i < N_OSC; i++) {
double target = 2.0 * M_PI * i / N_OSC + phase_offset
+ act_rms * sin(i * 0.39 + r * 1.7) * M_PI / 8.0;
/* Blend: carry 70% of old state, inject 30% new */
vr->theta[i] = vr->theta[i] * 0.7 + target * 0.3;
vr->omega[i] = (i - N_OSC / 2.0) * 0.2 * (1.0 + r * 0.5)
+ 0.15 * sin(layer * 0.27 + i * 1.1 + r * 0.8);
}
vr->utilization += 1.0;
}
/* COLLECT: blend reset */
{
vqpu_t *vc = &p->vqpus[mc->ring_id[RING_COLLECT]];
vc->K = 0.3;
double act_energy = 0;
for (int i = 0; i < p->D; i++) act_energy += fabs(x[i]);
act_energy /= p->D;
for (int i = 0; i < N_OSC; i++) {
int stride = p->D / N_OSC;
double local_act = 0;
for (int j = 0; j < stride && i * stride + j < p->D; j++)
local_act += x[i * stride + j];
double target = 2.0 * M_PI * i / N_OSC + local_act * M_PI / 8.0;
vc->theta[i] = vc->theta[i] * 0.5 + target * 0.5;
vc->omega[i] = (i - N_OSC / 2.0) * 0.2
+ act_energy * sin(i * 0.8 + layer * 0.17);
}
/* Partial reset of harmonics (not full wipe) */
for (int k = 0; k < N_HARM; k++) {
vc->c_re[k] *= 0.3;
vc->c_im[k] *= 0.3;
}
vc->utilization += 1.0;
}
/* ── Input tendrils: blend activation (continuous state) ── */
for (int i = 0; i < mc->n_inputs; i++) {
vqpu_t *v = &p->vqpus[mc->input_start + i];
if (v->role == ROLE_DORMANT) continue;
int chunk = (i * N_OSC + N_OSC <= p->D) ? N_OSC : (p->D - i * N_OSC);
if (chunk <= 0) break;
for (int o = 0; o < N_OSC; o++) {
double wave = 2.0 * M_PI * o / N_OSC;
double perturb = (o < chunk) ? x[i * N_OSC + o] * M_PI / 4.0 : 0.0;
/* Blend: 60% new signal, 40% carried state */
v->theta[o] = v->theta[o] * 0.4 + (wave + perturb) * 0.6;
}
v->active = 1;
v->utilization += 0.5;
}
/* ── Compute tendrils: rotating window per layer ── */
/* Only a subset of tendrils are active per layer.
* This creates lifecycle: used tendrils strengthen,
* unused ones decay → reclaim → replaced by fresh spawns. */
const uint8_t *gate_wp = wp + p->qw + p->kw + p->vw + p->ow;
int compute_used = 0;
int window_size = mc->n_compute / 4;
if (window_size < 32) window_size = 32;
if (window_size > mc->n_compute) window_size = mc->n_compute;
int window_start = (layer * window_size / 3) % mc->n_compute;
for (int w = 0; w < window_size; w++) {
int t = (window_start + w) % mc->n_compute;
int tid = mc->compute_start + t;
if (tid >= p->n_vqpus) break;
vqpu_t *v = &p->vqpus[tid];
if (v->role == ROLE_DORMANT) continue;
decode_ternary_to_lens(gate_wp, t, stride_gate, v->omega);
int act_base = (t * N_OSC) % p->D;
for (int i = 0; i < N_OSC; i++) {
double wave = 2.0 * M_PI * i / N_OSC;
double perturb = x[(act_base + i) % p->D] * M_PI / 4.0;
v->theta[i] = v->theta[i] * 0.3 + (wave + perturb) * 0.7;
}
v->active = 1;
v->utilization += 1.0;
compute_used++;
}
/* ── Activate core + output ── */
for (int r = 0; r < MACRO_RINGS; r++)
p->vqpus[mc->ring_id[r]].active = 1;
for (int i = 0; i < mc->n_outputs; i++) {
int oid = mc->output_start + i;
if (oid >= p->n_vqpus) break;
vqpu_t *v = &p->vqpus[oid];
if (v->role == ROLE_DORMANT) continue;
v->active = 1;
/* Partial harmonic decay (not full wipe) */
for (int k = 0; k < N_HARM; k++) {
v->c_re[k] *= 0.2;
v->c_im[k] *= 0.2;
}
v->utilization += 0.5;
}
/* ── Build hot set + SETTLE ── */
p->n_hot = 0;
for (int i = 0; i < p->n_vqpus; i++)
if (p->vqpus[i].active)
p->hot_set[p->n_hot++] = i;
settle_ring(p, SETTLE_STEPS);
/* ── Read products (same scatter readout as macro_forward_layer) ── */
memset(x_out, 0, p->D * sizeof(double));
/* Compute tendrils: harmonic scatter */
double max_product = 0;
int saturated_count = 0;
for (int t = 0; t < mc->n_compute; t++) {
int tid = mc->compute_start + t;
if (tid >= p->n_vqpus || p->vqpus[tid].role == ROLE_DORMANT) continue;
vqpu_t *v = &p->vqpus[tid];
double product = vqpu_read_products(v, p->g_coupling, p->lens_enhance);
if (fabs(product) > max_product) max_product = fabs(product);
if (fabs(product) > 0.5) saturated_count++;
for (int k = 1; k < N_HARM; k++) {
if (v->c_mag[k] < 0.001) continue;
double phase_addr = fmod(fabs(v->c_re[k] * 1000.0), (double)p->D);
int idx = (int)phase_addr;
if (idx >= 0 && idx < p->D)
x_out[idx] += product * v->c_mag[k];
}
int direct_idx = t * (p->D / (mc->n_compute > 0 ? mc->n_compute : 1));
if (direct_idx < p->D)
x_out[direct_idx] += product * 0.5;
}
/* Core PROC broadcast */
for (int r = RING_PROC_A; r <= RING_PROC_B; r++) {
vqpu_t *v = &p->vqpus[mc->ring_id[r]];
for (int k = 1; k < N_HARM; k++) {
if (v->c_mag[k] < 0.001) continue;
double product = vqpu_product(v, k, k, p->g_coupling, p->lens_enhance);
for (int i = 0; i < N_OSC; i++) {
int idx = (int)(fmod(fabs(v->theta[i]) * p->D / (2.0 * M_PI), p->D));
if (idx >= 0 && idx < p->D)
x_out[idx] += product * cos(v->theta[i]) * 0.1;
}
}
}
/* COLLECT harmonic summary */
{
vqpu_t *vc = &p->vqpus[mc->ring_id[RING_COLLECT]];
for (int i = 0; i < p->D; i++) {
double acc = 0;
for (int k = 1; k < N_HARM; k++)
acc += vc->c_re[k] * cos(2.0 * M_PI * k * i / p->D)
+ vc->c_im[k] * sin(2.0 * M_PI * k * i / p->D);
x_out[i] += acc * 5.0;
}
}
/* Output tendrils */
for (int i = 0; i < mc->n_outputs; i++) {
int oid = mc->output_start + i;
if (oid >= p->n_vqpus || p->vqpus[oid].role == ROLE_DORMANT) continue;
vqpu_t *v = &p->vqpus[oid];
int base = i * (p->D / mc->n_outputs);
int span = p->D / mc->n_outputs;
double val = v->c_re[CH_FUND] * 10.0;
for (int j = 0; j < span && base + j < p->D; j++)
x_out[base + j] += val;
}
/* Residual */
for (int i = 0; i < p->D; i++)
x_out[i] += x[i];
/* Output RMSNorm on last layer */
if (layer == p->n_layers - 1 && p->has_norms && p->norm_output) {
double ss = 0;
for (int i = 0; i < p->D; i++) ss += x_out[i] * x_out[i];
double rms = sqrt(ss / p->D + 1e-5);
double inv = 1.0 / rms;
for (int i = 0; i < p->D; i++)
x_out[i] = x_out[i] * inv * (double)p->norm_output[i];
}
/* ── Demand-driven spawning ── */
/* If >80% of compute tendrils are saturated, grow more */
if (compute_used > 0 && saturated_count > compute_used * 8 / 10) {
int grow = compute_used / 10;
if (grow < 4) grow = 4;
if (grow > 32) grow = 32;
int grown = 0;
for (int g = 0; g < grow; g++) {
int hub = (g % 2 == 0)
? mc->ring_id[RING_PROC_A]
: mc->ring_id[RING_PROC_B];
int id = spawn_tendril(p, hub, ROLE_GATE,
CH_FUND, CH_PROD4, 0.25);
if (id >= 0) {
mc->n_compute++;
grown++;
}
}
if (grown > 0)
printf(" [SPAWN] +%d compute tendrils (demand: %d/%d saturated)\n",
grown, saturated_count, compute_used);
}
/* Deactivate */
for (int i = 0; i < p->n_vqpus; i++)
p->vqpus[i].active = 0;
/* Age all tendrils — faster decay drives lifecycle */
for (int i = 0; i < p->n_vqpus; i++) {
p->vqpus[i].age++;
p->vqpus[i].utilization *= 0.95;
}
}
/* Forward declarations for JSON state emitter */
static void emit_state(const phoenix_t *p, const char *event);
static void emit_token(const phoenix_t *p, int pos, int tok, int sample,
double energy, double elapsed);
/* Interference-wave activation constants.
* PHASE_GAMMA — how strongly the per-layer weight drive rotates the phase
* PHASE_WAVELEN— carrier wavelength (dims) the field rides on (wave-rider)
* The propagating state is a complex phasor field that STAYS ON THE UNIT
* CIRCLE: magnitude never collapses, so there is no fixed point to fall
* into. The token's embedding seeds the phase; each layer's physics rotates
* it (interference = phase accumulation). Different tokens seed different
* phase, so the readout stays input-dependent across all layers instead of
* relaxing to the rings' intrinsic attractor. */
#define PHASE_GAMMA 0.15
#define PHASE_WAVELEN 64.0
/* ── Shared interference-wave forward ──
* Fills z[D] with the final phasor field (real part). The propagating state
* is a unit-magnitude complex field: the token's embedding seeds the phase,
* each layer's weight physics rotates it (interference = phase accumulation),
* and the magnitude never collapses. BOTH inference and training call this,
* so the self-tuner optimizes the exact computation that generates tokens. */
static void phase_forward(phoenix_t *p, int token, double *z) {
double *emb = calloc(p->D, sizeof(double));
double *phi = calloc(p->D, sizeof(double));
double *x_out = calloc(p->D, sizeof(double));
embed_token(p, token, emb);
for (int d = 0; d < p->D; d++) {
phi[d] = emb[d] * (M_PI / 2.0);
z[d] = cos(2.0 * M_PI * d / PHASE_WAVELEN + phi[d]);
}
for (int layer = 0; layer < p->n_layers; layer++) {
macro_forward_layer(p, layer, z, x_out);
for (int d = 0; d < p->D; d++) {
phi[d] += PHASE_GAMMA * x_out[d];
z[d] = cos(2.0 * M_PI * d / PHASE_WAVELEN + phi[d]);
}
}
free(emb); free(phi); free(x_out);
}
static int continuous_forward(phoenix_t *p, int token, int token_pos) {
if (!p->model_loaded || !p->core.ready) return -1;
double *z = calloc(p->D, sizeof(double));
double t0 = now_ms();
phase_forward(p, token, z);
double elapsed = now_ms() - t0;
memcpy(p->readout, z, p->D * sizeof(double));
int best = project_to_vocab(p, z);
double energy = 0;
for (int i = 0; i < p->D; i++) energy += fabs(z[i]);
/* Core coherences */
double core_coh[MACRO_RINGS];
for (int r = 0; r < MACRO_RINGS; r++)
core_coh[r] = p->vqpus[p->core.ring_id[r]].coherence;
int active = count_active_tendrils(p);
printf(" [%3d] tok=%d → %d E=%.0f "
"coh=[%.2f %.2f %.2f %.2f] "
"tendrils=%d conns=%d %.1fms (%.1f t/s)\n",
token_pos, token, best, energy,
core_coh[0], core_coh[1], core_coh[2], core_coh[3],
active, p->alive_conns, elapsed,
elapsed > 0 ? 1000.0 / elapsed : 0);
p->total_cycles++;
emit_token(p, token_pos, token, best, energy, elapsed);
free(z);
return best;
}
/* ═══════════════════════════════════════════════════════════════════
* SCHEDULER + THOUGHT CYCLES (self-modification between inferences)
* ═══════════════════════════════════════════════════════════════════ */
static void phoenix_idle_cycle(phoenix_t *p) {
double t0 = now_ms();
ckpt_check(p);
/* Compute ring coherence */
double sum = 0;
for (int i = 0; i < p->n_vqpus; i++) sum += p->vqpus[i].coherence;
p->ring_coherence = sum / p->n_vqpus;
if (!p->ckpt.pending) {
if (p->total_cycles % 30 == 15 && p->alive_conns > 20)
propose_prune(p);
if (p->total_cycles % 40 == 25)
propose_strengthen(p);
if (p->total_cycles % 100 == 99) {
double avg_util = 0;
for (int i = 0; i < p->n_vqpus; i++)
avg_util += p->vqpus[i].utilization;
avg_util /= p->n_vqpus;
if (avg_util > 0.6 && p->n_vqpus + 10 <= p->capacity)
propose_grow(p, 10);
}
}
/* Light settle on a subset */
p->n_hot = 0;
for (int i = 0; i < p->n_vqpus && p->n_hot < 30; i++) {
p->hot_set[p->n_hot++] = i;
p->vqpus[i].active = 1;
}
settle_ring(p, 20);
for (int i = 0; i < p->n_vqpus; i++) {
p->vqpus[i].active = 0;
p->vqpus[i].age++;
p->vqpus[i].utilization *= 0.99;
}
p->total_cycles++;
p->last_cycle_ms = now_ms() - t0;
}
/* ═══════════════════════════════════════════════════════════════════
* MAIN
* ═══════════════════════════════════════════════════════════════════ */
static void phoenix_free(phoenix_t *p) {
free(p->vqpus);
free(p->fabric);
free(p->hot_set);
free(p->layer_base);
free(p->readout);
free(p->ckpt.vqpus);
free(p->ckpt.fabric);
if (p->weight_base)
munmap((void *)p->weight_base, p->weights_size);
}
/* ── Build state file path from model path ── */
static void make_state_path(const char *model_path, char *out, int maxlen) {
strncpy(out, model_path, maxlen - 6);
out[maxlen - 6] = '\0';
char *dot = strrchr(out, '.');
if (dot) *dot = '\0';
strcat(out, ".bqmc");
}
/* ── JSON state emitter for real-time dashboard ──
* Emits one JSON line per event to a state log file.
* The Python dashboard tails this file and renders live. */
static FILE *g_state_log = NULL;
static void emit_state(const phoenix_t *p, const char *event) {
if (!g_state_log) return;
double coh[MACRO_RINGS];
for (int r = 0; r < MACRO_RINGS; r++)
coh[r] = p->vqpus[p->core.ring_id[r]].coherence;
double c2=0, c4=0, c6=0;
for (int r = 0; r < MACRO_RINGS; r++) {
c2 += p->vqpus[p->core.ring_id[r]].c_mag[CH_PROD2];
c4 += p->vqpus[p->core.ring_id[r]].c_mag[CH_PROD4];
c6 += p->vqpus[p->core.ring_id[r]].c_mag[CH_PROD6];
}
fprintf(g_state_log,
"{\"event\":\"%s\",\"tendrils\":%d,\"conns\":%d,\"coh\":[%.4f,%.4f,%.4f,%.4f],"
"\"c2\":%.4f,\"c4\":%.4f,\"c6\":%.4f,\"cycles\":%d,"
"\"tune_imp\":%d,\"tune_rev\":%d,\"tune_best\":%.2f}\n",
event,
count_active_tendrils(p), p->alive_conns,
coh[0], coh[1], coh[2], coh[3],
c2, c4, c6, p->total_cycles,
p->tune.improve_count, p->tune.revert_count, p->tune.best_score);
fflush(g_state_log);
}
static void emit_token(const phoenix_t *p, int pos, int tok, int sample,
double energy, double elapsed) {
if (!g_state_log) return;
double coh[MACRO_RINGS];
for (int r = 0; r < MACRO_RINGS; r++)
coh[r] = p->vqpus[p->core.ring_id[r]].coherence;
fprintf(g_state_log,
"{\"event\":\"token\",\"pos\":%d,\"tok\":%d,\"sample\":%d,"
"\"energy\":%.2f,\"elapsed_ms\":%.1f,\"tok_per_s\":%.1f,"
"\"tendrils\":%d,\"conns\":%d,"
"\"coh\":[%.4f,%.4f,%.4f,%.4f],"
"\"tune_imp\":%d,\"tune_rev\":%d,\"tune_best\":%.2f}\n",
pos, tok, sample, energy, elapsed,
elapsed > 0 ? 1000.0/elapsed : 0,
count_active_tendrils(p), p->alive_conns,
coh[0], coh[1], coh[2], coh[3],
p->tune.improve_count, p->tune.revert_count, p->tune.best_score);
fflush(g_state_log);
}
/* ═══════════════════════════════════════════════════════════════════
* SELF-TUNING SYSTEM
*
* The system fine-tunes its own omega (lens) profiles through
* sparse perturbation + evaluation. Like LoRA: learn a residual
* adjustment on top of frozen ternary weights.
*
* Cycle: perturb omega on N tendrils → run batch → measure quality
* → if better, commit (keep perturbation) → if worse, revert.
*
* Quality metric: output diversity (how many distinct predictions)
* + output confidence (inverse entropy of argmax distribution).
* No labels needed — self-supervised on intrinsic signal quality.
*
* SOLIDIFY: After many perturbation rounds, accumulated omega
* adjustments are "solidified" — the structure re-optimizes:
* 1. Prune tendrils whose omega drifted toward zero (low contribution)
* 2. Strengthen tendrils with high-traffic, high-omega-magnitude
* 3. Rewire connections based on accumulated traffic patterns
* 4. Reset perturbation baseline to the new solidified state
* ═══════════════════════════════════════════════════════════════════ */
/* ── Load training data from a text file ──
* Reads token IDs (one per line, or space-separated) from a file.
* If file doesn't exist, generates a simple sequence for self-supervision. */
static int tune_load_data(phoenix_t *p, const char *path) {
FILE *f = fopen(path, "r");
if (!f) {
/* No training file: generate synthetic sequence */
int n = 256;
p->tune.train_tokens = malloc(n * sizeof(int));
p->tune.n_train = n;
for (int i = 0; i < n; i++)
p->tune.train_tokens[i] = i; /* tokens 0..255 */
p->tune.train_pos = 0;
return n;
}
/* Read token IDs from file */
int capacity = 1024;
p->tune.train_tokens = malloc(capacity * sizeof(int));
p->tune.n_train = 0;
int tok;
while (fscanf(f, "%d", &tok) == 1) {
if (p->tune.n_train >= capacity) {
capacity *= 2;
p->tune.train_tokens = realloc(p->tune.train_tokens, capacity * sizeof(int));
}
p->tune.train_tokens[p->tune.n_train++] = tok;
}
fclose(f);
p->tune.train_pos = 0;
return p->tune.n_train;
}
/* ── Vocab statistics for the next-token objective (sampled) ──
* The training reward only needs to know how favored the true target is
* relative to the rest of the vocabulary — NOT the exact full-vocab argmax.
* Computing the target's logit exactly and estimating the logit distribution
* from a uniform stride sample of TRAIN_SAMPLE tokens turns an O(V·D) pass
* (262k×3840 ≈ 1e9 ops) into O(SAMPLE·D) (~1e6) — about 1000× cheaper — while
* preserving the z-score signal the hill-climber climbs. Inference still uses
* the exact project_to_vocab; only training uses this estimate.
*
* best_id is the argmax over {target} ∪ sample, so pred==target means the
* target out-scored every sampled token (a cheap top-of-vocab proxy). */
#define TRAIN_SAMPLE 256
static void vocab_stats(phoenix_t *p, const double *x, int target,
int *best_id, double *target_logit,
double *mean_out, double *std_out) {
const uint8_t *lm_head = p->weights + (size_t)p->layer_bytes * p->n_layers;
int stride = p->V / 4;
/* Exact logit for the true target token */
double tl = 0;
{
int byte_idx = target / 4, sh = (target % 4) * 2;
for (int d = 0; d < p->D; d++) {
int b = (lm_head[d * stride + byte_idx] >> sh) & 0x03;
if (b == 0) tl -= x[d];
else if (b == 2) tl += x[d];
}
}
/* Estimate the logit distribution from a uniform stride sample */
int step = p->V / TRAIN_SAMPLE;
if (step < 1) step = 1;
double best_logit = -1e30, sum = 0, sumsq = 0;
int bid = target, cnt = 0;
#pragma omp parallel
{
double lb = -1e30, s = 0, ss = 0;
int li = target, c = 0;
#pragma omp for schedule(static)
for (int idx = 0; idx < TRAIN_SAMPLE; idx++) {
int v = idx * step;
if (v >= p->V) continue;
int byte_idx = v / 4, sh = (v % 4) * 2;
double logit = 0;
for (int d = 0; d < p->D; d++) {
int b = (lm_head[d * stride + byte_idx] >> sh) & 0x03;
if (b == 0) logit -= x[d];
else if (b == 2) logit += x[d];
}
s += logit; ss += logit * logit; c++;
if (logit > lb) { lb = logit; li = v; }
}
#pragma omp critical
{
sum += s; sumsq += ss; cnt += c;
if (lb > best_logit) { best_logit = lb; bid = li; }
}
}
double mean = cnt ? sum / cnt : 0.0;
double var = cnt ? sumsq / cnt - mean * mean : 1.0;
if (var < 1e-9) var = 1e-9;
if (tl > best_logit) bid = target; /* target beat the whole sample */
*best_id = bid; *target_logit = tl;
*mean_out = mean; *std_out = sqrt(var);
}
/* ── Score one (input → target) next-token pair ──
* Runs the SAME phase_forward the chat pipeline uses, then rewards how
* strongly the model favors the true next token. */
static double tune_eval_pair(phoenix_t *p, int input, int target, int *predicted) {
double *z = calloc(p->D, sizeof(double));
phase_forward(p, input, z);
int best; double tl, mean, std;
vocab_stats(p, z, target, &best, &tl, &mean, &std);
*predicted = best;
free(z);
return (tl - mean) / std; /* target z-score: higher = better prediction */
}
/* ── Next-token training batch ──
* Walks the corpus as a sequence (input = tok[i], target = tok[i+1]), scores
* each pair, tracks argmax accuracy, and emits a "train" event carrying the
* most recent input→target→prediction rows for the dashboard. */
#define TRAIN_SHOW_ROWS 8
static double tune_eval_batch(phoenix_t *p, int batch_size) {
if (p->tune.n_train < 2 || !p->tune.train_tokens)
return 0.0; /* need at least one (input,target) pair */
if (batch_size > 64) batch_size = 64;
double total = 0;
int correct = 0;
int cin[64], ctgt[64], cpred[64];
int rows = 0;
for (int i = 0; i < batch_size; i++) {
int pos = p->tune.train_pos % (p->tune.n_train - 1);
int input = p->tune.train_tokens[pos];
int target = p->tune.train_tokens[pos + 1];
p->tune.train_pos++;
int pred;
double s = tune_eval_pair(p, input, target, &pred);
total += s;
if (pred == target) correct++;
if (rows < 64) { cin[rows] = input; ctgt[rows] = target; cpred[rows] = pred; rows++; }
}
double score = total / batch_size;
p->tune.last_accuracy = (double)correct / batch_size;
/* Emit training data for the dashboard panel */
if (g_state_log) {
fprintf(g_state_log,
"{\"event\":\"train\",\"pos\":%d,\"n_train\":%d,\"acc\":%.4f,"
"\"score\":%.4f,\"best\":%.4f,\"rows\":[",
p->tune.train_pos, p->tune.n_train,
p->tune.last_accuracy, score, p->tune.best_score);
int show = rows < TRAIN_SHOW_ROWS ? rows : TRAIN_SHOW_ROWS;
for (int r = 0; r < show; r++)
fprintf(g_state_log, "%s[%d,%d,%d]", r ? "," : "",
cin[r], ctgt[r], cpred[r]);
fprintf(g_state_log, "]}\n");
fflush(g_state_log);
}
return score;
}
/* ── Perturb the trainable physics gains (g_coupling, lens_enhance) ──
* The tuner must perturb parameters that actually reach the output. Most of
* the state in macro_forward_layer is rebuilt from scratch each layer — every
* ring/tendril theta and omega is re-derived from the activation and the
* fixed ternary weights, so perturbing omega (or fabric weights, which the
* final DFT overwrites) is a silent no-op: the score never moves.
*
* The mode-coupling gain matrix g_coupling[p][q] and the channel enhancement
* lens_enhance[k] are the exception — they scale every interference product
* that builds x_out (vqpu_product / vqpu_read_products) and are never
* regenerated. They ARE the model's control surface. We back them up here so
* tune_commit_revert can restore them if the perturbation hurts. */
static void tune_perturb(phoenix_t *p, int n_units, double lr) {
macro_core_t *mc = &p->core;
p->tune.n_perturbed = 0;
if (mc->n_compute <= 0) return;
int cap = (int)(sizeof(p->tune.perturb_idx) / sizeof(p->tune.perturb_idx[0]));
int n = n_units * 2; /* a handful of tendrils per round */
if (n > cap) n = cap;
if (n < 1) n = 1;
/* Build a candidate pool of all trainable tendrils: compute tendrils,
* both PROC rings, the COLLECT ring, and output tendrils. Each caller's
* lr (~0.008–0.01) was tuned for radian omega steps; for a multiplicative
* gain around 1.0 we want a ~10% step, so scale it up. */
double step = lr * 12.0;
/* Collect candidate vQPU indices that can be perturbed */
int pool[64];
int pool_n = 0;
/* Compute tendrils */
for (int t = 0; t < mc->n_compute && pool_n < 64; t++)
pool[pool_n++] = mc->compute_start + t;
/* PROC rings */
for (int r = RING_PROC_A; r <= RING_COLLECT && pool_n < 64; r++)
pool[pool_n++] = mc->ring_id[r];
/* Output tendrils */
for (int t = 0; t < mc->n_outputs && pool_n < 64; t++)
pool[pool_n++] = mc->output_start + t;
for (int t = 0; t < n; t++) {
int id = pool[rand() % pool_n];
if (id < 0 || id >= p->n_vqpus) continue;
vqpu_t *v = &p->vqpus[id];
if (v->role == ROLE_DORMANT) continue;
if (v->train_gain == 0.0) v->train_gain = 1.0;
/* Record for possible revert */
int slot = p->tune.n_perturbed++;
p->tune.perturb_idx[slot] = id;
p->tune.perturb_old[slot] = v->train_gain;
/* Box-Muller Gaussian, multiplicative */
double u1 = (rand() + 1.0) / (RAND_MAX + 1.0);
double u2 = (rand() + 1.0) / (RAND_MAX + 1.0);
double g = sqrt(-2 * log(u1)) * cos(2 * M_PI * u2);
v->train_gain *= (1.0 + g * step);
if (v->train_gain < 0.05) v->train_gain = 0.05;
if (v->train_gain > 8.0) v->train_gain = 8.0;
}
}
/* ── Commit or revert a perturbation round ──
* The tuner perturbs a handful of per-tendril output gains, so revert restores
* exactly those from the backup taken in tune_perturb. It deliberately does
* NOT touch the structural checkpoint (ckpt_*) — that belongs to the idle
* self-modifier and reverting it here would clobber unrelated topology work. */
static void tune_commit_revert(phoenix_t *p, double new_score) {
if (new_score >= p->tune.best_score) {
/* Keep perturbation — it improved quality */
p->tune.best_score = new_score;
p->tune.improve_count++;
} else {
/* Restore just the tendril gains we touched this round */
for (int i = 0; i < p->tune.n_perturbed; i++)
p->vqpus[p->tune.perturb_idx[i]].train_gain = p->tune.perturb_old[i];
p->tune.revert_count++;
}
}
/* ── SOLIDIFY: re-optimize structure based on accumulated state ──
*
* After many perturbation rounds, the system has explored the omega
* space and found what works. Solidify takes that learning and
* permanently reshapes the topology:
*
* 1. Find tendrils whose omega magnitude → near zero (low contribution)
* 2. Reclaim those tendrils (free resources)
* 3. Find tendrils with high traffic + high omega magnitude
* 4. Strengthen their connections (increase fabric weight)
* 5. Spawn new tendrils near high-traffic hubs
* 6. Reset the perturbation baseline to current solidified state
*/
static void tune_solidify(phoenix_t *p) {
int reclaimed = 0, strengthened = 0, spawned = 0;
/* 1. Find low-contribution tendrils (omega magnitude near zero) */
for (int i = 0; i < p->n_vqpus; i++) {
vqpu_t *v = &p->vqpus[i];
if (v->role != ROLE_GATE) continue;
if (!v->active) continue;
double omega_mag = 0;
for (int o = 0; o < N_OSC; o++)
omega_mag += fabs(v->omega[o]);
omega_mag /= N_OSC;
/* Also check utilization — low traffic + low omega = dead weight */
if (omega_mag < 0.05 && v->utilization < 0.1) {
/* Reclaim this tendril */
v->role = ROLE_DORMANT;
v->active = 0;
/* Remove its connections */
for (int c = 0; c < p->n_connections; c++) {
if (p->fabric[c].alive &&
(p->fabric[c].src == i || p->fabric[c].dst == i)) {
p->fabric[c].alive = 0;
p->alive_conns--;
}
}
reclaimed++;
}
}
/* 2. Strengthen high-traffic connections */
for (int c = 0; c < p->n_connections; c++) {
conn_t *conn = &p->fabric[c];
if (!conn->alive) continue;
if (conn->traffic > 5.0) {
conn->weight *= 1.1;
if (conn->weight > 1.0) conn->weight = 1.0;
strengthened++;
}
}
/* 3. Spawn new tendrils near the busiest hubs */
int busiest_hub = -1;
double max_traffic = 0;
for (int i = 0; i < p->n_vqpus; i++) {
if (p->vqpus[i].role == ROLE_GATE && p->vqpus[i].active) {
if (p->vqpus[i].utilization > max_traffic) {
max_traffic = p->vqpus[i].utilization;
busiest_hub = i;
}
}
}
if (busiest_hub >= 0 && p->n_vqpus < p->capacity) {
int hub_parent = p->vqpus[busiest_hub].layer_id >= 0
? p->core.ring_id[RING_PROC_A] : busiest_hub;
for (int s = 0; s < 3; s++) {
int id = spawn_tendril(p, hub_parent, ROLE_GATE,
CH_FUND, CH_PROD4, 0.3);
if (id >= 0) {
p->core.n_compute++;
spawned++;
}
}
}
/* 4. Don't reset best_score — keep the running best across solidify events */
printf(" [SOLIDIFY] reclaimed=%d strengthened=%d spawned=%d"
" → %d active, %d conns\n",
reclaimed, strengthened, spawned,
count_active_tendrils(p), p->alive_conns);
}
int main(int argc, char **argv) {
srand(42);
phoenix_t brain;
phoenix_init(&brain);
printf("Phoenix Brain — Living 4-Ring Macro Core\n");
printf("═══════════════════════════════════════════════════════\n");
printf(" 64 fixed oscillators + demand-driven tentacles\n");
printf(" Continuous state | Persistent topology | Self-pruning\n\n");
if (argc < 2) {
fprintf(stderr, "Usage: %s <model.bqsm> [num_tokens|--chat]\n", argv[0]);
return 1;
}
int chat_mode = (argc >= 3 && strcmp(argv[2], "--chat") == 0);
int n_tokens = argc >= 3 && !chat_mode ? atoi(argv[2]) : 20;
char state_path[512];
make_state_path(argv[1], state_path, sizeof(state_path));
/* Open state log for real-time dashboard */
g_state_log = fopen("/tmp/phoenix_state.jsonl", "w");
if (!g_state_log) g_state_log = stderr;
/* ── Phase 1: Load model weights ── */
printf(" Model: %s\n", argv[1]);
phoenix_ingest(&brain, argv[1]);
if (!brain.model_loaded) {
fprintf(stderr, "Failed to load model\n");
return 1;
}
/* ── Phase 2: Try to load saved state ── */
int resumed = 0;
if (state_load(&brain, state_path) == 0) {
/* Self-verify the loaded topology before trusting it. A state saved
* mid-restructure can be structurally inconsistent; repair what we
* can, and if the core rings themselves are gone, throw it away and
* rebuild from clean ingestion rather than crash later. */
int issues = verify_integrity(&brain, 1);
if (issues >= INTEGRITY_FATAL) {
printf(" [STATE] Loaded state failed integrity check (core rings invalid)"
" — discarding and re-ingesting clean topology\n");
phoenix_ingest(&brain, argv[1]);
} else {
if (issues > 0)
printf(" [STATE] Integrity check repaired %d issue(s) in loaded topology\n", issues);
else
printf(" [STATE] Integrity check passed — topology coherent\n");
printf(" [STATE] Resumed evolved topology from %s\n", state_path);
resumed = 1;
}
} else {
printf(" [STATE] No saved state — fresh topology from ingestion\n");
}
/* ── Print topology ── */
macro_core_t *mc = &brain.core;
int active = count_active_tendrils(&brain);
double ring_kb = (double)(brain.n_vqpus * sizeof(vqpu_t)) / 1024.0;
double fab_kb = (double)(brain.alive_conns * sizeof(conn_t)) / 1024.0;
printf("\n Topology:\n");
printf(" Core: 4 × %d = %d osc (permanent)\n", N_OSC, MACRO_RINGS * N_OSC);
printf(" Tendrils: %d active\n", active);
printf(" Connections:%d alive\n", brain.alive_conns);
printf(" Memory: %.1f KB ring + %.1f KB fabric = %.1f KB\n",
ring_kb, fab_kb, ring_kb + fab_kb);
if (resumed)
printf(" Cycles: %d (accumulated)\n", brain.total_cycles);
/* ── Phase 3: Continuous inference ── */
/* In chat mode, skip initial test tokens — phoenix reads from ring buffer */
int initial_tendrils = active;
int initial_conns = brain.alive_conns;
if (!chat_mode) {
printf("\n ── Continuous Inference (%d tokens) ──\n", n_tokens);
printf(" [pos] tok\u2192sample E=energy coh=[I A B C]"
" tendrils conns ms (t/s)\\n");
int test_tokens[] = { 0, 1, 2, 3, 4, 100, 200, 500, 1000, 2000,
5000, 10000, 42, 7, 13, 256, 512, 1024, 128, 64 };
int n_test = sizeof(test_tokens) / sizeof(test_tokens[0]);
if (n_tokens > n_test) n_tokens = n_test;
for (int pos = 0; pos < n_tokens; pos++) {
int tok = test_tokens[pos % n_test];
/* Continuous forward — phase state carries between tokens */
continuous_forward(&brain, tok, pos);
/* Between tokens: sweep dormant and run idle optimization */
if (pos > 0 && pos % 3 == 0) {
int reclaimed = sweep_dormant(&brain, 0.1);
if (reclaimed > 0) {
printf(" [SWEEP] Reclaimed %d dormant tendrils"
" \u2192 %d active, %d conns\\n",
reclaimed, count_active_tendrils(&brain),
brain.alive_conns);
/* Update compute count */
brain.core.n_compute -= reclaimed;
if (brain.core.n_compute < 0) brain.core.n_compute = 0;
}
/* Quick idle cycles for Hebbian adaptation */
for (int c = 0; c < 3; c++)
phoenix_idle_cycle(&brain);
}
}
}
/* ── Phase 3b: Chat mode — ring buffer token I/O ──
*
* When launched with --chat, phoenix maps two shared-memory ring buffers:
* - /tmp/phoenix_ring_in: dashboard writes token IDs (user input + predicted feedback)
* - /tmp/phoenix_ring_out: phoenix writes predicted token IDs (output to display)
*
* Ring buffer layout: [head:u32][tail:u32][size:u32][cap:u32][tokens:cap*u32]
* The dashboard pushes token IDs from tokenized user text. Phoenix pops them,
* runs inference through the wave-rider pipeline, and pushes the predicted
* token ID to the output ring. Self-tuning runs between predictions.
*
* Ring buffers never close — they persist across Start/Stop/restarts of
* the dashboard. The state file (.bqmc) holds the brain's evolved topology. */
#define RING_CAPACITY 4096
#define RING_BUF_SIZE (RING_CAPACITY * sizeof(uint32_t) + 16)
if (chat_mode) {
const char *ring_in_path = "/tmp/phoenix_ring_in";
const char *ring_out_path = "/tmp/phoenix_ring_out";
int fd_in = open(ring_in_path, O_RDWR);
int fd_out = open(ring_out_path, O_RDWR);
if (fd_in < 0 || fd_out < 0) {
fprintf(stderr, "Cannot open ring buffers. Start dashboard first.\n");
if (fd_in >= 0) close(fd_in);
if (fd_out >= 0) close(fd_out);
} else {
volatile uint32_t *ring_in = mmap(NULL, RING_BUF_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED, fd_in, 0);
volatile uint32_t *ring_out = mmap(NULL, RING_BUF_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED, fd_out, 0);
close(fd_in); close(fd_out);
if (ring_in == MAP_FAILED || ring_out == MAP_FAILED) {
fprintf(stderr, "mmap failed\n");
} else {
uint32_t last_sample = 0;
printf("\n ── Chat Mode: ring buffer token I/O ──\n");
printf(" Reading from /tmp/phoenix_ring_in\n");
printf(" Writing to /tmp/phoenix_ring_out\n");
/* Initialize self-tuning corpus for chat mode. The batch
* training block (post-chat) never runs here, so without this
* tune.n_train stays 0 and tune_eval_batch divides by zero. */
if (brain.tune.n_train <= 0) {
/* tune_load_data falls back to a synthetic 0..255 corpus
* if the file is missing. */
int nt = tune_load_data(&brain,
"/home/compunerd/models/train_tokens.txt");
brain.tune.perturb_lr = 0.01;
brain.tune.perturb_count = 8;
brain.tune.batch_size = 4;
brain.tune.train_pos = 0;
brain.tune.best_score = tune_eval_batch(&brain, brain.tune.batch_size);
printf(" Self-tune corpus: %d tokens, baseline score=%.2f\n",
nt, brain.tune.best_score);
}
printf("\n");
fflush(stdout);
int chat_pos = 0;
int idle_ticks = 0;
while (1) {
/* Poll ring_in: [head(0) tail(1) size(2) cap(3)] [tokens(4+)] */
uint32_t sz = ring_in[2];
if (sz == 0) {
phoenix_idle_cycle(&brain);
/* Self-verify periodically: the idle cycle restructures
* the topology, so re-check its integrity and repair any
* drift before it can crash a forward pass. */
if (idle_ticks % 100 == 0) {
int fixed = verify_integrity(&brain, 1);
if (fixed > 0 && g_state_log) {
fprintf(g_state_log,
"{\"event\":\"verify\",\"repaired\":%d,\"vqpus\":%d,\"conns\":%d}\n",
fixed, count_active_tendrils(&brain), brain.alive_conns);
fflush(g_state_log);
}
}
/* Self-tune while idle so best/imp/rev keep evolving,
* but rarely and cheaply: one perturbation eval only
* after ~3s of true idle (300 ticks), batch of 2. This
* keeps the loop responsive to incoming chat tokens —
* a full batch here would block input for ~10s. */
if (++idle_ticks % 300 == 0) {
tune_perturb(&brain, 4, 0.008);
brain.tune.train_pos = 0;
double score = tune_eval_batch(&brain, 2);
tune_commit_revert(&brain, score);
emit_state(&brain,
score >= brain.tune.best_score ? "tune_improve" : "tune_revert");
} else {
emit_state(&brain, "idle");
}
usleep(10000);
continue;
}
uint32_t head = ring_in[0];
uint32_t tok = ring_in[4 + head];
ring_in[0] = (head + 1) % RING_CAPACITY;
ring_in[2] = sz - 1;
if (tok == 0xFFFFFFFE) break;
if (tok >= (uint32_t)brain.V) continue;
if (g_state_log) {
fprintf(g_state_log,
"{\"event\":\"chat_input\",\"tok\":%u,\"pos\":%d}\n",
tok, chat_pos);
fflush(g_state_log);
}
int sample = continuous_forward(&brain, (int)tok, chat_pos);
if (sample < 0) sample = (int)tok; /* engine not ready */
last_sample = (uint32_t)sample;
/* Push the PREDICTED token to ring_out (not the input) */
uint32_t ot = ring_out[0]; uint32_t ot2 = ring_out[1];
uint32_t osz = ring_out[2];
uint32_t next = (ot2 + 1) % RING_CAPACITY;
if (next != ot) {
ring_out[4 + ot2] = last_sample;
ring_out[1] = next;
ring_out[2] = osz + 1;
}
chat_pos++;
/* Self-tuning every 5 tokens */
if (chat_pos % 5 == 0) {
tune_perturb(&brain, 4, 0.008 * (1.0 - chat_pos * 0.001));
brain.tune.train_pos = 0;
double score = tune_eval_batch(&brain, 4);
tune_commit_revert(&brain, score);
emit_state(&brain, score >= brain.tune.best_score ? "tune_improve" : "tune_revert");
}
/* Solidify every 15 tokens */
if (chat_pos % 15 == 0) {
tune_solidify(&brain);
emit_state(&brain, "solidify");
}
if (chat_pos % 50 == 0)
state_save(&brain, state_path);
}
/* Sentinel */
uint32_t ot = ring_out[0]; uint32_t ot2 = ring_out[1]; uint32_t osz = ring_out[2];
uint32_t next = (ot2 + 1) % RING_CAPACITY;
if (next != ot) {
ring_out[4 + ot2] = 0xFFFFFFFE;
ring_out[1] = next;
ring_out[2] = osz + 1;
}
munmap((void*)ring_in, RING_BUF_SIZE);
munmap((void*)ring_out, RING_BUF_SIZE);
printf("Chat mode ended.\n");
}
}
}
/* ── Phase 4: Post-inference analysis ── */
active = count_active_tendrils(&brain);
printf("\n ── Post-Inference State ──\n");
/* Core ring state */
const char *ring_names[] = {"INTAKE ", "PROC_A ", "PROC_B ", "COLLECT"};
for (int r = 0; r < MACRO_RINGS; r++) {
vqpu_t *v = &brain.vqpus[mc->ring_id[r]];
printf(" %s: coh=%.3f c₂=%.3f c₄=%.3f c₆=%.3f util=%.2f\n",
ring_names[r], v->coherence,
v->c_mag[CH_PROD2], v->c_mag[CH_PROD4], v->c_mag[CH_PROD6],
v->utilization);
}
/* Product channels */
double ch_total[4] = {0};
for (int i = 0; i < brain.n_vqpus; i++) {
vqpu_t *v = &brain.vqpus[i];
if (v->role == ROLE_GATE) {
ch_total[0] += fabs(vqpu_product(v, 1, 1, brain.g_coupling, brain.lens_enhance));
ch_total[1] += fabs(vqpu_product(v, 2, 2, brain.g_coupling, brain.lens_enhance));
ch_total[2] += fabs(vqpu_product(v, 2, 4, brain.g_coupling, brain.lens_enhance));
ch_total[3] += fabs(vqpu_product(v, 1, 2, brain.g_coupling, brain.lens_enhance));
}
}
printf("\n Product channels:\n");
printf(" c₂(4×)=%.2f c₄(24×)=%.2f c₆(10×)=%.2f c₃(1×)=%.2f\n",
ch_total[0], ch_total[1], ch_total[2], ch_total[3]);
/* Lifecycle summary */
int delta_tendrils = active - initial_tendrils;
int delta_conns = brain.alive_conns - initial_conns;
printf("\n Lifecycle:\n");
printf(" Tendrils: %d → %d (%+d)\n",
initial_tendrils, active, delta_tendrils);
printf(" Connections: %d → %d (%+d)\n",
initial_conns, brain.alive_conns, delta_conns);
printf(" Cycles: %d total\n", brain.total_cycles);
printf(" Mods: %d confirmed, %d reverted\n",
brain.mod_confirms, brain.mod_reverts);
/* ── Phase 5: Self-tuning ── */
printf("\n ── Self-Tuning (omega perturbation + evaluation) ──\n");
/* Load training data (synthetic if no file) */
/* Load training data — prefer wiki corpus, fall back to sample texts */
const char *train_path = "/home/compunerd/models/train_wiki.txt";
FILE *tf = fopen(train_path, "r");
if (!tf) train_path = "/home/compunerd/models/train_tokens.txt";
else fclose(tf);
int n_train = tune_load_data(&brain, train_path);
brain.tune.best_score = 0;
brain.tune.perturb_lr = 0.01;
brain.tune.perturb_count = 8;
brain.tune.batch_size = 8;
brain.tune.improve_count = 0;
brain.tune.revert_count = 0;
printf(" Training data: %d tokens from %s\n", n_train, train_path);
printf(" Perturbing %d tendrils per round, lr=%.4f, batch=%d\n",
brain.tune.perturb_count, brain.tune.perturb_lr,
brain.tune.batch_size);
printf(" [round] score=cur best=best (imp/rev) tendrils conns\n");
/* Baseline evaluation */
brain.tune.train_pos = 0;
brain.tune.best_score = tune_eval_batch(&brain, brain.tune.batch_size);
printf(" [base] score=%.2f\n", brain.tune.best_score);
/* Run tuning rounds — autonomous mode: many rounds with periodic
* state saves so training persists across runs and can be stopped
* safely with checkpoint recovery. */
int n_rounds = 2000;
int save_every = 50;
for (int round = 0; round < n_rounds; round++) {
/* Perturb */
brain.tune.train_pos = 0;
tune_perturb(&brain, brain.tune.perturb_count, brain.tune.perturb_lr);
/* Evaluate with perturbation */
brain.tune.train_pos = 0;
double new_score = tune_eval_batch(&brain, brain.tune.batch_size);
/* Commit or revert */
tune_commit_revert(&brain, new_score);
int active_t = count_active_tendrils(&brain);
printf(" [%2d] score=%.2f best=%.2f (%d/%d) tend=%d conns=%d\n",
round + 1, new_score, brain.tune.best_score,
brain.tune.improve_count, brain.tune.revert_count,
active_t, brain.alive_conns);
/* Emit tuning state for dashboard */
brain.tune.best_score = brain.tune.best_score;
emit_state(&brain, new_score >= brain.tune.best_score ? "tune_improve" : "tune_revert");
/* Solidify every 5 rounds */
if ((round + 1) % 5 == 0) {
printf(" ── Solidifying structure ──\n");
tune_solidify(&brain);
emit_state(&brain, "solidify");
}
/* Decay learning rate over time, with a floor so training
* continues to learn — never let it decay to zero. */
brain.tune.perturb_lr *= 0.95;
if (brain.tune.perturb_lr < 0.001) brain.tune.perturb_lr = 0.001;
/* Periodic checkpoint so training state survives across runs */
if ((round + 1) % save_every == 0) {
state_save(&brain, state_path);
printf(" [ckpt] saved state to %s (round %d)\n",
state_path, round + 1);
}
}
printf("\n Tuning results:\n");
printf(" Improved: %d rounds\n", brain.tune.improve_count);
printf(" Reverted: %d rounds\n", brain.tune.revert_count);
printf(" Best score: %.2f\n", brain.tune.best_score);
/* ── Phase 6: Save evolved state ── */
state_save(&brain, state_path);
/* Final sweep for reporting */
int dormant = 0;
for (int i = 0; i < brain.n_vqpus; i++)
if (brain.vqpus[i].role == ROLE_DORMANT) dormant++;
printf("\n Summary\n");
printf(" ─────────────────────────────────────\n");
printf(" Core: %d osc (4 rings, permanent)\n", MACRO_RINGS * N_OSC);
printf(" Active: %d tendrils\n", active);
printf(" Dormant: %d (reclaimable)\n", dormant);
printf(" Connections: %d alive\n", brain.alive_conns);
printf(" State file: %s\n", state_path);
printf(" Memory: %.1f KB\n",
(double)(brain.n_vqpus * sizeof(vqpu_t) +
brain.alive_conns * sizeof(conn_t)) / 1024.0);
printf(" Tuning: %d improved, %d reverted (best=%.2f)\n",
brain.tune.improve_count, brain.tune.revert_count,
brain.tune.best_score);
phoenix_free(&brain);
return 0;
}