Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a79c8f4934 | ||
|
|
17f25089c6 | ||
|
|
5c29e2cd4f | ||
|
|
e958b3d3d6 | ||
|
|
dcfe7774f3 |
@@ -536,3 +536,82 @@ R@5407f8 = единичная нормировка (все 1.0000 в этом п
|
||||
### Статус
|
||||
Канонический путь чтения ПРИМЕНЁННОЙ маски: слот [ctx+0x540678] (кривая
|
||||
банды) — он стабилен и МАТЧИТ АУДИО в deep-фазах (±5%).
|
||||
|
||||
## ДОПОЛНЕНИЕ 24mm2: ПОЛНАЯ РЕЗОЛЮВСЯ ВСЕХ 10 ЯДЕР + ИСПРАВЛЕНИЯ DATAFLOW
|
||||
|
||||
Инструмент: статический резолв цепочки стаб→таблица→L2→IAT-слот по
|
||||
soothe_mem.bin (без live). Стаб = `movsxd rax,[idx@1826159a0]; lea r10,[tbl];
|
||||
jmp [r10+rax*8]`, idx=4, L2=`mov rax,[slot]; jmp rax`.
|
||||
|
||||
### Таблица резолва (исправляет 24jj!)
|
||||
| стаб | таблица | runtime | опознание по константам |
|
||||
|------|---------|---------|------------------------|
|
||||
| 140950 | 182617448 | **18026b820** | exp2/exp DOUBLE (ln2, log2e, 1021.5, 2^27) |
|
||||
| 140980 | 182617488 | **18027c120** | **logf** FLOAT (ряд −½,+⅓,−¼,+⅕,−⅙; ln2 hi/lo; 2^32) |
|
||||
| 1409b0 | 1826174c8 | **18028d1e0** | **powf/log+exp** DOUBLE (ряд log + магия expf вместе) |
|
||||
| 1409e0 | 182617508 | 180296c80 ✓ | **expf** FLOAT — ДЕКОДИРОВАН ПОЛНОСТЬЮ (ниже) |
|
||||
| 140a40 | 182617588 | 1802dc0e0 ✓ | exp-вариант FLOAT c hi/lo сплитами |
|
||||
| 140aa0 | 182617608 | **18030fee0** | **sincos** DOUBLE (1/6,1/120,1/5040; π hi/lo) |
|
||||
| 140ad0 | 182617648 | 180323f20 ✓ | кусочно-табличная DOUBLE (сетка Δ=0.00541521) |
|
||||
| 140b00 | 182617688 | **180367980** | pow/exp DOUBLE (1023/1022, магия 1.5·2^20) |
|
||||
| 140b30 | 1826176c8 | **1803831c0** | кусочно-табличная FLOAT (π/2, π/4, сетка 184.665!) |
|
||||
| 140b60 | 182617708 | 1803a06a0 ✓ | **DIVIDE** FLOAT B/A (rcp+квантование+vpermps-таблицы+полином невязки) |
|
||||
|
||||
**ИСПРАВЛЕНИЕ 24jj**: «140b30/140b60 → общий 1803a06a0» — НЕВЕРНО.
|
||||
FIR-секция вызывает 140b30 = 1803831c0 (табличная кривая), divide только в шаге 9c.
|
||||
|
||||
### ДИСПЕТЧЕР float/double
|
||||
Каждый call-site имеет ПАРУ стабов через `call [181bab008]; test eax,eax; jne`:
|
||||
float-стаб (eax==0) / double-стаб. Дескрипторы type_info СТАТИЧЕСКИ идентичны
|
||||
(оба →182650db8) ⇒ eax=0 ⇒ **double-ядра мертвы на нашем пути**; рендеры
|
||||
идут по float. Double-тела не транскрибируем (отмечено на будущее M8).
|
||||
|
||||
### expf 180296c80 — полная формула (горячий цикл, FMA-точно)
|
||||
```
|
||||
n = fma(log2e_hi=1.4427, x, MAGIC=12582912.0) ; округление до int
|
||||
k = n − MAGIC
|
||||
r = (x − 0.693146·k) − 1.42861e-06·k ; ln2 hi/lo
|
||||
p = (((0.00829172·r + 0.0418735)·r + 0.166674)·r + 0.499994)·r + 1)·r + 1
|
||||
out = bits( (k<<23) + bits(p) ) ; vpaddd сборка
|
||||
guard: |x|>87.3365 → slow-path; head/tail через vmaskmovps+popcnt-маски
|
||||
```
|
||||
Коэф. минимаксные — транскрибировать КАК ЕСТЬ.
|
||||
|
||||
### DIVIDE 1803a06a0 — структура (90%)
|
||||
```
|
||||
A=[rcx], B=[rdx], dst=[r8]; r9d=n
|
||||
q0 = rcp(A); q0 += 2^23-magic (округление); q = q0 & 0xfff00000 ; 12 бит
|
||||
e = (q>>23); idx = q>>20 → vpermps tbl@1821269c0 (127±ε) и @182126a00
|
||||
err = 1 − q·A
|
||||
полином невязки {0.207515, −0.241687, 0.288535, −0.360671, ..., 0.240264, 0.0555119}
|
||||
сборка через магию 1.5·2^20 + vpslld 20
|
||||
результат ≈ B/A с точностью ~0.5 ulp
|
||||
```
|
||||
Таблицы коррекций сдамплены (per-mantissa-top-bits).
|
||||
|
||||
### ИСПРАВЛЕНИЯ DATAFLOW (по fn529fe0.dis, адреса call-sites)
|
||||
1. **Шаг 14 порядок ОБРАТЕН к BLOCKMAP 24ii**: сначала `bigkernel exp IN-PLACE
|
||||
на bands_curve` (52ae0e), ПОТОМ `bands_curve += (−1.0)` (52ae40, конст.
|
||||
1824c4680 через th2270).
|
||||
2. Шаг 9b точно: `vec6f8 += [ctx+54087c] · 0.8` (xmm10=0.8@1824c3e28,
|
||||
множитель виден в asm: mulss xmm6,xmm10 после movss xmm6,[54087c]).
|
||||
3. Шаг 9a: `vec698 *= (xmm12=1.0 − [54087c])` ⇒ zero-fill при дефолтах ✓.
|
||||
4. Шаг 10 combine dc40: аргументы rcx=ACC_i(**таблица указателей @0x5407c8**,
|
||||
НЕ дампилась rendersnap2!), rdx=bands_curve_i(@678+i), r8=vec6f8(@6f8),
|
||||
семантика dst=r8: vec6f8 = bands_curve_i − ACC_i. ACC-слот надо ДОБАВИТЬ
|
||||
в SLOTS rendersnap2 (0x5407c8).
|
||||
5. Шаги 15/16 подтверждены: th2000/th1c40 array-mul; затем rbx=[5406a8]
|
||||
(kWarp) — array-mul на bands_curve.
|
||||
6. Эпилог: скалярная часть из decomp (consumers_out 100-143): mix-веса,
|
||||
`fVar17 = [540874] − expf(DAT_1824c4704=-ln1000)` → bands += f17·[540888].
|
||||
|
||||
### Call-site карта больших ядер (fn529fe0)
|
||||
```
|
||||
52a63a/52a641: 140980(logf-float)/1409b0 — pre-combine #1
|
||||
52ab84/52ab8b: 140b60(divide)/140950 — шаг 9c
|
||||
52acd? : (шаги 10–12 мелкие ILT)
|
||||
52ae0e/52ae15: 1409e0(expf)/140ad0 — шаг 14 нелинейность
|
||||
52b32c/52b336: 1409e0(expf)/140ad0 — шаг 17 (повтор)
|
||||
52b3a0/52b3aa: 140a40(exp-var)/140b00 — пост-17
|
||||
52b716/52b71d: 140b30(кривая-float)/140aa0 — FIR-секция
|
||||
```
|
||||
|
||||
@@ -3940,3 +3940,84 @@ STATE = [ctx+0x540788] (спектральная память, читаетс
|
||||
### Практический статус
|
||||
dual-семейство: корпус 0.193 (формулы + калибровка). Канон нетронут (2.286).
|
||||
Все инструменты/датасеты воспроизводимы. ~85 коммитов запушено.
|
||||
|
||||
## ============ 24mm2: ВСЕ 10 ЯДЕР РАЗРЕЗОЛВЛЕНЫ СТАТИЧЕСКИ; expf/divide декодированы; каскад-сим стартовал ============
|
||||
|
||||
### Декод (детали в BLOCKMAP 24mm2)
|
||||
1. Полный статический резолв стаб→tbl[4]→L2→IAT всех десяти bigkernel'ов
|
||||
БЕЗ live-процесса. Исправлена ошибка 24jj: 140b30≠140b60 (FIR вызывает
|
||||
табличную кривую 1803831c0, divide 1803a06a0 — только шаг 9c).
|
||||
2. Библиотека ядер опознана: expf/logf/powf/sincos/exp2-double + кусочно-
|
||||
табличная кривая (float/double). Пары стабов на call-site = float/double
|
||||
диспетчер через type_info; double-ветка мертва (дескрипторы совпадают).
|
||||
3. expf 180296c80 декодирован до формулы (минимакс-полином + битовая
|
||||
сборка (k<<23)+bits(p), guard 87.3365).
|
||||
4. Divide 1803a06a0: rcp → квантование 12 бит → vpermps-таблицы коррекции
|
||||
(@1821269c0/a00, сдамплены) → полином невязки → сборка 1.5·2^20.
|
||||
5. Шаг-14 порядок исправлен: exp ДО +=(−1). ACC-таблица @0x5407c8 — не
|
||||
дампилась, добавить в rendersnap2 SLOTS.
|
||||
|
||||
### Следующее (в работе)
|
||||
- Каскад-сим scripts/cascade_sim.py: вход tract_multi_in.txt, якоря ph040;
|
||||
divide/expf сначала numpy-эквиваленты (структурная фаза), C++-порт с
|
||||
FMA-точной транскрипцией после замыкания структуры.
|
||||
|
||||
## ============ ПРОРЫВ 24mm3: ПРИМЕНЁННАЯ МАСКА = СТЕПЕНЬ ТРЕКА: mask = trk^γ, γ=1.760561 (точно) ============
|
||||
|
||||
### Факт (по всем sc_* датасетам, чистые стационарные кадры)
|
||||
```
|
||||
cur@678 = trk@688 ^ γ
|
||||
trk@688 = exp(scr@628) ; бит-в-бит (allclose rtol 1e-3)
|
||||
γ = 1.760561 ; rms фита РОВНО 0 на чистых кадрах
|
||||
; (tt0 n=37, sens18/24, qmap_q3/q6, q0.3)
|
||||
```
|
||||
Кадры с γ=1.000000 (тоже точные!) — фаза ДО применения степени;
|
||||
−0.5/0/41.75/82.99 — переходные/полиморфные состояния слотов.
|
||||
Вариации 1.7603–1.7605 у части датасетов = лёгкая пер-бин модуляция
|
||||
поверх степени (warp-класс), не разброс константы.
|
||||
|
||||
### Следствие 1: кат_дБ = −γ·scr·(20/ln10)
|
||||
Проверка: multi4b @bin43: scr=−0.6481 → −1.760561·0.6481·8.6859 = 9.90 дБ
|
||||
= измеренному deep-кату tt-PK1. ВСЕ прежние калибровки (α,β,c) фитились
|
||||
против −scr·γ ⇒ γ был поглощён в α!
|
||||
|
||||
### Следствие 2: структура детектора переформулируется
|
||||
```
|
||||
scr(f) = дизайн-сигнал детектора (log-домен, ноль вне пиков)
|
||||
mask(f) = exp(γ · scr(f)) ; γ вычисляется цепочкой шагов 9–19
|
||||
```
|
||||
γ НЕ хранится в бинаре (поиск точных f32/f64 бит — пусто, только
|
||||
кусочные таблицы ~1.7596..1.7611 @181c72xxx) ⇒ γ возникает из алгебры
|
||||
(divide+add+exp каскада). Задача симулятора: воспроизвести γ из операций.
|
||||
|
||||
### Методическая заметка
|
||||
rendersnap-кадры полиморфны: отбирать только кадры где (а) trk==exp(scr),
|
||||
(б) fit γ имеет rms<1e-5, (в) нет нулей в 678. Критерий отбора встроен
|
||||
в scan-скрипты следующего раунда.
|
||||
|
||||
## ============ 24mm4: ЦЕЛЬ СИМУЛЯТОРА = scr(f); ТОЧЕЧНЫЕ ЗАКОНЫ ОТВЕРГНУТЫ НА 447 БИНАХ; cascade_sim.py ============
|
||||
|
||||
### Сквозная валидация степенного закона (scripts/cascade_sim.py)
|
||||
- multi4b/ph073: γ=1.760561 (fit rms 1.1e-07), закон mask=trk^γ:
|
||||
rms 0.0064 дБ / 48 бинов | multi4b/ph065: 0.0006 дБ / 103 бина
|
||||
- multi6: identity-фаза ph034 (γ=1, маска==trk, 499 бинов rms 0) даёт ВСЕ
|
||||
шесть нотчей ±0.03 дБ; γ-фаза ph037: 0.0006 дБ.
|
||||
- Отбор кадров формализован (pick_clean_frame): две фазы (γ*≈1.760561 и
|
||||
identity γ=1), критерий fit-rms<1e-4.
|
||||
|
||||
### Детекторный вход: точечные законы окончательно мертвы
|
||||
На multi6/ph034 по всем 447 значимым бинам: corr(−scr, ln X) ≤ 0.36 для
|
||||
X ∈ {lvl, am·S/res, am·S, S/res, am·res, S·lvl, am·S/√res}; лучший
|
||||
двухпараметрический фит rms 0.20 (нужно <0.05 дБ). scr(f) зависит от
|
||||
ОКРЕСТНОСТИ спектра ⇒ воспроизводится только спектральным каскадом
|
||||
(частотные IIR шагов детектора, коэф. 533340). Это и есть остаток Задачи №1.
|
||||
|
||||
### Состояние на закрытие сессии
|
||||
1. Все 10 ядер резолвлены+опознаны; expf/divide декодированы до формул
|
||||
(BLOCKMAP 24mm2). Каноническая C++ транскрипция ядер — после замыкания
|
||||
структуры каскада.
|
||||
2. Применение: mask=trk^1.760561, trk=exp(scr); γ вычисляется цепочкой —
|
||||
источник γ в алгебре divide/add/exp шагов 9–19 (поиск в декоде).
|
||||
3. Симулятор: scripts/cascade_sim.py (каркас + валидатор + отбор кадров).
|
||||
Следующий раунд: оп-за-оп декод тела каскада между lvl_raw и scr
|
||||
(частотные IIR с коэф. 24cc → vec6f8/bands_curve), затем C++ порт.
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env python3
|
||||
"""cascade_sim.py — структурный симулятор тракта маски soothe2 (float-путь).
|
||||
|
||||
Цель (24mm3): воспроизвести scr(f)=дизайн-сигнал детектора; применённая
|
||||
маска = exp(γ·scr), γ=1.760561 (точно), trk@688=exp(scr@628) бит-в-бит.
|
||||
|
||||
Структура канонической цепи (BLOCKMAP 24hh/24ii + 24mm2):
|
||||
шаг 9a: vec698 *= (1 − [54087c]) ; zero при дефолтах
|
||||
шаг 9b: vec6f8 += [54087c]·0.8 ; xmm10=0.8 @1824c3e28
|
||||
шаг 9c: bands_curve_i /= ... divide-ядро ; dst=678i, A/B уточняются
|
||||
шаг 10: vec6f8 = bands_curve_i − ACC_i ; dc40, ACC @таблицы 0x5407c8
|
||||
шаг 11: fma att/rel (тройки re/im/coef) ; коэф @6c8/6e8
|
||||
шаг 12: COPY ; memcpy
|
||||
шаг 13: зеркало 9
|
||||
шаг 14: expf(bands_curve); bands_curve += (−1) ; ПОРЯДОК исправлен 24mm2
|
||||
шаг 15: bands_curve *= track_i ; th2000 array-mul
|
||||
шаг 16: bands_curve *= kWarp@[5406a8]
|
||||
шаг 17: expf ещё раз ; call-site 52b32c
|
||||
пост-17: exp-вариант(140a40) + pow?(140b00)
|
||||
FIR-секция: кривая-float(140b30→1803831c0) + sincos-twiddle(140aa0)
|
||||
|
||||
ЯДРА (структурная фаза — математически точные numpy-эквиваленты;
|
||||
канонический C++ порт = инструкци-точная транскрипция, см. BLOCKMAP 24mm2):
|
||||
"""
|
||||
import numpy as np
|
||||
import glob
|
||||
import os
|
||||
|
||||
GAMMA = 1.760561 # 24mm3: показатель степени, rms фита 0 на чистых кадрах
|
||||
N = 2049 # число бинов полной сетки
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- ядра ----
|
||||
def k_exp(x):
|
||||
"""expf-ядро 180296c80. Структурная фаза: np.exp.
|
||||
Каноническая формула (для C++ порта, FMA-точно):
|
||||
n = fma(log2e_hi=1.4427f, x, 12582912.0f); k = n - MAGIC
|
||||
r = (x - 0.693146f*k) - 1.42861e-06f*k
|
||||
p = (((0.00829172f*r+0.0418735f)*r+0.166674f)*r+0.499994f)*r+1)*r+1
|
||||
out = bits((k<<23) + bits(p)); guard |x|>87.3365 -> slow path
|
||||
"""
|
||||
return np.exp(x)
|
||||
|
||||
|
||||
def k_div(a, b):
|
||||
"""divide-ядро 1803a06a0: dst = B/A (~0.5 ulp, rcp+таблицы+полином).
|
||||
Структурная фаза: точное деление."""
|
||||
return b / a
|
||||
|
||||
|
||||
# ------------------------------------------------------------ данные -----
|
||||
def load_tract(path):
|
||||
"""tract_*.txt: k am res lvl_raw band_level prewarp w"""
|
||||
t = np.loadtxt(path)
|
||||
return {'am': t[:, 1], 'res': t[:, 2], 'lvl': t[:, 3]}
|
||||
|
||||
|
||||
def load_frame(npz):
|
||||
"""Слоты кадра rendersnap2 → dict[int, np.ndarray]."""
|
||||
d = np.load(npz)
|
||||
out = {}
|
||||
for k in d.keys():
|
||||
if k.startswith('0x'):
|
||||
out[int(k[2:], 16)] = d[k]
|
||||
return out, d['t_snap']
|
||||
|
||||
|
||||
def pick_clean_frame(ds_dir, min_bins=8):
|
||||
"""Отбор чистых стационарных кадров по фазам (24mm3):
|
||||
возвращает лучший на фазе γ* (~1.7606, маска применена)
|
||||
и лучший на фазе γ=1 (степень ещё не применена)."""
|
||||
classes = {'gamma': None, 'identity': None}
|
||||
for f in sorted(glob.glob(os.path.join(ds_dir, 'ph*.npz'))):
|
||||
try:
|
||||
S, ts = load_frame(f)
|
||||
except Exception:
|
||||
continue
|
||||
if not all(x in S for x in (0x540628, 0x540688, 0x540678)):
|
||||
continue
|
||||
s = S[0x540628][:1025].astype(np.float64)
|
||||
t = S[0x540688][:1025].astype(np.float64)
|
||||
c = S[0x540678][:1025].astype(np.float64)
|
||||
ok = (t > 1e-30) & (c > 1e-30) & np.isfinite(s)
|
||||
if ok.sum() < 50:
|
||||
continue
|
||||
lt = np.log(t[ok])
|
||||
lc = np.log(c[ok])
|
||||
sel = np.abs(lt) > 0.05
|
||||
if sel.sum() < min_bins:
|
||||
continue
|
||||
g = float(np.sum(lt[sel] * lc[sel]) / np.sum(lt[sel] ** 2))
|
||||
rms = float(np.sqrt(np.mean((lc[sel] - g * lt[sel]) ** 2)))
|
||||
depth = float(-lc.min())
|
||||
key = 'gamma' if abs(g - GAMMA) < 0.01 else \
|
||||
('identity' if abs(g - 1.0) < 1e-4 else None)
|
||||
if key is None or rms > 1e-4:
|
||||
continue
|
||||
cand = (depth, f, s, t, c, g, rms)
|
||||
if classes[key] is None or depth > classes[key][0]:
|
||||
classes[key] = cand
|
||||
return classes
|
||||
|
||||
|
||||
# ------------------------------------------------------- валидация -------
|
||||
def validate_scr(sim_scr, cap_scr, tol_db=0.05):
|
||||
"""rms в дБ между симулированным и захваченным scr."""
|
||||
m = np.abs(cap_scr) > 0.02
|
||||
err = (sim_scr[m] - cap_scr[m]) * (20 / np.log(10))
|
||||
return float(np.sqrt(np.mean(err ** 2))), int(m.sum())
|
||||
|
||||
|
||||
def main():
|
||||
import sys
|
||||
ds = sys.argv[1] if len(sys.argv) > 1 else '/tmp/opencode/sc_multi6'
|
||||
tract = sys.argv[2] if len(sys.argv) > 2 else '/tmp/opencode/tract_multi6.txt'
|
||||
|
||||
classes = pick_clean_frame(ds)
|
||||
ph_g = classes['gamma']
|
||||
ph_i = classes['identity']
|
||||
if not ph_g and not ph_i:
|
||||
print('нет чистых кадров в', ds)
|
||||
return
|
||||
for lbl, best in (('γ-фаза', ph_g), ('identity', ph_i)):
|
||||
if not best:
|
||||
continue
|
||||
_, f, scr, trk, cur, gamma_fit, grms = best
|
||||
n = len(scr)
|
||||
cut_meas = -20 / np.log(10) * np.log(np.maximum(cur, 1e-30))
|
||||
g_use = gamma_fit
|
||||
cut_sim = g_use * (-scr) * 20 / np.log(10)
|
||||
e = cut_sim - cut_meas
|
||||
sel = np.abs(cut_meas) > 0.1
|
||||
rms_db = float(np.sqrt(np.mean(e[sel] ** 2))) if sel.any() else 0.0
|
||||
print(f'{lbl}: {os.path.basename(f)} γ={gamma_fit:.6f} (rms {grms:.1e}) '
|
||||
f'закон: rms={rms_db:.4f} дБ / {int(sel.sum())} бинов')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -18,7 +18,7 @@ import time
|
||||
|
||||
import numpy as np
|
||||
|
||||
SLOTS = [0x540668, 0x540548, 0x540550, 0x540598, 0x540628,
|
||||
SLOTS = [0x540668, 0x540548, 0x540550, 0x540598, 0x540628, 0x5406f8,
|
||||
0x540678, 0x540688, 0x5406c8, 0x5406e8, 0x540768,
|
||||
0x540788, 0x5407f8]
|
||||
NARR = 8194
|
||||
|
||||
Reference in New Issue
Block a user