(checkpoint_folder)
| 33 | |
| 34 | |
| 35 | def load_evolution_data(checkpoint_folder): |
| 36 | meta_path = os.path.join(checkpoint_folder, "metadata.json") |
| 37 | programs_dir = os.path.join(checkpoint_folder, "programs") |
| 38 | if not os.path.exists(meta_path) or not os.path.exists(programs_dir): |
| 39 | logger.info(f"Missing metadata.json or programs dir in {checkpoint_folder}") |
| 40 | return {"archive": [], "nodes": [], "edges": [], "checkpoint_dir": checkpoint_folder} |
| 41 | with open(meta_path) as f: |
| 42 | meta = json.load(f) |
| 43 | |
| 44 | nodes = [] |
| 45 | id_to_program = {} |
| 46 | pids = set() |
| 47 | for island_idx, id_list in enumerate(meta.get("islands", [])): |
| 48 | for pid in id_list: |
| 49 | prog_path = os.path.join(programs_dir, f"{pid}.json") |
| 50 | |
| 51 | # Keep track of PIDs and if one is double, append "-copyN" to the PID |
| 52 | if pid in pids: |
| 53 | base_pid = pid |
| 54 | |
| 55 | # If base_pid already has a "-copyN" suffix, strip it |
| 56 | if "-copy" in base_pid: |
| 57 | base_pid = base_pid.rsplit("-copy", 1)[0] |
| 58 | |
| 59 | # Find the next available copy number |
| 60 | copy_num = 1 |
| 61 | while f"{base_pid}-copy{copy_num}" in pids: |
| 62 | copy_num += 1 |
| 63 | pid = f"{base_pid}-copy{copy_num}" |
| 64 | pids.add(pid) |
| 65 | |
| 66 | if os.path.exists(prog_path): |
| 67 | with open(prog_path) as pf: |
| 68 | prog = json.load(pf) |
| 69 | sanitize_program_for_visualization(prog) |
| 70 | prog["id"] = pid |
| 71 | prog["island"] = island_idx |
| 72 | nodes.append(prog) |
| 73 | id_to_program[pid] = prog |
| 74 | else: |
| 75 | logger.debug(f"Program file not found: {prog_path}") |
| 76 | |
| 77 | edges = [] |
| 78 | for prog in nodes: |
| 79 | parent_id = prog.get("parent_id") |
| 80 | if parent_id and parent_id in id_to_program: |
| 81 | edges.append({"source": parent_id, "target": prog["id"]}) |
| 82 | |
| 83 | logger.info(f"Loaded {len(nodes)} nodes and {len(edges)} edges from {checkpoint_folder}") |
| 84 | return { |
| 85 | "archive": meta.get("archive", []), |
| 86 | "nodes": nodes, |
| 87 | "edges": edges, |
| 88 | "checkpoint_dir": checkpoint_folder, |
| 89 | } |
| 90 | |
| 91 | def sanitize_program_for_visualization(program: dict[str, Any]) -> None: |
| 92 | for k, v in program["metrics"].items(): |
no test coverage detected