diff --git a/devito/ir/iet/utils.py b/devito/ir/iet/utils.py index 2bac05733c..a31c82973a 100644 --- a/devito/ir/iet/utils.py +++ b/devito/ir/iet/utils.py @@ -123,8 +123,7 @@ def derive_parameters(iet, drop_locals=False, ordering='default'): # Maybe filter out all other compiler-generated objects if drop_locals: - parameters = [p for p in parameters - if not (p.is_ArrayBasic or p.is_LocalObject)] + parameters = [p for p in parameters if not p.is_LocalType] # NOTE: This is requested by the caller when the parameters are used to # construct Callables whose signature only depends on the object types, diff --git a/devito/types/array.py b/devito/types/array.py index e45c3d78c9..34237f01bf 100644 --- a/devito/types/array.py +++ b/devito/types/array.py @@ -6,17 +6,27 @@ from devito.tools import (Reconstructable, as_tuple, c_restrict_void_p, dtype_to_ctype, dtypes_vector_mapper, is_integer) -from devito.types.basic import AbstractFunction +from devito.types.basic import AbstractFunction, LocalType from devito.types.utils import CtypesFactory, DimensionTuple __all__ = ['Array', 'ArrayMapped', 'ArrayObject', 'PointerArray', 'Bundle', 'ComponentAccess', 'Bag'] -class ArrayBasic(AbstractFunction): +class ArrayBasic(AbstractFunction, LocalType): is_ArrayBasic = True + __rkwargs__ = AbstractFunction.__rkwargs__ + ('is_const', 'liveness') + + def __init_finalize__(self, *args, **kwargs): + super().__init_finalize__(*args, **kwargs) + + self._liveness = kwargs.get('liveness', 'lazy') + assert self._liveness in ['eager', 'lazy'] + + self._is_const = kwargs.get('is_const', False) + @classmethod def __indices_setup__(cls, *args, **kwargs): dimensions = kwargs['dimensions'] @@ -46,6 +56,10 @@ def shape(self): def shape_allocated(self): return self.symbolic_shape + @property + def is_const(self): + return self._is_const + class Array(ArrayBasic): @@ -101,8 +115,8 @@ class Array(ArrayBasic): is_Array = True - __rkwargs__ = (AbstractFunction.__rkwargs__ + - ('dimensions', 'liveness', 'scope', 'initvalue')) + __rkwargs__ = (ArrayBasic.__rkwargs__ + + ('dimensions', 'scope', 'initvalue')) def __new__(cls, *args, **kwargs): kwargs.update({'options': {'evaluate': False}}) @@ -116,9 +130,6 @@ def __new__(cls, *args, **kwargs): def __init_finalize__(self, *args, **kwargs): super().__init_finalize__(*args, **kwargs) - self._liveness = kwargs.get('liveness', 'lazy') - assert self._liveness in ['eager', 'lazy'] - self._scope = kwargs.get('scope', 'heap') assert self._scope in ['heap', 'stack', 'static', 'constant', 'shared'] @@ -143,10 +154,6 @@ def __padding_setup__(self, **kwargs): raise TypeError("`padding` must be int or %d-tuple of ints" % self.ndim) return DimensionTuple(*padding, getters=self.dimensions) - @property - def liveness(self): - return self._liveness - @property def scope(self): return self._scope @@ -155,14 +162,6 @@ def scope(self): def _C_ctype(self): return POINTER(dtype_to_ctype(self.dtype)) - @property - def _mem_internal_eager(self): - return self._liveness == 'eager' - - @property - def _mem_internal_lazy(self): - return self._liveness == 'lazy' - @property def _mem_stack(self): return self._scope in ('stack', 'shared') diff --git a/devito/types/basic.py b/devito/types/basic.py index d1dd3dcb93..10e07087b2 100644 --- a/devito/types/basic.py +++ b/devito/types/basic.py @@ -259,6 +259,7 @@ class Basic(CodeSymbol): is_Bundle = False is_Object = False is_LocalObject = False + is_LocalType = False # Created by the user is_Input = False @@ -1662,3 +1663,35 @@ class IrregularFunctionInterface: @property def nbytes_max(self): raise NotImplementedError + + +class LocalType(Basic): + """ + This is the abstract base class for local types, which are + generated by the compiler in C rather than in Python. + + Notes + ----- + Subclasses should setup `_liveness`. + """ + + is_LocalType = True + + @property + def liveness(self): + return self._liveness + + @property + def _mem_internal_eager(self): + return self._liveness == 'eager' + + @property + def _mem_internal_lazy(self): + return self._liveness == 'lazy' + + """ + A modifier added to the subclass C declaration when it appears + in a function signature. For example, a subclass might define `_C_modifier = '&'` + to impose pass-by-reference semantics. + """ + _C_modifier = None diff --git a/devito/types/object.py b/devito/types/object.py index 3768dc76fd..cba54b0add 100644 --- a/devito/types/object.py +++ b/devito/types/object.py @@ -5,7 +5,7 @@ from devito.tools import Pickable, as_tuple, sympy_mutex from devito.types.args import ArgProvider from devito.types.caching import Uncached -from devito.types.basic import Basic +from devito.types.basic import Basic, LocalType from devito.types.utils import CtypesFactory __all__ = ['Object', 'LocalObject', 'CompositeObject'] @@ -155,7 +155,7 @@ def fields(self): return [i for i, _ in self.pfields] -class LocalObject(AbstractObject): +class LocalObject(AbstractObject, LocalType): """ Object with derived type defined inside an Operator. @@ -193,10 +193,6 @@ def _hashable_content(self): self.cargs + (self.initvalue, self.liveness, self.is_global)) - @property - def liveness(self): - return self._liveness - @property def is_global(self): return self._is_global @@ -235,21 +231,6 @@ def _C_free(self): """ return None - _C_modifier = None - """ - A modifier added to the LocalObject's C declaration when the object appears - in a function signature. For example, a subclass might define `_C_modifier = '&'` - to impose pass-by-reference semantics. - """ - - @property - def _mem_internal_eager(self): - return self._liveness == 'eager' - - @property - def _mem_internal_lazy(self): - return self._liveness == 'lazy' - @property def _mem_global(self): return self._is_global