Coverage for / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / auto_parallel / sapp_nd / memory_estimation / _ppb.py: 98%
120 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-07-06 05:41 +0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-07-06 05:41 +0800
1# Copyright 2025 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"""PPB input module"""
17from hyper_parallel.auto_parallel.sapp_nd.nd.common.layer_type import LayerType
18from hyper_parallel.auto_parallel.sapp_nd.memory_estimation.evaluators.utils import EvalUtils
21class _PPB:
22 """Pipeline balance payload builder."""
24 def __init__(self, eval_cfg, inner_dyn_fun):
25 self.eval_cfg = eval_cfg
26 self._inner_dynamic_mem = inner_dyn_fun
27 self.mb = EvalUtils.mb
29 def add_to_ppb_list(self, ppb_lay_desc, desc):
30 """layer description list preparation"""
31 if desc:
32 already_comp = False
33 body_idx = 0
34 for d in ppb_lay_desc:
35 if all(v == d[k] for k, v in desc.items()):
36 # already exist desc
37 d["nb_layer"] += 1
38 already_comp = True
39 if d["type"] == "BODY":
40 body_idx += 1
41 if desc and not already_comp:
42 desc["nb_layer"] = 1
43 if desc["type"] == "BODY":
44 desc["name"] = f"BODY_{body_idx}"
45 else:
46 desc["name"] = desc["type"]
47 ppb_lay_desc += [desc]
49 def lay_ppb(self, ccfg, ctx, res_stat):
50 """layer description preparation"""
51 ctx.enable_node_log = False
52 desc = {}
53 desc["model_name"] = ccfg.model_name
54 if ctx.current_node == ctx.head_node:
55 d_emb = self.mb(sum(self._inner_dynamic_mem(ppb=True)))
56 desc["type"] = "HEAD"
57 desc["memory_parameter"] = self.mb(res_stat) + d_emb
58 # desc["time"] = perfs[0]
59 desc["time"] = 1
60 elif ctx.current_node == ctx.tail_node:
61 d_out = self.mb(sum(self._inner_dynamic_mem(ppb=True)))
62 desc["type"] = "TAIL"
63 desc["memory_parameter"] = self.mb(res_stat) + d_out
64 # desc["time"] = perfs[-1]
65 desc["time"] = 1
66 else:
67 ctx.current_node = LayerType.NOT_REC_LAYER
68 dyn_nrec = self._inner_dynamic_mem(ppb=True)
69 ctx.current_node = LayerType.SEL_REC_LAYER
70 dyn_srec = self._inner_dynamic_mem(ppb=True)
71 ctx.current_node = LayerType.FULL_REC_LAYER
72 dyn_frec = self._inner_dynamic_mem(ppb=True)
73 c = max(dyn_nrec[1], dyn_srec[1], dyn_frec[1]) # Temporary
74 desc["type"] = "BODY"
75 desc["memory_parameter"] = self.mb(res_stat)
76 desc["memory_parameter"] += self.mb(c)
77 desc["memory_activation"] = self.mb(dyn_nrec[0])
78 desc["memory_select_rec"] = self.mb(dyn_srec[0])
79 desc["memory_recompute"] = self.mb(dyn_frec[0])
80 desc["time"] = 1
81 ctx.enable_node_log = True
82 # if any(
83 # k in desc and desc[k] > 0
84 # for k in [
85 # "memory_parameter",
86 # "memory_activation",
87 # "memory_recompute",
88 # "memory_select_rec",
89 # ]
90 # ):
91 # # Ignore values 0
92 # return desc
93 return desc
95 def ppb_combine_bodies(self, ppb_lay_desc):
96 """combine descriptions into a new body"""
97 if not self.eval_cfg.ppb_combined:
98 return
99 for new_body in self.eval_cfg.ppb_combined:
100 desc = {
101 "model_name": "combined",
102 "type": "BODY",
103 "memory_parameter": 0,
104 "memory_activation": 0,
105 "memory_select_rec": 0,
106 "memory_recompute": 0,
107 "time": 1,
108 "nb_layer": 1,
109 "name": "COMBINED",
110 }
111 idx = -1
112 for mod, t in new_body:
113 target = next(
114 (
115 d
116 for d in ppb_lay_desc
117 if d["model_name"] == mod and d["type"] == t.upper()
118 ),
119 None,
120 )
121 if target:
122 desc["model_name"] += "_" + mod
123 desc["name"] += "_" + target["name"]
124 for m in desc:
125 if m.startswith("memory") and m in target:
126 desc[m] += target[m]
127 target_idx = ppb_lay_desc.index(target)
128 idx = target_idx if idx < 0 else min(idx, target_idx)
129 del ppb_lay_desc[target_idx]
130 idx = max(idx, 0)
131 ppb_lay_desc.insert(idx, desc)
133 def lay_ppb_new(self, ccfg, ctx, res_stat):
134 """layer description preparation"""
135 ctx.enable_node_log = False
136 desc = {}
137 desc["model_name"] = ccfg.model_name
138 desc["memory_activation"] = {"NONE": 0, "FULL": 0}
139 if ctx.current_node == ctx.head_node:
140 d_emb = self.mb(sum(self._inner_dynamic_mem(ppb=True)))
141 desc["memory_parameter"] = self.mb(res_stat) + d_emb
142 desc["type"] = "HEAD"
143 elif ctx.current_node == ctx.tail_node:
144 d_out = self.mb(sum(self._inner_dynamic_mem(ppb=True)))
145 desc["memory_parameter"] = self.mb(res_stat) + d_out
146 desc["type"] = "TAIL"
147 else:
148 ctx.current_node = LayerType.NOT_REC_LAYER
149 dyn_nrec = self._inner_dynamic_mem(ppb=True)
150 ctx.current_node = LayerType.FULL_REC_LAYER
151 dyn_frec = self._inner_dynamic_mem(ppb=True)
152 c = max(dyn_nrec[1], dyn_frec[1]) # Temporary
153 desc["memory_parameter"] = self.mb(res_stat)
154 desc["memory_parameter"] += self.mb(c)
155 desc["memory_activation"]["NONE"] = self.mb(dyn_nrec[0])
156 desc["memory_activation"]["FULL"] = self.mb(dyn_frec[0])
157 desc["type"] = "BODY"
158 desc["options"] = ["NONE", "FULL"]
159 desc["forward_time"] = {"NONE": 1, "FULL": 1}
160 desc["backward_time"] = {"NONE": 1, "FULL": 1}
161 desc["time"] = 1
162 ctx.enable_node_log = True
163 # if any(
164 # k > 0
165 # for k in [
166 # desc["memory_parameter"],
167 # desc["memory_activation"]["NONE"],
168 # desc["memory_activation"]["FULL"],
169 # ]
170 # ):
171 # # Ignore values 0
172 # return desc
173 # return {}
174 return desc
176 def ppb_combine_bodies_new(self, ppb_lay_desc):
177 """combine descriptions into a new body"""
178 if not self.eval_cfg.ppb_combined:
179 return
180 for new_body in self.eval_cfg.ppb_combined:
181 desc = {
182 "model_name": "combined",
183 "type": "BODY",
184 "memory_parameter": 0,
185 "memory_activation": {"NONE": 0, "FULL": 0},
186 "options": ["NONE", "FULL"],
187 "forward_time": {"NONE": 1, "FULL": 1},
188 "backward_time": {"NONE": 1, "FULL": 1},
189 "time": 1,
190 "nb_layer": 1,
191 "name": "COMBINED",
192 }
193 idx = -1
194 for mod, t in new_body:
195 target = next(
196 (
197 d
198 for d in ppb_lay_desc
199 if d["model_name"] == mod and d["type"] == t.upper()
200 ),
201 None,
202 )
203 if target:
204 desc["model_name"] += "_" + mod
205 desc["name"] += "_" + target["name"]
206 desc["memory_parameter"] += target["memory_parameter"]
207 desc["memory_activation"]["NONE"] += target[
208 "memory_activation"
209 ]["NONE"]
210 desc["memory_activation"]["FULL"] += target[
211 "memory_activation"
212 ]["FULL"]
213 target_idx = ppb_lay_desc.index(target)
214 idx = target_idx if idx < 0 else min(idx, target_idx)
215 del ppb_lay_desc[target_idx]
216 idx = max(idx, 0)
217 ppb_lay_desc.insert(idx, desc)