| """Ray-matched causal persistence benchmark; no ground-truth policy access.""" |
| from pathlib import Path |
| import argparse,csv,json,time,platform,sys |
| ROOT=Path(__file__).resolve().parents[1] |
| sys.path.insert(0,str(ROOT)) |
| import numpy as np |
| from aureole import WorldMemory,freeze,draw,correct,exact_mse |
| from aureole.core import proposal_from_bound |
| from aureole.renderer import Scene,VisibilityPrior,receiver_grid,light_grid,unoccluded,physical_table |
|
|
|
|
| def cluster_interval(values,seed=992): |
| """95% percentile interval over independent scenes, not individual pixels.""" |
| x=np.asarray(values,float) |
| rng=np.random.default_rng(seed) |
| means=x[rng.integers(0,len(x),(10000,len(x)))].mean(1) |
| return [float(v) for v in np.percentile(means,[2.5,97.5])] |
|
|
|
|
| def run(followup=False,output="reproduced_results"): |
| config=json.loads((ROOT/("experiments_followup.json" if followup else "experiments.json")).read_text()) |
| prefix="followup" if followup else "rendering" |
| points=receiver_grid(*config["receiver_grid"]);lights=light_grid(config["emitter_grid_side"]) |
| height,width=config["receiver_grid"]; vh,vw=config["viewport"] |
| methods=config["methods"];prior=VisibilityPrior(ROOT/"models/visibility_prior.npz") |
| phase_frames=[(phase,i) for phase,n in config["phases"].items() for i in range(n)] |
| rows=[];prep=[];snapshots={};start=time.perf_counter();n=config["rays_per_receiver_per_frame"] |
| for scene_id in config["scene_ids"]: |
| scene=Scene.create(scene_id);changed=scene.changed() |
| tic=time.perf_counter();features=scene.features(points[:,None,:],lights[None,:,:]);p_all=prior(features) |
| prior_seconds=time.perf_counter()-tic |
| bound0=unoccluded(points,lights);bound1=unoccluded(points,lights,True,0.7) |
| |
| truth0=physical_table(scene,points,lights,bound0) |
| truth1=physical_table(scene,points,lights,bound1) |
| truth2=physical_table(changed,points,lights,bound1) |
| prep.append({"scene":scene_id,"prior_all_receivers_seconds":prior_seconds,"prior_receiver_emitter_pairs":len(points)*len(lights)}) |
| for seed in config["replicate_seeds"]: |
| memory={method:WorldMemory(len(points),len(lights),f"scene-{scene_id}") for method in methods} |
| rngs={method:np.random.default_rng(seed+scene_id*1000) for method in methods} |
| for frame,(phase,phase_frame) in enumerate(phase_frames): |
| if phase=="revisit" and phase_frame==0: |
| for m in memory.values():m.advance(config["unseen_ticks_before_revisit"]) |
| memory["screen_cv"].retain_only(np.array([],dtype=int)) |
| x0=2+(phase_frame%4);y0=8 |
| ids=(np.arange(y0,y0+vh)[:,None]*width+np.arange(x0,x0+vw)[None,:]).ravel() |
| b=(bound1 if phase in ("relight","hidden_change") else bound0)[ids] |
| current_scene=changed if phase=="hidden_change" else scene |
| offline_truth=(truth2 if phase=="hidden_change" else truth1 if phase=="relight" else truth0)[ids] |
| target=offline_truth.sum(1) |
| for method in methods: |
| tic=time.perf_counter();m=memory[method] |
| if method=="screen_cv":m.retain_only(ids) |
| base_prior=np.full((len(ids),len(lights)),0.5) if method=="constant_world_cv" else p_all[ids] |
| if method=="raw_importance":v=np.zeros_like(base_prior) |
| elif method=="neural_cv":v=base_prior |
| else:v=m.predict(ids,base_prior) |
| q=proposal_from_bound(b,v,m.trusted(ids),active=(method in ("world_active_cv","world_guarded_cv"))) |
| snapshot=freeze(b*v[...,None],q) |
| j=draw(snapshot,n,rngs[method]) |
| observed_visibility=current_scene.visibility(points[ids,None,:],lights[j]) |
| physical=b[np.arange(len(ids))[:,None],j]*observed_visibility[...,None] |
| result=correct(snapshot,j,physical) |
| if method=="world_plugin":result=snapshot.integral.copy() |
| conflicts=0 |
| if method not in ("raw_importance","neural_cv"): |
| conflicts=m.commit(ids,j,observed_visibility,revise_on_conflict=(method=="world_guarded_cv")) |
| m.advance() |
| runtime=time.perf_counter()-tic |
| |
| conditional=(np.mean((snapshot.integral-target)**2,axis=1) if method=="world_plugin" |
| else exact_mse(offline_truth,snapshot,n)) |
| rows.append({"scene":scene_id,"seed":seed,"phase":phase,"phase_frame":phase_frame, |
| "frame":frame,"method":method,"mse":float(np.mean((result-target)**2)), |
| "conditional_expected_mse":float(conditional.mean()), |
| "mean_error":float(np.mean(result-target)),"negative_channel_fraction":float(np.mean(result<0)), |
| "rays":len(ids)*n,"runtime_seconds":runtime,"memory_bytes":0 if method in ("raw_importance","neural_cv") else m.nbytes, |
| "observed_conflicting_ray_entries":conflicts,"epoch_after":m.epoch, |
| "known_fraction_after":float(np.isfinite(m.values[ids]).mean())}) |
| if scene_id==config["scene_ids"][0] and seed==config["replicate_seeds"][0] and phase_frame==0 and phase in ("revisit","hidden_change"): |
| snapshots[f"{phase}_{method}"]=result.reshape(vh,vw,3) |
| snapshots[f"{phase}_reference"]=target.reshape(vh,vw,3) |
| print(f"completed scene {scene_id}; {len(rows)} frame-method observations",flush=True) |
| out=ROOT/output;out.mkdir(parents=True,exist_ok=True) |
| with (out/f"{prefix}_raw.csv").open("w",newline="") as handle: |
| writer=csv.DictWriter(handle,fieldnames=list(rows[0]));writer.writeheader();writer.writerows(rows) |
| summary=[] |
| for phase in config["phases"]: |
| for method in methods: |
| subset=[r for r in rows if r["phase"]==phase and r["method"]==method] |
| scene_values=[np.mean([r["conditional_expected_mse"] for r in subset if r["scene"]==scene_id]) for scene_id in config["scene_ids"]] |
| summary.append({"phase":phase,"method":method,"expected_mse":float(np.mean(scene_values)), |
| "expected_mse_scene_bootstrap_95":cluster_interval(scene_values), |
| "observed_mse":float(np.mean([r["mse"] for r in subset])), |
| "negative_channel_fraction":float(np.mean([r["negative_channel_fraction"] for r in subset])), |
| "cpu_median_ms":float(np.median([r["runtime_seconds"] for r in subset])*1000), |
| "cpu_p99_ms":float(np.quantile([r["runtime_seconds"] for r in subset],.99)*1000)}) |
| comparisons=[] |
| for phase in config["phases"]: |
| pairs=([("world_guarded_cv","world_active_cv"),("world_guarded_cv","world_cv"),("world_guarded_cv","raw_importance"),("world_guarded_cv","screen_cv")] |
| if followup else [("world_cv","screen_cv"),("world_cv","raw_importance"),("world_active_cv","world_cv"),("world_cv","constant_world_cv"),("world_cv","world_plugin")]) |
| for contender,baseline in pairs: |
| a=[];b=[] |
| for sid in config["scene_ids"]: |
| a.append(np.mean([r["conditional_expected_mse"] for r in rows if r["scene"]==sid and r["phase"]==phase and r["method"]==contender])) |
| b.append(np.mean([r["conditional_expected_mse"] for r in rows if r["scene"]==sid and r["phase"]==phase and r["method"]==baseline])) |
| a=np.array(a);b=np.array(b) |
| rng=np.random.default_rng(299);draws=rng.integers(0,len(a),(10000,len(a))) |
| ratios=1-a[draws].mean(1)/np.maximum(b[draws].mean(1),1e-30) |
| comparisons.append({"phase":phase,"contender":contender,"baseline":baseline, |
| "relative_expected_mse_reduction":float(1-a.mean()/max(b.mean(),1e-30)), |
| "scene_bootstrap_95":[float(v) for v in np.percentile(ratios,[2.5,97.5])]}) |
| report={"protocol":config,"elapsed_seconds":time.perf_counter()-start,"environment":{"python":platform.python_version(),"numpy":np.__version__,"device":"cpu"}, |
| "record_count":len(rows),"total_physical_ray_calls":int(sum(r["rays"] for r in rows)), |
| "per_persistent_method_memory_bytes":len(points)*len(lights)*8, |
| "prior_preparation":prep,"summary":summary,"comparisons":comparisons, |
| "limitations":["Only a direct-light floor/three-sphere scene family; no game engine or full path tracing.", |
| "Ray counts match. Compute, bandwidth, and VRAM do not match; report is not an equal-frame-time comparison.", |
| "Clock gap has no observations; it is not 500 fully rendered frames.", |
| "CPU timings exclude shared feature/prior preparation and privileged reference enumeration; not full-renderer frame times.", |
| "Hidden changes deliberately omit invalidation and use the stale prior; controls remain fallible.", |
| "Negative linear-radiance estimates are retained for statistical metrics. Display clipping introduces bias.", |
| "Small scene-cluster intervals characterize this generator only; no cross-game generalization claim."]} |
| (out/f"{prefix}_report.json").write_text(json.dumps(report,indent=2)+"\n") |
| np.savez_compressed(out/f"{prefix}_example_frames.npz",**snapshots) |
| print(json.dumps({"records":len(rows),"elapsed_seconds":report["elapsed_seconds"],"comparisons":comparisons},indent=2)) |
|
|
| if __name__=="__main__": |
| parser=argparse.ArgumentParser();parser.add_argument("--followup",action="store_true") |
| parser.add_argument("--output",default="reproduced_results",help="Keep new runs separate from the recorded release evidence") |
| args=parser.parse_args();run(args.followup,args.output) |
|
|