| import math |
| import os |
| import pandas as pd |
| import random |
| import shutil |
| import time |
|
|
| from code_generation import generate_and_debug, prepare_working_folder, code_execution, get_results |
| from program_database import ProgramsDatabase, ProgramsDatabaseConfig |
| |
| def get_seed_score(nRMSE, convergence_rate): |
| return { |
| 'bucketed_convergence_rate': int(max(0, convergence_rate)*4), |
| 'bucketed_nRMSE': int(-math.log10(min(1e9, nRMSE))*10) |
| } |
|
|
| def funsearch(cfg): |
| num_trials = cfg.method.num_debugging_trials_per_sample |
| pde_name = cfg.pde.name |
| working_folder = cfg.working_folder |
| model_name = cfg.model.name |
| num_search_rounds = cfg.method.num_search_rounds |
| num_initial_seeds = cfg.method.num_initial_seeds |
| use_sample_solver_init = cfg.method.use_sample_solver_init |
| assert use_sample_solver_init, 'Sample solvers must be enabled for refinement' |
|
|
| sample_solver_folder = os.path.join( |
| 'solvers', pde_name, cfg.pde.pde_setting_name, 'seeds' |
| ) |
| sample_solver_info = pd.read_csv( |
| os.path.join(sample_solver_folder, 'seed_results.csv') |
| ) |
|
|
| prepare_working_folder( |
| cfg, |
| working_folder=working_folder, |
| pde_name=pde_name, |
| use_sample_solver_init=use_sample_solver_init |
| ) |
|
|
| pd_cfg = ProgramsDatabaseConfig() |
| program_db = ProgramsDatabase(pd_cfg) |
|
|
| |
| seed_path = os.path.join( |
| '../archived_logs', |
| pde_name, |
| cfg.pde.pde_setting_name, |
| 'repeated_sample', |
| model_name |
| ) |
| subdirectories = [d for d in os.listdir(seed_path) if os.path.isdir(os.path.join(seed_path, d))] |
| assert len(subdirectories) == 1, 'Only one subdirectory is expected' |
| seed_path = os.path.join(seed_path, subdirectories[0]) |
| result_sheet = pd.read_csv(os.path.join(seed_path, 'test_results.csv')) |
|
|
| for i in range(num_initial_seeds): |
| relevant_files = [ |
| 'errors_{idx}.txt', |
| 'implementation_{idx}.py', |
| 'output_{idx}.txt', |
| ] |
|
|
| complete_seed = True |
| for file in relevant_files: |
| if not os.path.exists(os.path.join(seed_path, file.format(idx=i))): |
| complete_seed = False |
| break |
| if result_sheet[result_sheet['round'] == i].empty: |
| complete_seed = False |
| |
| seed_info = result_sheet[result_sheet['round'] == i].to_numpy().tolist()[0] |
| seed_info = [str(x) for x in seed_info] |
| if seed_info[1] == 'failed': |
| complete_seed = False |
|
|
| if not complete_seed: |
| continue |
|
|
| |
| for file in relevant_files: |
| source_file = os.path.join(seed_path, file.format(idx=int(i))) |
| destination_file = os.path.join(working_folder, file.format(idx=int(i))) |
| shutil.copy(source_file, destination_file) |
| with open(os.path.join(working_folder, 'test_results.csv'), 'a') as f: |
| seed_info[0] = str(int(i)) |
| f.write(','.join(seed_info) + '\n') |
| |
| |
| seed_score = get_seed_score(float(seed_info[1]), float(seed_info[3])) |
| with open(os.path.join(working_folder, f'implementation_{i}.py'), 'r') as f: |
| implementation = f.readlines() |
| program_len = len(implementation) |
| program_db.register_program( |
| program=i, |
| program_len=program_len, |
| island_id=None, |
| scores_per_test=seed_score, |
| ) |
|
|
| for i in range(num_initial_seeds, num_initial_seeds+num_search_rounds): |
| island_id, seed_ids = program_db.get_seed() |
| try: |
| relative_error, elapsed_time, avg_rate = generate_and_debug( |
| cfg, |
| round_idx=i, |
| num_trials=num_trials, |
| pde_name=pde_name, |
| working_folder=working_folder, |
| seed_implementations=seed_ids, |
| model_name=model_name |
| ) |
| seed_score = get_seed_score(float(relative_error), float(avg_rate)) |
| with open(os.path.join(working_folder, f'implementation_{i}.py'), 'r') as f: |
| implementation = f.readlines() |
| program_len = len(implementation) |
| program_db.register_program( |
| program=i, |
| program_len=program_len, |
| island_id=island_id, |
| scores_per_test=seed_score, |
| ) |
| except Exception as e: |
| print(f'Error in round {i}: {e}. Move on to the next sample.') |
| |
|
|
| |
| results = pd.read_csv(os.path.join(working_folder, 'test_results.csv')) |
| keywords = ['nRMSE', 'elapsed_time', 'convergence_rate'] |
| for keyword in keywords: |
| results[keyword] = pd.to_numeric(results[keyword], errors="coerce") |
| |
| sorted_results = results.sort_values(by=keywords, ascending=[True, True, False]) |
| best_idx = int(sorted_results.head(1)["round"].values[0]) |
| |
| test_run_id = 999 |
| shutil.copy( |
| os.path.join(working_folder, f'implementation_{best_idx}.py'), |
| os.path.join(working_folder, f'implementation_{test_run_id}.py') |
| ) |
| execution_results = code_execution( |
| cfg, |
| working_folder = working_folder, |
| round_idx=test_run_id, |
| pde_name=pde_name, |
| eval_dataset=os.path.join( |
| cfg.root_dataset_folder, |
| cfg.pde.dataset_folder_for_eval.replace('_development.hdf5', '.hdf5') |
| ) |
| ) |
|
|
| if execution_results['exit_code'] != 0: |
| relative_error, elapsed_time, avg_rate = None, None, None |
| else: |
| relative_error, elapsed_time, avg_rate = get_results( |
| os.path.join(working_folder, f'output_{test_run_id}.txt') |
| ) |
| with open(os.path.join(working_folder, 'final_result.txt'), 'w') as f: |
| f.write('best_idx,relative_error,elapsed_time,avg_rate\n') |
| f.write(f'{best_idx},{relative_error},{elapsed_time},{avg_rate}\n') |
|
|