@@ -320,14 +320,17 @@ def lex_le(self, other):
320320 def lex_lt (self , other ):
321321 return self .timestamp < other .timestamp
322322
323- def distance (self , other ):
323+ def distance (self , other , logical = False ):
324324 """
325325 Compute the distance from ``self`` to ``other``.
326326
327327 Parameters
328328 ----------
329329 other : TimedAccess
330330 The TimedAccess w.r.t. which the distance is computed.
331+ logical : bool
332+ Compute a logical distance rather than true distance (i.e. ignoring
333+ degenerating indices created by size 1 buffers etc).
331334 """
332335 if isinstance (self .access , ComponentAccess ) and \
333336 isinstance (other .access , ComponentAccess ) and \
@@ -392,7 +395,7 @@ def distance(self, other):
392395 # objects falls back to zero, as any other value would be
393396 # nonsensical
394397 ret .append (S .Zero )
395- elif degenerating_indices (self [n ], other [n ], self .function ):
398+ elif degenerating_indices (self [n ], other [n ], self .function , logical = logical ):
396399 # Special case: `sai` and `oai` may be different symbolic objects
397400 # but they can be proved to systematically generate the same value
398401 ret .append (S .Zero )
@@ -786,6 +789,13 @@ def is_storage_related(self, dims=None):
786789 return False
787790
788791
792+ class LogicalDependence (Dependence ):
793+
794+ @cached_property
795+ def distance (self ):
796+ return self .source .distance (self .sink , logical = True )
797+
798+
789799class DependenceGroup (set ):
790800
791801 @cached_property
@@ -1111,20 +1121,21 @@ def d_flow(self):
11111121 return DependenceGroup (self .d_flow_gen ())
11121122
11131123 @memoized_generator
1114- def d_anti_gen (self ):
1124+ def d_anti_gen (self , depcls = Dependence ):
11151125 """Generate the anti (or "write-after-read") dependences."""
11161126 for k , v in self .writes .items ():
11171127 for w in v :
11181128 for r in self .reads_smart_gen (k ):
11191129 if any (not rule (r , w ) for rule in self .rules ):
11201130 continue
11211131
1122- dependence = Dependence (r , w )
1132+ dependence = depcls (r , w )
11231133
11241134 if dependence .is_imaginary :
11251135 continue
11261136
11271137 distance = dependence .distance
1138+
11281139 try :
11291140 is_anti = distance > 0 or (r .lex_lt (w ) and distance == 0 )
11301141 except TypeError :
@@ -1140,6 +1151,14 @@ def d_anti(self):
11401151 """Anti (or "write-after-read") dependences."""
11411152 return DependenceGroup (self .d_anti_gen ())
11421153
1154+ @cached_property
1155+ def d_anti_logical (self ):
1156+ """
1157+ Anti (or "write-after-read") dependences using logical rather than true
1158+ distances.
1159+ """
1160+ return DependenceGroup (self .d_anti_gen (depcls = LogicalDependence ))
1161+
11431162 @memoized_generator
11441163 def d_output_gen (self ):
11451164 """Generate the output (or "write-after-write") dependences."""
@@ -1425,7 +1444,7 @@ def disjoint_test(e0, e1, d, it):
14251444 return not bool (i0 .intersect (i1 ))
14261445
14271446
1428- def degenerating_indices (i0 , i1 , function ):
1447+ def degenerating_indices (i0 , i1 , function , logical = False ):
14291448 """
14301449 True if `i0` and `i1` are indices that are possibly symbolically
14311450 different, but they can be proved to systematically degenerate to the
@@ -1440,17 +1459,19 @@ def degenerating_indices(i0, i1, function):
14401459
14411460 # Case 2: SteppingDimension corresponding to buffer of size 1
14421461 # Extract dimension from both IndexAccessFunctions -> d0, d1
1443- try :
1444- d0 = i0 .d
1445- except AttributeError :
1446- d0 = i0
1447- try :
1448- d1 = i1 .d
1449- except AttributeError :
1450- d1 = i1
1462+ # Skipped if doing a purely logical check
1463+ if not logical :
1464+ try :
1465+ d0 = i0 .d
1466+ except AttributeError :
1467+ d0 = i0
1468+ try :
1469+ d1 = i1 .d
1470+ except AttributeError :
1471+ d1 = i1
14511472
1452- with suppress (AttributeError ):
1453- if d0 is d1 and d0 .is_Stepping and function ._size_domain [d0 ] == 1 :
1454- return True
1473+ with suppress (AttributeError ):
1474+ if d0 is d1 and d0 .is_Stepping and function ._size_domain [d0 ] == 1 :
1475+ return True
14551476
14561477 return False
0 commit comments