Coverage for  / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / codegen / emit / bundle.py: 33%

39 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-10-25 05:45 +0800

1# Copyright 2026 Huawei Technologies Co., Ltd 

2# Licensed under the Apache License, Version 2.0 

3# ============================================================================ 

4"""Bundle emission: the entry the codegen manager calls to produce an artifact. 

5 

6``emit_bundle`` is what the manager calls: it is invoked as 

7``emit_bundle(layout, meta)`` (manager.ensure_codegen_artifact) after the plan has 

8been derived and frozen into ``meta``. So this layer never derives anything — 

9it renders the already-frozen contract into a ``files`` dict 

10(filename -> content), and the manager stages + atomically swaps the whole 

11bundle (including ``codegen_meta.json``) in one directory switch. 

12 

13The whole bundle is written as one atomic unit: ``emit_bundle`` 

14returns the modeling file, its diff, and ``__init__.py`` as a dict, and 

15``write_bundle_atomic`` stages them alongside the meta in a temp sibling then 

16swaps the directory in. A half-written bundle can never be imported. 

17 

18``meta`` carries the frozen plan, resolved source, and parallel dimensions, so 

19passing separate copies would create a second source of truth. 

20""" 

21from __future__ import annotations 

22 

23import logging 

24import os 

25from typing import Any 

26 

27from hyper_parallel.codegen.artifact import ArtifactLayout 

28from hyper_parallel.codegen.emit.diff import unified_diff 

29from hyper_parallel.codegen.emit.modeling import ( 

30 copy_original_modeling, 

31 emit_modeling_file, 

32) 

33 

34logger = logging.getLogger(__name__) 

35 

36 

37def emit_bundle(layout: ArtifactLayout, meta: Any) -> dict[str, str]: 

38 """Render the artifact bundle for one frozen ``meta``. 

39 

40 Manager-facing entry point. Returns a ``filename -> content`` dict 

41 holding the generated modeling file, the unified diff against the original 

42 source, and ``__init__.py``; the caller (manager) stages and atomically 

43 swaps the bundle, then writes ``codegen_meta.json`` last inside the 

44 staging dir. 

45 

46 ``meta.covered`` is prepared by the manager before emission. 

47 """ 

48 original_text = copy_original_modeling(meta.source) 

49 generated_text = emit_modeling_file(meta) 

50 

51 modeling_name = os.path.basename(layout.modeling_path) 

52 diff_text = emit_diff(original_text, generated_text, layout) 

53 

54 logger.info( 

55 "codegen: rendered bundle %s (modeling %s, %d plan boundaries)", 

56 layout.artifact_dir, 

57 modeling_name, 

58 len(getattr(meta, "param_plan", None) or {}), 

59 ) 

60 files = { 

61 # Filename keys (not absolute paths): write_bundle_atomic stages them 

62 # in a temp sibling and swaps the whole directory in. 

63 modeling_name: generated_text, 

64 os.path.basename(layout.diff_path): diff_text, 

65 "__init__.py": emit_init_file(layout), 

66 } 

67 # A ``<remote>`` source is 

68 # shipped inside the checkpoint and uses single-dot relative imports 

69 # (``from .configuration_deepseek import ...``) that resolve against its 

70 # own package. The loader compiles the generated file as the synthetic 

71 # package ``hyper_parallel_generated.<digest>``, so those siblings must be 

72 # IN the bundle and registered under that package. Copy the transitive 

73 # closure of the source's relative imports here (original basenames), and 

74 # record what was copied so preflight/loader can tell a stale bundle. 

75 siblings: dict[str, str] = {} 

76 source_obj = meta.source 

77 source_module = ( 

78 source_obj.get("module_name") if isinstance(source_obj, dict) 

79 else getattr(source_obj, "module_name", None) 

80 ) 

81 if source_module == "<remote>": 

82 from hyper_parallel.codegen.source.resolver import resolve_remote_siblings 

83 

84 resolved = resolve_remote_siblings(source_obj) 

85 for path in resolved.values(): 

86 basename = os.path.basename(path) 

87 with open(path, "r", encoding="utf-8", errors="replace") as handle: 

88 siblings[basename] = handle.read() 

89 files.update(siblings) 

90 if siblings: 

91 meta.remote_siblings = sorted(siblings) 

92 return files 

93 

94 

95def emit_init_file(layout: ArtifactLayout) -> str: 

96 """Render the bundle's ``__init__.py`` text. 

97 

98 The bundle is imported by file location (loader.import_generated_module), 

99 not as a package, so this file carries no re-exports — it only marks the 

100 directory and records what the bundle is for a reader who opens it. 

101 """ 

102 return ( 

103 '"""Generated codegen bundle — DO NOT EDIT MANUALLY.\n' 

104 "\n" 

105 f"Generated from: {layout.yaml_path}\n" 

106 "Regenerate by re-running training with ``codegen: true``; the bundle\n" 

107 "is rebuilt whenever the codegen signature changes.\n" 

108 '"""\n' 

109 ) 

110 

111 

112def emit_diff(original_text: str, generated_text: str, layout: ArtifactLayout) -> str: 

113 """Render the unified diff from the original source to the generated file. 

114 

115 Returned rather than written so ``emit_bundle`` can write the whole bundle 

116 in one atomic call. 

117 """ 

118 return unified_diff( 

119 original_text, 

120 generated_text, 

121 fromfile=f"a/{_source_basename(layout)}", 

122 tofile=f"b/{os.path.basename(layout.modeling_path)}", 

123 ) 

124 

125 

126def _source_basename(layout: ArtifactLayout) -> str: 

127 """Diff ``fromfile`` label: the original modeling filename.""" 

128 name = os.path.basename(layout.modeling_path) 

129 if name.endswith("_gen_npu.py"): 

130 return name[: -len("_gen_npu.py")] + ".py" 

131 return name 

132 

133 

134__all__ = [ 

135 "emit_bundle", 

136 "emit_diff", 

137 "emit_init_file", 

138 "emit_modeling_file", 

139]