-
-
Notifications
You must be signed in to change notification settings - Fork 83
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
Ensure trial notes are transferred when renamed #703
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #703 +/- ##
==========================================
+ Coverage 62.88% 65.80% +2.92%
==========================================
Files 35 35
Lines 2250 2293 +43
==========================================
+ Hits 1415 1509 +94
+ Misses 835 784 -51 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your pull request. I left a comment.
Thank you for the swift review. Let me know if there's another method to work around this! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understood, you're right. Maybe the notes should have used the trial.number instead of the trial_id as the key, but maintaining backward compatibility with that change would be difficult. So I think it would be best to merge this PR first.
I left some review comments.
optuna_dashboard/_note.py
Outdated
def transfer_notes(storage: BaseStorage, src_study: optuna.Study, dst_study: optuna.Study) -> None: | ||
system_attrs = storage.get_study_system_attrs(study_id=src_study._study_id) | ||
|
||
def transfer(src_trial_id: Optional[int], dst_trial_id: Optional[int]) -> None: | ||
note = get_note_from_system_attrs(system_attrs, src_trial_id)["body"] | ||
save_note_with_version(storage, dst_study._study_id, dst_trial_id, 0, note) | ||
delete_notes(storage, src_study._study_id, src_trial_id) | ||
|
||
# Transfer individual trial notes | ||
for src_trial, dst_trial in zip(src_study.get_trials(), dst_study.get_trials()): | ||
transfer(src_trial._trial_id, dst_trial._trial_id) | ||
|
||
# Transfer study note | ||
NO_SRC_TRIAL, NO_DST_TRIAL = None, None | ||
transfer(NO_SRC_TRIAL, NO_DST_TRIAL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say we don't need to delete original notes. How about making it copy
instead of transfer
since we can reduce the number of storage API calls?
def transfer_notes(storage: BaseStorage, src_study: optuna.Study, dst_study: optuna.Study) -> None: | |
system_attrs = storage.get_study_system_attrs(study_id=src_study._study_id) | |
def transfer(src_trial_id: Optional[int], dst_trial_id: Optional[int]) -> None: | |
note = get_note_from_system_attrs(system_attrs, src_trial_id)["body"] | |
save_note_with_version(storage, dst_study._study_id, dst_trial_id, 0, note) | |
delete_notes(storage, src_study._study_id, src_trial_id) | |
# Transfer individual trial notes | |
for src_trial, dst_trial in zip(src_study.get_trials(), dst_study.get_trials()): | |
transfer(src_trial._trial_id, dst_trial._trial_id) | |
# Transfer study note | |
NO_SRC_TRIAL, NO_DST_TRIAL = None, None | |
transfer(NO_SRC_TRIAL, NO_DST_TRIAL) | |
def copy_notes(storage: BaseStorage, src_study: optuna.Study, dst_study: optuna.Study) -> None: | |
system_attrs = storage.get_study_system_attrs(study_id=src_study._study_id) | |
# Copy individual trial notes | |
for src_trial, dst_trial in zip(src_study.get_trials(), dst_study.get_trials()): | |
note = get_note_from_system_attrs(system_attrs, src_trial._trial_id)["body"] | |
save_note_with_version(storage, dst_study._study_id, dst_trial._trial_id, 0, note) | |
# Copy study note | |
note = get_note_from_system_attrs(system_attrs, None)["body"] | |
save_note_with_version(storage, dst_study._study_id, None, 0, note) |
optuna_dashboard/_app.py
Outdated
@@ -176,6 +177,7 @@ def delete_study(study_id: int) -> dict[str, Any]: | |||
delete_all_artifacts(artifact_store, storage, study_id) | |||
|
|||
try: | |||
note.delete_study_notes(storage, study_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
study_system_attrs
will be removed in storage.delete_study()
so that you don't need to delete notes here.
note.delete_study_notes(storage, study_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update! Looks great to me. I left one minor comment though.
optuna_dashboard/_app.py
Outdated
@@ -165,6 +165,7 @@ def rename_study(study_id: int) -> dict[str, Any]: | |||
response.status = 500 | |||
return {"reason": "Failed to load the new study"} | |||
|
|||
note.copy_notes(storage, src_study, dst_study) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you move this line to under the L155 to make it show error messages to users?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update! LGTM.
Contributor License Agreement
This repository (
optuna-dashboard
) and Goptuna share common code.This pull request may therefore be ported to Goptuna.
Make sure that you understand the consequences concerning licenses and check the box below if you accept the term before creating this pull request.
Reference Issues/PRs
Fixes #660
What does this implement/fix? Explain your changes.
This PR defines a few more functions in _note, to delete and transfer notes for a study/trial. Tests are also added, and I've tested this manually locally.
chrome_WvXYApKXjn.mp4