"""HPC spectral objective: folded error pyramid, DC/vesica penalty, shaping. The C engine scores a block with:: E = sum_i w_i e_i^2 + (dc_lambda / n) * (sum_i e_i)^2 + (vw_lambda / n) * sum_{pairs} (e_i + e_{i+n/2})^2 and the fold tree generalises the vesica term to every periodic level. V2 keeps the exact same objective and adds a vectorised implementation of the D6/vesica greedy code descent. """ from __future__ import annotations from functools import lru_cache import numpy as np from .config import HPCConfig from .q2k import QK_K, dequantize_params @lru_cache(maxsize=64) def _fold_weights_cached(n: int, dc_lambda: float, vw_lambda: float, depth: int, gamma: float) -> np.ndarray: levels = int(np.log2(n)) if (1 << levels) != n: raise ValueError("fold pyramid requires a power-of-two length") weights = np.zeros(levels, dtype=np.float64) g = 1.0 for k in range(1, levels + 1): if k == levels: weights[k - 1] = dc_lambda / n elif k <= depth: weights[k - 1] = (vw_lambda / n) * g g *= gamma weights.setflags(write=False) return weights def fold_weights(n: int, cfg: HPCConfig) -> np.ndarray: return _fold_weights_cached( n, cfg.dc_lambda, cfg.vw_lambda, cfg.fold_depth, cfg.fold_gamma ) def fold_build(errors: np.ndarray) -> np.ndarray: e = np.asarray(errors, dtype=np.float64) n = e.size py = np.empty(n - 1, dtype=np.float64) src = e offset = 0 m = n // 2 while m >= 1: dst = src[:m] + src[m : 2 * m] py[offset : offset + m] = dst src = dst offset += m m //= 2 return py def fold_energy(pyramid: np.ndarray, weights: np.ndarray) -> float: acc = 0.0 offset = 0 m = pyramid.size // 2 + 1 level = 0 while m >= 1: if weights[level] != 0.0: v = pyramid[offset : offset + m] acc += float(weights[level] * np.dot(v, v)) offset += m m //= 2 level += 1 return acc def spectral_penalty( errors: np.ndarray, cfg: HPCConfig, dc_carry: float = 0.0 ) -> float: if not cfg.use_spectral or (cfg.dc_lambda == 0.0 and cfg.vw_lambda == 0.0): return 0.0 pyramid = fold_build(errors) pyramid[-1] += dc_carry return fold_energy(pyramid, fold_weights(errors.size, cfg)) def objective( x: np.ndarray, w: np.ndarray | None, d, dmin, ls: np.ndarray, lm: np.ndarray, codes: np.ndarray, cfg: HPCConfig, dc_carry: float = 0.0, ) -> tuple[float, float]: xh = dequantize_params(d, dmin, ls, lm, codes) e = np.asarray(x, dtype=np.float64) - xh.astype(np.float64) sse = float(np.dot(np.asarray(w, dtype=np.float64), e * e)) if w is not None else float(np.dot(e, e)) return sse + spectral_penalty(e, cfg, dc_carry), sse def refine_codes_hadamard( x: np.ndarray, w: np.ndarray | None, d, dmin, ls: np.ndarray, lm: np.ndarray, codes: np.ndarray, cfg: HPCConfig, dc_carry: float = 0.0, ) -> np.ndarray: """Deterministic greedy descent of ``4*vesica^2 + (DC + carry)^2``. Same acceptance rule as the C Phase-4 shaper, but the whole 256-element search is evaluated as four vectorised candidate matrices per pass. """ x = np.asarray(x, dtype=np.float64) out = np.asarray(codes, dtype=np.uint8).copy() ww = np.ones(QK_K, dtype=np.float64) if w is None else np.asarray(w, dtype=np.float64) d_sub = np.repeat(np.float32(d) * np.asarray(ls, dtype=np.float32), 16).astype(np.float64) m_sub = np.repeat(np.float32(dmin) * np.asarray(lm, dtype=np.float32), 16).astype(np.float64) active = d_sub >= 1.0e-15 if not np.any(active): return out xh = d_sub * out.astype(np.float64) - m_sub e_live = x - xh sse_live = float(np.dot(ww, e_live * e_live)) sse_cap = sse_live * (1.0 + cfg.sse_budget) v_live = e_live[: QK_K // 2] + e_live[QK_K // 2 :] vesica = float(np.dot(v_live, v_live)) dc = float(np.sum(e_live)) + dc_carry metric = 4.0 * vesica + dc * dc idx = np.arange(QK_K) pi = np.where(idx < QK_K // 2, idx, idx - QK_K // 2) for _ in range(QK_K): best_delta = 0.0 best_k = -1 best_q = 0 for q_try in range(4): e_new = x - (d_sub * q_try - m_sub) delta_e = e_new - e_live sse_alt = sse_live + ww * (e_new * e_new - e_live * e_live) mask = (sse_alt <= sse_cap) & active & (out != q_try) if not np.any(mask): continue v_new = v_live[pi] + delta_e vesica_alt = vesica - v_live[pi] * v_live[pi] + v_new * v_new dc_alt = dc + delta_e delta = metric - (4.0 * vesica_alt + dc_alt * dc_alt) delta = np.where(mask, delta, -np.inf) k = int(np.argmax(delta)) if delta[k] > best_delta: best_delta = float(delta[k]) best_k = k best_q = q_try if best_k < 0: break old_e = e_live[best_k] new_e = x[best_k] - (d_sub[best_k] * best_q - m_sub[best_k]) de = new_e - old_e p = pi[best_k] v_live[p] += de vesica += v_live[p] * v_live[p] - (v_live[p] - de) * (v_live[p] - de) dc += de metric = 4.0 * vesica + dc * dc sse_live += ww[best_k] * (new_e * new_e - old_e * old_e) e_live[best_k] = new_e out[best_k] = np.uint8(best_q) return out def dc_nudge_codes( x: np.ndarray, d, dmin, ls: np.ndarray, lm: np.ndarray, codes: np.ndarray, w: np.ndarray | None, carry: float, cfg: HPCConfig, max_passes: int = 4, ) -> np.ndarray: """Spend a bounded SSE budget to cancel the rolling DC residual. Equivalent in spirit to Phase 4.8 of the C engine: the reconstruction target is always the true weight, only the codeword choice changes. """ x = np.asarray(x, dtype=np.float64) out = np.asarray(codes, dtype=np.uint8).copy() ww = np.ones(QK_K, dtype=np.float64) if w is None else np.asarray(w, dtype=np.float64) d_sub = np.repeat(np.float32(d) * np.asarray(ls, dtype=np.float32), 16).astype(np.float64) m_sub = np.repeat(np.float32(dmin) * np.asarray(lm, dtype=np.float32), 16).astype(np.float64) active = d_sub >= 1.0e-15 if not np.any(active): return out e = x - (d_sub * out.astype(np.float64) - m_sub) sse = float(np.dot(ww, e * e)) cap = sse * (1.0 + cfg.sse_budget) residual = float(np.sum(e)) + carry for _ in range(max_passes): best_improvement = 0.0 best_k = -1 best_q = 0 for q_try in range(4): e_new = x - (d_sub * q_try - m_sub) mask = active & (out != q_try) sse_alt = sse + ww * (e_new * e_new - e * e) mask &= sse_alt <= cap if not np.any(mask): continue improvement = np.abs(residual) - np.abs(residual + (e_new - e)) improvement = np.where(mask, improvement, -np.inf) k = int(np.argmax(improvement)) if improvement[k] > best_improvement: best_improvement = float(improvement[k]) best_k = k best_q = q_try if best_k < 0: break old_e = e[best_k] new_e = x[best_k] - (d_sub[best_k] * best_q - m_sub[best_k]) de = new_e - old_e residual += de sse += ww[best_k] * (new_e * new_e - old_e * old_e) e[best_k] = new_e out[best_k] = np.uint8(best_q) if abs(residual) < 1.0e-12: break return out def pin_dc_codes_uniform( x: np.ndarray, d: np.ndarray, codes: np.ndarray, unit: np.ndarray, lo: int, hi: int, budget_frac: float = 0.05, max_rounds: int = 96, ) -> tuple[np.ndarray, int]: """Zero-DC pin for single-scale lattices (``Q4_0`` nibble, ``Q3_K`` signed grid). These formats carry only one free fp16 parameter per block, so the exact ``sum(e) == 0`` scale re-solve that gives ``Q2_K`` its free lunch is structurally degenerate (``sum(a) ~= 0`` for symmetric code vectors, and the ``fp16`` scale granularity turns any forced ``d`` move into a large SSE penalty). The pin therefore spends ``budget_frac`` of each block's SSE (an exchange, never a free move) flipping codes toward the DC residual: each round picks, per block, the cheapest-to-DC flip direction and position by the ``SSE cost / |delta DC|`` ratio (cheap "free" strict-improvement flips first), applies it until the budget is spent or the residual is below half a flip quantum. Measured on real tensors: ``Q3_K`` DC RMS −82% at ~0.9% extra SSE; ``Q4_0`` −43% at ~1.3% (the symmetric ``[-8, 7]`` grid has half the DC slack of ``Q3_K``'s signed ``sc`` units, so its residual lands at the flip-quantum floor rather than ~0). Deterministic; safe on any input state. """ X = np.asarray(x, dtype=np.float64) B, n = X.shape codes = np.asarray(codes, dtype=np.int64).copy() unit = np.broadcast_to(np.asarray(unit, dtype=np.float64), codes.shape) if B == 0 or budget_frac <= 0.0: return codes, 0 d = np.asarray(d, dtype=np.float64) d_sub = np.repeat(d[:, None], n, axis=1) rows = np.arange(B) e = X - d_sub * codes * unit dc = e.sum(axis=1) sse0 = np.sum(e * e, axis=1) cap = sse0 * float(budget_frac) spent = np.zeros(B) touched = np.zeros(B, dtype=bool) tol = np.abs(d) * 0.5 for _ in range(max_rounds): want_cost = np.full(B, np.inf) want_pos = np.full(B, -1, dtype=np.int64) want_dir = np.zeros(B, dtype=np.int64) for direction in (1, -1): if direction == 1: sel = codes < hi else: sel = codes > lo de = np.where(sel, float(direction), 0.0) * unit * -d_sub dE = 2.0 * e * de + de * de push = dc[:, None] * de < 0.0 valid = sel & push ratio = np.where(valid & (np.abs(de) > 1.0e-300), dE / np.abs(np.where(valid, de, 1.0)), np.inf) pmin = np.argmin(ratio, axis=1) rmin = ratio[rows, pmin] cmin = dE[rows, pmin] take = np.isfinite(rmin) & (rmin < want_cost) want_cost = np.where(take, cmin, want_cost) want_pos = np.where(take, pmin, want_pos) want_dir = np.where(take, direction, want_dir) want = (np.abs(dc) > tol) & (want_pos >= 0) & (spent + want_cost <= cap) if not np.any(want): break bi = np.where(want)[0] pos = want_pos[bi] dirv = want_dir[bi] de = -d_sub[bi, pos] * dirv * unit[bi, pos] spent[bi] += 2.0 * e[bi, pos] * de + de * de e[bi, pos] += de codes[bi, pos] += dirv dc[bi] += de touched[bi] = True return codes, int(np.sum(touched)) def pin_dc_codes_uniform_cuda( x: "torch.Tensor", d: "torch.Tensor", codes: "torch.Tensor", unit: "torch.Tensor", lo: int, hi: int, budget_frac: float = 0.05, max_rounds: int = 96, ) -> tuple["torch.Tensor", int]: """GPU port of :func:`pin_dc_codes_uniform` (same greedy exchange). ``x``/``d``/``codes``/``unit`` all live on one CUDA device; ``codes`` is int64 and is updated in place (returned tensor is the same object). Float32 throughout — matches the CUDA pipeline's precision, and the exchange is self-correcting (any round that slightly mis-ranks a flip simply loses one candidate, the residual still never regresses SSE beyond ``budget_frac`` of the block's starting SSE). """ import torch if budget_frac <= 0.0 or codes.shape[0] == 0: return codes, 0 X = x.float() B, n = X.shape dev = X.device if codes.dtype != torch.int64: codes = codes.to(torch.int64) d = d.to(dev).float() if unit.dim() == 1 and unit.numel() == n: unit = unit[None, :] unit = unit.to(dev).float() if unit.shape[0] == 1 and B != 1: unit = unit.expand(B, n) d_col = d[:, None] e = X - d_col * codes.float() * unit dc = e.sum(dim=1) sse0 = (e * e).sum(dim=1) cap = sse0 * float(budget_frac) spent = torch.zeros(B, device=dev) rows = torch.arange(B, device=dev) tol = d.abs() * 0.5 touched = 0 for _ in range(max_rounds): want_cost = torch.full((B,), float("inf"), device=dev) want_pos = torch.full((B,), -1, dtype=torch.int64, device=dev) want_dir = torch.zeros(B, dtype=torch.int64, device=dev) for direction in (1, -1): sel = (codes < hi) if direction == 1 else (codes > lo) de = sel.float() * (float(direction) * unit * -d_col) dE = 2.0 * e * de + de * de valid = sel & (dc[:, None] * de < 0.0) ratio = torch.where(valid, dE.abs() / de.abs().clamp_min(1.0e-30), torch.inf) pmin = ratio.argmin(dim=1) rmin = ratio[rows, pmin] cmin = dE[rows, pmin] take = torch.isfinite(rmin) & (rmin < want_cost) want_cost = torch.where(take, cmin, want_cost) want_pos = torch.where(take, pmin, want_pos) want_dir = torch.where(take, torch.full_like(want_dir, direction), want_dir) want = ( (dc.abs() > tol) & (want_pos >= 0) & (spent + want_cost <= cap) ) if not bool(want.any()): break bi = want.nonzero(as_tuple=False).squeeze(1) pos = want_pos[bi] dirv = want_dir[bi] de = -d[bi] * dirv.float() * unit[bi, pos] spent[bi] += 2.0 * e[bi, pos] * de + de * de e[bi, pos] += de codes[bi, pos] += dirv dc[bi] += de touched += int(bi.numel()) return codes, touched