Coverage for / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / auto_parallel / sapp_ppb / pp_sim_adapter.py: 61%
33 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-08-21 04:29 +0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-08-21 04:29 +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"""PP simulator — pipeline parallelism schedule simulation."""
17from __future__ import annotations
19import logging
20from typing import Any, Optional
22from hyper_parallel.auto_parallel.sapp_ppb.pp_config_builder.layer_loader import (
23 SAPP_PPB_AVAILABLE,
24)
25from hyper_parallel.auto_parallel.sapp_ppb.pp_config_builder.yaml_parser import (
26 YamlOptimizationConfig,
27)
28from hyper_parallel.auto_parallel.sapp_ppb.pp_modeling.pp_structs import PPBOutput
30logger = logging.getLogger(__name__)
33class PPSimulator:
34 """Pipeline parallelism schedule simulator.
36 Wraps :class:`SappPipeline.simulate` and provides high-level methods
37 for simulating ILP-optimized pipeline schedules.
39 Args:
40 pipeline: A solved :class:`SappPipeline` instance.
41 yaml_config: YAML configuration with pipeline topology.
42 constant_memory: Constant memory per stage (MB).
44 Example:
45 >>> sim = PPSimulator(pipeline, yaml_config, constant_mem)
46 >>> result = sim.simulate_from_ilp(sim_comm_time=0.1)
47 """
49 def __init__(
50 self,
51 pipeline: Any,
52 yaml_config: YamlOptimizationConfig,
53 constant_memory: int,
54 ) -> None:
55 """Initialize PPSimulator.
57 Args:
58 pipeline: A solved :class:`SappPipeline` instance.
59 yaml_config: YAML configuration with pipeline topology.
60 constant_memory: Constant memory per stage (MB).
61 """
62 self._pipeline = pipeline
63 self._yaml_config = yaml_config
64 self._constant_memory = constant_memory
66 def simulate_from_ilp(
67 self,
68 sim_comm_time: float = 0.0,
69 ) -> Optional[PPBOutput]:
70 """Run PipelineSimulator using ILP solver output for accurate step time.
72 Delegates to :meth:`SappPipeline.simulate` which internally calls
73 ``get_fw_time()``, ``get_recompute_time()``,
74 ``get_memory_activation()``, and ``get_memory_parameter()``
75 to build and run the :class:`PipelineSimulator`. The resulting
76 ``end_time`` reflects the true pipeline schedule (1F1B / VPP
77 with warmup-steady-cooldown phases, P2P communication, bubble
78 overlap) — far more accurate than
79 ``max_stage_time × micro_batch_num``.
81 Args:
82 sim_comm_time: P2P communication time between adjacent stages
83 (ms). Passed to the pipeline simulator only; does NOT
84 affect ILP optimization. Default 0.0 (no communication
85 delay).
87 Returns:
88 :class:`PPBOutput` with ``simulation_status="success"`` and
89 populated ``simulator_end_time``, ``simulator_bubbles``,
90 ``simulator_peak_memory``; or ``None`` if the pipeline has
91 not been solved yet or the simulation cannot run.
93 Example:
94 >>> sim = PPSimulator(pipeline, yaml_config, constant_mem)
95 >>> result = sim.simulate_from_ilp(sim_comm_time=0.1)
96 >>> result.simulator_end_time
97 1234.5
98 """
99 if not SAPP_PPB_AVAILABLE or self._pipeline is None:
100 return None
102 if self._yaml_config.micro_batch_num < self._yaml_config.pp_degree:
103 logger.warning(
104 "micro_batch_num (%d) < pp_degree (%d); simulator skipped.",
105 self._yaml_config.micro_batch_num, self._yaml_config.pp_degree,
106 )
107 return None
109 try:
110 end_time = self._pipeline.simulate(
111 show=False, comm_time=sim_comm_time,
112 )
114 if end_time is None or end_time <= 0:
115 return None
117 sim_instance = self._pipeline.simulator
118 return PPBOutput(
119 simulation_status="success",
120 simulator_end_time=sim_instance.end_time,
121 simulator_bubbles=dict(sim_instance.bubbles),
122 simulator_peak_memory=list(sim_instance.peak_memory),
123 )
124 except ValueError as exc:
125 logger.warning("Simulator failed with ValueError: %s", exc)
126 return None
127 except Exception as exc:
128 from hyper_parallel.auto_parallel.sapp_ppb.simulator.causal_error import CausalCommError, CausalError # pylint: disable=C0415
129 if isinstance(exc, (CausalCommError, CausalError)):
130 logger.warning("Simulator failed with %s: %s", type(exc).__name__, exc)
131 return None
132 raise