@@ -144,6 +144,37 @@ def test_multiple_tile_sizes(self, par_tile):
144144 assert trees [3 ][1 ].pragmas [0 ].ccode .value == \
145145 f'acc parallel loop { sclause } present(src,src_gp,src_wx,src_wy,src_wz,u)'
146146
147+ def test_short_multi_tile_keeps_outer_dim_blocked (self ):
148+ """
149+ A multi `par-tile` entry shorter than the nest it lands on must not cost
150+ the outermost Dimension its BlockDimension: on a device, dropping it
151+ would leave `x` iterated outside the offloaded nest.
152+ """
153+ grid = Grid (shape = (8 , 8 , 8 ))
154+
155+ u = TimeFunction (name = "u" , grid = grid , space_order = 4 )
156+ v = TimeFunction (name = "v" , grid = grid , space_order = 4 )
157+
158+ eqns = [Eq (u .forward , u .dx ),
159+ Eq (v .forward , u .forward .dx )]
160+
161+ # The second entry is 2D, while the nest it lands on is 3D
162+ par_tile = ((32 , 4 , 4 ), (16 , 4 ))
163+
164+ op = Operator (eqns , platform = 'nvidiaX' , language = 'openacc' ,
165+ opt = (
166+ 'advanced' ,
167+ {'par-tile' : par_tile , 'blocklevels' : 1 , 'blockinner' : True }))
168+
169+ bns , _ = assert_blocking (op , {'x0_blk0' , 'x1_blk0' })
170+
171+ expected = ((4 , 4 , 32 ), (4 , 4 , 16 ))
172+ for root , v in zip (bns .values (), expected , strict = True ):
173+ iters = FindNodes (Iteration ).visit (root )
174+ iters = [i for i in iters if i .dim .is_Block and i .dim ._depth == 1 ]
175+ assert len (iters ) == len (v )
176+ assert all (i .step == j for i , j in zip (iters , v , strict = True ))
177+
147178 def test_multi_tile_blocking_structure (self ):
148179 grid = Grid (shape = (8 , 8 , 8 ))
149180
0 commit comments