Skip to content

Commit cae7e6a

Browse files
committed
compiler: Support unguarded task groups
1 parent a5a6e1f commit cae7e6a

1 file changed

Lines changed: 25 additions & 11 deletions

File tree

devito/passes/iet/orchestration.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
from devito.exceptions import CompilationError
88
from devito.ir.iet import (
9-
AsyncCall, AsyncCallable, BlankLine, BusyWait, Call, Callable, Conditional, DummyExpr,
10-
FindNodes, List, SyncSpot, SyncSpotRegion, Transformer, derive_parameters,
9+
AsyncCall, AsyncCallable, BlankLine, Block, BusyWait, Call, Callable, Conditional,
10+
DummyExpr, FindNodes, List, SyncSpot, SyncSpotRegion, Transformer, derive_parameters,
1111
make_callable
1212
)
1313
from devito.ir.iet.visitors import LazyVisitor
@@ -54,12 +54,21 @@ def _fuse_tasks(self, iet):
5454
subs1 = {}
5555

5656
for tasks in groups.values():
57+
subs1.update({task.spot: SyncSpot(task.releases) for task in tasks})
58+
59+
# Unguarded tasks form separate groups and can share one SyncSpot
60+
if tasks[0].guard is None:
61+
sync_ops = tuple(op for task in tasks for op in task.sync_ops)
62+
sync_ops += tuple(tasks[-1].releases)
63+
# Blocks preserve the local scope of each task body
64+
body = [Block(body=task.spot.body) for task in tasks]
65+
subs1[tasks[-1].spot] = SyncSpot(sync_ops, body=body)
66+
continue
67+
5768
spots = [SyncSpot(task.sync_ops,
5869
body=Conditional(task.guard, task.spot.body))
5970
for task in tasks]
60-
6171
insertions[tasks[-1].anchor].append(SyncSpotRegion(spots))
62-
subs1.update({task.spot: SyncSpot(task.releases) for task in tasks})
6372

6473
if not subs1:
6574
return iet
@@ -252,7 +261,7 @@ def ordered(sync_spots):
252261

253262
class CollectTasks(LazyVisitor):
254263

255-
"""Collect and group guarded asynchronous SyncSpots."""
264+
"""Collect and group compatible asynchronous SyncSpots."""
256265

257266
def _post_visit(self, ret):
258267
groups = defaultdict(list)
@@ -269,25 +278,30 @@ def visit_Conditional(self, o, **kwargs):
269278
yield from self._visit(o.children, **kwargs)
270279

271280
def visit_SyncSpot(self, o, iteration=None, condition=None, anchor=None):
272-
if iteration is not None and condition is not None:
281+
if iteration is not None:
273282
syncs = as_mapper(o.sync_ops, type)
274283

275284
optypes = set(syncs)
276285
for optype in (PrefetchUpdate, WithLock):
277286
if optypes != {optype, ReleaseLock}:
278287
continue
279288

280-
# Task SyncSpots inherit a guard without an `else` branch from
281-
# the originating Cluster
282-
assert not condition.else_body
289+
guard = None
290+
if condition is not None:
291+
# Task SyncSpots inherit a guard without an `else` branch
292+
# from the originating Cluster
293+
assert not condition.else_body
294+
guard = condition.condition
283295

284296
sync_ops = syncs[optype]
285297

286298
gid, = {i.gid for i in sync_ops}
287299
if gid is not None:
288-
task = Task(o, condition.condition, anchor or condition,
300+
task = Task(o, guard, anchor or condition,
289301
sync_ops, syncs[ReleaseLock])
290-
yield (iteration, gid, optype, anchor is not None), task
302+
key = (iteration, gid, optype, anchor is not None,
303+
condition is not None)
304+
yield key, task
291305

292306
break
293307

0 commit comments

Comments
 (0)