Coverage for / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / auto_parallel / sapp_nd / nd / common / layer_order.py: 100%
22 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-10-25 05:45 +0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-10-25 05:45 +0800
1# Copyright 2026 Huawei Technologies Co., Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ============================================================================
15"""Where the layers of a pipeline partition sit, in model order.
17A partition lists each stage's chunks and each chunk's layers. Model order
18is the order of the layers in the model, which a layer's kind and its
19recompute range count in: chunk by chunk across the stages, and back up
20them in the second chunk of a V schedule.
21"""
22from typing import Any, List, Optional, Sequence, Tuple
24from hyper_parallel.auto_parallel.sapp_nd.nd.common.layer_type import LayerType
26# The layer type the partition places for each recompute option.
27_TYPES = {
28 "none": LayerType.NOT_REC_LAYER,
29 "full": LayerType.FULL_REC_LAYER,
30 "selective": LayerType.SEL_REC_LAYER,
31}
34def get_model_order(cfg: Any, stages: List) -> List[Tuple[int, int, int]]:
35 """Positions ``(stage, chunk, index)`` of the regular layers, in model order.
37 Model order runs chunk by chunk across the stages, and back up them in
38 the second chunk of a V schedule; walking the stages one at a time is
39 only the same order without interleaving. This is the order the memory
40 backbone gives layers their groups in.
41 """
42 positions = [
43 (stage_id, chunk_id, lay_id)
44 for chunk_id in range(cfg.vp)
45 for stage_id in range(cfg.p)
46 for lay_id, layer in enumerate(stages[stage_id][chunk_id])
47 if layer not in (LayerType.EMBEDDING_LAYER, LayerType.OUTPUT_LAYER)
48 ]
49 if cfg.pp_sched == "zero_bubble_v":
50 # First-chunk entries less the embedding, as the memory backbone counts.
51 first = sum(len(stage[0]) for stage in stages) - 1
52 positions = positions[:first] + positions[first:][::-1]
53 return positions
56def stated_recompute(ccfg: Any) -> Optional[Tuple[Any, ...]]:
57 """Return the recompute ranges a config states, or ``None`` when it states none.
59 An empty tuple is a statement too: no layer recomputes.
60 """
61 ranges = getattr(ccfg, "recompute_ranges", None)
62 return ranges if isinstance(ranges, tuple) else None
65def layer_switches(ccfg: Any) -> Optional[Tuple[Any, ...]]:
66 """Return each layer's own recompute switches in model order, or ``None`` where ``rec_op`` holds the one setting."""
67 switches = getattr(ccfg, "layer_switches", None)
68 return switches if isinstance(switches, tuple) else None
71def layer_recompute_types(ranges: Sequence[Any], layers: int) -> List[LayerType]:
72 """Return the layer type of each of *layers* layers in model order.
74 Each layer takes the option of the recompute range that covers it, and
75 a layer no range covers is not recomputed.
76 """
77 types = [LayerType.NOT_REC_LAYER] * layers
78 for item in ranges:
79 stop = layers if item.count is None else min(layers, item.first + item.count)
80 for index in range(item.first, stop):
81 types[index] = _TYPES[item.option]
82 return types