Skip to content

Commit 3738b2d

Browse files
Bugfix
1 parent 7ffa2c9 commit 3738b2d

2 files changed

Lines changed: 36 additions & 9 deletions

File tree

accelforge/frontend/mapping/mapping.py

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from pydantic import ConfigDict, Discriminator, Tag, computed_field
3232
import sympy
3333

34+
from accelforge.frontend.renames import EinsumName
3435
from accelforge.util._basetypes import (
3536
# Parsing helpers for the input files.
3637
EvalableModel,
@@ -318,7 +319,13 @@ class Loop(MappingNode):
318319
rank_variable: set[RankVariable] | RankVariable
319320
""" The rank variable(s) iterated over in this loop. This may be a
320321
single rank variable, or a set of rank variables if the loop is shared between
321-
multiple Einsums. """
322+
multiple Einsums.
323+
324+
NOTE FOR DEVELOPERS: If the rank variable is a set DURING PMAPPIN GENERATION, then
325+
it means that the loop is a placeholder for multiple loops in the given Einsum. They
326+
will be split into multiple loops later. If the rank variable
327+
328+
"""
322329

323330
tile_shape: EvalsTo[sympy.Symbol | sympy.Expr | int | str] = "symbol"
324331
"""
@@ -353,6 +360,12 @@ class Loop(MappingNode):
353360
tile_shape for details.
354361
"""
355362

363+
_einsum_to_rank_variables: dict[EinsumName, set[RankVariable]] = {}
364+
"""
365+
If there are multiple rank variables in this loop, this dictionary says which rank
366+
variables belong to which Einsum.
367+
"""
368+
356369
_calculated_n_iterations: (
357370
Literal["symbol"] | sympy.Symbol | sympy.Expr | int | str | None
358371
) = None
@@ -1073,6 +1086,14 @@ def _pop_loop_group(groups: list[list[MappingNode]]) -> list[MappingNode]:
10731086
# variables and assume that rank variable translation would fix it.
10741087
assert len(my_loop_group) == 1 or len(other_loop_group) == 1
10751088
has_one, may_not_have_one = my_loop_group, other_loop_group
1089+
1090+
my_rv = set()
1091+
other_rv = set()
1092+
for m in my_loop_group:
1093+
my_rv |= m.rank_variable if isinstance(m.rank_variable, set) else set([m.rank_variable])
1094+
for o in other_loop_group:
1095+
other_rv |= o.rank_variable if isinstance(o.rank_variable, set) else set([o.rank_variable])
1096+
10761097
if len(has_one) != 1:
10771098
has_one, may_not_have_one = other_loop_group, my_loop_group
10781099

@@ -1095,8 +1116,14 @@ def _pop_loop_group(groups: list[list[MappingNode]]) -> list[MappingNode]:
10951116

10961117
may_not_have_one.remove(l2)
10971118
rv = l2.rank_variable
1119+
for compute in self.get_nodes_of_type(Compute):
1120+
for r in my_rv:
1121+
l._einsum_to_rank_variables[compute.einsum] = r
10981122
rv = rv if isinstance(rv, set) else set([rv])
10991123
l.rank_variable = l.rank_variable | rv
1124+
for compute in other.get_nodes_of_type(Compute):
1125+
for r in other_rv:
1126+
l._einsum_to_rank_variables[compute.einsum] = r
11001127
to_add = [l]
11011128

11021129
zipped_groups.append(to_add)
@@ -1542,15 +1569,17 @@ def split_reservations(self):
15421569
new_nodes.append(node)
15431570
self.nodes = new_nodes
15441571

1545-
def split_loop_with_multiple_rank_variables(self, stride_and_halo: dict[str, tuple[int, int]]):
1572+
def split_loop_with_multiple_rank_variables(self, einsum_name: EinsumName):
15461573
new_nodes = []
1547-
my_rank_variables = set(x[1] for x in stride_and_halo)
15481574
for node in self.nodes:
15491575
if isinstance(node, Loop) and isinstance(node.rank_variable, set):
1550-
ranks_in_stride_and_halo = node.rank_variable & my_rank_variables
1551-
assert len(ranks_in_stride_and_halo) == 1, f"Expected 1 rank in stride and halo, got {len(ranks_in_stride_and_halo)}"
1576+
if einsum_name not in node._einsum_to_rank_variables:
1577+
raise ValueError(
1578+
f"Loop {node.compact_str()} has multiple rank variables. Make "
1579+
f"sure to populate _einsum_to_rank_variables for this loop."
1580+
)
15521581
new_node = copy.copy(node)
1553-
new_node.rank_variable = ranks_in_stride_and_halo.pop()
1582+
new_node.rank_variable = node._einsum_to_rank_variables[einsum_name]
15541583
new_nodes.append(new_node)
15551584
else:
15561585
new_nodes.append(node)

accelforge/model/main.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,7 @@ def evaluate_mapping(
113113
)
114114

115115
pmapping.split_reservations()
116-
pmapping.split_loop_with_multiple_rank_variables(
117-
job.stride_and_halo[einsum_name]
118-
)
116+
pmapping.split_loop_with_multiple_rank_variables(job.einsum_name)
119117
pmapping.split_tensor_holders_with_multiple_tensors()
120118
_add_backing_to_tensor_holders(pmapping)
121119

0 commit comments

Comments
 (0)