omniopt2 7093__py3-none-any.whl → 7098__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- .omniopt.py +184 -215
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.omniopt.py +184 -215
- {omniopt2-7093.dist-info → omniopt2-7098.dist-info}/METADATA +1 -1
- {omniopt2-7093.dist-info → omniopt2-7098.dist-info}/RECORD +35 -35
- omniopt2.egg-info/PKG-INFO +1 -1
- pyproject.toml +1 -1
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.colorfunctions.sh +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.general.sh +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.helpers.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.omniopt_plot_cpu_ram_usage.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.omniopt_plot_general.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.omniopt_plot_gpu_usage.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.omniopt_plot_kde.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.omniopt_plot_scatter.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.omniopt_plot_scatter_generation_method.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.omniopt_plot_scatter_hex.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.omniopt_plot_time_and_exit_code.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.omniopt_plot_trial_index_result.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.omniopt_plot_worker.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.random_generator.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.shellscript_functions +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/.tpe.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/LICENSE +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/apt-dependencies.txt +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/omniopt +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/omniopt_docker +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/omniopt_evaluate +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/omniopt_plot +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/omniopt_share +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/requirements.txt +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/setup.py +0 -0
- {omniopt2-7093.data → omniopt2-7098.data}/data/bin/test_requirements.txt +0 -0
- {omniopt2-7093.dist-info → omniopt2-7098.dist-info}/WHEEL +0 -0
- {omniopt2-7093.dist-info → omniopt2-7098.dist-info}/licenses/LICENSE +0 -0
- {omniopt2-7093.dist-info → omniopt2-7098.dist-info}/top_level.txt +0 -0
.omniopt.py
CHANGED
@@ -565,6 +565,7 @@ class ConfigLoader:
|
|
565
565
|
verbose_break_run_search_table: bool
|
566
566
|
send_anonymized_usage_stats: bool
|
567
567
|
max_failed_jobs: Optional[int]
|
568
|
+
max_abandoned_retrial: int
|
568
569
|
show_ram_every_n_seconds: int
|
569
570
|
config_toml: Optional[str]
|
570
571
|
config_json: Optional[str]
|
@@ -653,6 +654,7 @@ class ConfigLoader:
|
|
653
654
|
optional.add_argument('--calculate_pareto_front_of_job', help='This can be used to calculate a pareto-front for a multi-objective job that previously has results, but has been cancelled, and has no pareto-front (yet)', type=str, nargs='+', default=[])
|
654
655
|
optional.add_argument('--show_generate_time_table', help='Generate a table at the end, showing how much time was spent trying to generate new points', action='store_true', default=False)
|
655
656
|
optional.add_argument('--force_choice_for_ranges', help='Force float ranges to be converted to choice', action='store_true', default=False)
|
657
|
+
optional.add_argument('--max_abandoned_retrial', help='Maximum number retrials to get when a job is abandoned post-generation', default=20, type=int)
|
656
658
|
|
657
659
|
speed.add_argument('--dont_warm_start_refitting', help='Do not keep Model weights, thus, refit for every generator (may be more accurate, but slower)', action='store_true', default=False)
|
658
660
|
speed.add_argument('--refit_on_cv', help='Refit on Cross-Validation (helps in accuracy, but makes generating new points slower)', action='store_true', default=False)
|
@@ -794,9 +796,13 @@ if args.seed is not None:
|
|
794
796
|
|
795
797
|
set_rng_seed(args.seed)
|
796
798
|
|
799
|
+
@beartype
|
800
|
+
def _fatal_error(message: str, code: int) -> None:
|
801
|
+
print_red(message)
|
802
|
+
my_exit(code)
|
803
|
+
|
797
804
|
if args.max_eval is None and args.generation_strategy is None and args.continue_previous_job is None and (not args.calculate_pareto_front_of_job or len(args.calculate_pareto_front_of_job) == 0):
|
798
|
-
|
799
|
-
my_exit(104)
|
805
|
+
_fatal_error("Either --max_eval or --generation_strategy must be set.", 104)
|
800
806
|
|
801
807
|
arg_result_names = []
|
802
808
|
arg_result_min_or_max = []
|
@@ -1273,8 +1279,7 @@ class ExternalProgramGenerationNode(ExternalGenerationNode):
|
|
1273
1279
|
if param_type == ParameterType.STRING:
|
1274
1280
|
return "STRING"
|
1275
1281
|
|
1276
|
-
|
1277
|
-
my_exit(33)
|
1282
|
+
_fatal_error(f"Unknown data type {param_type}", 33)
|
1278
1283
|
|
1279
1284
|
return ""
|
1280
1285
|
|
@@ -1303,8 +1308,7 @@ class ExternalProgramGenerationNode(ExternalGenerationNode):
|
|
1303
1308
|
"values": param.values
|
1304
1309
|
}
|
1305
1310
|
else:
|
1306
|
-
|
1307
|
-
my_exit(15)
|
1311
|
+
_fatal_error(f"Unknown parameter type: {param}", 15)
|
1308
1312
|
|
1309
1313
|
return serialized
|
1310
1314
|
|
@@ -1583,8 +1587,7 @@ if isinstance(args.num_parallel_jobs, int) or helpers.looks_like_int(args.num_pa
|
|
1583
1587
|
num_parallel_jobs = int(args.num_parallel_jobs)
|
1584
1588
|
|
1585
1589
|
if num_parallel_jobs <= 0:
|
1586
|
-
|
1587
|
-
my_exit(106)
|
1590
|
+
_fatal_error(f"--num_parallel_jobs must be 1 or larger, is {num_parallel_jobs}", 106)
|
1588
1591
|
|
1589
1592
|
class SearchSpaceExhausted (Exception):
|
1590
1593
|
pass
|
@@ -1836,11 +1839,9 @@ def log_nr_of_workers() -> None:
|
|
1836
1839
|
with open(logfile_nr_workers, mode='a+', encoding="utf-8") as f:
|
1837
1840
|
f.write(str(nr_current_workers) + "\n")
|
1838
1841
|
except FileNotFoundError:
|
1839
|
-
|
1840
|
-
my_exit(99)
|
1842
|
+
_fatal_error(f"It seems like the folder for writing {logfile_nr_workers} was deleted during the run. Cannot continue.", 99)
|
1841
1843
|
except OSError as e:
|
1842
|
-
|
1843
|
-
my_exit(199)
|
1844
|
+
_fatal_error(f"Tried writing log_nr_of_workers to file {logfile_nr_workers}, but failed with error: {e}. This may mean that the file system you are running on is instable. OmniOpt2 probably cannot do anything about it.", 199)
|
1844
1845
|
|
1845
1846
|
return None
|
1846
1847
|
|
@@ -2015,12 +2016,10 @@ else:
|
|
2015
2016
|
if os.path.exists(prev_job_file):
|
2016
2017
|
global_vars["joined_run_program"] = get_file_as_string(prev_job_file)
|
2017
2018
|
else:
|
2018
|
-
|
2019
|
-
my_exit(44)
|
2019
|
+
_fatal_error(f"The previous job file {prev_job_file} could not be found. You may forgot to add the run number at the end.", 44)
|
2020
2020
|
|
2021
2021
|
if not args.tests and len(global_vars["joined_run_program"]) == 0 and not args.calculate_pareto_front_of_job:
|
2022
|
-
|
2023
|
-
my_exit(19)
|
2022
|
+
_fatal_error("--run_program was empty", 19)
|
2024
2023
|
|
2025
2024
|
global_vars["experiment_name"] = args.experiment_name
|
2026
2025
|
|
@@ -2029,20 +2028,17 @@ def load_global_vars(_file: str) -> None:
|
|
2029
2028
|
global global_vars
|
2030
2029
|
|
2031
2030
|
if not os.path.exists(_file):
|
2032
|
-
|
2033
|
-
my_exit(44)
|
2031
|
+
_fatal_error(f"You've tried to continue a non-existing job: {_file}", 44)
|
2034
2032
|
try:
|
2035
2033
|
with open(_file, encoding="utf-8") as f:
|
2036
2034
|
global_vars = json.load(f)
|
2037
2035
|
except Exception as e:
|
2038
|
-
|
2039
|
-
my_exit(44)
|
2036
|
+
_fatal_error(f"Error while loading old global_vars: {e}, trying to load {_file}", 44)
|
2040
2037
|
|
2041
2038
|
@beartype
|
2042
2039
|
def load_or_exit(filepath: str, error_msg: str, exit_code: int) -> None:
|
2043
2040
|
if not os.path.exists(filepath):
|
2044
|
-
|
2045
|
-
my_exit(exit_code)
|
2041
|
+
_fatal_error(error_msg, exit_code)
|
2046
2042
|
|
2047
2043
|
@beartype
|
2048
2044
|
def get_file_content_or_exit(filepath: str, error_msg: str, exit_code: int) -> str:
|
@@ -2052,8 +2048,7 @@ def get_file_content_or_exit(filepath: str, error_msg: str, exit_code: int) -> s
|
|
2052
2048
|
@beartype
|
2053
2049
|
def check_param_or_exit(param: Any, error_msg: str, exit_code: int) -> None:
|
2054
2050
|
if param is None:
|
2055
|
-
|
2056
|
-
my_exit(exit_code)
|
2051
|
+
_fatal_error(error_msg, exit_code)
|
2057
2052
|
|
2058
2053
|
@beartype
|
2059
2054
|
def check_continue_previous_job(continue_previous_job: Optional[str]) -> dict:
|
@@ -2103,8 +2098,7 @@ def load_time_or_exit(_args: Any) -> None:
|
|
2103
2098
|
print_yellow(f"Time-setting: The contents of {time_file} do not contain a single number")
|
2104
2099
|
else:
|
2105
2100
|
if len(args.calculate_pareto_front_of_job) == 0:
|
2106
|
-
|
2107
|
-
my_exit(19)
|
2101
|
+
_fatal_error("Missing --time parameter. Cannot continue.", 19)
|
2108
2102
|
|
2109
2103
|
@beartype
|
2110
2104
|
def load_mem_gb_or_exit(_args: Any) -> Optional[int]:
|
@@ -2122,8 +2116,7 @@ def load_mem_gb_or_exit(_args: Any) -> Optional[int]:
|
|
2122
2116
|
print_yellow(f"mem_gb-setting: The contents of {mem_gb_file} do not contain a single number")
|
2123
2117
|
return None
|
2124
2118
|
|
2125
|
-
|
2126
|
-
my_exit(19)
|
2119
|
+
_fatal_error("--mem_gb needs to be set", 19)
|
2127
2120
|
|
2128
2121
|
return None
|
2129
2122
|
|
@@ -2145,8 +2138,7 @@ def load_max_eval_or_exit(_args: Any) -> None:
|
|
2145
2138
|
if _args.max_eval:
|
2146
2139
|
set_max_eval(_args.max_eval)
|
2147
2140
|
if _args.max_eval <= 0:
|
2148
|
-
|
2149
|
-
my_exit(19)
|
2141
|
+
_fatal_error("--max_eval must be larger than 0", 19)
|
2150
2142
|
elif _args.continue_previous_job:
|
2151
2143
|
max_eval_file = f"{_args.continue_previous_job}/state_files/max_eval"
|
2152
2144
|
max_eval_content = get_file_content_or_exit(max_eval_file, f"neither --max_eval nor file {max_eval_file} found", 19)
|
@@ -2285,8 +2277,7 @@ if not SYSTEM_HAS_SBATCH:
|
|
2285
2277
|
num_parallel_jobs = 1
|
2286
2278
|
|
2287
2279
|
if SYSTEM_HAS_SBATCH and not args.force_local_execution and args.raw_samples < args.num_parallel_jobs:
|
2288
|
-
|
2289
|
-
my_exit(48)
|
2280
|
+
_fatal_error(f"Has --raw_samples={args.raw_samples}, but --num_parallel_jobs={args.num_parallel_jobs}. Cannot continue, since --raw_samples must be larger or equal to --num_parallel_jobs.", 48)
|
2290
2281
|
|
2291
2282
|
@beartype
|
2292
2283
|
def save_global_vars() -> None:
|
@@ -2426,14 +2417,12 @@ def get_bounds(this_args: Union[str, list], j: int) -> Tuple[float, float]:
|
|
2426
2417
|
try:
|
2427
2418
|
lower_bound = float(this_args[j + 2])
|
2428
2419
|
except Exception:
|
2429
|
-
|
2430
|
-
my_exit(181)
|
2420
|
+
_fatal_error(f"\n{this_args[j + 2]} is not a number", 181)
|
2431
2421
|
|
2432
2422
|
try:
|
2433
2423
|
upper_bound = float(this_args[j + 3])
|
2434
2424
|
except Exception:
|
2435
|
-
|
2436
|
-
my_exit(181)
|
2425
|
+
_fatal_error(f"\n{this_args[j + 3]} is not a number", 181)
|
2437
2426
|
|
2438
2427
|
return lower_bound, upper_bound
|
2439
2428
|
|
@@ -2482,8 +2471,7 @@ def create_range_param(name: str, lower_bound: Union[float, int], upper_bound: U
|
|
2482
2471
|
@beartype
|
2483
2472
|
def handle_grid_search(name: Union[list, str], lower_bound: Union[float, int], upper_bound: Union[float, int], value_type: str) -> dict:
|
2484
2473
|
if lower_bound is None or upper_bound is None:
|
2485
|
-
|
2486
|
-
my_exit(91)
|
2474
|
+
_fatal_error("handle_grid_search: lower_bound or upper_bound is None", 91)
|
2487
2475
|
|
2488
2476
|
return {}
|
2489
2477
|
|
@@ -2587,8 +2575,7 @@ def validate_value_type(value_type: str) -> None:
|
|
2587
2575
|
@beartype
|
2588
2576
|
def parse_fixed_param(classic_params: list, params: list, j: int, this_args: Union[str, list], name: Union[list, str], search_space_reduction_warning: bool) -> Tuple[int, list, list, bool]:
|
2589
2577
|
if len(this_args) != 3:
|
2590
|
-
|
2591
|
-
my_exit(181)
|
2578
|
+
_fatal_error("⚠ --parameter for type fixed must have 3 parameters: <NAME> fixed <VALUE>", 181)
|
2592
2579
|
|
2593
2580
|
value = this_args[j + 2]
|
2594
2581
|
|
@@ -2611,8 +2598,7 @@ def parse_fixed_param(classic_params: list, params: list, j: int, this_args: Uni
|
|
2611
2598
|
@beartype
|
2612
2599
|
def parse_choice_param(classic_params: list, params: list, j: int, this_args: Union[str, list], name: Union[list, str], search_space_reduction_warning: bool) -> Tuple[int, list, list, bool]:
|
2613
2600
|
if len(this_args) != 3:
|
2614
|
-
|
2615
|
-
my_exit(181)
|
2601
|
+
_fatal_error("⚠ --parameter for type choice must have 3 parameters: <NAME> choice <VALUE,VALUE,VALUE,...>", 181)
|
2616
2602
|
|
2617
2603
|
values = re.split(r'\s*,\s*', str(this_args[j + 2]))
|
2618
2604
|
|
@@ -2658,12 +2644,10 @@ def parse_experiment_parameters() -> Tuple[list, list]:
|
|
2658
2644
|
name = this_args[j]
|
2659
2645
|
|
2660
2646
|
if name in invalid_names:
|
2661
|
-
|
2662
|
-
my_exit(181)
|
2647
|
+
_fatal_error(f"\n⚠ Name for argument no. {j} is invalid: {name}. Invalid names are: {', '.join(invalid_names)}", 181)
|
2663
2648
|
|
2664
2649
|
if name in param_names:
|
2665
|
-
|
2666
|
-
my_exit(181)
|
2650
|
+
_fatal_error(f"\n⚠ Parameter name '{name}' is not unique. Names for parameters must be unique!", 181)
|
2667
2651
|
|
2668
2652
|
param_names.append(name)
|
2669
2653
|
global_param_names.append(name)
|
@@ -2671,8 +2655,7 @@ def parse_experiment_parameters() -> Tuple[list, list]:
|
|
2671
2655
|
try:
|
2672
2656
|
param_type = this_args[j + 1]
|
2673
2657
|
except Exception:
|
2674
|
-
|
2675
|
-
my_exit(181)
|
2658
|
+
_fatal_error("Not enough arguments for --parameter", 181)
|
2676
2659
|
|
2677
2660
|
param_parsers = {
|
2678
2661
|
"range": parse_range_param,
|
@@ -2681,13 +2664,11 @@ def parse_experiment_parameters() -> Tuple[list, list]:
|
|
2681
2664
|
}
|
2682
2665
|
|
2683
2666
|
if param_type not in param_parsers:
|
2684
|
-
|
2685
|
-
my_exit(181)
|
2667
|
+
_fatal_error(f"⚠ Parameter type '{param_type}' not yet implemented.", 181)
|
2686
2668
|
|
2687
2669
|
if param_type not in valid_types:
|
2688
2670
|
valid_types_string = ', '.join(valid_types)
|
2689
|
-
|
2690
|
-
my_exit(181)
|
2671
|
+
_fatal_error(f"\n⚠ Invalid type {param_type}, valid types are: {valid_types_string}", 181)
|
2691
2672
|
|
2692
2673
|
j, params, classic_params, search_space_reduction_warning = param_parsers[param_type](classic_params, params, j, this_args, name, search_space_reduction_warning)
|
2693
2674
|
|
@@ -2704,31 +2685,26 @@ def parse_experiment_parameters() -> Tuple[list, list]:
|
|
2704
2685
|
@beartype
|
2705
2686
|
def check_factorial_range() -> None:
|
2706
2687
|
if args.model and args.model == "FACTORIAL":
|
2707
|
-
|
2708
|
-
my_exit(181)
|
2688
|
+
_fatal_error("\n⚠ --model FACTORIAL cannot be used with range parameter", 181)
|
2709
2689
|
|
2710
2690
|
@beartype
|
2711
2691
|
def check_if_range_types_are_invalid(value_type: str, valid_value_types: list) -> None:
|
2712
2692
|
if value_type not in valid_value_types:
|
2713
2693
|
valid_value_types_string = ", ".join(valid_value_types)
|
2714
|
-
|
2715
|
-
my_exit(181)
|
2694
|
+
_fatal_error(f"⚠ {value_type} is not a valid value type. Valid types for range are: {valid_value_types_string}", 181)
|
2716
2695
|
|
2717
2696
|
@beartype
|
2718
2697
|
def check_range_params_length(this_args: Union[str, list]) -> None:
|
2719
2698
|
if len(this_args) != 5 and len(this_args) != 4 and len(this_args) != 6:
|
2720
|
-
|
2721
|
-
my_exit(181)
|
2699
|
+
_fatal_error("\n⚠ --parameter for type range must have 4 (or 5, the last one being optional and float by default, or 6, while the last one is true or false) parameters: <NAME> range <START> <END> (<TYPE (int or float)>, <log_scale: bool>)", 181)
|
2722
2700
|
|
2723
2701
|
@beartype
|
2724
2702
|
def die_181_or_91_if_lower_and_upper_bound_equal_zero(lower_bound: Union[int, float], upper_bound: Union[int, float]) -> None:
|
2725
2703
|
if upper_bound is None or lower_bound is None:
|
2726
|
-
|
2727
|
-
my_exit(91)
|
2704
|
+
_fatal_error("die_181_or_91_if_lower_and_upper_bound_equal_zero: upper_bound or lower_bound is None. Cannot continue.", 91)
|
2728
2705
|
if upper_bound == lower_bound:
|
2729
2706
|
if lower_bound == 0:
|
2730
|
-
|
2731
|
-
my_exit(181)
|
2707
|
+
_fatal_error(f"⚠ Lower bound and upper bound are equal: {lower_bound}, cannot automatically fix this, because they -0 = +0 (usually a quickfix would be to set lower_bound = -upper_bound)", 181)
|
2732
2708
|
print_red(f"⚠ Lower bound and upper bound are equal: {lower_bound}, setting lower_bound = -upper_bound")
|
2733
2709
|
if upper_bound is not None:
|
2734
2710
|
lower_bound = -upper_bound
|
@@ -3170,8 +3146,7 @@ def calculate_signed_weighted_euclidean_distance(_args: Union[dict, List[float]]
|
|
3170
3146
|
pattern = r'^\s*-?\d+(\.\d+)?\s*(,\s*-?\d+(\.\d+)?\s*)*$'
|
3171
3147
|
|
3172
3148
|
if not re.fullmatch(pattern, weights_string):
|
3173
|
-
|
3174
|
-
my_exit(32)
|
3149
|
+
_fatal_error(f"String '{weights_string}' does not match pattern {pattern}", 32)
|
3175
3150
|
|
3176
3151
|
weights = [float(w.strip()) for w in weights_string.split(",") if w.strip()]
|
3177
3152
|
|
@@ -4214,8 +4189,7 @@ def abandon_job(job: Job, trial_index: int) -> bool:
|
|
4214
4189
|
print_debug(f"abandon_job: removing job {job}, trial_index: {trial_index}")
|
4215
4190
|
global_vars["jobs"].remove((job, trial_index))
|
4216
4191
|
else:
|
4217
|
-
|
4218
|
-
my_exit(9)
|
4192
|
+
_fatal_error("ax_client could not be found", 9)
|
4219
4193
|
except Exception as e:
|
4220
4194
|
print(f"ERROR in line {get_line_info()}: {e}")
|
4221
4195
|
print_debug(f"ERROR in line {get_line_info()}: {e}")
|
@@ -4320,8 +4294,7 @@ def save_checkpoint(trial_nr: int = 0, eee: Union[None, str, Exception] = None)
|
|
4320
4294
|
if ax_client:
|
4321
4295
|
ax_client.save_to_json_file(filepath=checkpoint_filepath)
|
4322
4296
|
else:
|
4323
|
-
|
4324
|
-
my_exit(9)
|
4297
|
+
_fatal_error("Something went wrong using the ax_client", 9)
|
4325
4298
|
except Exception as e:
|
4326
4299
|
save_checkpoint(trial_nr + 1, e)
|
4327
4300
|
|
@@ -4417,8 +4390,7 @@ def get_ax_param_representation(data: dict) -> dict:
|
|
4417
4390
|
|
4418
4391
|
print("data:")
|
4419
4392
|
pprint(data)
|
4420
|
-
|
4421
|
-
my_exit(19)
|
4393
|
+
_fatal_error(f"Unknown data range {data['type']}", 19)
|
4422
4394
|
|
4423
4395
|
return {}
|
4424
4396
|
|
@@ -4448,8 +4420,7 @@ def set_torch_device_to_experiment_args(experiment_args: Union[None, dict]) -> T
|
|
4448
4420
|
if experiment_args:
|
4449
4421
|
experiment_args["choose_generation_strategy_kwargs"]["torch_device"] = torch_device
|
4450
4422
|
else:
|
4451
|
-
|
4452
|
-
my_exit(90)
|
4423
|
+
_fatal_error("experiment_args could not be created.", 90)
|
4453
4424
|
|
4454
4425
|
if experiment_args:
|
4455
4426
|
return experiment_args, gpu_string, gpu_color
|
@@ -4459,8 +4430,7 @@ def set_torch_device_to_experiment_args(experiment_args: Union[None, dict]) -> T
|
|
4459
4430
|
@beartype
|
4460
4431
|
def die_with_47_if_file_doesnt_exists(_file: str) -> None:
|
4461
4432
|
if not os.path.exists(_file):
|
4462
|
-
|
4463
|
-
my_exit(47)
|
4433
|
+
_fatal_error(f"Cannot find {_file}", 47)
|
4464
4434
|
|
4465
4435
|
@beartype
|
4466
4436
|
def copy_state_files_from_previous_job(continue_previous_job: str) -> None:
|
@@ -4740,8 +4710,7 @@ def set_experiment_constraints(experiment_constraints: Optional[list], experimen
|
|
4740
4710
|
if equation:
|
4741
4711
|
experiment_args["parameter_constraints"].append(constraints_string)
|
4742
4712
|
else:
|
4743
|
-
|
4744
|
-
my_exit(19)
|
4713
|
+
_fatal_error(f"Experiment constraint '{constraints_string}' is invalid. Cannot continue.", 19)
|
4745
4714
|
|
4746
4715
|
file_path = os.path.join(get_current_run_folder(), "state_files", "constraints")
|
4747
4716
|
|
@@ -4836,8 +4805,7 @@ def get_experiment_parameters(_params: list) -> Tuple[AxClient, Union[list, dict
|
|
4836
4805
|
global ax_client
|
4837
4806
|
|
4838
4807
|
if not ax_client:
|
4839
|
-
|
4840
|
-
my_exit(9)
|
4808
|
+
_fatal_error("Something went wrong with the ax_client", 9)
|
4841
4809
|
|
4842
4810
|
gpu_string = ""
|
4843
4811
|
gpu_color = "green"
|
@@ -4884,8 +4852,7 @@ def get_experiment_parameters(_params: list) -> Tuple[AxClient, Union[list, dict
|
|
4884
4852
|
json.dump(experiment_parameters, outfile)
|
4885
4853
|
|
4886
4854
|
if not os.path.exists(checkpoint_filepath):
|
4887
|
-
|
4888
|
-
my_exit(47)
|
4855
|
+
_fatal_error(f"{checkpoint_filepath} not found. Cannot continue_previous_job without.", 47)
|
4889
4856
|
|
4890
4857
|
with open(f'{get_current_run_folder()}/checkpoint_load_source', mode='w', encoding="utf-8") as f:
|
4891
4858
|
print(f"Continuation from checkpoint {continue_previous_job}", file=f)
|
@@ -4923,17 +4890,13 @@ def get_experiment_parameters(_params: list) -> Tuple[AxClient, Union[list, dict
|
|
4923
4890
|
new_metrics = [Metric(k) for k in arg_result_names if k not in ax_client.metric_names]
|
4924
4891
|
ax_client.experiment.add_tracking_metrics(new_metrics)
|
4925
4892
|
except AssertionError as error:
|
4926
|
-
|
4927
|
-
my_exit(102)
|
4893
|
+
_fatal_error(f"An error has occurred while creating the experiment (0): {error}. This can happen when you have invalid parameter constraints.", 102)
|
4928
4894
|
except ValueError as error:
|
4929
|
-
|
4930
|
-
my_exit(49)
|
4895
|
+
_fatal_error(f"An error has occurred while creating the experiment (1): {error}", 49)
|
4931
4896
|
except TypeError as error:
|
4932
|
-
|
4933
|
-
my_exit(49)
|
4897
|
+
_fatal_error(f"An error has occurred while creating the experiment (2): {error}. This is probably a bug in OmniOpt2.", 49)
|
4934
4898
|
except ax.exceptions.core.UserInputError as error:
|
4935
|
-
|
4936
|
-
my_exit(49)
|
4899
|
+
_fatal_error(f"An error occurred while creating the experiment (3): {error}", 49)
|
4937
4900
|
|
4938
4901
|
return ax_client, experiment_parameters, experiment_args, gpu_string, gpu_color
|
4939
4902
|
|
@@ -5001,8 +4964,7 @@ def parse_single_experiment_parameter_table(classic_params: Optional[Union[list,
|
|
5001
4964
|
|
5002
4965
|
rows.append([str(param["name"]), get_type_short(_type), "", "", ", ".join(values), "", ""])
|
5003
4966
|
else:
|
5004
|
-
|
5005
|
-
my_exit(15)
|
4967
|
+
_fatal_error(f"Type {_type} is not yet implemented in the overview table.", 15)
|
5006
4968
|
|
5007
4969
|
k = k + 1
|
5008
4970
|
|
@@ -5072,8 +5034,7 @@ def print_ax_parameter_constraints_table(experiment_args: dict) -> None:
|
|
5072
5034
|
@beartype
|
5073
5035
|
def print_result_names_overview_table() -> None:
|
5074
5036
|
if not ax_client:
|
5075
|
-
|
5076
|
-
my_exit(101)
|
5037
|
+
_fatal_error("Tried to access ax_client in print_result_names_overview_table, but it failed, because the ax_client was not defined.", 101)
|
5077
5038
|
|
5078
5039
|
return None
|
5079
5040
|
|
@@ -5703,8 +5664,7 @@ def insert_job_into_ax_client(arm_params: dict, result: dict, new_job_type: str
|
|
5703
5664
|
done_converting = False
|
5704
5665
|
|
5705
5666
|
if ax_client is None or not ax_client:
|
5706
|
-
|
5707
|
-
my_exit(101)
|
5667
|
+
_fatal_error("insert_job_into_ax_client: ax_client was not defined where it should have been", 101)
|
5708
5668
|
|
5709
5669
|
while not done_converting:
|
5710
5670
|
try:
|
@@ -6100,8 +6060,7 @@ def mark_trial_as_failed(trial_index: int, _trial: Any) -> None:
|
|
6100
6060
|
print_debug(f"Marking trial {_trial} as failed")
|
6101
6061
|
try:
|
6102
6062
|
if not ax_client:
|
6103
|
-
|
6104
|
-
my_exit(101)
|
6063
|
+
_fatal_error("mark_trial_as_failed: ax_client is not defined", 101)
|
6105
6064
|
|
6106
6065
|
return None
|
6107
6066
|
|
@@ -6135,8 +6094,7 @@ def _finish_job_core_helper_complete_trial(trial_index: int, raw_result: dict) -
|
|
6135
6094
|
ax_client.update_trial_data(trial_index=trial_index, raw_data=raw_result)
|
6136
6095
|
print_debug(f"Completing trial: {trial_index} with result: {raw_result} after failure... Done!")
|
6137
6096
|
else:
|
6138
|
-
|
6139
|
-
my_exit(234)
|
6097
|
+
_fatal_error(f"Error completing trial: {e}", 234)
|
6140
6098
|
|
6141
6099
|
@beartype
|
6142
6100
|
def _finish_job_core_helper_mark_success(_trial: ax.core.trial.Trial, result: Union[float, int, tuple]) -> None:
|
@@ -6195,8 +6153,7 @@ def finish_job_core(job: Any, trial_index: int, this_jobs_finished: int) -> int:
|
|
6195
6153
|
else:
|
6196
6154
|
_finish_job_core_helper_mark_failure(job, trial_index, _trial)
|
6197
6155
|
else:
|
6198
|
-
|
6199
|
-
my_exit(9)
|
6156
|
+
_fatal_error("ax_client could not be found or used", 9)
|
6200
6157
|
|
6201
6158
|
print_debug(f"finish_job_core: removing job {job}, trial_index: {trial_index}")
|
6202
6159
|
global_vars["jobs"].remove((job, trial_index))
|
@@ -6269,8 +6226,8 @@ def finish_previous_jobs(new_msgs: List[str]) -> None:
|
|
6269
6226
|
global JOBS_FINISHED
|
6270
6227
|
|
6271
6228
|
if not ax_client:
|
6272
|
-
|
6273
|
-
|
6229
|
+
_fatal_error("ax_client failed", 101)
|
6230
|
+
|
6274
6231
|
return None
|
6275
6232
|
|
6276
6233
|
this_jobs_finished = 0
|
@@ -6425,8 +6382,7 @@ def orchestrator_start_trial(params_from_out_file: Union[dict, str], trial_index
|
|
6425
6382
|
print_debug(f"orchestrator_start_trial: appending job {new_job} to global_vars['jobs'], trial_index: {trial_index}")
|
6426
6383
|
global_vars["jobs"].append((new_job, trial_index))
|
6427
6384
|
else:
|
6428
|
-
|
6429
|
-
my_exit(9)
|
6385
|
+
_fatal_error("executor or ax_client could not be found properly", 9)
|
6430
6386
|
|
6431
6387
|
@beartype
|
6432
6388
|
def handle_exclude_node(stdout_path: str, hostname_from_out_file: Union[None, str]) -> None:
|
@@ -6496,8 +6452,7 @@ def _orchestrate(stdout_path: str, trial_index: int) -> None:
|
|
6496
6452
|
if handler:
|
6497
6453
|
handler()
|
6498
6454
|
else:
|
6499
|
-
|
6500
|
-
my_exit(210)
|
6455
|
+
_fatal_error(f"Orchestrator: {behav} not yet implemented!", 210)
|
6501
6456
|
|
6502
6457
|
@beartype
|
6503
6458
|
def write_continue_run_uuid_to_file() -> None:
|
@@ -6537,14 +6492,12 @@ def execute_evaluation(_params: list) -> Optional[int]:
|
|
6537
6492
|
print_debug(f"execute_evaluation({_params})")
|
6538
6493
|
trial_index, parameters, trial_counter, next_nr_steps, phase = _params
|
6539
6494
|
if not ax_client:
|
6540
|
-
|
6541
|
-
my_exit(9)
|
6495
|
+
_fatal_error("Failed to get ax_client", 9)
|
6542
6496
|
|
6543
6497
|
return None
|
6544
6498
|
|
6545
6499
|
if not executor:
|
6546
|
-
|
6547
|
-
my_exit(9)
|
6500
|
+
_fatal_error("executor could not be found", 9)
|
6548
6501
|
|
6549
6502
|
return None
|
6550
6503
|
|
@@ -6608,8 +6561,7 @@ def exclude_defective_nodes() -> None:
|
|
6608
6561
|
if executor:
|
6609
6562
|
executor.update_parameters(exclude=excluded_string)
|
6610
6563
|
else:
|
6611
|
-
|
6612
|
-
my_exit(9)
|
6564
|
+
_fatal_error("executor could not be found", 9)
|
6613
6565
|
|
6614
6566
|
@beartype
|
6615
6567
|
def handle_failed_job(error: Union[None, Exception, str], trial_index: int, new_job: Optional[Job]) -> None:
|
@@ -6638,8 +6590,7 @@ def cancel_failed_job(trial_index: int, new_job: Job) -> None:
|
|
6638
6590
|
if ax_client:
|
6639
6591
|
ax_client.log_trial_failure(trial_index=trial_index)
|
6640
6592
|
else:
|
6641
|
-
|
6642
|
-
my_exit(101)
|
6593
|
+
_fatal_error("ax_client not defined", 101)
|
6643
6594
|
except Exception as e:
|
6644
6595
|
print(f"ERROR in line {get_line_info()}: {e}")
|
6645
6596
|
new_job.cancel()
|
@@ -6807,14 +6758,11 @@ def has_no_post_generation_constraints_or_matches_constraints(_post_generation_c
|
|
6807
6758
|
@beartype
|
6808
6759
|
def die_101_if_no_ax_client_or_experiment_or_gs() -> None:
|
6809
6760
|
if ax_client is None:
|
6810
|
-
|
6811
|
-
my_exit(101)
|
6761
|
+
_fatal_error("Error: ax_client is not defined", 101)
|
6812
6762
|
elif ax_client.experiment is None:
|
6813
|
-
|
6814
|
-
my_exit(101)
|
6763
|
+
_fatal_error("Error: ax_client.experiment is not defined", 101)
|
6815
6764
|
elif global_gs is None:
|
6816
|
-
|
6817
|
-
my_exit(101)
|
6765
|
+
_fatal_error("Error: global_gs is not defined", 101)
|
6818
6766
|
|
6819
6767
|
@beartype
|
6820
6768
|
def get_batched_arms(nr_of_jobs_to_get: int) -> list:
|
@@ -6822,8 +6770,7 @@ def get_batched_arms(nr_of_jobs_to_get: int) -> list:
|
|
6822
6770
|
attempts = 0
|
6823
6771
|
|
6824
6772
|
if global_gs is None:
|
6825
|
-
|
6826
|
-
my_exit(107)
|
6773
|
+
_fatal_error("Global generation strategy is not set. This is a bug in OmniOpt2.", 107)
|
6827
6774
|
|
6828
6775
|
return []
|
6829
6776
|
|
@@ -6855,101 +6802,140 @@ def get_batched_arms(nr_of_jobs_to_get: int) -> list:
|
|
6855
6802
|
|
6856
6803
|
return batched_arms
|
6857
6804
|
|
6858
|
-
@disable_logs
|
6859
6805
|
@beartype
|
6860
6806
|
def _fetch_next_trials(nr_of_jobs_to_get: int, recursion: bool = False) -> Optional[Tuple[Dict[int, Any], bool]]:
|
6861
|
-
|
6807
|
+
die_101_if_no_ax_client_or_experiment_or_gs()
|
6862
6808
|
|
6863
6809
|
if not ax_client:
|
6864
|
-
|
6865
|
-
my_exit(9)
|
6810
|
+
_fatal_error("ax_client was not defined", 9)
|
6866
6811
|
|
6867
6812
|
if global_gs is None:
|
6868
|
-
|
6869
|
-
my_exit(107)
|
6813
|
+
_fatal_error("Global generation strategy is not set. This is a bug in OmniOpt2.", 107)
|
6870
6814
|
|
6871
|
-
|
6815
|
+
return _generate_trials(nr_of_jobs_to_get, recursion)
|
6872
6816
|
|
6873
|
-
|
6817
|
+
@beartype
|
6818
|
+
def _generate_trials(n: int, recursion: bool) -> Tuple[Dict[int, Any], bool]:
|
6819
|
+
global gotten_jobs
|
6874
6820
|
|
6821
|
+
trials_dict: Dict[int, Any] = {}
|
6875
6822
|
trial_durations: List[float] = []
|
6876
6823
|
|
6877
|
-
|
6824
|
+
start_time = time.time()
|
6825
|
+
cnt = 0
|
6826
|
+
retries = 0
|
6827
|
+
max_retries = args.max_abandoned_retrial
|
6878
6828
|
|
6879
6829
|
try:
|
6880
|
-
|
6830
|
+
while cnt < n and retries < max_retries:
|
6831
|
+
for arm in get_batched_arms(n - cnt):
|
6832
|
+
if cnt >= n:
|
6833
|
+
break
|
6881
6834
|
|
6882
|
-
|
6835
|
+
print_debug(f"Fetching trial {cnt + 1}/{n}...")
|
6836
|
+
progressbar_description([_get_trials_message(cnt + 1, n, trial_durations)])
|
6883
6837
|
|
6884
|
-
|
6838
|
+
try:
|
6839
|
+
result = _create_and_handle_trial(arm)
|
6840
|
+
if result is not None:
|
6841
|
+
trial_index, trial_duration, trial_successful = result
|
6885
6842
|
|
6886
|
-
|
6887
|
-
|
6888
|
-
|
6843
|
+
except TrialRejected as e:
|
6844
|
+
print_debug(f"Trial rejected: {e}")
|
6845
|
+
retries += 1
|
6846
|
+
continue
|
6889
6847
|
|
6890
|
-
|
6848
|
+
trial_durations.append(trial_duration)
|
6891
6849
|
|
6892
|
-
|
6850
|
+
if trial_successful:
|
6851
|
+
cnt += 1
|
6852
|
+
trials_dict[trial_index] = arm.parameters
|
6853
|
+
gotten_jobs += 1
|
6893
6854
|
|
6894
|
-
|
6895
|
-
generator_run = GeneratorRun(
|
6896
|
-
arms=[arm],
|
6897
|
-
generation_node_name=global_gs.current_node_name
|
6898
|
-
)
|
6855
|
+
return _finalize_generation(trials_dict, cnt, n, start_time)
|
6899
6856
|
|
6900
|
-
|
6901
|
-
|
6857
|
+
except Exception as e:
|
6858
|
+
return _handle_generation_failure(e, n, recursion)
|
6902
6859
|
|
6903
|
-
|
6904
|
-
|
6860
|
+
class TrialRejected(Exception):
|
6861
|
+
pass
|
6905
6862
|
|
6906
|
-
|
6907
|
-
|
6863
|
+
@beartype
|
6864
|
+
def _create_and_handle_trial(arm: Any) -> Optional[Tuple[int, float, bool]]:
|
6865
|
+
start = time.time()
|
6908
6866
|
|
6909
|
-
|
6867
|
+
if global_gs is None:
|
6868
|
+
_fatal_error("global_gs is not set", 107)
|
6910
6869
|
|
6911
|
-
|
6912
|
-
print_debug(f"Marking trial as abandoned since it doesn't fit a Post-Generation-constraint: {params}")
|
6913
|
-
trial.mark_abandoned()
|
6914
|
-
abandoned_trial_indices.append(trial_index)
|
6915
|
-
else:
|
6916
|
-
trial.mark_running(no_runner_required=True)
|
6870
|
+
return None
|
6917
6871
|
|
6918
|
-
|
6872
|
+
_current_node_name = global_gs.current_node_name
|
6919
6873
|
|
6920
|
-
|
6921
|
-
|
6874
|
+
trial_index = ax_client.experiment.num_trials
|
6875
|
+
generator_run = GeneratorRun(
|
6876
|
+
arms=[arm],
|
6877
|
+
generation_node_name=_current_node_name
|
6878
|
+
)
|
6922
6879
|
|
6923
|
-
|
6924
|
-
|
6880
|
+
trial = ax_client.experiment.new_trial(generator_run)
|
6881
|
+
params = arm.parameters
|
6925
6882
|
|
6926
|
-
|
6927
|
-
|
6928
|
-
|
6929
|
-
|
6883
|
+
if not has_no_post_generation_constraints_or_matches_constraints(post_generation_constraints, params):
|
6884
|
+
print_debug(f"Trial {trial_index} does not meet post-generation constraints. Marking abandoned.")
|
6885
|
+
trial.mark_abandoned()
|
6886
|
+
abandoned_trial_indices.append(trial_index)
|
6887
|
+
raise TrialRejected("Post-generation constraints not met.")
|
6930
6888
|
|
6931
|
-
|
6932
|
-
|
6933
|
-
|
6934
|
-
my_exit(242)
|
6935
|
-
except (ax.exceptions.core.SearchSpaceExhausted, ax.exceptions.generation_strategy.GenerationStrategyRepeatedPoints, ax.exceptions.generation_strategy.MaxParallelismReachedException) as e:
|
6936
|
-
if str(e) not in error_8_saved:
|
6937
|
-
if recursion is False and args.revert_to_random_when_seemingly_exhausted:
|
6938
|
-
print_yellow(f"\n⚠Error 8: {e} From now (done jobs: {count_done_jobs()}) on, random points will be generated.")
|
6939
|
-
else:
|
6940
|
-
print_red(f"\n⚠Error 8: {e}")
|
6889
|
+
trial.mark_running(no_runner_required=True)
|
6890
|
+
end = time.time()
|
6891
|
+
return trial_index, float(end - start), True
|
6941
6892
|
|
6942
|
-
|
6893
|
+
@beartype
|
6894
|
+
def _finalize_generation(trials_dict: Dict[int, Any], cnt: int, requested: int, start_time: float) -> Tuple[Dict[int, Any], bool]:
|
6895
|
+
total_time = time.time() - start_time
|
6943
6896
|
|
6944
|
-
|
6945
|
-
|
6897
|
+
log_gen_times.append(total_time)
|
6898
|
+
log_nr_gen_jobs.append(cnt)
|
6946
6899
|
|
6947
|
-
|
6900
|
+
avg_time_str = f"{total_time / cnt:.2f} s/job" if cnt else "n/a"
|
6901
|
+
progressbar_description([f"requested {requested} jobs, got {cnt}, {avg_time_str}"])
|
6902
|
+
|
6903
|
+
return trials_dict, False
|
6904
|
+
|
6905
|
+
@beartype
|
6906
|
+
def _handle_generation_failure(
|
6907
|
+
e: Exception,
|
6908
|
+
requested: int,
|
6909
|
+
recursion: bool
|
6910
|
+
) -> Tuple[Dict[int, Any], bool]:
|
6911
|
+
if isinstance(e, np.linalg.LinAlgError):
|
6912
|
+
_handle_linalg_error(e)
|
6913
|
+
my_exit(242)
|
6948
6914
|
|
6949
|
-
|
6915
|
+
elif isinstance(e, (
|
6916
|
+
ax.exceptions.core.SearchSpaceExhausted,
|
6917
|
+
ax.exceptions.generation_strategy.GenerationStrategyRepeatedPoints,
|
6918
|
+
ax.exceptions.generation_strategy.MaxParallelismReachedException
|
6919
|
+
)):
|
6920
|
+
msg = str(e)
|
6921
|
+
if msg not in error_8_saved:
|
6922
|
+
_print_exhaustion_warning(e, recursion)
|
6923
|
+
error_8_saved.append(msg)
|
6924
|
+
|
6925
|
+
if not recursion and args.revert_to_random_when_seemingly_exhausted:
|
6926
|
+
print_debug("Switching to random search strategy.")
|
6927
|
+
set_global_gs_to_random()
|
6928
|
+
return _fetch_next_trials(requested, True)
|
6950
6929
|
|
6951
6930
|
return {}, True
|
6952
6931
|
|
6932
|
+
@beartype
|
6933
|
+
def _print_exhaustion_warning(e: Exception, recursion: bool) -> None:
|
6934
|
+
if not recursion and args.revert_to_random_when_seemingly_exhausted:
|
6935
|
+
print_yellow(f"\n⚠Error 8: {e} From now (done jobs: {count_done_jobs()}) on, random points will be generated.")
|
6936
|
+
else:
|
6937
|
+
print_red(f"\n⚠Error 8: {e}")
|
6938
|
+
|
6953
6939
|
@beartype
|
6954
6940
|
def get_model_kwargs() -> dict:
|
6955
6941
|
if 'Cont_X_trans_Y_trans' in args.transforms:
|
@@ -7376,8 +7362,7 @@ def parse_generation_strategy_string(gen_strat_str: str) -> Tuple[list, int]:
|
|
7376
7362
|
matching_model = get_matching_model_name(model_name)
|
7377
7363
|
|
7378
7364
|
if matching_model in ["RANDOMFOREST", "EXTERNAL_GENERATOR"]:
|
7379
|
-
|
7380
|
-
my_exit(56)
|
7365
|
+
_fatal_error(f"Model {matching_model} is not valid for custom generation strategy.", 56)
|
7381
7366
|
|
7382
7367
|
if matching_model:
|
7383
7368
|
gen_strat_list.append({matching_model: nr})
|
@@ -7412,8 +7397,7 @@ def write_state_file(name: str, var: str) -> None:
|
|
7412
7397
|
file_path = f"{get_current_run_folder()}/state_files/{name}"
|
7413
7398
|
|
7414
7399
|
if os.path.isdir(file_path):
|
7415
|
-
|
7416
|
-
my_exit(246)
|
7400
|
+
_fatal_error(f"{file_path} is a dir. Must be a file.", 246)
|
7417
7401
|
|
7418
7402
|
makedirs(os.path.dirname(file_path))
|
7419
7403
|
|
@@ -7460,8 +7444,7 @@ def continue_not_supported_on_custom_generation_strategy() -> None:
|
|
7460
7444
|
generation_strategy_file = f"{args.continue_previous_job}/state_files/custom_generation_strategy"
|
7461
7445
|
|
7462
7446
|
if os.path.exists(generation_strategy_file):
|
7463
|
-
|
7464
|
-
my_exit(247)
|
7447
|
+
_fatal_error("Trying to continue a job which was started with --generation_strategy. This is currently not possible.", 247)
|
7465
7448
|
|
7466
7449
|
@beartype
|
7467
7450
|
def get_step_name(model_name: str, nr: int) -> str:
|
@@ -7503,8 +7486,7 @@ def get_torch_device_str() -> str:
|
|
7503
7486
|
def create_node(model_name: str, threshold: int, next_model_name: Optional[str]) -> Union[RandomForestGenerationNode, GenerationNode]:
|
7504
7487
|
if model_name == "RANDOMFOREST":
|
7505
7488
|
if len(arg_result_names) != 1:
|
7506
|
-
|
7507
|
-
my_exit(251)
|
7489
|
+
_fatal_error("Currently, RANDOMFOREST does not support Multi-Objective-Optimization", 251)
|
7508
7490
|
|
7509
7491
|
node = RandomForestGenerationNode(
|
7510
7492
|
num_samples=threshold,
|
@@ -7518,8 +7500,7 @@ def create_node(model_name: str, threshold: int, next_model_name: Optional[str])
|
|
7518
7500
|
|
7519
7501
|
if model_name == "TPE":
|
7520
7502
|
if len(arg_result_names) != 1:
|
7521
|
-
|
7522
|
-
my_exit(108)
|
7503
|
+
_fatal_error(f"Has {len(arg_result_names)} results. TPE currently only supports single-objective-optimization.", 108)
|
7523
7504
|
|
7524
7505
|
node = ExternalProgramGenerationNode(f"python3 {script_dir}/.tpe.py", "TPE")
|
7525
7506
|
|
@@ -7532,8 +7513,7 @@ def create_node(model_name: str, threshold: int, next_model_name: Optional[str])
|
|
7532
7513
|
|
7533
7514
|
if model_name == "EXTERNAL_GENERATOR":
|
7534
7515
|
if args.external_generator is None or args.external_generator == "":
|
7535
|
-
|
7536
|
-
my_exit(204)
|
7516
|
+
_fatal_error("--external_generator is missing. Cannot create points for EXTERNAL_GENERATOR without it.", 204)
|
7537
7517
|
|
7538
7518
|
node = ExternalProgramGenerationNode(args.external_generator)
|
7539
7519
|
|
@@ -7770,8 +7750,7 @@ def handle_exceptions_create_and_execute_next_runs(e: Exception) -> int:
|
|
7770
7750
|
print_red(f"Error 2: {e}")
|
7771
7751
|
elif isinstance(e, ax.exceptions.core.DataRequiredError):
|
7772
7752
|
if "transform requires non-empty data" in str(e) and args.num_random_steps == 0:
|
7773
|
-
|
7774
|
-
my_exit(233)
|
7753
|
+
_fatal_error(f"Error 3: {e} Increase --num_random_steps to at least 1 to continue.", 233)
|
7775
7754
|
else:
|
7776
7755
|
print_debug(f"Error 4: {e}")
|
7777
7756
|
elif isinstance(e, RuntimeError):
|
@@ -7922,8 +7901,7 @@ executor.update_parameters(
|
|
7922
7901
|
if args.exclude:
|
7923
7902
|
print_yellow(f"Excluding the following nodes: {args.exclude}")
|
7924
7903
|
else:
|
7925
|
-
|
7926
|
-
my_exit(9)
|
7904
|
+
_fatal_error("executor could not be found", 9)
|
7927
7905
|
|
7928
7906
|
@beartype
|
7929
7907
|
def set_global_executor() -> None:
|
@@ -8178,8 +8156,7 @@ def set_orchestrator() -> None:
|
|
8178
8156
|
def check_if_has_random_steps() -> None:
|
8179
8157
|
with console.status("[bold green]Checking if has random steps..."):
|
8180
8158
|
if (not args.continue_previous_job and "--continue" not in sys.argv) and (args.num_random_steps == 0 or not args.num_random_steps) and args.model not in ["EXTERNAL_GENERATOR", "SOBOL", "PSEUDORANDOM"]:
|
8181
|
-
|
8182
|
-
my_exit(233)
|
8159
|
+
_fatal_error("You have no random steps set. This is only allowed in continued jobs. To start, you need either some random steps, or a continued run.", 233)
|
8183
8160
|
|
8184
8161
|
@beartype
|
8185
8162
|
def add_exclude_to_defective_nodes() -> None:
|
@@ -8192,8 +8169,7 @@ def add_exclude_to_defective_nodes() -> None:
|
|
8192
8169
|
@beartype
|
8193
8170
|
def check_max_eval(_max_eval: int) -> None:
|
8194
8171
|
if not _max_eval:
|
8195
|
-
|
8196
|
-
my_exit(19)
|
8172
|
+
_fatal_error("--max_eval needs to be set!", 19)
|
8197
8173
|
|
8198
8174
|
@beartype
|
8199
8175
|
def parse_parameters() -> Any:
|
@@ -8648,23 +8624,19 @@ def get_result_minimize_flag(path_to_calculate: str, resname: str) -> bool:
|
|
8648
8624
|
result_min_max_path = os.path.join(path_to_calculate, "result_min_max.txt")
|
8649
8625
|
|
8650
8626
|
if not os.path.isdir(path_to_calculate):
|
8651
|
-
|
8652
|
-
my_exit(24)
|
8627
|
+
_fatal_error(f"Error: Directory '{path_to_calculate}' does not exist.", 24)
|
8653
8628
|
|
8654
8629
|
if not os.path.isfile(result_names_path) or not os.path.isfile(result_min_max_path):
|
8655
|
-
|
8656
|
-
my_exit(24)
|
8630
|
+
_fatal_error(f"Error: Missing 'result_names.txt' or 'result_min_max.txt' in '{path_to_calculate}'.", 24)
|
8657
8631
|
|
8658
8632
|
try:
|
8659
8633
|
with open(result_names_path, "r", encoding="utf-8") as f:
|
8660
8634
|
names = [line.strip() for line in f]
|
8661
8635
|
except Exception as e:
|
8662
|
-
|
8663
|
-
my_exit(24)
|
8636
|
+
_fatal_error(f"Error: Failed to read 'result_names.txt': {e}", 24)
|
8664
8637
|
|
8665
8638
|
if resname not in names:
|
8666
|
-
|
8667
|
-
my_exit(24)
|
8639
|
+
_fatal_error(f"Error: Result name '{resname}' not found in 'result_names.txt'.", 24)
|
8668
8640
|
|
8669
8641
|
index = names.index(resname)
|
8670
8642
|
|
@@ -8672,12 +8644,10 @@ def get_result_minimize_flag(path_to_calculate: str, resname: str) -> bool:
|
|
8672
8644
|
with open(result_min_max_path, "r", encoding="utf-8") as f:
|
8673
8645
|
minmax = [line.strip().lower() for line in f]
|
8674
8646
|
except Exception as e:
|
8675
|
-
|
8676
|
-
my_exit(24)
|
8647
|
+
_fatal_error(f"Error: Failed to read 'result_min_max.txt': {e}", 24)
|
8677
8648
|
|
8678
8649
|
if index >= len(minmax):
|
8679
|
-
|
8680
|
-
my_exit(24)
|
8650
|
+
_fatal_error(f"Error: Not enough entries in 'result_min_max.txt' for index {index}.", 24)
|
8681
8651
|
|
8682
8652
|
return minmax[index] == "min"
|
8683
8653
|
|
@@ -9406,8 +9376,7 @@ def complex_tests(_program_name: str, wanted_stderr: str, wanted_exit_code: int,
|
|
9406
9376
|
program_path: str = f"./.tests/test_wronggoing_stuff.bin/bin/{_program_name}"
|
9407
9377
|
|
9408
9378
|
if not os.path.exists(program_path):
|
9409
|
-
|
9410
|
-
my_exit(18)
|
9379
|
+
_fatal_error(f"Program path {program_path} not found!", 18)
|
9411
9380
|
|
9412
9381
|
program_path_with_program: str = f"{program_path}"
|
9413
9382
|
|