/* 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 #include #include #include #include #include #include #include #include #include #include /* ── 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 [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; }