omniopt2 8178__py3-none-any.whl → 9171__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.
- .gitignore +2 -0
- .helpers.py +0 -9
- .omniopt.py +1717 -1151
- .omniopt_plot_scatter.py +1 -1
- .omniopt_plot_scatter_hex.py +1 -1
- .omniopt_plot_trial_index_result.py +1 -0
- .pareto.py +134 -0
- .shellscript_functions +24 -15
- .tests/pylint.rc +0 -4
- .tpe.py +4 -3
- README.md +1 -1
- omniopt +92 -55
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.helpers.py +0 -9
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.omniopt.py +1717 -1151
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.omniopt_plot_scatter.py +1 -1
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.omniopt_plot_scatter_hex.py +1 -1
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.omniopt_plot_trial_index_result.py +1 -0
- omniopt2-9171.data/data/bin/.pareto.py +134 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.shellscript_functions +24 -15
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.tpe.py +4 -3
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/omniopt +92 -55
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/omniopt_docker +60 -60
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/omniopt_plot +1 -1
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/pylint.rc +0 -4
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/requirements.txt +3 -4
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/test_requirements.txt +1 -0
- {omniopt2-8178.dist-info → omniopt2-9171.dist-info}/METADATA +6 -6
- omniopt2-9171.dist-info/RECORD +73 -0
- omniopt2.egg-info/PKG-INFO +6 -6
- omniopt2.egg-info/SOURCES.txt +1 -0
- omniopt2.egg-info/requires.txt +4 -4
- omniopt_docker +60 -60
- omniopt_plot +1 -1
- pyproject.toml +1 -1
- requirements.txt +3 -4
- test_requirements.txt +1 -0
- omniopt2-8178.dist-info/RECORD +0 -71
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.colorfunctions.sh +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.general.sh +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.omniopt_plot_cpu_ram_usage.py +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.omniopt_plot_general.py +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.omniopt_plot_gpu_usage.py +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.omniopt_plot_kde.py +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.omniopt_plot_scatter_generation_method.py +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.omniopt_plot_time_and_exit_code.py +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.omniopt_plot_worker.py +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/.random_generator.py +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/LICENSE +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/apt-dependencies.txt +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/omniopt_evaluate +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/omniopt_share +0 -0
- {omniopt2-8178.data → omniopt2-9171.data}/data/bin/setup.py +0 -0
- {omniopt2-8178.dist-info → omniopt2-9171.dist-info}/WHEEL +0 -0
- {omniopt2-8178.dist-info → omniopt2-9171.dist-info}/licenses/LICENSE +0 -0
- {omniopt2-8178.dist-info → omniopt2-9171.dist-info}/top_level.txt +0 -0
|
@@ -79,7 +79,7 @@ if ORIGINAL_PWD:
|
|
|
79
79
|
os.chdir(ORIGINAL_PWD)
|
|
80
80
|
|
|
81
81
|
@beartype
|
|
82
|
-
def set_title(df_filtered: pd.DataFrame, result_column_values: pd.
|
|
82
|
+
def set_title(df_filtered: pd.DataFrame, result_column_values: pd.Series, num_entries: int, _min: Union[int, float, None], _max: Union[int, float, None]) -> None:
|
|
83
83
|
title = helpers.get_title(args, result_column_values, df_filtered, num_entries, _min, _max)
|
|
84
84
|
|
|
85
85
|
if fig:
|
|
@@ -93,7 +93,7 @@ if ORIGINAL_PWD:
|
|
|
93
93
|
os.chdir(ORIGINAL_PWD)
|
|
94
94
|
|
|
95
95
|
@beartype
|
|
96
|
-
def set_title(df_filtered: pd.DataFrame, result_column_values: pd.
|
|
96
|
+
def set_title(df_filtered: pd.DataFrame, result_column_values: pd.Series, num_entries: int, _min: Union[float, int, None] = None, _max: Union[float, int, None] = None) -> None:
|
|
97
97
|
title = helpers.get_title(args, result_column_values, df_filtered, num_entries, _min, _max)
|
|
98
98
|
|
|
99
99
|
if fig:
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import importlib.util
|
|
3
|
+
from typing import Tuple, List, Dict, Any
|
|
4
|
+
from rich.table import Table
|
|
5
|
+
from rich.text import Text
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# ----------------- Helpers import -----------------
|
|
10
|
+
script_dir = os.path.dirname(os.path.realpath(__file__))
|
|
11
|
+
helpers_file: str = f"{script_dir}/.helpers.py"
|
|
12
|
+
spec = importlib.util.spec_from_file_location(
|
|
13
|
+
name="helpers",
|
|
14
|
+
location=helpers_file,
|
|
15
|
+
)
|
|
16
|
+
if spec is not None and spec.loader is not None:
|
|
17
|
+
helpers = importlib.util.module_from_spec(spec)
|
|
18
|
+
spec.loader.exec_module(helpers)
|
|
19
|
+
else:
|
|
20
|
+
raise ImportError(f"Could not load module from {helpers_file}")
|
|
21
|
+
|
|
22
|
+
# ----------------- Table utilities -----------------
|
|
23
|
+
def pareto_front_table_filter_rows(rows: List[Dict[str, str]], idxs: List[int]) -> List[Dict[str, str]]:
|
|
24
|
+
result = []
|
|
25
|
+
for row in rows:
|
|
26
|
+
try:
|
|
27
|
+
trial_index = int(row["trial_index"])
|
|
28
|
+
except (KeyError, ValueError):
|
|
29
|
+
continue
|
|
30
|
+
|
|
31
|
+
if row.get("trial_status", "").strip().upper() == "COMPLETED" and trial_index in idxs:
|
|
32
|
+
result.append(row)
|
|
33
|
+
return result
|
|
34
|
+
|
|
35
|
+
def pareto_front_table_add_headers(table: Table, param_cols: List[str], result_cols: List[str]) -> None:
|
|
36
|
+
for col in param_cols:
|
|
37
|
+
table.add_column(col, justify="center")
|
|
38
|
+
for col in result_cols:
|
|
39
|
+
table.add_column(Text(f"{col}", style="cyan"), justify="center")
|
|
40
|
+
|
|
41
|
+
def pareto_front_table_add_rows(table: Table, rows: List[Dict[str, str]], param_cols: List[str], result_cols: List[str]) -> None:
|
|
42
|
+
for row in rows:
|
|
43
|
+
values = [str(helpers.to_int_when_possible(row[col])) for col in param_cols]
|
|
44
|
+
result_values = [Text(str(helpers.to_int_when_possible(row[col])), style="cyan") for col in result_cols]
|
|
45
|
+
table.add_row(*values, *result_values, style="bold green")
|
|
46
|
+
|
|
47
|
+
# ----------------- Pareto internal utilities -----------------
|
|
48
|
+
def _validate_xy(x: np.ndarray, y: np.ndarray) -> None:
|
|
49
|
+
if x.shape != y.shape:
|
|
50
|
+
raise ValueError("Input arrays x and y must have the same shape.")
|
|
51
|
+
if x.size == 0:
|
|
52
|
+
raise ValueError("Input arrays must not be empty.")
|
|
53
|
+
if not np.isfinite(x).all() or not np.isfinite(y).all():
|
|
54
|
+
raise ValueError("Input arrays must contain only finite numbers (no NaN/Inf).")
|
|
55
|
+
|
|
56
|
+
def _point_dominates(xi: float, yi: float, xj: float, yj: float, x_minimize: bool, y_minimize: bool) -> bool:
|
|
57
|
+
"""Return True if j dominates i (standard weak Pareto: >= in all, > in at least one)."""
|
|
58
|
+
if x_minimize:
|
|
59
|
+
x_better_eq = xj <= xi
|
|
60
|
+
x_strict = xj < xi
|
|
61
|
+
else:
|
|
62
|
+
x_better_eq = xj >= xi
|
|
63
|
+
x_strict = xj > xi
|
|
64
|
+
|
|
65
|
+
if y_minimize:
|
|
66
|
+
y_better_eq = yj <= yi
|
|
67
|
+
y_strict = yj < yi
|
|
68
|
+
else:
|
|
69
|
+
y_better_eq = yj >= yi
|
|
70
|
+
y_strict = yj > yi
|
|
71
|
+
|
|
72
|
+
return x_better_eq and y_better_eq and (x_strict or y_strict)
|
|
73
|
+
|
|
74
|
+
def _find_dominated(x: np.ndarray, y: np.ndarray, x_minimize: bool, y_minimize: bool) -> np.ndarray:
|
|
75
|
+
n = len(x)
|
|
76
|
+
is_dominated = np.zeros(n, dtype=bool)
|
|
77
|
+
for i in range(n):
|
|
78
|
+
if is_dominated[i]:
|
|
79
|
+
continue
|
|
80
|
+
xi, yi = x[i], y[i]
|
|
81
|
+
for j in range(n):
|
|
82
|
+
if i == j:
|
|
83
|
+
continue
|
|
84
|
+
xj, yj = x[j], y[j]
|
|
85
|
+
if _point_dominates(xi, yi, xj, yj, x_minimize, y_minimize):
|
|
86
|
+
is_dominated[i] = True
|
|
87
|
+
break
|
|
88
|
+
return is_dominated
|
|
89
|
+
|
|
90
|
+
# ----------------- Public Pareto functions -----------------
|
|
91
|
+
def pareto_front_general(
|
|
92
|
+
x: np.ndarray,
|
|
93
|
+
y: np.ndarray,
|
|
94
|
+
x_minimize: bool = True,
|
|
95
|
+
y_minimize: bool = True
|
|
96
|
+
) -> np.ndarray:
|
|
97
|
+
try:
|
|
98
|
+
xa = np.asarray(x, dtype=float).ravel()
|
|
99
|
+
ya = np.asarray(y, dtype=float).ravel()
|
|
100
|
+
_validate_xy(xa, ya)
|
|
101
|
+
is_dominated = _find_dominated(xa, ya, x_minimize, y_minimize)
|
|
102
|
+
return np.where(~is_dominated)[0]
|
|
103
|
+
except Exception as e:
|
|
104
|
+
print("Error in pareto_front_general:", str(e))
|
|
105
|
+
return np.array([], dtype=int)
|
|
106
|
+
|
|
107
|
+
def pareto_front_filter_complete_points(
|
|
108
|
+
path_to_calculate: str,
|
|
109
|
+
records: Dict[Tuple[int, str], Dict[str, Dict[str, float]]],
|
|
110
|
+
primary_name: str,
|
|
111
|
+
secondary_name: str
|
|
112
|
+
) -> List[Tuple[Tuple[int, str], float, float]]:
|
|
113
|
+
points = []
|
|
114
|
+
for key, metrics in records.items():
|
|
115
|
+
means = metrics['means']
|
|
116
|
+
if primary_name in means and secondary_name in means:
|
|
117
|
+
points.append((key, means[primary_name], means[secondary_name]))
|
|
118
|
+
if len(points) == 0:
|
|
119
|
+
raise ValueError(f"No full data points with both objectives found in {path_to_calculate}.")
|
|
120
|
+
return points
|
|
121
|
+
|
|
122
|
+
def pareto_front_select_pareto_points(
|
|
123
|
+
x: np.ndarray,
|
|
124
|
+
y: np.ndarray,
|
|
125
|
+
x_minimize: bool,
|
|
126
|
+
y_minimize: bool,
|
|
127
|
+
points: List[Tuple[Any, float, float]],
|
|
128
|
+
num_points: int
|
|
129
|
+
) -> List[Tuple[Any, float, float]]:
|
|
130
|
+
indices = pareto_front_general(x, y, x_minimize, y_minimize)
|
|
131
|
+
# Sort by x ascending
|
|
132
|
+
sorted_indices = indices[np.argsort(x[indices])]
|
|
133
|
+
selected_points = [points[i] for i in sorted_indices[:num_points]]
|
|
134
|
+
return selected_points
|
|
@@ -207,13 +207,14 @@
|
|
|
207
207
|
bar="${bar} "
|
|
208
208
|
done
|
|
209
209
|
|
|
210
|
-
printf "[%s]
|
|
210
|
+
printf "[%s] \n" "$bar"
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
function ppip {
|
|
214
214
|
MODULE=$1
|
|
215
215
|
AS_REQUIREMENT_OF=$2
|
|
216
216
|
NUMBER_OF_MAIN_MODULES=$3
|
|
217
|
+
STR=$4
|
|
217
218
|
|
|
218
219
|
set +e
|
|
219
220
|
|
|
@@ -222,7 +223,7 @@
|
|
|
222
223
|
PROGRESSBAR=$(generate_progress_bar_setup "$NUMBER_OF_MAIN_MODULES")
|
|
223
224
|
|
|
224
225
|
if [[ -z $CI ]]; then
|
|
225
|
-
green_reset_line "${PROGRESSBAR}
|
|
226
|
+
green_reset_line "${PROGRESSBAR}➤${STR}Installing $MODULE "
|
|
226
227
|
fi
|
|
227
228
|
|
|
228
229
|
|
|
@@ -235,10 +236,10 @@
|
|
|
235
236
|
if [[ "$MODULE" != "$AS_REQUIREMENT_OF" ]] && [[ "$AS_REQUIREMENT_OF" != "-" ]]; then
|
|
236
237
|
k=0
|
|
237
238
|
|
|
238
|
-
for i in $(pip3 install --disable-pip-version-check --dry-run "$MODULE" | grep -v "already satisfied" | grep "Collecting" | sed -e 's#Collecting ##' | grep -v "^$MODULE$"); do
|
|
239
|
+
for i in $(pip3 install --default-timeout=300 --default-timeout=300 --disable-pip-version-check --dry-run "$MODULE" | grep -v "already satisfied" | grep "Collecting" | sed -e 's#Collecting ##' | grep -v "^$MODULE$"); do
|
|
239
240
|
if [[ "$i" != "$MODULE" ]]; then
|
|
240
241
|
if [[ $k -eq 0 ]]; then
|
|
241
|
-
green_reset_line "${PROGRESSBAR}
|
|
242
|
+
green_reset_line "${PROGRESSBAR}➤${STR}Installing requirements for $MODULE"
|
|
242
243
|
fi
|
|
243
244
|
ppip "$i" "$MODULE" "$NUMBER_OF_MAIN_MODULES" || {
|
|
244
245
|
red_reset_line "❌Failed to install $i."
|
|
@@ -251,11 +252,11 @@
|
|
|
251
252
|
done
|
|
252
253
|
|
|
253
254
|
if [[ $k -gt 0 ]]; then
|
|
254
|
-
green_reset_line "${PROGRESSBAR}
|
|
255
|
+
green_reset_line "${PROGRESSBAR}➤${STR}Installed all requirements for $MODULE, now installing the package itself..."
|
|
255
256
|
fi
|
|
256
257
|
fi
|
|
257
258
|
|
|
258
|
-
green_reset_line "${PROGRESSBAR}
|
|
259
|
+
green_reset_line "${PROGRESSBAR}➤${STR}Installing $MODULE..."
|
|
259
260
|
mkdir -p logs
|
|
260
261
|
export PIP_DISABLE_PIP_VERSION_CHECK=1
|
|
261
262
|
INSTALL_ERRORS_FILE="logs/install_errors"
|
|
@@ -265,8 +266,8 @@
|
|
|
265
266
|
fi
|
|
266
267
|
|
|
267
268
|
if [[ -z $DEBUG ]]; then
|
|
268
|
-
pip3 --disable-pip-version-check install -q $MODULE >&2 2>> $INSTALL_ERRORS_FILE || pip3 --disable-pip-version-check install $MODULE >&2 2>> $INSTALL_ERRORS_FILE || {
|
|
269
|
-
red_reset_line "❌Failed to install $MODULE. Check $INSTALL_ERRORS_FILE"
|
|
269
|
+
pip3 --default-timeout=300 --disable-pip-version-check install -q $MODULE >&2 2>> $INSTALL_ERRORS_FILE || pip3 --default-timeout=300 --disable-pip-version-check install $MODULE >&2 2>> $INSTALL_ERRORS_FILE || {
|
|
270
|
+
red_reset_line "❌Failed to install $MODULE. Check $INSTALL_ERRORS_FILE\n"
|
|
270
271
|
|
|
271
272
|
if [[ -n $CI ]] || { [[ -f /proc/self/cgroup ]] && grep -qE '/docker|/lxc' /proc/self/cgroup; }; then
|
|
272
273
|
cat "$INSTALL_ERRORS_FILE"
|
|
@@ -275,8 +276,8 @@
|
|
|
275
276
|
exit 20
|
|
276
277
|
}
|
|
277
278
|
else
|
|
278
|
-
pip3 --disable-pip-version-check install $MODULE >&2 2>> $INSTALL_ERRORS_FILE || pip3 --disable-pip-version-check install $MODULE >&2 2>> $INSTALL_ERRORS_FILE || {
|
|
279
|
-
red_reset_line "❌Failed to install $MODULE. Check $INSTALL_ERRORS_FILE"
|
|
279
|
+
pip3 --default-timeout=300 --disable-pip-version-check install $MODULE >&2 2>> $INSTALL_ERRORS_FILE || pip3 --default-timeout=300 --disable-pip-version-check install $MODULE >&2 2>> $INSTALL_ERRORS_FILE || {
|
|
280
|
+
red_reset_line "❌Failed to install $MODULE. Check $INSTALL_ERRORS_FILE\n"
|
|
280
281
|
|
|
281
282
|
if [[ -n $CI ]] || { [[ -f /proc/self/cgroup ]] && grep -qE '/docker|/lxc' /proc/self/cgroup; }; then
|
|
282
283
|
cat "$INSTALL_ERRORS_FILE"
|
|
@@ -323,17 +324,25 @@
|
|
|
323
324
|
MAX_NR="${#install_those[@]}"
|
|
324
325
|
NUMBER_OF_INSTALLED_MODULES=$(get_nr_of_already_installed_modules)
|
|
325
326
|
|
|
326
|
-
|
|
327
|
+
MAX_PERCENT=100
|
|
327
328
|
|
|
328
329
|
for key in "${!install_those[@]}"; do
|
|
330
|
+
idx=$((idx+1))
|
|
329
331
|
install_this=${install_those[$key]}
|
|
330
|
-
|
|
332
|
+
percent=$((idx * 100 / MAX_NR))
|
|
333
|
+
|
|
334
|
+
PROGRESSBAR=$(generate_progress_bar "$idx" "$MAX_NR")
|
|
335
|
+
|
|
336
|
+
STR="Checking ${idx_padded}/${MAX_NR}, ${percent_padded}%: "
|
|
337
|
+
|
|
331
338
|
if [[ -z $CI ]]; then
|
|
332
|
-
|
|
339
|
+
printf -v idx_padded "%*d" "${#MAX_NR}" "$idx"
|
|
340
|
+
printf -v percent_padded "%*d" "${#MAX_PERCENT}" "$percent"
|
|
341
|
+
green_reset_line "${PROGRESSBAR}➤$STR$install_this..."
|
|
333
342
|
fi
|
|
334
343
|
|
|
335
344
|
if ! echo "$FROZEN" | grep -q "$install_this"; then
|
|
336
|
-
ppip "$install_this" "-" "$MAX_NR"
|
|
345
|
+
ppip "$install_this" "-" "$MAX_NR" "$STR"
|
|
337
346
|
fi
|
|
338
347
|
done
|
|
339
348
|
|
|
@@ -451,7 +460,7 @@
|
|
|
451
460
|
exit 20
|
|
452
461
|
}
|
|
453
462
|
|
|
454
|
-
downgrade_output=$(pip3 --disable-pip-version-check install -q pip==24.0) || {
|
|
463
|
+
downgrade_output=$(pip3 --default-timeout=300 --disable-pip-version-check install -q pip==24.0) || {
|
|
455
464
|
red_text "Failed to downgrade pip. Output:"
|
|
456
465
|
red_text "$downgrade_output"
|
|
457
466
|
}
|
|
@@ -2,7 +2,8 @@ import sys
|
|
|
2
2
|
import os
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
|
-
from typing import Optional
|
|
5
|
+
from typing import Optional, Any
|
|
6
|
+
|
|
6
7
|
try:
|
|
7
8
|
import optuna
|
|
8
9
|
from optuna.trial import create_trial
|
|
@@ -52,7 +53,7 @@ def tpe_suggest_point(trial: optuna.Trial, parameters: dict) -> dict:
|
|
|
52
53
|
if pvaltype == 'INT':
|
|
53
54
|
point[param_name] = trial.suggest_int(param_name, rmin, rmax)
|
|
54
55
|
elif pvaltype == 'FLOAT':
|
|
55
|
-
point[param_name] = trial.suggest_float(param_name, rmin, rmax)
|
|
56
|
+
point[param_name] = trial.suggest_float(param_name, rmin, rmax) # type: ignore[assignment]
|
|
56
57
|
else:
|
|
57
58
|
raise ValueError(f"Unsupported type {pvaltype} for RANGE")
|
|
58
59
|
|
|
@@ -162,7 +163,7 @@ def add_existing_trial_to_study(study: optuna.study.study.Study, trial_entry: li
|
|
|
162
163
|
)
|
|
163
164
|
|
|
164
165
|
@beartype
|
|
165
|
-
def get_best_or_new_point(study:
|
|
166
|
+
def get_best_or_new_point(study: Any, parameters: dict, direction: str) -> dict:
|
|
166
167
|
best_trial_value = study.best_trial.value
|
|
167
168
|
if best_trial_value is not None:
|
|
168
169
|
if (direction == "minimize" and best_trial_value < 1e6) or \
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# Step 1:
|
|
6
6
|
# It checks whether the environment already exists, and
|
|
7
7
|
# if so, loads it.
|
|
8
|
-
# If it doesn't exist
|
|
8
|
+
# If it doesn't exist, it creates it in
|
|
9
9
|
# ~/.omniax_$(uname -m)_$(python3 --version | sed -e 's# #_#g')
|
|
10
10
|
# i.e. e.g. ~/.omniax_x86_64_Python_3.11.2/ . This is done so that there
|
|
11
11
|
# is no need for multiple installations, so that, once installed, it doesn't
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
#SBATCH --signal=B:USR1@600
|
|
32
32
|
|
|
33
33
|
{
|
|
34
|
-
SCRIPT_DIR=$(dirname $(realpath "$0"))
|
|
34
|
+
SCRIPT_DIR=$(dirname "$(realpath "$0")")
|
|
35
35
|
|
|
36
36
|
if [ -n "${SLURM_JOB_ID:-}" ] ; then
|
|
37
37
|
set +e
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
set -e
|
|
53
53
|
fi
|
|
54
54
|
|
|
55
|
-
source $SCRIPT_DIR/.colorfunctions.sh
|
|
55
|
+
source "$SCRIPT_DIR/.colorfunctions.sh"
|
|
56
56
|
|
|
57
57
|
cancelled_manually=0
|
|
58
58
|
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
|
|
82
82
|
function end_all_bg_processes {
|
|
83
83
|
for bg_job_id in $(jobs -p | sed -e 's#.*][[:space:]]*+[[:space:]]*##' -e 's#[[:space:]].*##'); do
|
|
84
|
-
kill $bg_job_id 2>/dev/null >/dev/null
|
|
84
|
+
kill "$bg_job_id" 2>/dev/null >/dev/null
|
|
85
85
|
done
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -110,8 +110,8 @@
|
|
|
110
110
|
|
|
111
111
|
if (command -v sbatch >/dev/null && [[ -n "$SLURM_JOB_ID" ]]) || ! command -v sbatch >/dev/null; then
|
|
112
112
|
already_logging_this_command=1
|
|
113
|
-
exec 1> >(tee -ia $bash_logname)
|
|
114
|
-
exec 2> >(tee -ia $bash_logname >& 2)
|
|
113
|
+
exec 1> >(tee -ia "$bash_logname")
|
|
114
|
+
exec 2> >(tee -ia "$bash_logname" >& 2)
|
|
115
115
|
fi
|
|
116
116
|
else
|
|
117
117
|
echo "uuidgen is not installed. It's recommended you install it." >&2
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
ram_children=0
|
|
125
125
|
|
|
126
126
|
for pid in $(pgrep -P $$); do
|
|
127
|
-
child_ram=$(grep VmRSS /proc/$pid/status 2>/dev/null | awk '{print $2 / 1024}')
|
|
127
|
+
child_ram=$(grep VmRSS "/proc/$pid/status" 2>/dev/null | awk '{print $2 / 1024}')
|
|
128
128
|
ram_children=$(awk -v a="$ram_children" -v b="$child_ram" 'BEGIN {print a + b}')
|
|
129
129
|
done
|
|
130
130
|
|
|
@@ -153,6 +153,7 @@
|
|
|
153
153
|
|
|
154
154
|
if [[ -n $RUN_UUID ]]; then
|
|
155
155
|
if ! [[ -e "logs/${RUN_UUID}_ram_log" ]]; then
|
|
156
|
+
mkdir -p logs
|
|
156
157
|
echo "time,ram,ram_children" > "logs/${RUN_UUID}_ram_log"
|
|
157
158
|
fi
|
|
158
159
|
|
|
@@ -169,7 +170,7 @@
|
|
|
169
170
|
while true; do
|
|
170
171
|
date_str=$(date +"%Y-%m-%d %H:%M:%S")
|
|
171
172
|
echo -e "\n\n$date_str -> $(show_ram)\n\n" >&2
|
|
172
|
-
sleep $n
|
|
173
|
+
sleep "$n"
|
|
173
174
|
done
|
|
174
175
|
}
|
|
175
176
|
|
|
@@ -210,7 +211,7 @@
|
|
|
210
211
|
fi
|
|
211
212
|
|
|
212
213
|
if [[ ! -e $file ]]; then
|
|
213
|
-
echo "Cannot parse non-
|
|
214
|
+
echo "Cannot parse non-existent toml." >&2
|
|
214
215
|
return 1
|
|
215
216
|
fi
|
|
216
217
|
|
|
@@ -237,7 +238,7 @@
|
|
|
237
238
|
fi
|
|
238
239
|
|
|
239
240
|
if [[ ! -e "$file" ]]; then
|
|
240
|
-
echo "Cannot parse non-
|
|
241
|
+
echo "Cannot parse non-existent yaml." >&2
|
|
241
242
|
return 1
|
|
242
243
|
fi
|
|
243
244
|
|
|
@@ -269,7 +270,7 @@
|
|
|
269
270
|
fi
|
|
270
271
|
|
|
271
272
|
if [[ ! -e "$file" ]]; then
|
|
272
|
-
echo "Cannot parse non-
|
|
273
|
+
echo "Cannot parse non-existent json." >&2
|
|
273
274
|
return 1
|
|
274
275
|
fi
|
|
275
276
|
|
|
@@ -336,7 +337,7 @@
|
|
|
336
337
|
|
|
337
338
|
int_re='^[+-]?[0-9]+$'
|
|
338
339
|
|
|
339
|
-
if [[ -n $
|
|
340
|
+
if [[ -n $PRINT_SEPARATOR ]]; then # for tests, so that things are properly visually separated
|
|
340
341
|
echo ""
|
|
341
342
|
echo "========================================================================"
|
|
342
343
|
echo ""
|
|
@@ -345,10 +346,35 @@
|
|
|
345
346
|
send_anonymized_usage_stats=0
|
|
346
347
|
already_shown_oo_base_url_msg=0
|
|
347
348
|
|
|
349
|
+
function run_live_share {
|
|
350
|
+
if [[ $RUN_UUID != "" ]]; then
|
|
351
|
+
full_log_file="$ORIGINAL_PWD/logs/$RUN_UUID"
|
|
352
|
+
if [[ -e "$full_log_file" ]]; then
|
|
353
|
+
set +e
|
|
354
|
+
run_folder=$(cat "$full_log_file" | grep "Run-folder:" | sed -e 's#Run-folder: ##')
|
|
355
|
+
if [[ -z $run_folder ]]; then
|
|
356
|
+
true
|
|
357
|
+
else
|
|
358
|
+
bash "$SCRIPT_DIR/omniopt_share" --username="$USER" "$run_folder" 2>/dev/null >/dev/null
|
|
359
|
+
fi
|
|
360
|
+
set -e
|
|
361
|
+
else
|
|
362
|
+
red_text "--live_share enabled, but $full_log_file could not be found. Cannot share once again in finalization.\n"
|
|
363
|
+
fi
|
|
364
|
+
fi
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function start_periodic_live_share {
|
|
368
|
+
while true; do
|
|
369
|
+
run_live_share 2>/dev/null >/dev/null
|
|
370
|
+
sleep 10
|
|
371
|
+
done
|
|
372
|
+
}
|
|
373
|
+
|
|
348
374
|
function myexit {
|
|
349
375
|
CODE=$1
|
|
350
376
|
|
|
351
|
-
end_all_bg_processes
|
|
377
|
+
end_all_bg_processes 2>/dev/null
|
|
352
378
|
|
|
353
379
|
if [[ $follow -eq 1 ]]; then
|
|
354
380
|
if [[ -z $CODE ]] || ! [[ $CODE =~ $int_re ]]; then
|
|
@@ -381,29 +407,15 @@
|
|
|
381
407
|
|
|
382
408
|
if [[ $follow -eq 1 ]] || ! command -v sbatch 2>/dev/null >/dev/null || [[ $force_local_execution -eq 1 ]]; then
|
|
383
409
|
if [[ $live_share -eq 1 ]]; then
|
|
384
|
-
|
|
385
|
-
full_log_file="$ORIGINAL_PWD/logs/$RUN_UUID"
|
|
386
|
-
if [[ -e "$full_log_file" ]]; then
|
|
387
|
-
set +e
|
|
388
|
-
run_folder=$(cat "$full_log_file" | grep "Run-folder:" | sed -e 's#Run-folder: ##')
|
|
389
|
-
if [[ -z $run_folder ]]; then
|
|
390
|
-
true
|
|
391
|
-
else
|
|
392
|
-
bash $SCRIPT_DIR/omniopt_share --username="$USER" "$run_folder" 2>/dev/null >/dev/null
|
|
393
|
-
fi
|
|
394
|
-
set -e
|
|
395
|
-
else
|
|
396
|
-
red_text "--live_share enabled, but $full_log_file could not be found. Cannot share once again in finalization.\n"
|
|
397
|
-
fi
|
|
398
|
-
fi
|
|
410
|
+
run_live_share
|
|
399
411
|
fi
|
|
400
412
|
fi
|
|
401
413
|
|
|
402
|
-
exit $CODE
|
|
414
|
+
exit "$CODE"
|
|
403
415
|
}
|
|
404
416
|
|
|
405
417
|
function get_anon_user_id {
|
|
406
|
-
user_groups=$(echo "$(echo $USER | sha512sum)|groups=$(groups | tr ' ' '\n' | sort | sha512sum)")
|
|
418
|
+
user_groups=$(echo "$(echo "$USER" | sha512sum)|groups=$(groups | tr ' ' '\n' | sort | sha512sum)")
|
|
407
419
|
fixed_iv=$(echo -n "$user_groups" | sha512sum | cut -c1-32)
|
|
408
420
|
encrypted=$(echo -n "$user_groups" | openssl enc -aes-256-cbc -a -pass pass:"$(echo "$(groups | tr ' ' '\n' | sort | sha512sum)-$USER" | sha512sum | rev | sha512sum)" -iv "$fixed_iv" -nosalt -pbkdf2)
|
|
409
421
|
echo "$encrypted" | sha512sum | rev | sha512sum | rev | sha512sum | sha512sum | sed -e 's#[[:space:]].*##' | cut -c1-32
|
|
@@ -499,7 +511,11 @@
|
|
|
499
511
|
if [ $minutes -eq 1 ]; then
|
|
500
512
|
result="in about $minutes minute"
|
|
501
513
|
else
|
|
502
|
-
|
|
514
|
+
if [ $minutes -eq 0 ]; then
|
|
515
|
+
result="soon"
|
|
516
|
+
else
|
|
517
|
+
result="in about $minutes minutes"
|
|
518
|
+
fi
|
|
503
519
|
fi
|
|
504
520
|
echo "$result"
|
|
505
521
|
return
|
|
@@ -600,7 +616,7 @@
|
|
|
600
616
|
|
|
601
617
|
echo ""
|
|
602
618
|
caller
|
|
603
|
-
echo "Runtime (calltracer): $(displaytime $SECONDS), PID: $$"
|
|
619
|
+
echo "Runtime (calltracer): $(displaytime "$SECONDS"), PID: $$"
|
|
604
620
|
else
|
|
605
621
|
echo ""
|
|
606
622
|
fi
|
|
@@ -619,7 +635,7 @@
|
|
|
619
635
|
if [[ $python_pid =~ $re ]] ; then
|
|
620
636
|
if [[ -z "$already_sent_signal" ]]; then
|
|
621
637
|
if command -v ps 2>/dev/null >/dev/null; then
|
|
622
|
-
if ps auxf | grep $python_pid 2>/dev/null >/dev/null; then
|
|
638
|
+
if ps auxf | grep "$python_pid" 2>/dev/null >/dev/null; then
|
|
623
639
|
already_sent_signal=1
|
|
624
640
|
echo -e "\nSending USR1 to $python_pid (python). Reason: $REASON"
|
|
625
641
|
kill -USR1 "$python_pid"
|
|
@@ -632,7 +648,7 @@
|
|
|
632
648
|
fi
|
|
633
649
|
|
|
634
650
|
if [[ $kill_python_if_started_already_shown -eq 0 ]]; then
|
|
635
|
-
echo "Runtime (kill_python_if_started): $(displaytime $SECONDS), PID: $$"
|
|
651
|
+
echo "Runtime (kill_python_if_started): $(displaytime "$SECONDS"), PID: $$"
|
|
636
652
|
kill_python_if_started_already_shown=1
|
|
637
653
|
fi
|
|
638
654
|
|
|
@@ -677,7 +693,7 @@
|
|
|
677
693
|
|
|
678
694
|
printf "%02d:%02d:%02d\n" "$hours" "$minutes" "$seconds"
|
|
679
695
|
elif [[ $var =~ $time_re ]]; then
|
|
680
|
-
echo $var
|
|
696
|
+
echo "$var"
|
|
681
697
|
else
|
|
682
698
|
red_text "ERROR: $var is not a valid input. Must be a number of minutes (digits) or HH:MM:SS\n"
|
|
683
699
|
|
|
@@ -1004,6 +1020,10 @@ $complex_options_str
|
|
|
1004
1020
|
args_string+=" --help "
|
|
1005
1021
|
;;
|
|
1006
1022
|
|
|
1023
|
+
--memray)
|
|
1024
|
+
export RUN_WITH_MEMRAY=1
|
|
1025
|
+
;;
|
|
1026
|
+
|
|
1007
1027
|
--flame_graph)
|
|
1008
1028
|
export RUN_WITH_PYSPY=1
|
|
1009
1029
|
;;
|
|
@@ -1182,12 +1202,12 @@ EOF
|
|
|
1182
1202
|
if [[ "$commits_since_tag" -gt 0 ]]; then
|
|
1183
1203
|
if [[ "$checkout_to_latest_tested_version" -eq "1" ]]; then
|
|
1184
1204
|
yellow_text "--checkout_to_latest_tested_version enabled. Checking out to $tag_commit_hash..."
|
|
1185
|
-
git -C "$SCRIPT_DIR" checkout $tag_commit_hash >/dev/null 2>/dev/null || {
|
|
1205
|
+
git -C "$SCRIPT_DIR" checkout "$tag_commit_hash" >/dev/null 2>/dev/null || {
|
|
1186
1206
|
red_text "\nFailed to checkout to latest version. Try not using --checkout_to_latest_tested_version.\n"
|
|
1187
1207
|
myexit 211
|
|
1188
1208
|
}
|
|
1189
1209
|
|
|
1190
|
-
bash omniopt $*
|
|
1210
|
+
bash omniopt "$*"
|
|
1191
1211
|
exit_code=$?
|
|
1192
1212
|
|
|
1193
1213
|
myexit $exit_code
|
|
@@ -1619,14 +1639,29 @@ EOF
|
|
|
1619
1639
|
set +e
|
|
1620
1640
|
trap - ERR
|
|
1621
1641
|
|
|
1642
|
+
live_share_pid=""
|
|
1643
|
+
|
|
1644
|
+
if [[ $live_share -eq 1 ]]; then
|
|
1645
|
+
start_periodic_live_share &
|
|
1646
|
+
live_share_pid=$!
|
|
1647
|
+
fi
|
|
1648
|
+
|
|
1622
1649
|
if [[ -z $RUN_WITH_COVERAGE ]]; then
|
|
1623
|
-
if [[ -
|
|
1624
|
-
stdbuf -e 0 -o 0 python3 "$SCRIPT_DIR/.omniopt.py" $args_string
|
|
1625
|
-
EXIT_CODE=$?
|
|
1626
|
-
else
|
|
1650
|
+
if [[ -n $RUN_WITH_PYSPY ]]; then
|
|
1627
1651
|
echo "Starting OmniOpt with Py-Spy"
|
|
1628
1652
|
pip install py-spy
|
|
1629
|
-
stdbuf -e 0 -o 0 py-spy record --rate 10 --subprocesses --native --output $RUN_UUID.svg python3 -- "$SCRIPT_DIR/.omniopt.py" $args_string
|
|
1653
|
+
stdbuf -e 0 -o 0 py-spy record --rate 10 --subprocesses --native --output "$RUN_UUID.svg" python3 -- "$SCRIPT_DIR/.omniopt.py" $args_string
|
|
1654
|
+
EXIT_CODE=$?
|
|
1655
|
+
elif [[ -n $RUN_WITH_MEMRAY ]]; then
|
|
1656
|
+
echo "Starting OmniOpt with MemRay."
|
|
1657
|
+
echo "Check later on with 'memray flamegraph $RUN_UUID.bin'"
|
|
1658
|
+
export PYTORCH_NO_CUDA_MEMORY_CACHING=1
|
|
1659
|
+
export PYTHONFAULTHANDLER=1
|
|
1660
|
+
pip install memray
|
|
1661
|
+
stdbuf -e 0 -o 0 memray run -o "$RUN_UUID.bin" -- "$SCRIPT_DIR/.omniopt.py" $args_string
|
|
1662
|
+
EXIT_CODE=$?
|
|
1663
|
+
else
|
|
1664
|
+
stdbuf -e 0 -o 0 python3 "$SCRIPT_DIR/.omniopt.py" $args_string
|
|
1630
1665
|
EXIT_CODE=$?
|
|
1631
1666
|
fi
|
|
1632
1667
|
else
|
|
@@ -1635,6 +1670,10 @@ EOF
|
|
|
1635
1670
|
EXIT_CODE=$?
|
|
1636
1671
|
fi
|
|
1637
1672
|
|
|
1673
|
+
if [[ $live_share -eq 1 ]] && [[ -n $live_share_pid ]]; then
|
|
1674
|
+
kill -9 $live_share_pid >/dev/null 2>/dev/null
|
|
1675
|
+
fi
|
|
1676
|
+
|
|
1638
1677
|
set -e
|
|
1639
1678
|
trap 'calltracer' ERR
|
|
1640
1679
|
|
|
@@ -1842,7 +1881,7 @@ EOF
|
|
|
1842
1881
|
kill_tail_when_squeue_job_empty "$started_job_nr" &
|
|
1843
1882
|
|
|
1844
1883
|
tail_log_file() {
|
|
1845
|
-
trap 'ask_cancel' SIGINT
|
|
1884
|
+
#trap 'ask_cancel' SIGINT
|
|
1846
1885
|
# weird exec stuff for disabling the "Terminated" message coming from kill
|
|
1847
1886
|
exec 3>&2 # 3 is now a copy of 2
|
|
1848
1887
|
exec 2> /dev/null # 2 now points to /dev/null
|
|
@@ -1881,39 +1920,37 @@ EOF
|
|
|
1881
1920
|
tail_log_file
|
|
1882
1921
|
|
|
1883
1922
|
if [[ $already_logging_this_command -eq 0 ]]; then
|
|
1884
|
-
exec 1> >(tee -ia $bash_logname)
|
|
1885
|
-
exec 2> >(tee -ia $bash_logname >& 2)
|
|
1923
|
+
exec 1> >(tee -ia "$bash_logname")
|
|
1924
|
+
exec 2> >(tee -ia "$bash_logname" >& 2)
|
|
1886
1925
|
fi
|
|
1887
1926
|
|
|
1888
1927
|
|
|
1889
1928
|
exit_code_lines=$(grep -i "exit-code:*" "$LOG_PATH" 2>/dev/null)
|
|
1890
|
-
|
|
1891
|
-
|
|
1929
|
+
exit_code_lines_lines=$?
|
|
1930
|
+
if [ $exit_code_lines_lines -ne 0 ] || [ -z "$exit_code_lines" ]; then
|
|
1892
1931
|
exit_code_lines=""
|
|
1893
1932
|
fi
|
|
1894
1933
|
|
|
1895
1934
|
exit_code_sed=$(echo "$exit_code_lines" | sed -e 's#Exit-Code:*[[:space:]]*##i' -e 's#,.*##')
|
|
1896
|
-
|
|
1897
|
-
|
|
1935
|
+
exit_code_sed_sed=$?
|
|
1936
|
+
if [ $exit_code_sed_sed -ne 0 ] || [ -z "$exit_code_sed" ]; then
|
|
1898
1937
|
exit_code_sed=""
|
|
1899
1938
|
fi
|
|
1900
1939
|
|
|
1901
1940
|
exit_code_tail=$(echo "$exit_code_sed" | tail -n1)
|
|
1902
|
-
|
|
1903
|
-
|
|
1941
|
+
exit_code_tail_tail=$?
|
|
1942
|
+
if [ $exit_code_tail_tail -ne 0 ] || [ -z "$exit_code_tail" ]; then
|
|
1904
1943
|
exit_code_tail=""
|
|
1905
1944
|
fi
|
|
1906
1945
|
|
|
1907
|
-
exit_code_only_digits=$(echo "$exit_code_tail" | grep -o '[0-9]\+')
|
|
1946
|
+
exit_code_only_digits=$(echo "$exit_code_tail" | grep -o '[0-9]\+' | tail -n1)
|
|
1908
1947
|
if [ -z "$exit_code_only_digits" ]; then
|
|
1909
|
-
echo "WARN: No valid exit code found, setting it to 3"
|
|
1910
1948
|
exit_code_only_digits=3
|
|
1911
1949
|
fi
|
|
1912
1950
|
|
|
1913
1951
|
exit_code="$exit_code_only_digits"
|
|
1914
1952
|
|
|
1915
1953
|
if ! [[ "$exit_code" =~ ^[0-9]+$ ]]; then
|
|
1916
|
-
echo "WARN: exit_code invalid ('$exit_code'), setting to 3"
|
|
1917
1954
|
exit_code=3
|
|
1918
1955
|
fi
|
|
1919
1956
|
|
|
@@ -1979,7 +2016,7 @@ EOF
|
|
|
1979
2016
|
fi
|
|
1980
2017
|
|
|
1981
2018
|
if [[ $show_runtime -eq 0 ]]; then
|
|
1982
|
-
echo "Runtime (end): $(displaytime $SECONDS), PID: $$"
|
|
2019
|
+
echo "Runtime (end): $(displaytime "$SECONDS"), PID: $$"
|
|
1983
2020
|
fi
|
|
1984
2021
|
|
|
1985
2022
|
if [[ -n $RUN_WITH_COVERAGE ]]; then
|