已合并
feat: 抽取原子方法以实现并行编译 wrapper、tiling、kernel #1799
CactiCode创建于 16 天前
feat: 抽取原子方法以实现并行编译 wrapper、tiling、kernel #1799
已合并
共 6 个文件变更+351-179
| @@ -23,7 +23,6 @@ import platform | |||
| 23 | import tempfile | 23 | import tempfile |
| 24 | import uuid | 24 | import uuid |
| 25 | from contextlib import contextmanager, nullcontext | 25 | from contextlib import contextmanager, nullcontext |
| 26 | -from concurrent.futures import ThreadPoolExecutor, as_completed | ||
| 27 | from threading import Lock | 26 | from threading import Lock |
| 28 | import time | 27 | import time |
| 29 | from dataclasses import dataclass | 28 | from dataclasses import dataclass |
| @@ -333,7 +332,7 @@ def link_pgo_executable(target_file, obj_files, mspti_link_flags): | |||
| 333 | return target_file | 332 | return target_file |
| 334 | 333 | ||
| 335 | 334 | ||
| 336 | -def extract_aicore_binary(device_obj_file, output_file): | 335 | +def extract_aicore_binary(kernel_obj_path, output_file): |
| 337 | objcopy = shutil.which("llvm-objcopy") | 336 | objcopy = shutil.which("llvm-objcopy") |
| 338 | if objcopy is None: | 337 | if objcopy is None: |
| 339 | objcopy = os.path.join( | 338 | objcopy = os.path.join( |
| @@ -342,7 +341,7 @@ def extract_aicore_binary(device_obj_file, output_file): | |||
| 342 | if not os.path.isfile(objcopy): | 341 | if not os.path.isfile(objcopy): |
| 343 | raise CompileError("llvm-objcopy is required for Inductor PGO device binary") | 342 | raise CompileError("llvm-objcopy is required for Inductor PGO device binary") |
| 344 | run_compile_command( | 343 | run_compile_command( |
| 345 | - [objcopy, "--dump-section", f".aicore_binary={output_file}", device_obj_file], | 344 | + [objcopy, "--dump-section", f".aicore_binary={output_file}", kernel_obj_path], |
| 346 | "ExtractPgoDeviceBinary", | 345 | "ExtractPgoDeviceBinary", |
| 347 | ) | 346 | ) |
| 348 | if not os.path.isfile(output_file) or os.path.getsize(output_file) == 0: | 347 | if not os.path.isfile(output_file) or os.path.getsize(output_file) == 0: |
| @@ -831,22 +830,10 @@ def compile_host_objs(args: argparse.Namespace, temp_dir, pch_path=None): | |||
| 831 | if not host_files: | 830 | if not host_files: |
| 832 | return [] | 831 | return [] |
| 833 | pch_state = {"path": pch_path, "lock": Lock()} | 832 | pch_state = {"path": pch_path, "lock": Lock()} |
| 834 | - if len(host_files) == 1: | 833 | + return [ |
| 835 | - return [compile_host_obj_file(args, temp_dir, host_files[0], pch_state)] | 834 | + compile_host_obj_file(args, temp_dir, source_file, pch_state) |
| 836 | - | 835 | + for source_file in host_files |
| 837 | - obj_files = [None] * len(host_files) | 836 | + ] |
| 838 | - worker_count = get_host_compile_worker_count(len(host_files)) | ||
| 839 | - with ThreadPoolExecutor(max_workers=worker_count) as executor: | ||
| 840 | - future_to_index = { | ||
| 841 | - executor.submit( | ||
| 842 | - compile_host_obj_file, args, temp_dir, source_file, pch_state | ||
| 843 | - ): index | ||
| 844 | - for index, source_file in enumerate(host_files) | ||
| 845 | - } | ||
| 846 | - for future in as_completed(future_to_index): | ||
| 847 | - index = future_to_index[future] | ||
| 848 | - obj_files[index] = future.result() | ||
| 849 | - return obj_files | ||
| 850 | 837 | ||
| 851 | 838 | ||
| 852 | 839 | ||
| @@ -909,27 +896,30 @@ def compile_device_obj(args: argparse.Namespace, temp_dir): | |||
| 909 | return f"{temp_dir}/device/{base_device_file}.o" | 896 | return f"{temp_dir}/device/{base_device_file}.o" |
| 910 | 897 | ||
| 911 | 898 | ||
| 912 | -@inductor_compile_duration("BuildDeviceSo") | 899 | +@inductor_compile_duration("LinkKernelSo") |
| 913 | -def build_device_so(args: argparse.Namespace, host_obj_path, temp_dir): | 900 | +def link_kernel_so( |
| 914 | - device_obj_path = compile_device_obj(args, temp_dir) | 901 | + args: argparse.Namespace, tiling_obj_paths, temp_dir, kernel_obj_path |
| 902 | +): | ||
| 903 | + if not kernel_obj_path: | ||
| 904 | + raise ValueError("kernel_obj_path is required for linking") | ||
| 905 | + | ||
| 915 | target_file = os.path.join(temp_dir, os.path.basename(args.output_file)) | 906 | target_file = os.path.join(temp_dir, os.path.basename(args.output_file)) |
| 916 | - obj_files = [device_obj_path] | 907 | + obj_files = [kernel_obj_path] |
| 917 | - host_obj_paths = normalize_to_list(host_obj_path) | 908 | + tiling_obj_paths = normalize_to_list(tiling_obj_paths) |
| 918 | - if host_obj_paths: | 909 | + if tiling_obj_paths: |
| 919 | - obj_files = host_obj_paths + obj_files | 910 | + obj_files = tiling_obj_paths + obj_files |
| 920 | obj_files = append_shared_cv_wrapper_so(args, obj_files) | 911 | obj_files = append_shared_cv_wrapper_so(args, obj_files) |
| 921 | link_libraries = ( | 912 | link_libraries = ( |
| 922 | CV_HOST_LINK_LIBRARIES | 913 | CV_HOST_LINK_LIBRARIES |
| 923 | - if host_obj_paths and is_cv_fusion_compile(args) | 914 | + if tiling_obj_paths and is_cv_fusion_compile(args) |
| 924 | - else (HOST_LINK_LIBRARIES if host_obj_paths else None) | 915 | + else (HOST_LINK_LIBRARIES if tiling_obj_paths else None) |
| 916 | + ) | ||
| 917 | + return link_shared( | ||
| 918 | + target_file, | ||
| 919 | + obj_files, | ||
| 920 | + link_libraries=link_libraries, | ||
| 921 | + extra_link_options=get_shared_cv_wrapper_rpath_options(args), | ||
| 925 | ) | 922 | ) |
| 926 | - with InductorCompileDuration(args, "LinkDeviceSo"): | ||
| 927 | - return link_shared( | ||
| 928 | - target_file, | ||
| 929 | - obj_files, | ||
| 930 | - link_libraries=link_libraries, | ||
| 931 | - extra_link_options=get_shared_cv_wrapper_rpath_options(args), | ||
| 932 | - ) | ||
| 933 | 923 | ||
| 934 | 924 | ||
| 935 | def clean_before_modify(temp_dir): | 925 | def clean_before_modify(temp_dir): |
| @@ -1183,56 +1173,64 @@ def try_static_shape_compile(args: argparse.Namespace, temp_dir, so_path): | |||
| 1183 | return True | 1173 | return True |
| 1184 | 1174 | ||
| 1185 | 1175 | ||
| 1186 | -def link_host_target(args, temp_dir, pch_path=None): | 1176 | +@inductor_compile_duration("LinkTilingSo") |
| 1187 | - # 处理 host 编译阶段 | 1177 | +def link_tiling_so(args, tiling_obj_paths, temp_dir): |
| 1188 | - if pch_path is None: | 1178 | + """Link an existing set of tiling objects into the tiling shared library.""" |
| 1189 | - host_obj_paths = append_shared_cv_wrapper_so( | 1179 | + if not tiling_obj_paths: |
| 1190 | - args, compile_host_objs(args, temp_dir) | 1180 | + raise ValueError("tiling object files are required for linking") |
| 1191 | - ) | 1181 | + |
| 1192 | - else: | 1182 | + tiling_obj_paths = append_shared_cv_wrapper_so( |
| 1193 | - host_obj_paths = append_shared_cv_wrapper_so( | 1183 | + args, normalize_to_list(tiling_obj_paths) |
| 1194 | - args, compile_host_objs(args, temp_dir, pch_path) | 1184 | + ) |
| 1195 | - ) | ||
| 1196 | so_file = os.path.join(temp_dir, os.path.basename(args.output_file)) | 1185 | so_file = os.path.join(temp_dir, os.path.basename(args.output_file)) |
| 1197 | link_libraries = ( | 1186 | link_libraries = ( |
| 1198 | CV_HOST_LINK_LIBRARIES if is_cv_fusion_compile(args) else HOST_LINK_LIBRARIES | 1187 | CV_HOST_LINK_LIBRARIES if is_cv_fusion_compile(args) else HOST_LINK_LIBRARIES |
| 1199 | ) | 1188 | ) |
| 1200 | if getattr(args, "pgo_runner_file", None) is not None: | 1189 | if getattr(args, "pgo_runner_file", None) is not None: |
| 1201 | link_libraries = link_libraries + ["ascendcl", "runtime"] | 1190 | link_libraries = link_libraries + ["ascendcl", "runtime"] |
| 1202 | - with InductorCompileDuration(args, "LinkHostSo"): | 1191 | + return link_shared( |
| 1203 | - link_shared( | 1192 | + so_file, |
| 1204 | - so_file, | 1193 | + tiling_obj_paths, |
| 1205 | - host_obj_paths, | 1194 | + link_libraries=link_libraries, |
| 1206 | - link_libraries=link_libraries, | 1195 | + extra_link_options=get_shared_cv_wrapper_rpath_options(args), |
| 1207 | - extra_link_options=get_shared_cv_wrapper_rpath_options(args), | 1196 | + ) |
| 1208 | - ) | ||
| 1209 | - return so_file | ||
| 1210 | 1197 | ||
| 1211 | 1198 | ||
| 1212 | 1199 | ||
| 1213 | -def link_kernel_target(args, host_obj_path, temp_dir): | 1200 | +def build_kernel_target(args, tiling_obj_paths, temp_dir): |
| 1214 | - if args.stage == "device": | 1201 | + """Compile device objects and build the final kernel shared library.""" |
| 1215 | - if args.tiling_repr is not None or has_inductor_const_tiling_data( | 1202 | + if args.stage == "device" and ( |
| 1216 | - args, temp_dir | 1203 | + args.tiling_repr is not None or has_inductor_const_tiling_data(args, temp_dir) |
| 1217 | - ): | 1204 | + ): |
| 1218 | - if args.tiling_repr is not None: | 1205 | + if args.tiling_repr is not None: |
| 1219 | - print("process static shape kernel with tiling_repr") | 1206 | + print("process static shape kernel with tiling_repr") |
| 1220 | - static_shape_kernel_proc(args, temp_dir, args.tiling_repr) | 1207 | + static_shape_kernel_proc(args, temp_dir, args.tiling_repr) |
| 1221 | 1208 | ||
| 1222 | - # 首次编译 | 1209 | + kernel_obj_path = compile_device_obj(args, temp_dir) |
| 1223 | - so_file = build_device_so(args, host_obj_path, temp_dir) | 1210 | + so_file = link_kernel_so(args, tiling_obj_paths, temp_dir, kernel_obj_path) |
| 1224 | - | 1211 | + if args.stage == "device" or not try_static_shape_compile(args, temp_dir, so_file): |
| 1225 | - # kernel_compile场景一次性生成so,链接device.o | ||
| 1226 | - if args.stage == "device": | ||
| 1227 | return so_file | 1212 | return so_file |
| 1228 | 1213 | ||
| 1229 | - # jit_compile场景,检测是否为静态shape | 1214 | + # 静态 shape 重编译后,重新生成 device.o 并链接最终产物。 |
| 1230 | - re_compile = try_static_shape_compile(args, temp_dir, so_file) | 1215 | + kernel_obj_path = compile_device_obj(args, temp_dir) |
| 1231 | - if not re_compile: | 1216 | + return link_kernel_so(args, tiling_obj_paths, temp_dir, kernel_obj_path) |
| 1217 | + | ||
| 1218 | + | ||
| 1219 | + | ||
| 1220 | +def build_kernel_target_from_objects(args, tiling_obj_paths, kernel_obj_path, temp_dir): | ||
| 1221 | + """Build the final kernel from precompiled host and device objects.""" | ||
| 1222 | + if not tiling_obj_paths: | ||
| 1223 | + raise ValueError("host object files are required") | ||
| 1224 | + if not kernel_obj_path: | ||
| 1225 | + raise ValueError("device object path is required") | ||
| 1226 | + | ||
| 1227 | + so_file = link_kernel_so(args, tiling_obj_paths, temp_dir, kernel_obj_path) | ||
| 1228 | + if not try_static_shape_compile(args, temp_dir, so_file): | ||
| 1232 | return so_file | 1229 | return so_file |
| 1233 | 1230 | ||
| 1234 | - # 重编译,最终产物链接host.o+device.o | 1231 | + # 静态 shape 重编译会修改 device 源码,需生成新的 device.o。 |
| 1235 | - return build_device_so(args, host_obj_path, temp_dir) | 1232 | + kernel_obj_path = compile_device_obj(args, temp_dir) |
| 1233 | + return link_kernel_so(args, tiling_obj_paths, temp_dir, kernel_obj_path) | ||
| 1236 | 1234 | ||
| 1237 | 1235 | ||
| 1238 | 1236 | ||
| @@ -1263,7 +1261,11 @@ def build_host_output(args, pch_path=None): | |||
| 1263 | ) | 1261 | ) |
| 1264 | if should_build_sidecars: | 1262 | if should_build_sidecars: |
| 1265 | args.pgo_generation = uuid.uuid4().hex | 1263 | args.pgo_generation = uuid.uuid4().hex |
| 1266 | - so_file = link_host_target(args, args.temp_dir, pch_path) | 1264 | + if pch_path is None: |
| 1265 | + tiling_obj_paths = compile_host_objs(args, args.temp_dir) | ||
| 1266 | + else: | ||
| 1267 | + tiling_obj_paths = compile_host_objs(args, args.temp_dir, pch_path) | ||
| 1268 | + so_file = link_tiling_so(args, tiling_obj_paths, args.temp_dir) | ||
| 1267 | if not should_build_sidecars: | 1269 | if not should_build_sidecars: |
| 1268 | return so_file | 1270 | return so_file |
| 1269 | try: | 1271 | try: |
| @@ -1284,21 +1286,72 @@ def build_host_output(args, pch_path=None): | |||
| 1284 | return so_file | 1286 | return so_file |
| 1285 | 1287 | ||
| 1286 | 1288 | ||
| 1289 | +def parse_object_paths(value): | ||
| 1290 | + if not value: | ||
| 1291 | + return [] | ||
| 1292 | + return [path for path in value.split(";") if path] | ||
| 1293 | + | ||
| 1294 | + | ||
| 1295 | +def validate_artifact_paths(paths, kind): | ||
| 1296 | + if not paths: | ||
| 1297 | + raise CompileError(f"{kind} artifact paths are empty") | ||
| 1298 | + missing = [ | ||
| 1299 | + path for path in paths if not isinstance(path, str) or not os.path.isfile(path) | ||
| 1300 | + ] | ||
| 1301 | + if missing: | ||
| 1302 | + raise CompileError(f"{kind} artifact files are missing: {missing}") | ||
| 1303 | + | ||
| 1304 | + | ||
| 1287 | def main(args): | 1305 | def main(args): |
| 1288 | print("compile args:", args) | 1306 | print("compile args:", args) |
| 1289 | src_directory = os.getcwd() | 1307 | src_directory = os.getcwd() |
| 1290 | os.chdir(args.temp_dir) | 1308 | os.chdir(args.temp_dir) |
| 1291 | print("change work dir:", os.getcwd()) | 1309 | print("change work dir:", os.getcwd()) |
| 1310 | + # 原子编译 stage 返回结构化 artifact,避免进程间共享 Python 状态。 | ||
| 1292 | try: | 1311 | try: |
| 1293 | if args.stage == "host": | 1312 | if args.stage == "host": |
| 1294 | with host_compile_batch(args) as pch_path: | 1313 | with host_compile_batch(args) as pch_path: |
| 1295 | so_file = build_host_output(args, pch_path) | 1314 | so_file = build_host_output(args, pch_path) |
| 1315 | + elif args.stage == "host_obj": | ||
| 1316 | + with host_compile_batch(args) as pch_path: | ||
| 1317 | + tiling_obj_paths = compile_host_objs(args, args.temp_dir, pch_path) | ||
| 1318 | + return { | ||
| 1319 | + "version": 1, | ||
Z | |||
| 1320 | + "stage": "host_obj", | ||
| 1321 | + "tiling_obj_paths": tiling_obj_paths, | ||
| 1322 | + "tiling_source_paths": normalize_to_list(args.host_files), | ||
| 1323 | + "shared_cv_wrapper_so": getattr(args, "shared_cv_wrapper_so", None), | ||
| 1324 | + } | ||
| 1325 | + elif args.stage == "device_obj": | ||
| 1326 | + kernel_obj_path = compile_device_obj(args, args.temp_dir) | ||
| 1327 | + return { | ||
| 1328 | + "version": 1, | ||
| 1329 | + "stage": "device_obj", | ||
| 1330 | + "kernel_obj_path": kernel_obj_path, | ||
| 1331 | + "kernel_source_path": args.device_files, | ||
| 1332 | + } | ||
| 1333 | + elif args.stage == "link": | ||
| 1334 | + tiling_obj_paths = parse_object_paths(args.tiling_obj_paths) | ||
| 1335 | + kernel_obj_path = args.kernel_obj_path | ||
| 1336 | + validate_artifact_paths(tiling_obj_paths, "host object") | ||
| 1337 | + validate_artifact_paths( | ||
| 1338 | + [kernel_obj_path, args.kernel_source_path], "device artifact" | ||
| 1339 | + ) | ||
| 1340 | + args.host_files = parse_object_paths(args.tiling_source_paths) | ||
| 1341 | + args.device_files = args.kernel_source_path | ||
| 1342 | + args.shared_cv_wrapper_so = args.shared_cv_wrapper_so or None | ||
| 1343 | + so_file = build_kernel_target_from_objects( | ||
| 1344 | + args, tiling_obj_paths, kernel_obj_path, args.temp_dir | ||
| 1345 | + ) | ||
| 1296 | elif args.stage == "device": | 1346 | elif args.stage == "device": |
| 1297 | - so_file = link_kernel_target(args, None, args.temp_dir) | 1347 | + so_file = build_kernel_target(args, None, args.temp_dir) |
| 1298 | else: # all | 1348 | else: # all |
| 1299 | with host_compile_batch(args) as pch_path: | 1349 | with host_compile_batch(args) as pch_path: |
| 1300 | - host_obj_paths = compile_host_objs(args, args.temp_dir, pch_path) | 1350 | + if pch_path is None: |
| 1301 | - so_file = link_kernel_target(args, host_obj_paths, args.temp_dir) | 1351 | + tiling_obj_paths = compile_host_objs(args, args.temp_dir) |
| 1352 | + else: | ||
| 1353 | + tiling_obj_paths = compile_host_objs(args, args.temp_dir, pch_path) | ||
| 1354 | + so_file = build_kernel_target(args, tiling_obj_paths, args.temp_dir) | ||
| 1302 | if so_file is not None: | 1355 | if so_file is not None: |
| 1303 | copy_so_to_output(so_file, args, src_directory) | 1356 | copy_so_to_output(so_file, args, src_directory) |
| 1304 | finally: | 1357 | finally: |
| @@ -20,6 +20,9 @@ import re | |||
| 20 | HOST_DEFAULT_CXX11_ABI = "-D_GLIBCXX_USE_CXX11_ABI=1" | 20 | HOST_DEFAULT_CXX11_ABI = "-D_GLIBCXX_USE_CXX11_ABI=1" |
| 21 | HOST_CXX11_ABI_PREFIX = "-D_GLIBCXX_USE_CXX11_ABI=" | 21 | HOST_CXX11_ABI_PREFIX = "-D_GLIBCXX_USE_CXX11_ABI=" |
| 22 | INDUCTOR_COMPILE_TRACE_LABEL = "InductorCompile" | 22 | INDUCTOR_COMPILE_TRACE_LABEL = "InductorCompile" |
| 23 | +SOURCES_TILING_STRUCT = "tiling_struct_code" | ||
| 24 | +SOURCES_HOST_IMPL = "host_impl_code" | ||
| 25 | +SOURCES_KERNEL_IMPL = "kernel_impl_code" | ||
| 23 | SPLIT_BEGIN_PREFIX = "// AUTOFUSE_SPLIT_FILE_BEGIN:" | 26 | SPLIT_BEGIN_PREFIX = "// AUTOFUSE_SPLIT_FILE_BEGIN:" |
| 24 | SPLIT_END_PREFIX = "// AUTOFUSE_SPLIT_FILE_END:" | 27 | SPLIT_END_PREFIX = "// AUTOFUSE_SPLIT_FILE_END:" |
| 25 | SPLIT_HEADER_KEY = "TilingHead" | 28 | SPLIT_HEADER_KEY = "TilingHead" |
| @@ -119,7 +122,16 @@ def parse_compile_args(argv): | |||
| 119 | type=str, | 122 | type=str, |
| 120 | help="Compile options of tiling and kernel.", | 123 | help="Compile options of tiling and kernel.", |
| 121 | ) | 124 | ) |
| 122 | - return parser.parse_args(argv) | 125 | + parser.add_argument("--tiling_obj_paths", default="", type=str) |
| 126 | + parser.add_argument("--tiling_source_paths", default="", type=str) | ||
| 127 | + parser.add_argument("--kernel_obj_path", default="", type=str) | ||
| 128 | + parser.add_argument("--kernel_source_path", default="", type=str) | ||
| 129 | + parser.add_argument("--shared_cv_wrapper_so", default="", type=str) | ||
| 130 | + # 使用 parse_known_args 容忍上层透传的未声明参数,避免触发 SystemExit 终止编译。 | ||
| 131 | + args, unknown = parser.parse_known_args(argv) | ||
| 132 | + if unknown: | ||
| 133 | + print(f"[CompileArgs] ignored unrecognized arguments: {unknown}") | ||
| 134 | + return args | ||
| 123 | 135 | ||
| 124 | 136 | ||
| 125 | def generate_file(dst_dir, file_name, text): | 137 | def generate_file(dst_dir, file_name, text): |
| @@ -311,11 +323,42 @@ def has_inductor_pgo_split(host_impl_code): | |||
| 311 | return bool(keys & {SPLIT_PGO_RUNNER_KEY, SPLIT_PGO_DEVICE_SOURCE_KEY}) | 323 | return bool(keys & {SPLIT_PGO_RUNNER_KEY, SPLIT_PGO_DEVICE_SOURCE_KEY}) |
| 312 | 324 | ||
| 313 | 325 | ||
| 314 | -def write_host_sources(host_file_path, base_host_file, graph_name, host_impl_code): | 326 | +def write_single_host_source(host_file_path, base_host_file, host_impl_code): |
| 327 | + generate_file(host_file_path, base_host_file, host_impl_code) | ||
| 328 | + return os.path.join(host_file_path, base_host_file) | ||
| 329 | + | ||
| 330 | + | ||
| 331 | +def write_merged_host_sources(host_file_path, base_host_file, host_impl_code): | ||
| 332 | + """Generate one host source file while preserving split headers. | ||
| 333 | + | ||
| 334 | + cpp 段合并为单个源文件(单文件编译),header 段仍拆出为独立 .h 文件, | ||
| 335 | + 供 cpp 段中间的 #include "autofuse_tiling_func_*.h" 引用。 | ||
| 336 | + """ | ||
| 315 | if not has_split_host_marker(host_impl_code): | 337 | if not has_split_host_marker(host_impl_code): |
| 316 | - generate_file(host_file_path, base_host_file, host_impl_code) | 338 | + return write_single_host_source(host_file_path, base_host_file, host_impl_code) |
| 317 | - return os.path.join(host_file_path, base_host_file) | 339 | + |
| 318 | - return write_split_host_sources(host_file_path, graph_name, host_impl_code) | 340 | + headers, cpp_sources = parse_split_host_sources(host_impl_code) |
| 341 | + for key, content in headers.items(): | ||
| 342 | + generate_file(host_file_path, SPLIT_HEADER_FILES[key], content) | ||
| 343 | + | ||
| 344 | + is_split_format = is_versioned_split_format(headers) | ||
| 345 | + merged = [] | ||
| 346 | + for _key, cpp_content in cpp_sources: | ||
| 347 | + if is_split_format: | ||
| 348 | + content = cpp_content | ||
| 349 | + else: | ||
| 350 | + content = add_split_header_include(cpp_content) | ||
| 351 | + if merged and content.startswith(SPLIT_HEADER_INCLUDE): | ||
| 352 | + content = content[len(SPLIT_HEADER_INCLUDE):] # fmt: skip | ||
| 353 | + merged.append(content.rstrip("\n")) | ||
| 354 | + generate_file(host_file_path, base_host_file, "\n".join(merged) + "\n") | ||
| 355 | + return os.path.join(host_file_path, base_host_file) | ||
| 356 | + | ||
| 357 | + | ||
| 358 | +def write_host_sources(host_file_path, base_host_file, graph_name, host_impl_code): | ||
Z 不用的逻辑还需要吗 ![]() ![]() | |||
| 359 | + # host 编译为单个 cpp 源文件(cpp 段合并),header 段拆出独立 .h 供 include 引用。 | ||
| 360 | + # 多文件拆分逻辑保留在 write_split_host_sources 中备用,但当前不调用。 | ||
| 361 | + return write_merged_host_sources(host_file_path, base_host_file, host_impl_code) | ||
| 319 | 362 | ||
| 320 | 363 | ||
| 321 | def parse_env_flags(env_name): | 364 | def parse_env_flags(env_name): |
| @@ -395,7 +438,10 @@ def prepare_compile_context(argv, stage, tiling_repr): | |||
| 395 | args = parse_compile_args(argv) | 438 | args = parse_compile_args(argv) |
| 396 | args.stage = stage | 439 | args.stage = stage |
| 397 | args.tiling_repr = tiling_repr | 440 | args.tiling_repr = tiling_repr |
| 398 | - if stage == "host" and HOST_CXX11_ABI_PREFIX not in args.compile_options: | 441 | + if ( |
| 442 | + stage in ("host", "host_obj") | ||
| 443 | + and HOST_CXX11_ABI_PREFIX not in args.compile_options | ||
| 444 | + ): | ||
| 399 | args.compile_options = ( | 445 | args.compile_options = ( |
| 400 | args.compile_options + " " + HOST_DEFAULT_CXX11_ABI | 446 | args.compile_options + " " + HOST_DEFAULT_CXX11_ABI |
| 401 | ).strip() | 447 | ).strip() |
| @@ -413,8 +459,8 @@ def prepare_compile_context(argv, stage, tiling_repr): | |||
| 413 | 459 | ||
| 414 | def write_compile_host_sources(sources, args, tiling_def_file, base_host_file): | 460 | def write_compile_host_sources(sources, args, tiling_def_file, base_host_file): |
| 415 | host_file_path = os.path.join(args.temp_dir, "host") | 461 | host_file_path = os.path.join(args.temp_dir, "host") |
| 416 | - generate_file(host_file_path, tiling_def_file, sources["tiling_struct_code"]) | 462 | + generate_file(host_file_path, tiling_def_file, sources[SOURCES_TILING_STRUCT]) |
| 417 | - host_impl_code = sources["host_impl_code"] | 463 | + host_impl_code = sources[SOURCES_HOST_IMPL] |
| 418 | if not ( | 464 | if not ( |
| 419 | has_split_host_marker(host_impl_code) and has_inductor_pgo_split(host_impl_code) | 465 | has_split_host_marker(host_impl_code) and has_inductor_pgo_split(host_impl_code) |
| 420 | ): | 466 | ): |
| @@ -422,12 +468,12 @@ def write_compile_host_sources(sources, args, tiling_def_file, base_host_file): | |||
| 422 | host_file_path, base_host_file, args.graph_name, host_impl_code | 468 | host_file_path, base_host_file, args.graph_name, host_impl_code |
| 423 | ) | 469 | ) |
| 424 | return | 470 | return |
| 425 | - if args.stage != "host": | 471 | + if args.stage not in ("host", "host_obj"): |
| 426 | raise ascendc_compile.CompileError( | 472 | raise ascendc_compile.CompileError( |
| 427 | "Inductor PGO sidecar is supported only in host_compile stage" | 473 | "Inductor PGO sidecar is supported only in host_compile stage" |
| 428 | ) | 474 | ) |
| 429 | device_file_path = os.path.join(args.temp_dir, "device") | 475 | device_file_path = os.path.join(args.temp_dir, "device") |
| 430 | - generate_file(device_file_path, tiling_def_file, sources["tiling_struct_code"]) | 476 | + generate_file(device_file_path, tiling_def_file, sources[SOURCES_TILING_STRUCT]) |
| 431 | args.host_files, args.pgo_runner_file, args.pgo_device_file = ( | 477 | args.host_files, args.pgo_runner_file, args.pgo_device_file = ( |
| 432 | write_inductor_pgo_sources( | 478 | write_inductor_pgo_sources( |
| 433 | host_file_path, device_file_path, args.graph_name, host_impl_code | 479 | host_file_path, device_file_path, args.graph_name, host_impl_code |
| @@ -440,8 +486,8 @@ def write_compile_host_sources(sources, args, tiling_def_file, base_host_file): | |||
| 440 | 486 | ||
| 441 | def write_compile_device_sources(sources, args, tiling_def_file, base_device_file): | 487 | def write_compile_device_sources(sources, args, tiling_def_file, base_device_file): |
| 442 | device_file_path = os.path.join(args.temp_dir, "device") | 488 | device_file_path = os.path.join(args.temp_dir, "device") |
| 443 | - generate_file(device_file_path, tiling_def_file, sources["tiling_struct_code"]) | 489 | + generate_file(device_file_path, tiling_def_file, sources[SOURCES_TILING_STRUCT]) |
| 444 | - generate_file(device_file_path, base_device_file, sources["kernel_impl_code"]) | 490 | + generate_file(device_file_path, base_device_file, sources[SOURCES_KERNEL_IMPL]) |
| 445 | args.device_files = os.path.join(device_file_path, base_device_file) | 491 | args.device_files = os.path.join(device_file_path, base_device_file) |
| 446 | 492 | ||
| 447 | 493 | ||
| @@ -449,12 +495,12 @@ def execute_compile(sources, args): | |||
| 449 | tiling_def_file = "autofuse_tiling_data.h" | 495 | tiling_def_file = "autofuse_tiling_data.h" |
| 450 | base_host_file = args.graph_name + "_tiling_func.cpp" | 496 | base_host_file = args.graph_name + "_tiling_func.cpp" |
| 451 | base_device_file = args.graph_name + "_op_kernel.cpp" | 497 | base_device_file = args.graph_name + "_op_kernel.cpp" |
| 452 | - if args.stage in ["all", "host"]: | 498 | + if args.stage in ["all", "host", "host_obj"]: |
| 453 | with InductorCompileDuration( | 499 | with InductorCompileDuration( |
| 454 | args.trace_stage, "WriteHostSource", args.graph_name | 500 | args.trace_stage, "WriteHostSource", args.graph_name |
| 455 | ): | 501 | ): |
| 456 | write_compile_host_sources(sources, args, tiling_def_file, base_host_file) | 502 | write_compile_host_sources(sources, args, tiling_def_file, base_host_file) |
| 457 | - if args.stage in ["all", "device"]: | 503 | + if args.stage in ["all", "device", "device_obj"]: |
| 458 | with InductorCompileDuration( | 504 | with InductorCompileDuration( |
| 459 | args.trace_stage, "WriteDeviceSource", args.graph_name | 505 | args.trace_stage, "WriteDeviceSource", args.graph_name |
| 460 | ): | 506 | ): |
| @@ -465,10 +511,33 @@ def execute_compile(sources, args): | |||
| 465 | with InductorCompileDuration( | 511 | with InductorCompileDuration( |
| 466 | args.trace_stage, "BuildCompiledArtifacts", args.graph_name | 512 | args.trace_stage, "BuildCompiledArtifacts", args.graph_name |
| 467 | ): | 513 | ): |
| 468 | - ascendc_compile.main(args) | 514 | + result = ascendc_compile.main(args) |
| 515 | + if result is not None: | ||
| 516 | + return _compile_result(args, result) | ||
| 517 | + if args.stage == "link": | ||
| 518 | + return args.output_file | ||
| 469 | return args.temp_dir | 519 | return args.temp_dir |
| 470 | 520 | ||
| 471 | 521 | ||
| 522 | +def _compile_result(args, result): | ||
| 523 | + if args.stage == "host_obj": | ||
| 524 | + return { | ||
| 525 | + "version": 1, | ||
| 526 | + "stage": args.stage, | ||
| 527 | + "tiling_obj_paths": result["tiling_obj_paths"], | ||
| 528 | + "tiling_source_paths": result["tiling_source_paths"], | ||
| 529 | + "shared_cv_wrapper_so": result.get("shared_cv_wrapper_so"), | ||
| 530 | + } | ||
| 531 | + if args.stage == "device_obj": | ||
| 532 | + return { | ||
| 533 | + "version": 1, | ||
| 534 | + "stage": args.stage, | ||
| 535 | + "kernel_obj_path": result["kernel_obj_path"], | ||
| 536 | + "kernel_source_path": result["kernel_source_path"], | ||
| 537 | + } | ||
| 538 | + return result | ||
| 539 | + | ||
| 540 | + | ||
| 472 | def compile_core( | 541 | def compile_core( |
| 473 | sources, argv: List[str], stage="all", tiling_repr=None, trace_stage=None | 542 | sources, argv: List[str], stage="all", tiling_repr=None, trace_stage=None |
| 474 | ): | 543 | ): |
| @@ -508,9 +577,9 @@ def compile_core( | |||
| 508 | def jit_compile(tiling_def, host_tiling, op_kernel, argv: List[str]): | 577 | def jit_compile(tiling_def, host_tiling, op_kernel, argv: List[str]): |
| 509 | return compile_core( | 578 | return compile_core( |
| 510 | { | 579 | { |
| 511 | - "tiling_struct_code": tiling_def, | 580 | + SOURCES_TILING_STRUCT: tiling_def, |
| 512 | - "host_impl_code": host_tiling, | 581 | + SOURCES_HOST_IMPL: host_tiling, |
| 513 | - "kernel_impl_code": op_kernel, | 582 | + SOURCES_KERNEL_IMPL: op_kernel, |
| 514 | }, | 583 | }, |
| 515 | argv, | 584 | argv, |
| 516 | trace_stage="jit_compile", | 585 | trace_stage="jit_compile", |
| @@ -520,9 +589,9 @@ def jit_compile(tiling_def, host_tiling, op_kernel, argv: List[str]): | |||
| 520 | def host_compile(tiling_def_code, tiling_impl_code, argv: List[str]): | 589 | def host_compile(tiling_def_code, tiling_impl_code, argv: List[str]): |
| 521 | return compile_core( | 590 | return compile_core( |
| 522 | { | 591 | { |
| 523 | - "tiling_struct_code": tiling_def_code, | 592 | + SOURCES_TILING_STRUCT: tiling_def_code, |
| 524 | - "host_impl_code": tiling_impl_code, | 593 | + SOURCES_HOST_IMPL: tiling_impl_code, |
| 525 | - "kernel_impl_code": None, | 594 | + SOURCES_KERNEL_IMPL: None, |
| 526 | }, | 595 | }, |
| 527 | argv, | 596 | argv, |
| 528 | "host", | 597 | "host", |
| @@ -535,9 +604,9 @@ def kernel_compile( | |||
| 535 | ): | 604 | ): |
| 536 | return compile_core( | 605 | return compile_core( |
| 537 | { | 606 | { |
| 538 | - "tiling_struct_code": tiling_def_code, | 607 | + SOURCES_TILING_STRUCT: tiling_def_code, |
| 539 | - "host_impl_code": None, | 608 | + SOURCES_HOST_IMPL: None, |
| 540 | - "kernel_impl_code": kernel_impl_code, | 609 | + SOURCES_KERNEL_IMPL: kernel_impl_code, |
| 541 | }, | 610 | }, |
| 542 | argv, | 611 | argv, |
| 543 | "device", | 612 | "device", |
| @@ -546,6 +615,52 @@ def kernel_compile( | |||
| 546 | ) | 615 | ) |
| 547 | 616 | ||
| 548 | 617 | ||
| 618 | +def build_tiling_obj(tiling_def_code, tiling_impl_code, argv: List[str]): | ||
| 619 | + """编译 host 侧 tiling 函数为 .o,不链接。供外层(torchair)并行调度。""" | ||
| 620 | + return compile_core( | ||
| 621 | + { | ||
| 622 | + SOURCES_TILING_STRUCT: tiling_def_code, | ||
| 623 | + SOURCES_HOST_IMPL: tiling_impl_code, | ||
| 624 | + SOURCES_KERNEL_IMPL: None, | ||
| 625 | + }, | ||
| 626 | + argv, | ||
| 627 | + "host_obj", | ||
| 628 | + trace_stage="build_tiling_obj", | ||
| 629 | + ) | ||
| 630 | + | ||
| 631 | + | ||
| 632 | +def build_kernel_obj( | ||
| 633 | + tiling_def_code, kernel_impl_code, argv: List[str], *, tiling_repr=None | ||
| 634 | +): | ||
| 635 | + """编译 device 侧 kernel 代码为 .o,不链接。供外层(torchair)并行调度。""" | ||
| 636 | + return compile_core( | ||
| 637 | + { | ||
| 638 | + SOURCES_TILING_STRUCT: tiling_def_code, | ||
| 639 | + SOURCES_HOST_IMPL: None, | ||
| 640 | + SOURCES_KERNEL_IMPL: kernel_impl_code, | ||
| 641 | + }, | ||
| 642 | + argv, | ||
| 643 | + "device_obj", | ||
| 644 | + tiling_repr, | ||
| 645 | + trace_stage="build_kernel_obj", | ||
| 646 | + ) | ||
| 647 | + | ||
| 648 | + | ||
| 649 | +def build_kernel_so(tiling_def_code, argv: List[str], *, tiling_repr=None): | ||
| 650 | + """链接 host.o + device.o,产出最终 kernel.so。""" | ||
| 651 | + return compile_core( | ||
| 652 | + { | ||
| 653 | + SOURCES_TILING_STRUCT: tiling_def_code, | ||
| 654 | + SOURCES_HOST_IMPL: None, | ||
| 655 | + SOURCES_KERNEL_IMPL: None, | ||
| 656 | + }, | ||
| 657 | + argv, | ||
| 658 | + "link", | ||
| 659 | + tiling_repr, | ||
| 660 | + trace_stage="build_kernel_so", | ||
| 661 | + ) | ||
| 662 | + | ||
| 663 | + | ||
| 549 | def get_inductor_pgo_mspti_config_from_dir(mspti_dir): | 664 | def get_inductor_pgo_mspti_config_from_dir(mspti_dir): |
| 550 | mspti_dir = os.path.realpath(mspti_dir) | 665 | mspti_dir = os.path.realpath(mspti_dir) |
| 551 | include_file = os.path.join(mspti_dir, "include", "mspti.h") | 666 | include_file = os.path.join(mspti_dir, "include", "mspti.h") |
| @@ -12,7 +12,6 @@ | |||
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | - | ||
| 16 | 15 | ||
| 17 | 16 | ||
| 18 | 17 | ||
| @@ -37,33 +36,27 @@ bool HasDynamicSymbol(const std::string &path, const std::string &symbol) { | |||
| 37 | return RunCommand("nm -D " + path + " 2>/dev/null | grep -q ' " + symbol + "$'") == 0; | 36 | return RunCommand("nm -D " + path + " 2>/dev/null | grep -q ' " + symbol + "$'") == 0; |
| 38 | } | 37 | } |
| 39 | 38 | ||
| 40 | -size_t CountFilesWithSuffix(const std::string &dir, const std::string &suffix) { | ||
| 41 | - size_t count = 0; | ||
| 42 | - for (const auto &entry : std::filesystem::directory_iterator(dir)) { | ||
| 43 | - const std::string file_name = entry.path().filename().string(); | ||
| 44 | - if (file_name.size() >= suffix.size() && | ||
| 45 | - file_name.compare(file_name.size() - suffix.size(), suffix.size(), suffix) == 0) { | ||
| 46 | - count++; | ||
| 47 | - } | ||
| 48 | - } | ||
| 49 | - return count; | ||
| 50 | -} | ||
| 51 | - | ||
| 52 | void VerifySplitHostArtifacts(const std::string &host_dir) { | 39 | void VerifySplitHostArtifacts(const std::string &host_dir) { |
| 40 | + // host 编译为单个 cpp 源文件(cpp 段合并),header 段拆出独立 .h 供 include 引用。 | ||
| 41 | + // 新格式(含 TilingStateHeader)下 codegen 不再单独输出 TilingHead/common.h, | ||
| 42 | + // 公共结构体定义已内联进合并后的 cpp 翻译单元,故 common.h 与 base/entry/tail 一致均不存在。 | ||
| 53 | EXPECT_FALSE(FileExists(host_dir + "/autofuse_tiling_func_common.h")); | 43 | EXPECT_FALSE(FileExists(host_dir + "/autofuse_tiling_func_common.h")); |
| 54 | - EXPECT_FALSE(FileExists(host_dir + "/autofuse_tiling_func_base.h")); | ||
| 55 | - EXPECT_FALSE(FileExists(host_dir + "/autofuse_tiling_func_entry.h")); | ||
| 56 | - EXPECT_FALSE(FileExists(host_dir + "/autofuse_tiling_func_tail.h")); | ||
| 57 | ASSERT_TRUE(FileExists(host_dir + "/autofuse_tiling_func_state.h")); | 44 | ASSERT_TRUE(FileExists(host_dir + "/autofuse_tiling_func_state.h")); |
| 58 | ASSERT_TRUE(FileExists(host_dir + "/autofuse_tiling_func_log.h")); | 45 | ASSERT_TRUE(FileExists(host_dir + "/autofuse_tiling_func_log.h")); |
| 59 | ASSERT_TRUE(FileExists(host_dir + "/autofuse_tiling_func_pgo.h")); | 46 | ASSERT_TRUE(FileExists(host_dir + "/autofuse_tiling_func_pgo.h")); |
| 60 | ASSERT_TRUE(FileExists(host_dir + "/autofuse_tiling_func_solver.h")); | 47 | ASSERT_TRUE(FileExists(host_dir + "/autofuse_tiling_func_solver.h")); |
| 61 | ASSERT_TRUE(FileExists(host_dir + "/autofuse_tiling_func_api.h")); | 48 | ASSERT_TRUE(FileExists(host_dir + "/autofuse_tiling_func_api.h")); |
| 62 | - const std::string tail = ReadFile(host_dir + "/inductor_topn_tiling_func_schedule_group_tail.cpp"); | 49 | + EXPECT_FALSE(FileExists(host_dir + "/autofuse_tiling_func_base.h")); |
| 63 | - EXPECT_EQ(tail.find("#include"), std::string::npos); | 50 | + EXPECT_FALSE(FileExists(host_dir + "/autofuse_tiling_func_entry.h")); |
| 64 | - EXPECT_EQ(tail.find("#include \"autofuse_tiling_func_solver.h\""), std::string::npos); | 51 | + EXPECT_FALSE(FileExists(host_dir + "/autofuse_tiling_func_tail.h")); |
| 65 | - EXPECT_GE(CountFilesWithSuffix(host_dir, ".cpp"), 2U); | 52 | + // cpp 段合并为单个源文件,不再拆分多个 segment cpp(HeaderSelfContainedCheck 生成的 |
| 66 | - EXPECT_GE(CountFilesWithSuffix(host_dir, ".cpp.o"), 2U); | 53 | + // *.self_contained.cpp 仅用于头文件自包含校验,不计入产物结构检查)。 |
| 54 | + ASSERT_TRUE(FileExists(host_dir + "/inductor_topn_tiling_func.cpp")); | ||
| 55 | + EXPECT_FALSE(FileExists(host_dir + "/inductor_topn_tiling_func_schedule_group_tail.cpp")); | ||
| 56 | + EXPECT_FALSE(FileExists(host_dir + "/inductor_topn_tiling_func_solver_func.cpp")); | ||
| 57 | + const std::string merged = ReadFile(host_dir + "/inductor_topn_tiling_func.cpp"); | ||
| 58 | + EXPECT_NE(merged.find("extern \"C\" int64_t AutofuseTiling"), std::string::npos); | ||
| 59 | + EXPECT_NE(merged.find("extern \"C\" int64_t GenerateTopnSolutions"), std::string::npos); | ||
| 67 | } | 60 | } |
| 68 | 61 | ||
| 69 | std::string HeaderSelfContainedCheck() { | 62 | std::string HeaderSelfContainedCheck() { |
| @@ -165,6 +165,7 @@ def test_inductor_host_link_includes_acl_runtime(ascendc_compile_module, tmp_pat | |||
| 165 | stage="host", | 165 | stage="host", |
| 166 | graph_name="empty_tensor_graph", | 166 | graph_name="empty_tensor_graph", |
| 167 | pgo_runner_file=None, | 167 | pgo_runner_file=None, |
| 168 | + temp_dir=os.fspath(tmp_path), | ||
| 168 | ) | 169 | ) |
| 169 | 170 | ||
| 170 | def fake_compile_host_objs(*_args): | 171 | def fake_compile_host_objs(*_args): |
| @@ -184,6 +185,6 @@ def test_inductor_host_link_includes_acl_runtime(ascendc_compile_module, tmp_pat | |||
| 184 | 185 | ||
| 185 | ascendc_compile_module.module.link_shared = fake_link_shared | 186 | ascendc_compile_module.module.link_shared = fake_link_shared |
| 186 | 187 | ||
| 187 | - ascendc_compile_module.link_host_target(args, os.fspath(tmp_path)) | 188 | + ascendc_compile_module.build_host_output(args, os.fspath(tmp_path)) |
| 188 | 189 | ||
| 189 | assert "acl_rt" in captured["link_libraries"] | 190 | assert "acl_rt" in captured["link_libraries"] |
| @@ -523,13 +523,14 @@ def test_main_host_pgo_builds_bundle_and_skips_plain_copy( | |||
| 523 | events = [] | 523 | events = [] |
| 524 | args = _make_host_pgo_args(tmpdir, ("/mspti", [], [])) | 524 | args = _make_host_pgo_args(tmpdir, ("/mspti", [], [])) |
| 525 | 525 | ||
| 526 | - def fake_link_host_target(*_): | 526 | + def fake_link_tiling_so(*_): |
| 527 | return str(tmpdir.join("built_tiling.so")) | 527 | return str(tmpdir.join("built_tiling.so")) |
| 528 | 528 | ||
| 529 | def fake_build_pgo_sidecars(*_): | 529 | def fake_build_pgo_sidecars(*_): |
| 530 | return str(tmpdir.join("built_runner")), str(tmpdir.join("built_kernel")) | 530 | return str(tmpdir.join("built_runner")), str(tmpdir.join("built_kernel")) |
| 531 | 531 | ||
| 532 | - ascendc_compile_module.module.link_host_target = fake_link_host_target | 532 | + ascendc_compile_module.module.compile_host_objs = lambda *_: ["/tmp/build/host.o"] |
| 533 | + ascendc_compile_module.module.link_tiling_so = fake_link_tiling_so | ||
| 533 | ascendc_compile_module.module.build_pgo_sidecars = fake_build_pgo_sidecars | 534 | ascendc_compile_module.module.build_pgo_sidecars = fake_build_pgo_sidecars |
| 534 | args.pgo_ld_preload = "/mspti/lib64/libmspti.so" | 535 | args.pgo_ld_preload = "/mspti/lib64/libmspti.so" |
| 535 | 536 | ||
| @@ -572,7 +573,7 @@ def test_main_host_pgo_failure_falls_back_to_plain_tiling( | |||
| 572 | copied = [] | 573 | copied = [] |
| 573 | args = _make_host_pgo_args(tmpdir, ("/mspti", [], [])) | 574 | args = _make_host_pgo_args(tmpdir, ("/mspti", [], [])) |
| 574 | 575 | ||
| 575 | - def fake_link_host_target(*_): | 576 | + def fake_link_tiling_so(*_): |
| 576 | return str(tmpdir.join("built_tiling.so")) | 577 | return str(tmpdir.join("built_tiling.so")) |
| 577 | 578 | ||
| 578 | def fail_build_pgo_sidecars(*_): | 579 | def fail_build_pgo_sidecars(*_): |
| @@ -581,7 +582,8 @@ def test_main_host_pgo_failure_falls_back_to_plain_tiling( | |||
| 581 | def record_copy(so_file, compile_args, src_dir): | 582 | def record_copy(so_file, compile_args, src_dir): |
| 582 | copied.append((so_file, compile_args.output_file, src_dir)) | 583 | copied.append((so_file, compile_args.output_file, src_dir)) |
| 583 | 584 | ||
| 584 | - ascendc_compile_module.module.link_host_target = fake_link_host_target | 585 | + ascendc_compile_module.module.compile_host_objs = lambda *_: ["/tmp/build/host.o"] |
| 586 | + ascendc_compile_module.module.link_tiling_so = fake_link_tiling_so | ||
| 585 | ascendc_compile_module.module.build_pgo_sidecars = fail_build_pgo_sidecars | 587 | ascendc_compile_module.module.build_pgo_sidecars = fail_build_pgo_sidecars |
| 586 | ascendc_compile_module.module.copy_so_to_output = record_copy | 588 | ascendc_compile_module.module.copy_so_to_output = record_copy |
| 587 | 589 | ||
| @@ -597,15 +599,19 @@ def test_main_host_pgo_failure_falls_back_to_plain_tiling( | |||
| 597 | assert os.getcwd() == original_dir | 599 | assert os.getcwd() == original_dir |
| 598 | 600 | ||
| 599 | 601 | ||
| 600 | -def test_build_host_output_passes_pch_to_host_link(ascendc_compile_module, tmpdir): | 602 | +def test_build_host_output_passes_pch_to_host_compile(ascendc_compile_module, tmpdir): |
| 601 | args = _make_host_pgo_args(tmpdir, None) | 603 | args = _make_host_pgo_args(tmpdir, None) |
| 602 | captured = {} | 604 | captured = {} |
| 603 | 605 | ||
| 604 | - def fake_link_host_target(compile_args, temp_dir, pch_path=None): | 606 | + def fake_compile_host_objs(compile_args, temp_dir, pch_path): |
| 605 | captured["pch_path"] = pch_path | 607 | captured["pch_path"] = pch_path |
| 608 | + return ["/tmp/build/host.o"] | ||
| 609 | + | ||
| 610 | + def fake_link_tiling_so(compile_args, tiling_obj_paths, temp_dir): | ||
| 606 | return str(tmpdir.join("built_tiling.so")) | 611 | return str(tmpdir.join("built_tiling.so")) |
| 607 | 612 | ||
| 608 | - ascendc_compile_module.module.link_host_target = fake_link_host_target | 613 | + ascendc_compile_module.module.compile_host_objs = fake_compile_host_objs |
| 614 | + ascendc_compile_module.module.link_tiling_so = fake_link_tiling_so | ||
| 609 | 615 | ||
| 610 | result = ascendc_compile_module.build_host_output(args, "/tmp/cache/host.pch") | 616 | result = ascendc_compile_module.build_host_output(args, "/tmp/cache/host.pch") |
| 611 | 617 | ||
| @@ -619,7 +625,7 @@ def test_main_host_pgo_without_mspti_skips_sidecars_and_copies_plain_tiling( | |||
| 619 | copied = [] | 625 | copied = [] |
| 620 | args = _make_host_pgo_args(tmpdir, None) | 626 | args = _make_host_pgo_args(tmpdir, None) |
| 621 | 627 | ||
| 622 | - def fake_link_host_target(*_): | 628 | + def fake_build_host_output(*_): |
| 623 | return str(tmpdir.join("built_tiling.so")) | 629 | return str(tmpdir.join("built_tiling.so")) |
| 624 | 630 | ||
| 625 | def fail_build_pgo_sidecars(*_): | 631 | def fail_build_pgo_sidecars(*_): |
| @@ -628,7 +634,7 @@ def test_main_host_pgo_without_mspti_skips_sidecars_and_copies_plain_tiling( | |||
| 628 | def record_copy(so_file, compile_args, src_dir): | 634 | def record_copy(so_file, compile_args, src_dir): |
| 629 | copied.append(so_file) | 635 | copied.append(so_file) |
| 630 | 636 | ||
| 631 | - ascendc_compile_module.module.link_host_target = fake_link_host_target | 637 | + ascendc_compile_module.module.build_host_output = fake_build_host_output |
| 632 | ascendc_compile_module.module.build_pgo_sidecars = fail_build_pgo_sidecars | 638 | ascendc_compile_module.module.build_pgo_sidecars = fail_build_pgo_sidecars |
| 633 | ascendc_compile_module.module.copy_so_to_output = record_copy | 639 | ascendc_compile_module.module.copy_so_to_output = record_copy |
| 634 | 640 | ||
| @@ -654,15 +660,16 @@ def test_host_target_records_compile_and_link_stage( | |||
| 654 | "stage": "host", | 660 | "stage": "host", |
| 655 | "graph_name": "graph", | 661 | "graph_name": "graph", |
| 656 | "output_file": str(tmpdir.join("host.so")), | 662 | "output_file": str(tmpdir.join("host.so")), |
| 663 | + "temp_dir": str(tmpdir), | ||
| 657 | }, | 664 | }, |
| 658 | )() | 665 | )() |
| 659 | 666 | ||
| 660 | ascendc_compile_module.module.run_compile_command = _noop_run_compile_command | 667 | ascendc_compile_module.module.run_compile_command = _noop_run_compile_command |
| 661 | - ascendc_compile_module.link_host_target(args, str(tmpdir)) | 668 | + ascendc_compile_module.build_host_output(args, str(tmpdir)) |
| 662 | 669 | ||
| 663 | labels = [item[0] for item in ascendc_compile_module.duration_records] | 670 | labels = [item[0] for item in ascendc_compile_module.duration_records] |
| 664 | assert ["InductorCompile", "host", "CompileHostObj", "graph"] in labels | 671 | assert ["InductorCompile", "host", "CompileHostObj", "graph"] in labels |
| 665 | - assert ["InductorCompile", "host", "LinkHostSo", "graph"] in labels | 672 | + assert ["InductorCompile", "host", "LinkTilingSo", "graph"] in labels |
| 666 | assert capsys.readouterr().out == "" | 673 | assert capsys.readouterr().out == "" |
| 667 | 674 | ||
| 668 | 675 | ||
| @@ -690,11 +697,11 @@ def test_kernel_target_records_device_compile_and_link_stage( | |||
| 690 | )() | 697 | )() |
| 691 | 698 | ||
| 692 | ascendc_compile_module.module.run_compile_command = _noop_run_compile_command | 699 | ascendc_compile_module.module.run_compile_command = _noop_run_compile_command |
| 693 | - ascendc_compile_module.link_kernel_target(args, None, str(tmpdir)) | 700 | + ascendc_compile_module.build_kernel_target(args, None, str(tmpdir)) |
| 694 | 701 | ||
| 695 | labels = [item[0] for item in ascendc_compile_module.duration_records] | 702 | labels = [item[0] for item in ascendc_compile_module.duration_records] |
| 696 | assert ["InductorCompile", "device", "CompileDeviceObj", "graph"] in labels | 703 | assert ["InductorCompile", "device", "CompileDeviceObj", "graph"] in labels |
| 697 | - assert ["InductorCompile", "device", "LinkDeviceSo", "graph"] in labels | 704 | + assert ["InductorCompile", "device", "LinkKernelSo", "graph"] in labels |
| 698 | 705 | ||
| 699 | 706 | ||
| 700 | def test_compile_device_obj_includes_machine_asc_headers( | 707 | def test_compile_device_obj_includes_machine_asc_headers( |
| @@ -1662,16 +1669,9 @@ def test_compile_host_obj_rejects_multiple_sources_without_compile( | |||
| 1662 | assert "expects exactly one host source" in str(exc_info.value) | 1669 | assert "expects exactly one host source" in str(exc_info.value) |
| 1663 | 1670 | ||
| 1664 | 1671 | ||
| 1665 | -def _capture_build_device_so_link( | 1672 | +def _capture_link_kernel_so(ascendc_compile_module, args, host_obj_path, temp_dir): |
| 1666 | - ascendc_compile_module, args, host_obj_path, temp_dir | ||
| 1667 | -): | ||
| 1668 | captured = {} | 1673 | captured = {} |
| 1669 | 1674 | ||
| 1670 | - def fake_compile_device_obj(compile_args, temp_dir): | ||
| 1671 | - return "/tmp/build/device/kernel.cpp.o" | ||
| 1672 | - | ||
| 1673 | - ascendc_compile_module.module.compile_device_obj = fake_compile_device_obj | ||
| 1674 | - | ||
| 1675 | def fake_link_shared( | 1675 | def fake_link_shared( |
| 1676 | target_file, obj_files, link_libraries=None, extra_link_options=None | 1676 | target_file, obj_files, link_libraries=None, extra_link_options=None |
| 1677 | ): | 1677 | ): |
| @@ -1681,19 +1681,16 @@ def _capture_build_device_so_link( | |||
| 1681 | return target_file | 1681 | return target_file |
| 1682 | 1682 | ||
| 1683 | ascendc_compile_module.module.link_shared = fake_link_shared | 1683 | ascendc_compile_module.module.link_shared = fake_link_shared |
| 1684 | - ascendc_compile_module.build_device_so(args, host_obj_path, temp_dir) | 1684 | + ascendc_compile_module.link_kernel_so( |
| 1685 | + args, host_obj_path, temp_dir, "/tmp/build/device/kernel.cpp.o" | ||
| 1686 | + ) | ||
| 1685 | return captured | 1687 | return captured |
| 1686 | 1688 | ||
| 1687 | 1689 | ||
| 1688 | -def test_build_device_so_links_all_host_objects(ascendc_compile_module): | 1690 | +def test_link_kernel_so_links_all_host_objects(ascendc_compile_module): |
| 1689 | captured = {} | 1691 | captured = {} |
| 1690 | args = _make_compile_args() | 1692 | args = _make_compile_args() |
| 1691 | 1693 | ||
| 1692 | - def fake_compile_device_obj(compile_args, temp_dir): | ||
| 1693 | - return "/tmp/build/device/kernel.cpp.o" | ||
| 1694 | - | ||
| 1695 | - ascendc_compile_module.module.compile_device_obj = fake_compile_device_obj | ||
| 1696 | - | ||
| 1697 | def fake_link_shared( | 1694 | def fake_link_shared( |
| 1698 | target_file, obj_files, link_libraries=None, extra_link_options=None | 1695 | target_file, obj_files, link_libraries=None, extra_link_options=None |
| 1699 | ): | 1696 | ): |
| @@ -1705,14 +1702,16 @@ def test_build_device_so_links_all_host_objects(ascendc_compile_module): | |||
| 1705 | 1702 | ||
| 1706 | ascendc_compile_module.module.link_shared = fake_link_shared | 1703 | ascendc_compile_module.module.link_shared = fake_link_shared |
| 1707 | 1704 | ||
| 1708 | - result = ascendc_compile_module.build_device_so(args, ["a.o", "b.o"], "/tmp/build") | 1705 | + result = ascendc_compile_module.link_kernel_so( |
| 1706 | + args, ["a.o", "b.o"], "/tmp/build", "/tmp/build/device/kernel.cpp.o" | ||
| 1707 | + ) | ||
| 1709 | 1708 | ||
| 1710 | assert result == "/tmp/build/kernel.so" | 1709 | assert result == "/tmp/build/kernel.so" |
| 1711 | assert captured["obj_files"] == ["a.o", "b.o", "/tmp/build/device/kernel.cpp.o"] | 1710 | assert captured["obj_files"] == ["a.o", "b.o", "/tmp/build/device/kernel.cpp.o"] |
| 1712 | assert captured["link_libraries"] == ascendc_compile_module.HOST_LINK_LIBRARIES | 1711 | assert captured["link_libraries"] == ascendc_compile_module.HOST_LINK_LIBRARIES |
| 1713 | 1712 | ||
| 1714 | 1713 | ||
| 1715 | -def test_build_device_so_links_shared_cv_wrapper_so_for_cv_compile( | 1714 | +def test_link_kernel_so_links_shared_cv_wrapper_so_for_cv_compile( |
| 1716 | ascendc_compile_module, tmpdir | 1715 | ascendc_compile_module, tmpdir |
| 1717 | ): | 1716 | ): |
| 1718 | device_dir = tmpdir.mkdir("device") | 1717 | device_dir = tmpdir.mkdir("device") |
| @@ -1723,7 +1722,7 @@ def test_build_device_so_links_shared_cv_wrapper_so_for_cv_compile( | |||
| 1723 | args.shared_cv_wrapper_so = ( | 1722 | args.shared_cv_wrapper_so = ( |
| 1724 | "/tmp/run/cv_tiling_wrapper_cache/libautofuse_cv_tiling_wrapper.so" | 1723 | "/tmp/run/cv_tiling_wrapper_cache/libautofuse_cv_tiling_wrapper.so" |
| 1725 | ) | 1724 | ) |
| 1726 | - captured = _capture_build_device_so_link( | 1725 | + captured = _capture_link_kernel_so( |
| 1727 | ascendc_compile_module, args, ["graph.o"], "/tmp/build" | 1726 | ascendc_compile_module, args, ["graph.o"], "/tmp/build" |
| 1728 | ) | 1727 | ) |
| 1729 | 1728 | ||
| @@ -1738,7 +1737,7 @@ def test_build_device_so_links_shared_cv_wrapper_so_for_cv_compile( | |||
| 1738 | ] | 1737 | ] |
| 1739 | 1738 | ||
| 1740 | 1739 | ||
| 1741 | -def test_build_device_so_ignores_shared_cv_wrapper_so_for_non_cv_compile( | 1740 | +def test_link_kernel_so_ignores_shared_cv_wrapper_so_for_non_cv_compile( |
| 1742 | ascendc_compile_module, tmpdir | 1741 | ascendc_compile_module, tmpdir |
| 1743 | ): | 1742 | ): |
| 1744 | device_dir = tmpdir.mkdir("device") | 1743 | device_dir = tmpdir.mkdir("device") |
| @@ -1749,7 +1748,7 @@ def test_build_device_so_ignores_shared_cv_wrapper_so_for_non_cv_compile( | |||
| 1749 | args.shared_cv_wrapper_so = ( | 1748 | args.shared_cv_wrapper_so = ( |
| 1750 | "/tmp/run/cv_tiling_wrapper_cache/libautofuse_cv_tiling_wrapper.so" | 1749 | "/tmp/run/cv_tiling_wrapper_cache/libautofuse_cv_tiling_wrapper.so" |
| 1751 | ) | 1750 | ) |
| 1752 | - captured = _capture_build_device_so_link( | 1751 | + captured = _capture_link_kernel_so( |
| 1753 | ascendc_compile_module, args, ["graph.o"], str(tmpdir) | 1752 | ascendc_compile_module, args, ["graph.o"], str(tmpdir) |
| 1754 | ) | 1753 | ) |
| 1755 | 1754 | ||
| @@ -1757,7 +1756,7 @@ def test_build_device_so_ignores_shared_cv_wrapper_so_for_non_cv_compile( | |||
| 1757 | assert captured["link_libraries"] == ascendc_compile_module.HOST_LINK_LIBRARIES | 1756 | assert captured["link_libraries"] == ascendc_compile_module.HOST_LINK_LIBRARIES |
| 1758 | 1757 | ||
| 1759 | 1758 | ||
| 1760 | -def test_link_host_target_links_multiple_host_objects(ascendc_compile_module): | 1759 | +def test_build_host_output_links_multiple_host_objects(ascendc_compile_module): |
| 1761 | captured = {} | 1760 | captured = {} |
| 1762 | args = _make_compile_args( | 1761 | args = _make_compile_args( |
| 1763 | [ | 1762 | [ |
| @@ -1782,7 +1781,7 @@ def test_link_host_target_links_multiple_host_objects(ascendc_compile_module): | |||
| 1782 | 1781 | ||
| 1783 | ascendc_compile_module.module.link_shared = fake_link_shared | 1782 | ascendc_compile_module.module.link_shared = fake_link_shared |
| 1784 | 1783 | ||
| 1785 | - result = ascendc_compile_module.link_host_target(args, "/tmp/build") | 1784 | + result = ascendc_compile_module.link_tiling_so(args, ["a.o", "b.o"], "/tmp/build") |
| 1786 | 1785 | ||
| 1787 | assert result == "/tmp/build/kernel.so" | 1786 | assert result == "/tmp/build/kernel.so" |
| 1788 | assert captured["target_file"] == "/tmp/build/kernel.so" | 1787 | assert captured["target_file"] == "/tmp/build/kernel.so" |
| @@ -1791,7 +1790,7 @@ def test_link_host_target_links_multiple_host_objects(ascendc_compile_module): | |||
| 1791 | assert "acl_rt" in captured["link_libraries"] | 1790 | assert "acl_rt" in captured["link_libraries"] |
| 1792 | 1791 | ||
| 1793 | 1792 | ||
| 1794 | -def _capture_link_host_target_link(ascendc_compile_module, args, temp_dir): | 1793 | +def _capture_build_host_output_link(ascendc_compile_module, args, temp_dir): |
| 1795 | captured = {} | 1794 | captured = {} |
| 1796 | 1795 | ||
| 1797 | def fake_compile_host_objs(compile_args, temp_dir): | 1796 | def fake_compile_host_objs(compile_args, temp_dir): |
| @@ -1808,11 +1807,12 @@ def _capture_link_host_target_link(ascendc_compile_module, args, temp_dir): | |||
| 1808 | return target_file | 1807 | return target_file |
| 1809 | 1808 | ||
| 1810 | ascendc_compile_module.module.link_shared = fake_link_shared | 1809 | ascendc_compile_module.module.link_shared = fake_link_shared |
| 1811 | - ascendc_compile_module.link_host_target(args, temp_dir) | 1810 | + args.temp_dir = temp_dir |
| 1811 | + ascendc_compile_module.build_host_output(args) | ||
| 1812 | return captured | 1812 | return captured |
| 1813 | 1813 | ||
| 1814 | 1814 | ||
| 1815 | -def test_link_host_target_links_shared_cv_wrapper_so_for_cv_compile( | 1815 | +def test_build_host_output_links_shared_cv_wrapper_so_for_cv_compile( |
| 1816 | ascendc_compile_module, tmpdir | 1816 | ascendc_compile_module, tmpdir |
| 1817 | ): | 1817 | ): |
| 1818 | host_dir = tmpdir.mkdir("host") | 1818 | host_dir = tmpdir.mkdir("host") |
| @@ -1822,7 +1822,7 @@ def test_link_host_target_links_shared_cv_wrapper_so_for_cv_compile( | |||
| 1822 | args.shared_cv_wrapper_so = ( | 1822 | args.shared_cv_wrapper_so = ( |
| 1823 | "/tmp/run/cv_tiling_wrapper_cache/libautofuse_cv_tiling_wrapper.so" | 1823 | "/tmp/run/cv_tiling_wrapper_cache/libautofuse_cv_tiling_wrapper.so" |
| 1824 | ) | 1824 | ) |
| 1825 | - captured = _capture_link_host_target_link( | 1825 | + captured = _capture_build_host_output_link( |
| 1826 | ascendc_compile_module, args, "/tmp/build" | 1826 | ascendc_compile_module, args, "/tmp/build" |
| 1827 | ) | 1827 | ) |
| 1828 | 1828 | ||
| @@ -1836,7 +1836,7 @@ def test_link_host_target_links_shared_cv_wrapper_so_for_cv_compile( | |||
| 1836 | ] | 1836 | ] |
| 1837 | 1837 | ||
| 1838 | 1838 | ||
| 1839 | -def test_link_host_target_ignores_shared_cv_wrapper_so_for_non_cv_compile( | 1839 | +def test_build_host_output_ignores_shared_cv_wrapper_so_for_non_cv_compile( |
| 1840 | ascendc_compile_module, tmpdir | 1840 | ascendc_compile_module, tmpdir |
| 1841 | ): | 1841 | ): |
| 1842 | host_dir = tmpdir.mkdir("host") | 1842 | host_dir = tmpdir.mkdir("host") |
| @@ -1846,16 +1846,18 @@ def test_link_host_target_ignores_shared_cv_wrapper_so_for_non_cv_compile( | |||
| 1846 | args.shared_cv_wrapper_so = ( | 1846 | args.shared_cv_wrapper_so = ( |
| 1847 | "/tmp/run/cv_tiling_wrapper_cache/libautofuse_cv_tiling_wrapper.so" | 1847 | "/tmp/run/cv_tiling_wrapper_cache/libautofuse_cv_tiling_wrapper.so" |
| 1848 | ) | 1848 | ) |
| 1849 | - captured = _capture_link_host_target_link(ascendc_compile_module, args, str(tmpdir)) | 1849 | + captured = _capture_build_host_output_link( |
| 1850 | + ascendc_compile_module, args, str(tmpdir) | ||
| 1851 | + ) | ||
| 1850 | 1852 | ||
| 1851 | assert captured["obj_files"] == ["graph.o"] | 1853 | assert captured["obj_files"] == ["graph.o"] |
| 1852 | assert captured["link_libraries"] == ascendc_compile_module.HOST_LINK_LIBRARIES | 1854 | assert captured["link_libraries"] == ascendc_compile_module.HOST_LINK_LIBRARIES |
| 1853 | 1855 | ||
| 1854 | 1856 | ||
| 1855 | -def test_link_host_target_adds_acl_runtime_for_pgo_proxy(ascendc_compile_module): | 1857 | +def test_build_host_output_adds_acl_runtime_for_pgo_proxy(ascendc_compile_module): |
| 1856 | args = _make_compile_args(["/tmp/build/host/graph_tiling_func.cpp"]) | 1858 | args = _make_compile_args(["/tmp/build/host/graph_tiling_func.cpp"]) |
| 1857 | args.pgo_runner_file = "/tmp/build/host/graph_tiling_func_PgoRunner.cpp" | 1859 | args.pgo_runner_file = "/tmp/build/host/graph_tiling_func_PgoRunner.cpp" |
| 1858 | - captured = _capture_link_host_target_link( | 1860 | + captured = _capture_build_host_output_link( |
| 1859 | ascendc_compile_module, args, "/tmp/build" | 1861 | ascendc_compile_module, args, "/tmp/build" |
| 1860 | ) | 1862 | ) |
| 1861 | 1863 | ||
| @@ -1865,7 +1867,7 @@ def test_link_host_target_adds_acl_runtime_for_pgo_proxy(ascendc_compile_module) | |||
| 1865 | ] | 1867 | ] |
| 1866 | 1868 | ||
| 1867 | 1869 | ||
| 1868 | -def test_link_kernel_target_reuses_host_objects_for_static_recompile( | 1870 | +def test_build_kernel_target_reuses_host_objects_for_static_recompile( |
| 1869 | ascendc_compile_module, | 1871 | ascendc_compile_module, |
| 1870 | ): | 1872 | ): |
| 1871 | calls = [] | 1873 | calls = [] |
| @@ -1879,15 +1881,22 @@ def test_link_kernel_target_reuses_host_objects_for_static_recompile( | |||
| 1879 | fake_try_static_shape_compile | 1881 | fake_try_static_shape_compile |
| 1880 | ) | 1882 | ) |
| 1881 | 1883 | ||
| 1882 | - def fake_build_device_so(compile_args, host_obj_paths, temp_dir): | 1884 | + def fake_compile_device_obj(compile_args, temp_dir): |
| 1883 | - calls.append(list(host_obj_paths)) | 1885 | + return f"/tmp/build/device/kernel_{len(calls) + 1}.o" |
| 1886 | + | ||
| 1887 | + def fake_link_kernel_so(compile_args, tiling_obj_paths, temp_dir, kernel_obj_path): | ||
| 1888 | + calls.append((list(tiling_obj_paths), kernel_obj_path)) | ||
| 1884 | return f"/tmp/build/kernel_{len(calls)}.so" | 1889 | return f"/tmp/build/kernel_{len(calls)}.so" |
| 1885 | 1890 | ||
| 1886 | - ascendc_compile_module.module.build_device_so = fake_build_device_so | 1891 | + ascendc_compile_module.module.compile_device_obj = fake_compile_device_obj |
| 1892 | + ascendc_compile_module.module.link_kernel_so = fake_link_kernel_so | ||
| 1887 | 1893 | ||
| 1888 | - result = ascendc_compile_module.link_kernel_target( | 1894 | + result = ascendc_compile_module.build_kernel_target( |
| 1889 | args, ["a.o", "b.o"], "/tmp/build" | 1895 | args, ["a.o", "b.o"], "/tmp/build" |
| 1890 | ) | 1896 | ) |
| 1891 | 1897 | ||
| 1892 | assert result == "/tmp/build/kernel_2.so" | 1898 | assert result == "/tmp/build/kernel_2.so" |
| 1893 | - assert calls == [["a.o", "b.o"], ["a.o", "b.o"]] | 1899 | + assert [tiling_obj_paths for tiling_obj_paths, _ in calls] == [ |
| 1900 | + ["a.o", "b.o"], | ||
| 1901 | + ["a.o", "b.o"], | ||
| 1902 | + ] | ||
| @@ -254,7 +254,7 @@ def test_execute_compile_keeps_single_host_file_without_marker( | |||
| 254 | assert os.path.exists(host_file) | 254 | assert os.path.exists(host_file) |
| 255 | 255 | ||
| 256 | 256 | ||
| 257 | -def test_execute_compile_splits_host_files_with_marker(compile_adapter_module, tmpdir): | 257 | +def test_execute_compile_merges_host_files_with_marker(compile_adapter_module, tmpdir): |
| 258 | captured = {} | 258 | captured = {} |
| 259 | 259 | ||
| 260 | def fake_main(args): | 260 | def fake_main(args): |
| @@ -287,16 +287,17 @@ def test_execute_compile_splits_host_files_with_marker(compile_adapter_module, t | |||
| 287 | ) | 287 | ) |
| 288 | 288 | ||
| 289 | host_dir = os.path.join(str(tmpdir), "host") | 289 | host_dir = os.path.join(str(tmpdir), "host") |
| 290 | + # host 编译为单个 cpp 源文件(cpp 段合并),header 段拆出独立 .h 供 include 引用。 | ||
| 291 | + host_file = os.path.join(host_dir, "graph_tiling_func.cpp") | ||
| 292 | + assert captured["args"].host_files == host_file | ||
| 290 | assert os.path.exists(os.path.join(host_dir, "autofuse_tiling_func_common.h")) | 293 | assert os.path.exists(os.path.join(host_dir, "autofuse_tiling_func_common.h")) |
| 291 | - assert captured["args"].host_files == [ | 294 | + with open(host_file) as f: |
| 292 | - os.path.join(host_dir, "graph_tiling_func_solver_func.cpp"), | 295 | + merged = f.read() |
| 293 | - os.path.join(host_dir, "graph_tiling_func_asc_graph0_schedule_result0_g0.cpp"), | 296 | + assert merged.count('#include "autofuse_tiling_func_common.h"') == 1 |
| 294 | - ] | 297 | + assert 'extern "C" int Solver()' in merged |
| 295 | - for cpp_file in captured["args"].host_files: | 298 | + assert 'extern "C" int TilingFunc()' in merged |
| 296 | - with open(cpp_file) as f: | ||
| 297 | - assert f.read().count('#include "autofuse_tiling_func_common.h"') == 1 | ||
| 298 | assert not os.path.exists( | 299 | assert not os.path.exists( |
| 299 | - os.path.join(host_dir, "graph_tiling_func_TilingHead.cpp") | 300 | + os.path.join(host_dir, "graph_tiling_func_solver_func.cpp") |
| 300 | ) | 301 | ) |
| 301 | 302 | ||
| 302 | 303 | ||


这里是为了兼容性考虑么,后续版本会变化吗