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

BoundSymbol constructor to be cached #1576

Merged
merged 4 commits into from
Feb 4, 2021
Merged
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
19 changes: 14 additions & 5 deletions devito/types/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1203,16 +1203,25 @@ def __getitem__(self, indices, **kwargs):
__reduce_ex__ = Pickable.__reduce_ex__


class BoundSymbol(Symbol):
class BoundSymbol(AbstractSymbol):

"""
Wrapper class for Symbols that are bound to a symbolic data object.
"""

def __init_finalize__(self, *args, function=None, **kwargs):
self._function = function
Notes
-----
By deliberately inheriting from AbstractSymbol, a BoundSymbol won't be
in the devito cache. This will avoid cycling references in the cache
(e.g., an entry for a Function `u(x)` and an entry for `u._C_symbol` with
the latter's key including `u(x)`). This is totally fine. The BoundSymbol
is tied to a specific Function; once the Function gets out of scope, the
BoundSymbol will also become a garbage collector candidate.
"""

super().__init_finalize__(*args, **kwargs)
def __new__(cls, *args, function=None, **kwargs):
obj = AbstractSymbol.__new__(cls, *args, **kwargs)
obj._function = function
return obj

@property
def function(self):
Expand Down
13 changes: 13 additions & 0 deletions tests/test_caching.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,19 @@ def test_clear_cache(self, operate_on_empty_cache, nx=1000, ny=1000):

clear_cache()

def test_clear_cache_with_Csymbol(self, operate_on_empty_cache, nx=1000, ny=1000):
grid = Grid(shape=(nx, ny), dtype=np.float64)
cache_size = len(_SymbolCache)

u = Function(name='u', grid=grid, space_order=2)
# Both u and u(inds) added to cache
assert(len(_SymbolCache) == cache_size + 2)

u._C_symbol
# Cache size won't change since _C_symbol isn't cached by devito to
# avoid circular references in the cache
assert(len(_SymbolCache) == cache_size + 2)

def test_clear_cache_with_alive_symbols(self, operate_on_empty_cache,
nx=1000, ny=1000):
"""
Expand Down