@@ -1937,14 +1937,16 @@ def define(self, dimensions):
19371937class TestSubDomainArguments :
19381938
19391939 @staticmethod
1940- def _make_operator (left_shift = 0 , right_shift = 0 , grid = None , middle = False ):
1940+ def _make_operator (left_shift = 0 , right_shift = 0 , grid = None , middle = False ,
1941+ thickness = (8 , 8 )):
19411942 grid = grid or Grid (shape = (8 , 32 ))
19421943 y = grid .dimensions [- 1 ]
19431944
1944- yl = SubDimension .left ('yl' , y , 8 )
1945- yr = SubDimension .right ('yr' , y , 8 )
1945+ left , right = thickness
1946+ yl = SubDimension .left ('yl' , y , left )
1947+ yr = SubDimension .right ('yr' , y , right )
19461948 if middle :
1947- yl = yr = SubDimension .middle ('ym' , y , 8 , 8 )
1949+ yl = yr = SubDimension .middle ('ym' , y , left , right )
19481950
19491951 u = TimeFunction (name = 'u' , grid = grid , space_order = 8 )
19501952 v = TimeFunction (name = 'v' , grid = grid , space_order = 8 )
@@ -1979,7 +1981,11 @@ def test_stencil_gap(self, middle, left_shift, right_shift, margin, override):
19791981 dl , = [d for d in op .dimensions if d .is_Sub and not d .is_right ]
19801982 kwargs = {dl .ltkn .name : 32 - 8 - 8 - margin }
19811983
1982- if middle and margin < 0 :
1984+ if override == 'thickness' :
1985+ with pytest .raises (InvalidArgument ,
1986+ match = 'Cannot override SubDimension thickness' ):
1987+ op .arguments (time_M = 0 , ** kwargs )
1988+ elif middle and margin < 0 :
19831989 with pytest .raises (InvalidArgument , match = 'at least 8 interior points' ):
19841990 op .arguments (time_M = 0 , ** kwargs )
19851991 else :
@@ -2007,13 +2013,11 @@ def test_runtime_space_order(self, middle, space_order, margin):
20072013
20082014 @pytest .mark .parametrize ('side' , ['left' , 'right' ])
20092015 def test_empty_slab (self , side ):
2010- op , _ = self ._make_operator (right_shift = - 4 )
2011-
2012- d , = [d for d in op .dimensions if d .is_Sub and getattr (d , f'is_{ side } ' )]
2013- thickness = d .ltkn if side == 'left' else d .rtkn
2016+ thickness = (0 , 8 ) if side == 'left' else (8 , 0 )
2017+ op , _ = self ._make_operator (right_shift = - 4 , thickness = thickness )
20142018
20152019 # The active slab fills the local domain; the opposite slab is absent
2016- op .arguments (time_M = 0 , y_M = 7 , ** { thickness . name : 0 } )
2020+ op .arguments (time_M = 0 , y_M = 7 )
20172021
20182022 def test_before_autotuning (self ):
20192023 op , _ = self ._make_operator (right_shift = - 4 , middle = True )
@@ -2032,32 +2036,27 @@ def test_before_autotuning(self):
20322036 def test_distributed_middle (self , left , mode ):
20332037 grid = Grid (shape = (16 , 32 ), topology = (1 , 2 ))
20342038
2035- op , _ = self ._make_operator (grid = grid , middle = True )
2036-
2037- d , = [d for d in op .dimensions if d .is_Sub ]
2039+ op , _ = self ._make_operator (grid = grid , middle = True , thickness = (left , 0 ))
20382040
20392041 # Rank 0 has one point or an empty middle (possibly with inverted bounds).
20402042 # Only the global size determines whether the middle is large enough
2041- kwargs = {d .ltkn .name : left , d .rtkn .name : 0 }
2042-
20432043 if left == 25 :
20442044 with pytest .raises (InvalidArgument , match = 'at least 8 interior points' ):
2045- op .arguments (time_M = 0 , ** kwargs )
2045+ op .arguments (time_M = 0 )
20462046 else :
2047- op .arguments (time_M = 0 , ** kwargs )
2047+ op .arguments (time_M = 0 )
20482048
20492049 @pytest .mark .parallel (mode = [(2 , 'basic' )])
20502050 def test_collective_rejection (self , mode ):
20512051 grid = Grid (shape = (32 , 32 ), topology = (2 , 1 ))
20522052
20532053 op , _ = self ._make_operator (right_shift = - 4 , grid = grid , middle = True )
20542054
2055- dl , = [d for d in op .dimensions if d .is_Sub and d .is_middle ]
2056- left = 24 if grid .distributor .myrank == 0 else 0
2055+ upper = 22 if grid .distributor .myrank == 0 else 31
20572056
2058- # Only rank 0 has an insufficient middle; its peer has 24 interior points
2057+ # Only rank 0 has an insufficient middle; its peer has 16 interior points
20592058 with pytest .raises (InvalidArgument , match = 'interior points' ):
2060- op .arguments (time_M = 0 , ** { dl . ltkn . name : left } )
2059+ op .arguments (time_M = 0 , y_M = upper )
20612060
20622061 def test_function_on_subdomain (self ):
20632062 class Interior (SubDomain ):
@@ -2086,4 +2085,52 @@ def define(self, dimensions):
20862085 assert concrete .ltkn .name in args
20872086
20882087 with pytest .raises (InvalidArgument , match = 'at least 8 interior points' ):
2088+ op .arguments (y_M = 22 )
2089+
2090+ with pytest .raises (InvalidArgument ,
2091+ match = 'Cannot override SubDimension thickness' ):
20892092 op .arguments (** {concrete .ltkn .name : 17 })
2093+
2094+ def test_thickness_overrides (self ):
2095+ grid = Grid (shape = (32 ,))
2096+ x , = grid .dimensions
2097+ xi = SubDimension .left ('xi' , x , 4 )
2098+
2099+ f = Function (name = 'f' , grid = grid , space_order = 0 )
2100+
2101+ eq = Eq (f [xi ], 1 )
2102+
2103+ op = Operator (eq , name = 'thickness_overrides' )
2104+
2105+ d , = [d for d in op .dimensions if d .is_Sub ]
2106+
2107+ with pytest .raises (InvalidArgument ,
2108+ match = 'Cannot override SubDimension thickness' ):
2109+ op .apply (** {d .ltkn .name : 2 })
2110+
2111+ assert np .all (f .data == 0 )
2112+
2113+ @pytest .mark .parallel (mode = [(2 , 'basic' )])
2114+ def test_collective_thickness_rejection (self , mode ):
2115+ grid = Grid (shape = (32 ,))
2116+ x , = grid .dimensions
2117+ xi = SubDimension .middle ('xi' , x , 4 , 4 )
2118+
2119+ f = Function (name = 'f' , grid = grid , space_order = 0 )
2120+
2121+ eq = Eq (f [xi ], 1 )
2122+
2123+ op = Operator (eq , name = 'collective_thickness_rejection' )
2124+
2125+ d , = [d for d in op .dimensions if d .is_Sub ]
2126+ t = d .ltkn
2127+
2128+ # MPI clips the declared thicknesses without any explicit overrides
2129+ args = op .arguments ()
2130+ assert set (grid .distributor .comm .allgather (args [t .name ])) == {0 , 4 }
2131+
2132+ # Only rank 0 supplies an override; all ranks must reject it
2133+ kwargs = {t .name : 4 } if grid .distributor .myrank == 0 else {}
2134+ with pytest .raises (InvalidArgument ,
2135+ match = 'Cannot override SubDimension thickness' ):
2136+ op .arguments (** kwargs )
0 commit comments