Archive CIDM-v2 reproducible b2_r12_dual_precision_chain.py
Browse files
cidm_v2/source/B2_R12_P0_FIX1/b2_r12_dual_precision_chain.py
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""CIDM-v2 B2-R12/P0: frozen FP32-vs-FP64 full-chain autograd integrity audit.
|
| 2 |
+
|
| 3 |
+
Uses the ORIGINAL CIDM-v2 and B2-R6 weights, 2 TRAIN windows, and B2-R10
|
| 4 |
+
credit objective. No optimizer or future-label predictor input. No attempt
|
| 5 |
+
is made to interpret FP64 as improved deployed forecast accuracy.
|
| 6 |
+
"""
|
| 7 |
+
from __future__ import annotations
|
| 8 |
+
import copy, csv, json, math, time, zipfile
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
import torch
|
| 11 |
+
import b2_r11_backward_attribution as r11
|
| 12 |
+
from b2_r1_flux_control import check_zip
|
| 13 |
+
|
| 14 |
+
ARCHIVE_FIX1_SHA = 'b37e0539102afb4047028db72b8c93f32305f81adbd42551e0e3fcedb0eb9a6d'
|
| 15 |
+
|
| 16 |
+
def norm(t):
|
| 17 |
+
return float(torch.linalg.vector_norm(t.detach().reshape(-1).double()))
|
| 18 |
+
|
| 19 |
+
def catparam(params):
|
| 20 |
+
return torch.cat([(p.grad.detach().reshape(-1) if p.grad is not None
|
| 21 |
+
else torch.zeros_like(p).reshape(-1)) for p in params]).double()
|
| 22 |
+
|
| 23 |
+
def finite(t,name):
|
| 24 |
+
if not bool(torch.isfinite(t).all()): raise RuntimeError('NONFINITE_'+name)
|
| 25 |
+
|
| 26 |
+
def write_csv(dest,rows):
|
| 27 |
+
if not rows: return
|
| 28 |
+
dest=Path(dest)
|
| 29 |
+
with dest.open('w',newline='',encoding='utf-8') as f:
|
| 30 |
+
w=csv.DictWriter(f,fieldnames=list(rows[0])); w.writeheader();w.writerows(rows)
|
| 31 |
+
|
| 32 |
+
def write_json(dest,data):
|
| 33 |
+
Path(dest).write_text(json.dumps(data,indent=2,ensure_ascii=False,allow_nan=False,default=str),encoding='utf-8')
|
| 34 |
+
|
| 35 |
+
# B2-R12/P0 FIX1 - memory-safe exact per-example streaming and independent local VJP.
|
| 36 |
+
# Intentionally preserves original FP32/FP64 dynamics and two-TRAIN-window objective.
|
| 37 |
+
import os, gc
|
| 38 |
+
|
| 39 |
+
def _sample_precision_pass(core, head, h, y, sd, Q, dtype, task, kind, precision, sample_index):
|
| 40 |
+
"""Full BPTT for *one* original TRAIN window; free whole DAG before local VJPs.
|
| 41 |
+
|
| 42 |
+
Loss is the same per-example mean reduction used by the original batch=2 run.
|
| 43 |
+
Caller averages full head gradients and time components over the same 2 windows.
|
| 44 |
+
"""
|
| 45 |
+
params=tuple(head.parameters())
|
| 46 |
+
h=h.to(dtype=dtype,device=next(core.parameters()).device)
|
| 47 |
+
y=y.to(dtype=dtype,device=h.device)
|
| 48 |
+
sd=sd.to(dtype=dtype,device=h.device)
|
| 49 |
+
q=Q.to(dtype=dtype,device=h.device) if Q is not None else None
|
| 50 |
+
pred,loss,recs=r11.full_forward(core,head,h,y,sd,q)
|
| 51 |
+
finite(pred,f'{task}_{kind}_{precision}_sample{sample_index}_prediction')
|
| 52 |
+
finite(loss,f'{task}_{kind}_{precision}_sample{sample_index}_loss')
|
| 53 |
+
extra=[]
|
| 54 |
+
for rec in recs:
|
| 55 |
+
extra.extend((rec['gates'],rec['base'],rec['f'],rec['l'],rec['s'],rec['z_old']))
|
| 56 |
+
# ONE backward through entire trajectory, no retain_graph=True. Extract all
|
| 57 |
+
# necessary adjoints in the SAME autograd invocation before graph release.
|
| 58 |
+
req=params+tuple(extra)
|
| 59 |
+
vals=torch.autograd.grad(loss,req,allow_unused=True,retain_graph=False)
|
| 60 |
+
pvals=vals[:len(params)]; adjvals=vals[len(params):]
|
| 61 |
+
full=torch.cat([torch.zeros_like(p).reshape(-1).double() if v is None else v.detach().reshape(-1).double()
|
| 62 |
+
for p,v in zip(params,pvals)]).cpu()
|
| 63 |
+
finite(full,f'{task}_{kind}_{precision}_sample{sample_index}_head_grad')
|
| 64 |
+
per_step=[]
|
| 65 |
+
for j,rec in enumerate(recs):
|
| 66 |
+
gate_adj,base_adj,f_adj,l_adj,s_adj,z_adj=adjvals[j*6:(j+1)*6]
|
| 67 |
+
if any(v is None for v in (gate_adj,base_adj,f_adj,l_adj,s_adj)):
|
| 68 |
+
raise RuntimeError(f'MISSING_COTANGENT {task} {kind} {precision} sample={sample_index} lead={j+1}')
|
| 69 |
+
for label,v in [('gate',gate_adj),('base',base_adj),('flux',f_adj),('local',l_adj),('skew',s_adj)]:
|
| 70 |
+
finite(v,f'{task}_{kind}_{precision}_{label}_sample{sample_index}_lead{j+1}')
|
| 71 |
+
# local frozen HEAD replay with detached causal features. No full-trajectory graph.
|
| 72 |
+
g2=head(rec['base'].detach(),rec['prev_old'].detach(),rec['initial'].detach(),rec['amps'].detach(),j+1)
|
| 73 |
+
replay=float((g2.detach()-rec['gates'].detach()).abs().max())
|
| 74 |
+
if replay>(2e-6 if dtype==torch.float32 else 2e-11):
|
| 75 |
+
raise RuntimeError(f'HEAD_REPLAY_MISMATCH {task} {kind} {precision} sample={sample_index} lead={j+1} replay={replay}')
|
| 76 |
+
pp=torch.autograd.grad(g2,params,grad_outputs=gate_adj.detach(),allow_unused=True)
|
| 77 |
+
p=torch.cat([(torch.zeros_like(a).flatten() if v is None else v.detach().flatten()).double()
|
| 78 |
+
for a,v in zip(params,pp)]).cpu()
|
| 79 |
+
finite(p,f'{task}_{kind}_{precision}_sample{sample_index}_part_{j+1}')
|
| 80 |
+
# Independently reconstruct LOCAL VJPs with exact frozen operators and
|
| 81 |
+
# original cotangents. In particular, don't hold 12-step graph for VJPs.
|
| 82 |
+
z=rec['z_old'].detach().requires_grad_(True)
|
| 83 |
+
mm=core.model;coeff=mm.coefficients();skew=mm.skew-mm.skew.T
|
| 84 |
+
f2=coeff['flux']*mm.flux(z)
|
| 85 |
+
vf=torch.autograd.grad(f2,z,grad_outputs=f_adj.detach())[0]
|
| 86 |
+
l2=coeff['local']*torch.tanh(mm.local(z))
|
| 87 |
+
vl=torch.autograd.grad(l2,z,grad_outputs=l_adj.detach())[0]
|
| 88 |
+
s2=.035*torch.einsum('ij,bjhw->bihw',skew,z)
|
| 89 |
+
vs=torch.autograd.grad(s2,z,grad_outputs=s_adj.detach())[0]
|
| 90 |
+
sq=lambda v:norm(v)**2
|
| 91 |
+
per_step.append({'parameter_part':p,'gate_adj_sq':sq(gate_adj),'identity_sq':sq(base_adj),
|
| 92 |
+
'flux_sq':sq(vf),'local_sq':sq(vl),'skew_sq':sq(vs),
|
| 93 |
+
'latent_sq':(sq(z_adj) if z_adj is not None else None),
|
| 94 |
+
'replay':replay})
|
| 95 |
+
del g2,pp,p,z,f2,l2,s2,vf,vl,vs
|
| 96 |
+
out={'loss':float(loss.detach()),'full':full,'pred':pred.detach().cpu().double(), 'steps':per_step}
|
| 97 |
+
del recs, vals,adjvals,extra,loss,pred
|
| 98 |
+
gc.collect()
|
| 99 |
+
if h.device.type=='cuda':torch.cuda.empty_cache()
|
| 100 |
+
return out
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def numerical_pass(core,head,h,y,sd,Q,precision,task,kind):
|
| 104 |
+
"""Identical 2-window objective, streamed over original TRAIN windows 0/1.
|
| 105 |
+
|
| 106 |
+
Shared **CPU** backend by default makes FP32-vs-FP64 comparisons unconfounded
|
| 107 |
+
by different CUDA vs CPU convolution implementations. A user may opt into
|
| 108 |
+
CUDA for BOTH dtypes via CIDM_B2R12_FIX1_COMMON_DEVICE=cuda, but the script
|
| 109 |
+
refuses it for GPUs with <32 GiB of total memory, to avoid old 14.6GiB OOM.
|
| 110 |
+
"""
|
| 111 |
+
common=os.environ.get('CIDM_B2R12_FIX1_COMMON_DEVICE','cpu').strip().lower()
|
| 112 |
+
if common not in ('cpu','cuda'):raise RuntimeError('COMMON_BACKEND_MUST_BE_CPU_OR_CUDA')
|
| 113 |
+
if common=='cuda':
|
| 114 |
+
if not torch.cuda.is_available() or torch.cuda.get_device_properties(0).total_memory < 32*1024**3:
|
| 115 |
+
raise RuntimeError('COMMON_CUDA_BACKEND_REQUIRES_AT_LEAST_32G_GPU_USE_CPU_INSTEAD')
|
| 116 |
+
dev=torch.device(common)
|
| 117 |
+
dtype=torch.float32 if precision=='fp32' else torch.float64
|
| 118 |
+
# Copy from CPU first: never clone an entire CUDA model before transferring.
|
| 119 |
+
core=copy.deepcopy(core.to('cpu')).to(device=dev,dtype=dtype).eval().requires_grad_(False)
|
| 120 |
+
head=copy.deepcopy(head.to('cpu')).to(device=dev,dtype=dtype).eval().requires_grad_(True)
|
| 121 |
+
Q=Q.cpu() if Q is not None else None
|
| 122 |
+
h=h.cpu();y=y.cpu();sd=sd.cpu()
|
| 123 |
+
n=int(h.shape[0]);
|
| 124 |
+
if n<1:raise RuntimeError('NO_TRAIN_WINDOWS')
|
| 125 |
+
accumulator=None;parts=None;sum_perstep=None;loss_acc=0.;preds=[]
|
| 126 |
+
for i in range(n):
|
| 127 |
+
case=_sample_precision_pass(core,head,h[i:i+1],y[i:i+1],sd,Q,dtype,task,kind,precision,i)
|
| 128 |
+
w=1./n
|
| 129 |
+
loss_acc+=w*case['loss'];preds.append(case['pred'])
|
| 130 |
+
accumulator=case['full']*w if accumulator is None else accumulator+case['full']*w
|
| 131 |
+
if parts is None:
|
| 132 |
+
parts=[w*x['parameter_part'] for x in case['steps']]
|
| 133 |
+
sum_perstep=[{k:(x[k]*w*w if k!='replay' else x[k]) for k in ('gate_adj_sq','identity_sq','flux_sq','local_sq','skew_sq','latent_sq','replay')}
|
| 134 |
+
for x in case['steps']]
|
| 135 |
+
else:
|
| 136 |
+
for j,x in enumerate(case['steps']):
|
| 137 |
+
parts[j]+=w*x['parameter_part']
|
| 138 |
+
for k in ('gate_adj_sq','identity_sq','flux_sq','local_sq','skew_sq','latent_sq'):
|
| 139 |
+
if x[k] is not None:sum_perstep[j][k]=(sum_perstep[j][k] or 0)+x[k]*w*w
|
| 140 |
+
sum_perstep[j]['replay']=max(sum_perstep[j]['replay'],x['replay'])
|
| 141 |
+
del case
|
| 142 |
+
gc.collect()
|
| 143 |
+
if dev.type=='cuda':torch.cuda.empty_cache()
|
| 144 |
+
pred=torch.cat(preds,dim=0)
|
| 145 |
+
full=accumulator
|
| 146 |
+
gnorm=norm(full)
|
| 147 |
+
recon=torch.stack(parts).sum(dim=0)
|
| 148 |
+
rel=norm(recon-full)/max(gnorm,1e-30)
|
| 149 |
+
steps=[]
|
| 150 |
+
for t,(p,v) in enumerate(zip(parts,sum_perstep),start=1):
|
| 151 |
+
get=lambda key:math.sqrt(v[key]) if v[key] is not None else None
|
| 152 |
+
a=get('identity_sq');b=get('flux_sq')
|
| 153 |
+
steps.append({'task':task,'controller':kind,'precision':precision,'lead':t,
|
| 154 |
+
'parameter_part_l2':norm(p),'gate_adjoint_l2':get('gate_adj_sq'),
|
| 155 |
+
'identity_vjp_l2':a,'flux_vjp_l2':b,'local_vjp_l2':get('local_sq'),
|
| 156 |
+
'skew_vjp_l2':get('skew_sq'),
|
| 157 |
+
'flux_to_identity_vjp_ratio':b/max(a,1e-30),
|
| 158 |
+
'latent_adjoint_l2':get('latent_sq'),
|
| 159 |
+
'local_gate_replay_max_abs':v['replay']})
|
| 160 |
+
summary={'task':task,'controller':kind,'precision':precision,
|
| 161 |
+
'loss':loss_acc,'full_gradient_l2_fp64_reduce':gnorm,
|
| 162 |
+
'full_gradient_max_abs':float(full.abs().max()),
|
| 163 |
+
'partition_relative_error':rel,'partition_abs_residual_l2':norm(recon-full),
|
| 164 |
+
'cancellation_condition':sum(norm(x) for x in parts)/max(norm(recon),1e-30),
|
| 165 |
+
'first_step_flux_vjp_l2':steps[0]['flux_vjp_l2'],
|
| 166 |
+
'step1_parameter_part_l2':steps[0]['parameter_part_l2'],
|
| 167 |
+
'full_gradient_is_elementwise_finite':True,
|
| 168 |
+
'head_partition_strict_pass':rel<=1e-4,
|
| 169 |
+
'common_backend':common, 'streamed_train_windows':n,
|
| 170 |
+
'graph_retention':False,
|
| 171 |
+
'scoring_contract':'mean of original TRAIN window 0 and 1 per-window identical 12-step physical loss'}
|
| 172 |
+
return summary,steps,pred,full
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
def paired_case(task,core,cache,r6zip,device,heads_used=('operator','rotated'),limit=2):
|
| 176 |
+
"""All cross-precision cases use SAME engine, weights, TRAIN sample ids and loss.
|
| 177 |
+
|
| 178 |
+
The original archived seed17 checkpoint is validated before this method runs.
|
| 179 |
+
"""
|
| 180 |
+
ch=int(cache['splits']['train']['h'].shape[2]);d=int(core.model.skew.shape[0])
|
| 181 |
+
matched='swe_2d' if task=='smoke_2d' else ('burgers_1d' if task=='smoke_1d' else task)
|
| 182 |
+
heads=r11.load_heads(r6zip,matched,ch,'cpu')
|
| 183 |
+
Q=r11.orthogonal_matrix(d,32207,'cpu',torch.float32)
|
| 184 |
+
w=r11.Windows(cache['splits']['train']['h'],cache['splits']['train']['y'],cache['mean'],cache['std'])
|
| 185 |
+
ids=list(range(min(limit,len(w))));examples=[w[i] for i in ids]
|
| 186 |
+
h=torch.stack([a for a,b in examples]).cpu()
|
| 187 |
+
y=torch.stack([b for a,b in examples]).cpu()
|
| 188 |
+
sd=w.sd.cpu()
|
| 189 |
+
group=[];detail=[]
|
| 190 |
+
core=core.cpu()
|
| 191 |
+
for kind in heads_used:
|
| 192 |
+
head=heads[kind].cpu();q=Q if kind=='rotated' else None
|
| 193 |
+
a,rows_a,pa,ga=numerical_pass(core,head,h,y,sd,q,'fp32',task,kind)
|
| 194 |
+
b,rows_b,pb,gb=numerical_pass(core,head,h,y,sd,q,'fp64',task,kind)
|
| 195 |
+
div=float((pa-pb).abs().max())
|
| 196 |
+
reldiv=norm(pa-pb)/max(norm(pb),1e-30)
|
| 197 |
+
gcval=float(torch.dot(ga,gb)/(torch.linalg.vector_norm(ga)*torch.linalg.vector_norm(gb)).clamp_min(1e-300)) if norm(ga)>0 and norm(gb)>0 else 0.
|
| 198 |
+
grel=norm(ga-gb)/max(norm(gb),1e-30)
|
| 199 |
+
ratio=norm(ga)/max(norm(gb),1e-30)
|
| 200 |
+
for row in (a,b):
|
| 201 |
+
row.update({'forward_max_abs_fp32_vs_fp64':div,'forward_relative_l2_fp32_vs_fp64':reldiv,
|
| 202 |
+
'gradient_cosine_fp32_vs_fp64':gcval,
|
| 203 |
+
'gradient_relative_l2_fp32_vs_fp64':grel,
|
| 204 |
+
'gradient_norm_ratio_fp32_over_fp64':ratio,
|
| 205 |
+
'strict_partition_gate_1e_4':1e-4})
|
| 206 |
+
group.extend((a,b));detail.extend(rows_a+rows_b)
|
| 207 |
+
del pa,pb,ga,gb
|
| 208 |
+
gc.collect()
|
| 209 |
+
return group,detail
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
def run(parent,r6zip,r9zip,fix2zip,r11fix1zip,work,output,smoke=False,device='cpu'):
|
| 213 |
+
output=Path(output);work=Path(work)
|
| 214 |
+
output.mkdir(parents=True,exist_ok=True);work.mkdir(parents=True,exist_ok=True)
|
| 215 |
+
if r11.sha(r11fix1zip)!=ARCHIVE_FIX1_SHA:raise RuntimeError('R11_FIX1_UPLOADED_EVIDENCE_SHA_MISMATCH')
|
| 216 |
+
with zipfile.ZipFile(r11fix1zip) as z:
|
| 217 |
+
if z.testzip(): raise RuntimeError('R11_FIX1_EVIDENCE_CRC_ERROR')
|
| 218 |
+
rep=json.loads(z.read('report.json'));gate=json.loads(z.read('gradient_path_gate.json'))
|
| 219 |
+
if rep['status']!='FROZEN_ATTRIBUTION_DATA_COLLECTED_NUMERIC_GATE_FAIL_NO_TRAINING' or rep['temporal_rows']!=72 or gate['strict_numerical_gate_pass']:
|
| 220 |
+
raise RuntimeError('R11_FIX1_EVIDENCE_GATE_CONTRACT_MISMATCH')
|
| 221 |
+
if r11.sha(fix2zip)!=r11.PREV_FIX2_SHA:raise RuntimeError('R10_FIX2_EVIDENCE_SHA_MISMATCH')
|
| 222 |
+
r11.credit.validate_r6(r6zip);r11.credit.validate_r9(r9zip)
|
| 223 |
+
sums=[];steps=[];cases=[]
|
| 224 |
+
try:
|
| 225 |
+
if smoke:
|
| 226 |
+
cfg=r11.Config(profile='smoke')
|
| 227 |
+
for task,kind in [('smoke_1d','operator'),('smoke_2d','rotated')]:
|
| 228 |
+
cache=r11.make_synthetic_cache(cfg)
|
| 229 |
+
for split in ('train','val','test'):
|
| 230 |
+
if task=='smoke_1d':
|
| 231 |
+
cache['splits'][split]['h']=cache['splits'][split]['h'].mean(dim=-2)[...,:4]
|
| 232 |
+
cache['splits'][split]['y']=cache['splits'][split]['y'].mean(dim=-2)[...,:4]
|
| 233 |
+
else:
|
| 234 |
+
cache['splits'][split]['h']=cache['splits'][split]['h'][...,:2,:4]
|
| 235 |
+
cache['splits'][split]['y']=cache['splits'][split]['y'][...,:2,:4]
|
| 236 |
+
core=r11.UnifiedModel('V2_Ported_R5',1,8,12,4).to(device)
|
| 237 |
+
s,d=paired_case(task,core,cache,r6zip,device,(kind,),1)
|
| 238 |
+
sums.extend(s);steps.extend(d)
|
| 239 |
+
status='PROGRAM_ONLY_SMOKE_NO_SCIENCE'
|
| 240 |
+
else:
|
| 241 |
+
if parent is None or r11.sha(parent)!=r11.PARENT_SHA:raise RuntimeError('B0_PARENT_ZIP_SHA_MISMATCH')
|
| 242 |
+
with zipfile.ZipFile(parent) as z:
|
| 243 |
+
manifest,_=check_zip(z);cfg=r11.Config(**manifest['config'])
|
| 244 |
+
for task in r11.TASK_LIST:
|
| 245 |
+
core,cache,replay=r11.make_cache_checked(task,z,cfg,work,device)
|
| 246 |
+
s,d=paired_case(task,core,cache,r6zip,device)
|
| 247 |
+
sums.extend(s);steps.extend(d)
|
| 248 |
+
cases.append({'task':task,'archived_B0_checkpoint_replay':replay,'heads':2})
|
| 249 |
+
write_csv(output/'precision_case_summary.csv',sums)
|
| 250 |
+
write_csv(output/'temporal_vjp_gain.csv',steps)
|
| 251 |
+
write_json(output/'progress.json',{'tasks_completed':[v['task'] for v in cases]})
|
| 252 |
+
if len(sums)!=12 or len(steps)!=144 or len(cases)!=3:raise RuntimeError('INCOMPLETE_12_CASES_OR_144_STEPS')
|
| 253 |
+
status='FROZEN_DUAL_PRECISION_FIX1_COMPLETED_NO_TRAINING'
|
| 254 |
+
except Exception as e:
|
| 255 |
+
write_csv(output/'precision_case_summary.csv',sums);write_csv(output/'temporal_vjp_gain.csv',steps)
|
| 256 |
+
write_json(output/'failure_details.json',{'exception':repr(e),'cases_completed':cases})
|
| 257 |
+
raise
|
| 258 |
+
write_csv(output/'precision_case_summary.csv',sums);write_csv(output/'temporal_vjp_gain.csv',steps)
|
| 259 |
+
unresolved=[d for d in sums if not d['head_partition_strict_pass']]
|
| 260 |
+
swe=[d for d in sums if d['task']=='swe_2d']
|
| 261 |
+
gate={'experiment':'B2_R12_P0_FIX1','status':'DIAGNOSTIC_ONLY_NO_TRAINING',
|
| 262 |
+
'strict_partition_pass_all':len(unresolved)==0,
|
| 263 |
+
'unresolved':unresolved,'swe_precision_cases':swe,
|
| 264 |
+
'train_allowed':False,
|
| 265 |
+
'note':'FP64 full trajectory replay changes numerical precision; divergent FP32/FP64 forecasts cannot be compared as identical-path gradients. Branch VJP ratios are local cotangent amplification, NOT Jacobian spectral norms.'}
|
| 266 |
+
write_json(output/'precision_gate.json',gate)
|
| 267 |
+
rep={'experiment':'CIDM_v2_B2_R12_P0_FIX1_MemoryBoundedDualPrecision',
|
| 268 |
+
'status':status,'case_rows':len(sums),'time_rows':len(steps),'cases':cases,
|
| 269 |
+
'prior_R11_FIX1_SHA256':ARCHIVE_FIX1_SHA,'original_parent_frozen':True,
|
| 270 |
+
'updates':0,'train_allowed':False,'numeric_gate':gate['strict_partition_pass_all'],
|
| 271 |
+
'not_independent_external_holdout':True}
|
| 272 |
+
write_json(output/'report.json',rep)
|
| 273 |
+
return rep
|