Skip to content

Commit

Permalink
Merge pull request #918 from rainwoodman/mock-model-cycles
Browse files Browse the repository at this point in the history
Remove reference cycles between MockFactory and ModelFactory.
  • Loading branch information
aphearin authored May 2, 2019
2 parents 3a35033 + b1c05fd commit 6ce9862
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""
"""
import sys
import pytest
import numpy as np

Expand All @@ -13,6 +14,25 @@
__all__ = ('test_hearin15', )



@pytest.mark.skipif(sys.platform == 'win32',
reason="does not run on windows")
def test_memory_leak():
model = PrebuiltHodModelFactory('hearin15')
halocat = FakeSim()
import resource

model.populate_mock(halocat)
maxrss = []
for i in range(9):
model.mock.populate()
maxrss.append(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)

import numpy
# memory usage shall not increase significantly per run.
assert (numpy.diff(maxrss) < 1024).all()


def test_hearin15():
"""
"""
Expand Down
11 changes: 11 additions & 0 deletions halotools/empirical_models/factories/mock_factory_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from .mock_helpers import three_dim_pos_bundle, infer_mask_from_kwargs

from .. import model_helpers, model_defaults
import weakref

try:
from ... import mock_observables
Expand Down Expand Up @@ -76,6 +77,7 @@ def __init__(self, **kwargs):
except:
pass


# Create a list of halo properties that will be inherited by the mock galaxies
self.additional_haloprops = copy(model_defaults.default_haloprop_list_inherited_by_mock)

Expand All @@ -86,6 +88,15 @@ def __init__(self, **kwargs):

self.galaxy_table = Table()

@property
def model(self):
""" model, a weak reference to the model because mock is always a member of model """
return self._model()

@model.setter
def model(self, value):
self._model = weakref.ref(value)

@abstractmethod
def populate(self, **kwargs):
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,12 +276,17 @@ def update_param_dict_decorator(self, component_model, func_name):
:ref:`param_dict_mechanism`
"""

# do not pass self into the scope;
# assuming param_dict is not replaced during life cycle of self.
# passing `self` causes a cycle reference when
# the function is assigned as attributes of self.
__param_dict__ = self.param_dict
def decorated_func(*args, **kwargs):

# Update the param_dict as necessary
for key in list(self.param_dict.keys()):
for key in list(__param_dict__.keys()):
if key in component_model.param_dict:
component_model.param_dict[key] = self.param_dict[key]
component_model.param_dict[key] = __param_dict__[key]

func = getattr(component_model, func_name)
return func(*args, **kwargs)
Expand Down

0 comments on commit 6ce9862

Please sign in to comment.