Diff Coverage

Diff: origin/master...HEAD, staged and unstaged changes

Source File Diff Coverage (%) Missing Lines
hyper_parallel/compile/__init__.py 100%  
hyper_parallel/compile/pass_config.py 92.0% 114,118
hyper_parallel/compile/pass_plan.py 93.5% 106,108,230,236,277,326-327
hyper_parallel/compile/passes/base.py 100%  
hyper_parallel/compile/passes/overlap/schedule.py 100%  
hyper_parallel/compile/passes/parallel/fsdp_pass.py 100%  
hyper_parallel/compile/passes/parallel/pp_pass.py 100%  
hyper_parallel/compile/passes/pipeline.py 100%  
hyper_parallel/compile/trainer.py 100%  
hyper_parallel/compile/pass_config.py
110
111
112
113
114
115
116
117
118
119
120
121
            raise ValueError(
                f"fsdp_degree must be None or a positive int, got {self.fsdp_degree}"
            )
        if self.pp_degree is not None and self.pp_degree < 1:
            raise ValueError(
                f"pp_degree must be None or a positive int, got {self.pp_degree}"
            )
        if self.pp_microbatch_size < 1:
            raise ValueError(
                f"pp_microbatch_size must be >= 1, got {self.pp_microbatch_size}"
            )

hyper_parallel/compile/pass_plan.py
102
103
104
105
106
107
108
109
110
111
112
        merged = PassPlan()
        merged.fsdp_modules = {**self.fsdp_modules, **other.fsdp_modules}
        merged.fsdp_patterns = {**self.fsdp_patterns, **other.fsdp_patterns}
        if other.pp_module_fqns_per_stage is not None:
            merged.pp_module_fqns_per_stage = other.pp_module_fqns_per_stage
        elif self.pp_module_fqns_per_stage is not None:
            merged.pp_module_fqns_per_stage = self.pp_module_fqns_per_stage
        return merged

    def fsdp_wrap(self, module_fqn: str) -> "PassPlan":
        """Mark a specific module for FSDP wrapping (exact match).
226
227
228
229
230
231
232
233
234
        raise ValueError("Must provide either config_path or model_name")

    if config_path is None:
        if not model_name or not isinstance(model_name, str):
            raise ValueError("model_name must be a non-empty string")
        if ".." in model_name or "/" in model_name or "\\" in model_name:
            raise ValueError(
                f"Invalid model_name '{model_name}': must not contain path "
                "separators or parent directory references"
232
233
234
235
236
237
238
239
240
            raise ValueError(
                f"Invalid model_name '{model_name}': must not contain path "
                "separators or parent directory references"
            )
        config_path = DEFAULT_CONFIG_DIR / model_name / "config.yaml"
    else:
        config_path = Path(config_path)

    if not config_path.exists():
273
274
275
276
277
278
279
280
281
    section = config.get(key) or {}
    if not isinstance(section, dict):
        # A present-but-empty section parses to None and is normalized to {}
        # above, so anything landing here is a real scalar/sequence typo.
        raise ValueError(
            f"YAML '{key}' section must be a mapping (e.g. nested keys or an "
            f"empty section); got {type(section).__name__} in {config_path}"
        )
    return section
322
323
324
325
326
327
328
329
330
331
        if isinstance(stage, dict):
            stage_idx = stage.get("stage", idx)
            module_fqns = list(stage.get("modules", []))
        else:
            stage_idx = idx
            module_fqns = list(stage)
        plan.pp_stage(stage_idx, module_fqns)


def create_simple_pass_plan() -> PassPlan: