Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Augment exp_to_df with a "reason" column #1973

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions ax/service/tests/test_report_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,20 @@ def test_exp_to_df_trial_timing(self) -> None:
# the last trial should have NaN for rel_time_completed
self.assertTrue(df["time_completed"].isnull().iloc[2])

def test_exp_to_df_with_failure(self) -> None:
fail_reason = "test reason"

# Set up experiment with a failed trial
exp = get_branin_experiment(with_trial=True)
exp.trials[0].run()
exp.trials[0].mark_failed(reason=fail_reason)

df = exp_to_df(exp)
self.assertEqual(
set(EXPECTED_COLUMNS + ["reason"]) - set(df.columns), {OBJECTIVE_NAME}
)
self.assertEqual(f"{fail_reason}...", df["reason"].iloc[0])

def test_exp_to_df(self) -> None:
# MultiTypeExperiment should fail
exp = get_multi_type_experiment()
Expand Down
20 changes: 19 additions & 1 deletion ax/service/utils/report_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,24 @@ def exp_to_df(
df=arms_df, trials_dict=trial_to_status, column_name="trial_status"
)

# Add trial reason for failed or abandoned trials
trial_to_reason = {
index: (
f"{trial.failed_reason[:15]}..."
if trial.status.is_failed and trial.failed_reason is not None
else f"{trial.abandoned_reason[:15]}..."
if trial.status.is_abandoned and trial.abandoned_reason is not None
else None
)
for index, trial in trials
}

_merge_trials_dict_with_df(
df=arms_df,
trials_dict=trial_to_reason,
column_name="reason",
)

# Add generation_method, accounting for the generic case that generator_runs is of
# arbitrary length. Repeated methods within a trial are condensed via `set` and an
# empty set will yield "Unknown" as the method.
Expand Down Expand Up @@ -920,7 +938,7 @@ def exp_to_df(

exp_df = not_none(not_none(exp_df).sort_values(["trial_index"]))
initial_column_order = (
["trial_index", "arm_name", "trial_status", "generation_method"]
["trial_index", "arm_name", "trial_status", "reason", "generation_method"]
+ (run_metadata_fields or [])
+ (trial_properties_fields or [])
)
Expand Down