99from devito .data import LEFT , RIGHT
1010from devito .exceptions import InvalidArgument
1111from devito .logger import debug
12- from devito .tools import Pickable , is_integer , memoized_meth
12+ from devito .tools import Pickable , is_integer , is_number , memoized_meth
1313from devito .types .args import ArgProvider
1414from devito .types .basic import Symbol , DataSymbol , Scalar
15- from devito .types .caching import Cached
16- from devito .types .constant import Constant
1715
1816
1917__all__ = ['Dimension' , 'SpaceDimension' , 'TimeDimension' , 'DefaultDimension' ,
@@ -823,10 +821,8 @@ def bound_symbols(self):
823821 return self .parent .bound_symbols
824822
825823
826- class SubsamplingFactor (Constant , Cached ):
827-
828- __hash__ = sympy .Symbol .__hash__
829- _cache_key = Symbol ._cache_key
824+ class SubsamplingFactor (Scalar ):
825+ pass
830826
831827
832828class ConditionalDimension (DerivedDimension ):
@@ -905,40 +901,52 @@ class ConditionalDimension(DerivedDimension):
905901 is_NonlinearDerived = True
906902 is_Conditional = True
907903
908- __rkwargs__ = DerivedDimension .__rkwargs__ + ('factor' , 'condition' , 'indirect' )
904+ __rkwargs__ = DerivedDimension .__rkwargs__ + \
905+ ('symbolic_factor' , 'factor' , 'condition' , 'indirect' )
909906
910907 def __init_finalize__ (self , name , parent = None , factor = None , condition = None ,
911- indirect = False , ** kwargs ):
908+ indirect = False , symbolic_factor = None , ** kwargs ):
912909 # `parent=None` degenerates to a ConditionalDimension outside of
913910 # any iteration space
914911 if parent is None :
915912 parent = BOTTOM
916913
917914 super ().__init_finalize__ (name , parent )
918915
919- # Always make the factor symbolic to allow overrides with different factor.
920- if factor is None or factor == 1 :
916+ # Process subsampling factor
917+ fname = f"{ name } f"
918+ if factor is None :
921919 self ._factor = None
922- elif is_integer (factor ):
923- self ._factor = SubsamplingFactor ( name = f" { name } f" , value = factor ,
924- dtype = np . int32 )
925- elif factor . is_Constant and is_integer ( factor .data ):
926- self . _factor = factor
920+ elif is_number (factor ):
921+ self ._factor = int ( factor )
922+ elif factor . is_Constant :
923+ self . _factor = factor .data
924+ fname = factor . name
927925 else :
928926 raise ValueError ("factor must be an integer or integer Constant" )
929927
928+ if self ._factor is not None :
929+ # Always make the factor symbolic to allow overrides with different factor.
930+ self ._symbolic_factor = symbolic_factor or \
931+ SubsamplingFactor (name = fname , dtype = np .int32 , is_const = True )
932+ else :
933+ self ._symbolic_factor = None
934+
930935 self ._condition = condition
931936 self ._indirect = indirect
932937
933938 @property
934939 def spacing (self ):
935- s = self ._factor .data if self ._factor is not None else 1
936- return s * self .parent .spacing
940+ return self .factor * self .parent .spacing
937941
938942 @property
939943 def factor (self ):
940944 return self ._factor if self ._factor is not None else 1
941945
946+ @property
947+ def symbolic_factor (self ):
948+ return self ._symbolic_factor
949+
942950 @property
943951 def condition (self ):
944952 return self ._condition
@@ -960,7 +968,7 @@ def free_symbols(self):
960968
961969 def _arg_values (self , interval , grid = None , ** kwargs ):
962970 # Parent dimension define the interval
963- fact = self ._factor . data if self . _factor is not None else 1
971+ fact = self .factor
964972 toint = lambda x : math .ceil (x / fact )
965973 vals = {}
966974 try :
@@ -984,12 +992,8 @@ def _arg_defaults(self, _min=None, size=None, alias=None):
984992 dim = alias or self
985993 if dim .condition is not None or size is None or dim ._factor is None :
986994 return defaults
987- try :
988- # Is it a symbolic factor?
989- factor = defaults [dim ._factor .name ] = self ._factor .data
990- except AttributeError :
991- factor = dim ._factor
992995
996+ factor = defaults [dim .symbolic_factor .name ] = self .factor
993997 defaults [dim .parent .max_name ] = range (0 , factor * size - 1 )
994998
995999 return defaults
0 commit comments