| |
| """ |
| ARC-AGI NeuroGolf Championship - Main Entry Point |
| |
| Usage: |
| python -m neurogolf_solver.main --data_dir ARC-AGI/data/training/ --output_dir submission |
| python -m neurogolf_solver.main --kaggle --output_dir /kaggle/working/submission |
| python -m neurogolf_solver.main --data_dir ARC-AGI/data/training/ --arcgen_dir ARC-GEN-100K/ --use_wandb |
| """ |
|
|
| import argparse |
| import os |
| import sys |
| import time |
| import onnxruntime as ort |
| from .config import get_providers |
| from .data_loader import load_tasks_dir, load_tasks_kaggle |
| from .submission import run_tasks, generate_submission, print_summary |
| from .profiler import score_network |
| from .constants import EXCLUDED_TASKS, MAX_ONNX_FILESIZE |
|
|
| try: |
| import wandb |
| except ImportError: |
| wandb = None |
|
|
|
|
| def check_all_models(output_dir, strict_size, strict_score): |
| """Check all .onnx files for size limit and scoreability.""" |
| size_problems = [] |
| score_problems = [] |
| for f in sorted(os.listdir(output_dir)): |
| if not f.endswith('.onnx'): |
| continue |
| fpath = os.path.join(output_dir, f) |
| fsize = os.path.getsize(fpath) |
| if fsize > MAX_ONNX_FILESIZE: |
| size_problems.append((f, fsize)) |
| macs, memory, params = score_network(fpath) |
| if macs is None or memory is None or params is None: |
| score_problems.append(f) |
| if size_problems: |
| print(f"\n{'!'*70}") |
| print(f"FATAL: {len(size_problems)} .onnx files exceed 1.44MB limit:") |
| for f, sz in size_problems: |
| print(f" {f}: {sz:,} bytes ({sz/1024:.1f} KB)") |
| print(f"{'!'*70}") |
| if strict_size: |
| sys.exit(1) |
| if score_problems: |
| print(f"\nWARNING: {len(score_problems)} .onnx files unscorable by onnx_tool:") |
| for f in score_problems: |
| print(f" {f}") |
| if strict_score: |
| print("Stopping (--strict_score is on).") |
| sys.exit(1) |
| if not size_problems and not score_problems: |
| print(f"\nAll .onnx files pass size and score checks.") |
|
|
|
|
| def main(): |
| parser = argparse.ArgumentParser(description='NeuroGolf Solver v5') |
| parser.add_argument('--data_dir', default='ARC-AGI/data/training/') |
| parser.add_argument('--arcgen_dir', default='', help='Path to ARC-GEN-100K/ directory') |
| parser.add_argument('--output_dir', default='/kaggle/working/submission') |
| parser.add_argument('--kaggle', action='store_true', help='Use Kaggle task format') |
| parser.add_argument('--conv_budget', type=float, default=30.0, help='Seconds per conv solver per task') |
| parser.add_argument('--tasks', type=str, default='', help='Comma-separated task numbers') |
| parser.add_argument('--device', type=str, default='auto', choices=['auto', 'cpu', 'cuda']) |
| parser.add_argument('--use_wandb', action='store_true', help='Enable W&B logging') |
| parser.add_argument('--strict_size', type=bool, default=True, help='Halt if any .onnx > 1.44MB (default: True)') |
| parser.add_argument('--strict_score', type=bool, default=False, help='Halt if any model unscorable (default: False)') |
| args = parser.parse_args() |
| providers = get_providers(args.device) |
| config = {"device": args.device, "conv_budget": args.conv_budget, "data_dir": args.data_dir, "arcgen_dir": args.arcgen_dir, "tasks": args.tasks} |
| ort.set_default_logger_severity(3) |
| print(f"Using providers: {providers}") |
| print(f"Strict size: {args.strict_size} | Strict score: {args.strict_score}") |
| print(f"Max .onnx file size: {MAX_ONNX_FILESIZE:,} bytes") |
| if args.kaggle: |
| tasks = load_tasks_kaggle(args.data_dir) |
| else: |
| arcgen = args.arcgen_dir if args.arcgen_dir else None |
| tasks = load_tasks_dir(args.data_dir, arcgen_dir=arcgen) |
| total_arcgen = sum(len(t['data'].get('arc-gen', [])) for t in tasks.values()) |
| print(f"Loaded {len(tasks)} tasks ({total_arcgen} ARC-GEN examples)") |
| task_nums = [int(t) for t in args.tasks.split(',')] if args.tasks else sorted(tasks.keys()) |
| print(f"Solving {len(task_nums)} tasks") |
| print(f"Conv budget: {args.conv_budget}s per task") |
| print("=" * 70) |
| t0 = time.time() |
| if args.use_wandb and wandb is not None: |
| with wandb.init(project="neurogolf", name="solver_run", config=config): |
| results, costs_dict, total_score = run_tasks(task_nums, tasks, args.output_dir, providers, args.conv_budget, EXCLUDED_TASKS, use_wandb=True) |
| else: |
| results, costs_dict, total_score = run_tasks(task_nums, tasks, args.output_dir, providers, args.conv_budget, EXCLUDED_TASKS, use_wandb=False) |
| elapsed = time.time() - t0 |
| check_all_models(args.output_dir, args.strict_size, args.strict_score) |
| submission_info = generate_submission(args.output_dir, results, costs_dict, task_nums) |
| print_summary(results, submission_info, elapsed) |
|
|
| if __name__ == '__main__': |
| main() |
|
|