File size: 5,728 Bytes
28430a8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env python3
"""68_suite_v080.py — v0.8.0: VEREDITO CONSOLIDADO das propostas Qwen3.8.

Executa demo_qwen_v080 TRÊS vezes (a ablação JEPA usa o RNG global do candle
na inicialização — gates direcionais agregados sobre execuções), herda os 73
gates da v0.7.0 (suite_v070_final.json) e adiciona os gates das 4 propostas
analisadas/provadas/testadas em r-33:
  1. Newton analítico (verificador) — N-1..N-4
  2. Árvore pós-ordem iterativa — T-A7..T-A9
  3. Cayley exato (FNH) — F-9..F-12
  4. MoE vetorizada com gradiente restaurado (bug v080-1) — M-R6..M-R8
"""
import json, os, sys

def main():
    pasta = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    R = os.path.join(pasta, "resultados")
    rel = {"versao": "0.8.0", "blocos": {}, "gates": {}}

    def carrega(arq):
        p = os.path.join(R, arq)
        if os.path.exists(p):
            with open(p) as f:
                return json.load(f)
        return None

    # ---- bloco legado v0.7.0 (se presente)
    legado = carrega("suite_v070_final.json")
    if legado:
        g_legado = legado.get("gates", legado)
        ok = sum(1 for v in g_legado.values() if v is True)
        rel["blocos"]["legado_v070"] = f"{ok}/{len(g_legado)}"
        for k, v in g_legado.items():
            rel["gates"][f"legado_{k}"] = v

    # ---- demos v0.8.0 (3 execuções)
    import khtst_rust as k
    execucoes = [k.demo_qwen_v080() for _ in range(3)]

    # (1) Newton vs golden
    nvg = execucoes[0]["newton_vs_golden"]
    for nome, val in nvg["gates"].items():
        rel["gates"][f"q1_newton_{nome}"] = val
    rel["blocos"]["q1_newton"] = f"{sum(1 for v in nvg['gates'].values() if v)}/{len(nvg['gates'])}"
    rel["medicoes"] = {
        "q1": {kk: nvg[kk] for kk in
               ("t_golden", "t_newton", "n_aval_newton", "nll_golden", "nll_newton",
                "tempo_golden_s", "tempo_newton_s")},
    }

    # (2) Cayley vs polar
    cvp = execucoes[0]["cayley_vs_polar"]
    for nome, val in cvp["gates"].items():
        rel["gates"][f"q3_cayley_{nome}"] = val
    rel["blocos"]["q3_cayley"] = f"{sum(1 for v in cvp['gates'].values() if v)}/{len(cvp['gates'])}"
    rel["medicoes"]["q3"] = {kk: cvp[kk] for kk in
                             ("delta_ort_polar", "delta_ort_cayley",
                              "tempo_polar_s", "tempo_cayley_s", "speedup")}

    # (3) árvore iterativa
    arv = execucoes[0]["arvore_iter_vs_rec"]
    for nome, val in arv["gates"].items():
        rel["gates"][f"q2_arvore_{nome}"] = val
    rel["blocos"]["q2_arvore"] = f"{sum(1 for v in arv['gates'].values() if v)}/{len(arv['gates'])}"
    rel["medicoes"]["q2"] = {kk: arv[kk] for kk in
                             ("n_nos", "total_iter", "tempo_iter_s", "tempo_rec_s")}

    # (4) MoE vetorizada (determinística — valores/gradientes)
    moe = execucoes[0]["moe_vetorizada"]
    for nome, val in moe["gates"].items():
        rel["gates"][f"q4_moe_{nome}"] = val
    rel["blocos"]["q4_moe"] = f"{sum(1 for v in moe['gates'].values() if v)}/{len(moe['gates'])}"
    rel["medicoes"]["q4"] = {kk: moe[kk] for kk in
                             ("max_dif_valores", "tempo_ref_s", "tempo_vet_s",
                              "grad_roteador_vet", "grad_especialistas_vet")}

    # (5) ablação JEPA 3 braços — gates DIRECIONAIS nas 3 execuções
    quedas_moe, quedas_peq, quedas_den = [], [], []
    for ex in execucoes:
        ab = ex["ablacao_jepa_3_bracos_v080"]
        quedas_moe.append(ab["moe"]["queda_pct"])
        quedas_peq.append(ab["pequena"]["queda_pct"])
        quedas_den.append(ab["densa"]["queda_pct"])
    moe_min = min(quedas_moe)
    peq_max = max(quedas_peq)
    rel["gates"]["q5_ablacao_moe_aprende_3x"] = all(q > 30.0 for q in quedas_moe)
    rel["gates"]["q5_ablacao_moe_domina_pequena_3x"] = moe_min > peq_max
    rel["medicoes"]["q5"] = {
        "quedas_moe_pct": quedas_moe, "quedas_pequena_pct": quedas_peq,
        "quedas_densa_pct": quedas_den,
        "nota": "inicialização via RNG global do candle — gates direcionais",
    }
    rel["blocos"]["q5_ablacao"] = (
        f"{sum(1 for v in (rel['gates']['q5_ablacao_moe_aprende_3x'], rel['gates']['q5_ablacao_moe_domina_pequena_3x']) if v)}/2")

    # ---- provas cargo (contagem)
    try:
        import subprocess, re
        res = subprocess.run(
            ["cargo", "test", "--manifest-path", os.path.join(pasta, "Cargo.toml")],
            capture_output=True, text=True, timeout=1800,
            env={**os.environ, "PATH": os.environ["PATH"] + ":" + os.path.expanduser("~/.cargo/bin")},
        )
        saida = res.stdout + res.stderr
        linhas = [l for l in saida.splitlines() if "test result:" in l]
        m = re.search(r"(\d+) passed; (\d+) failed", linhas[0] if linhas else "")
        if m:
            total_c = int(m.group(1)) + int(m.group(2))
            rel["blocos"]["cargo"] = f"{m.group(1)}/{total_c}"
            rel["gates"]["cargo_todos_verdes"] = m.group(2) == "0"
        else:
            rel["blocos"]["cargo"] = "sem resultado"
            rel["gates"]["cargo_todos_verdes"] = False
    except Exception as e:
        rel["blocos"]["cargo"] = f"erro: {e}"
        rel["gates"]["cargo_todos_verdes"] = False

    # ---- veredito
    total = len(rel["gates"])
    ok = sum(1 for v in rel["gates"].values() if v is True)
    rel["veredito"] = f"{ok}/{total}"
    with open(os.path.join(R, "suite_v080_final.json"), "w") as f:
        json.dump(rel, f, indent=1, ensure_ascii=False)
    print(json.dumps({"blocos": rel["blocos"], "veredito": rel["veredito"]},
                     indent=1, ensure_ascii=False))
    sys.exit(0 if ok == total else 1)

if __name__ == "__main__":
    main()