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

BaseStorage.set_trial_param to return None instead of bool. #1327

Merged
merged 6 commits into from Jun 10, 2020

Conversation

hvy
Copy link
Member

@hvy hvy commented Jun 5, 2020

Motivation

See #1308.

Description of the changes

Fixes #1308 and the following.

  • The storage always sets, i.e the distribution compatibility check is removed. The check is performed by the trial.
  • Simplified Trial by removing _set_new_param_or_get_existing.

@hvy hvy added compatibility Change that breaks compatibility. optuna.storages Related to the `optuna.storages` submodule. This is automatically labeled by github-actions. labels Jun 5, 2020
assert trial.suggest_float("h", 0.5, 0.5, step=1.0) == 0.5 # Suggesting a param.
assert trial.suggest_float("h", 0.5, 0.5, step=1.0) == 0.5 # Suggesting the same param.
assert trial.suggest_int("i", 1, 1, log=True) == 1 # Suggesting a param.
assert trial.suggest_int("i", 1, 1, log=True) == 1 # Suggesting the same param.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can remove this test function altogether.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found it useful to make sure that sampler.sample_independent is not called. If you don't want to add the check, I think you can remove this test function.
If you remove this test, I'm not sure if there is a test that calls the distributions._get_single_value () method. I want to make sure that tests for the method are added when you remove this test.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, thanks for you suggestion. I changed this test to check the number of calls to distributions._get_single_value. What do you think?

@ytsmiling ytsmiling self-requested a review June 5, 2020 00:52
@codecov-commenter
Copy link

codecov-commenter commented Jun 5, 2020

Codecov Report

Merging #1327 into master will increase coverage by 1.16%.
The diff coverage is 96.96%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1327      +/-   ##
==========================================
+ Coverage   86.69%   87.85%   +1.16%     
==========================================
  Files          95       98       +3     
  Lines        7412     7339      -73     
==========================================
+ Hits         6426     6448      +22     
+ Misses        986      891      -95     
Impacted Files Coverage Δ
optuna/storages/base.py 67.59% <ø> (ø)
optuna/storages/in_memory.py 97.66% <ø> (-0.08%) ⬇️
optuna/distributions.py 93.68% <85.71%> (-0.31%) ⬇️
optuna/storages/cached_storage.py 96.44% <100.00%> (-0.04%) ⬇️
optuna/storages/rdb/storage.py 93.66% <100.00%> (-0.08%) ⬇️
optuna/storages/redis.py 94.13% <100.00%> (+1.02%) ⬆️
optuna/trial/_trial.py 92.10% <100.00%> (+0.49%) ⬆️
optuna/visualization/slice.py 98.18% <0.00%> (-0.04%) ⬇️
... and 38 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1c1b4ca...033b6e0. Read the comment docs.

Copy link
Member

@ytsmiling ytsmiling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for creating this PR.
Please correct me if it's wrong but does this PR remove distribution compatibility check across trials (both within a single worker and across multiple workers)? If yes, I think this point needs discussion.

@ytsmiling ytsmiling self-requested a review June 5, 2020 03:56
@hvy
Copy link
Member Author

hvy commented Jun 5, 2020

You are right, we should probably not change this behavior. Do you think we should put the check back to the storage? IMO, we can move this check to the trial to simplify the storage logic since it's possible with the current storage API. However, it might be suboptimal (if there are lots of conditionals) and we'll probably want some other storage API to optimize this check in follow-ups.

@hvy hvy changed the title BaseStorage.set_trial_param to return None instead of bool. [WIP] BaseStorage.set_trial_param to return None instead of bool. Jun 5, 2020
@hvy
Copy link
Member Author

hvy commented Jun 5, 2020

Let me fix the code so that the logic isn't altered for the case you described. I'll add tests on the trial layer as well.

@hvy hvy force-pushed the set-trial-param-no-return branch from 710032a to d463f3b Compare June 5, 2020 08:06
@hvy hvy changed the title [WIP] BaseStorage.set_trial_param to return None instead of bool. BaseStorage.set_trial_param to return None instead of bool. Jun 5, 2020
@hvy
Copy link
Member Author

hvy commented Jun 5, 2020

PTAL. I moved the distribution compatibility back to the storage from the trial. The reason being that we cannot keep the same behavior explained by @ytsmiling above otherwise. If we try to check for compatibility in the trial, we cannot guarantee the expected behavior in a distributed environment where all initial trials sample the same parameter (having the same name) but with different distributions as they're exposed to race condition when writing the sampled parameter back to the storage.

Copy link
Member

@ytsmiling ytsmiling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for addressing #1308. This PR looks almost good, but I left a minor comment and I'd like you to check that.

assert trial.suggest_float("h", 0.5, 0.5, step=1.0) == 0.5 # Suggesting a param.
assert trial.suggest_float("h", 0.5, 0.5, step=1.0) == 0.5 # Suggesting the same param.
assert trial.suggest_int("i", 1, 1, log=True) == 1 # Suggesting a param.
assert trial.suggest_int("i", 1, 1, log=True) == 1 # Suggesting the same param.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found it useful to make sure that sampler.sample_independent is not called. If you don't want to add the check, I think you can remove this test function.
If you remove this test, I'm not sure if there is a test that calls the distributions._get_single_value () method. I want to make sure that tests for the method are added when you remove this test.

@hvy
Copy link
Member Author

hvy commented Jun 8, 2020

Right, thanks for the suggestion about the test. I changes it to count the number of calls to distributions._get_single_value. What do you think? It's not the most beautiful code but I think it's acceptable for this test.

PTAL.

Copy link
Member

@ytsmiling ytsmiling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the quick fix. LGTM!

@toshihikoyanase toshihikoyanase self-assigned this Jun 9, 2020
Copy link
Member

@toshihikoyanase toshihikoyanase left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It basically looks good to me. I add a comment about a test case, but I think it is optional.

Comment on lines +639 to +642
if self._is_fixed_param(name, distribution):
param_value = storage.get_trial_system_attrs(trial_id)["fixed_params"][name]
elif distribution.single():
param_value = distributions._get_single_value(distribution)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is optional, but how about adding a test case to raise warnings if single-value distributions are given with fixed params that are out of ranges? This code correctly handles such a case, and I propose it for future development.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the suggestion. I added tests for enqueue_trial since it's relevant (although a bit stretched) to this PR.

@hvy
Copy link
Member Author

hvy commented Jun 10, 2020

PTAL.

Copy link
Member

@toshihikoyanase toshihikoyanase left a 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 swift action! LGTM.

@toshihikoyanase toshihikoyanase merged commit b5d680a into optuna:master Jun 10, 2020
@toshihikoyanase toshihikoyanase added this to the v2.0.0 milestone Jun 10, 2020
@hvy hvy deleted the set-trial-param-no-return branch June 10, 2020 02:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility Change that breaks compatibility. optuna.storages Related to the `optuna.storages` submodule. This is automatically labeled by github-actions.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unnecessary return value of BaseStorage.set_trial_param.
4 participants