8000 Use deepcopy to prevent reference cycles in Optimizer by freddyaboulton · Pull Request #1029 · scikit-optimize/scikit-optimize · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Feb 28, 2024. It is now read-only.

Use deepcopy to prevent reference cycles in Optimizer #1029

Merged
merged 4 commits into from
May 11, 2021

Conversation

freddyaboulton
Copy link
Contributor

Fixes #1028

@kernc I followed your suggestion to use locals but still need a deepcopy or else the reference cycle will still be present.

@freddyaboulton freddyaboulton marked this pull request as ready for review May 5, 2021 14:10
specs = {"args": copy.copy(inspect.currentframe().f_locals),
"function": inspect.currentframe().f_code.co_name}
specs = {"args": copy.deepcopy(locals()),
"function": copy.deepcopy(inspect.currentframe().f_code.co_name)}
Copy link
Contributor

Choose a reason for hiding this comment

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

What if we replace function with literal 'base_minimize' as in the other example? I don't like manual accounting, but what is the function of specs/'function' anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

@@ -171,7 +170,7 @@ def __init__(self, dimensions, base_estimator="gp",
model_queue_size=None,
acq_func_kwargs=None,
acq_optimizer_kwargs=None):
self.specs = {"args": copy.copy(inspect.currentframe().f_locals),
self.specs = {"args": copy.deepcopy(locals()),
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm thinking, if you drop self from locals(), copying shouldn't be necessary any longer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great call - didn't know self wasn't needed!

@@ -171,7 +169,9 @@ def __init__(self, dimensions, base_estimator="gp",
model_queue_size=None,
acq_func_kwargs=None,
acq_optimizer_kwargs=None):
self.specs = {"args": copy.copy(inspect.currentframe().f_locals),
args = locals()
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess the function call constructs a dict on the fly, but I'd do a locals().copy() to comply with the note here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

@@ -2 8000 09,8 +209,8 @@ def base_minimize(func, dimensions, base_estimator,
For more details related to the OptimizeResult object, refer
http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.OptimizeResult.html
"""
specs = {"args": copy.copy(inspect.currentframe().f_locals),
"function": inspect.currentframe().f_code.co_name}
specs = {"args": copy.deepcopy(locals()),
Copy link
Contributor
@kernc kernc May 5, 2021

Choose a reason for hiding this comment

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

Given that there's no deepcopying (or copying even) in the other example below, is deepcopy here necessary?

Did you maybe check the garbage graph afterwards? Are we safe?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point I kept the copy to be safe but after visualizing the graph of OptimizeResult and I don't see any circular references. The obj graph is quite big because the specs contain the global branin function but that's expected. Worth noting that if you pass an object method as the func argument to base_minimize, that object will be referred to by OptimizeResult as long as OptimizeResult lives.

skopt_res_min

@kernc kernc self-requested a review May 7, 2021 16:11
@glouppe glouppe merged commit 438a6da into scikit-optimize:master May 11, 2021
@glouppe
Copy link
Member
glouppe commented May 11, 2021

Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Optimizers cannot be freed by garbage collector
3 participants
0