@@ -1058,11 +1058,36 @@ def fp8_path_c_producer_gate_payload(
10581058 }
10591059
10601060
1061+ def _path_c_default_target() -> str:
1062+ """Resolve the default lowering target for Path C fused/direct-chain kernels.
1063+
1064+ On Apple silicon we lower to Metal; everywhere else (e.g. CUDA gb10) Metal is
1065+ unavailable, so fall back to CUDA. Detection mirrors mlx: ``mx.metal`` may be
1066+ present as a module yet report ``is_available() == False`` on non-Metal hosts.
1067+ """
1068+ metal = getattr(mx, "metal", None)
1069+ if metal is None or not metal.is_available():
1070+ return "cuda"
1071+ return "metal"
1072+
1073+
10611074def _tilelang_dev_roots() -> tuple[Path, ...]:
10621075 roots: list[Path] = []
1063- env_root = os.environ.get("TILELANG_DEV_BUILD_ROOT")
1064- if env_root:
1065- roots.append(Path(env_root).expanduser())
1076+ for env_name in ("TILELANG_DEV_BUILD_ROOT", "TILELANG_ROOT"):
1077+ env_root = os.environ.get(env_name)
1078+ if env_root:
1079+ roots.append(Path(env_root).expanduser())
1080+ # Derive the build dir of the installed `tilelang` package (real build with
1081+ # libtilelang.so), e.g. /home/dave/source/tilelang/build, as a candidate.
1082+ try:
1083+ import importlib.util
1084+
1085+ spec = importlib.util.find_spec("tilelang")
1086+ if spec is not None and spec.origin:
1087+ pkg_build = Path(spec.origin).parent.parent / "build"
1088+ roots.append(pkg_build)
1089+ except Exception:
1090+ pass
10661091 roots.extend(
10671092 [
10681093 ROOT.parent / "tl_apache_tvm_swap",
@@ -1110,6 +1135,10 @@ def ensure_tilelang_dev_env_for_path_c() -> None:
11101135 tvm_dir = build_root / "tvm"
11111136 if not lib_dir.exists() or not tvm_dir.exists():
11121137 continue
1138+ # Skip stub-only build dirs (e.g. tl_apache_tvm_swap/build holds only
1139+ # libcudart_stub.so etc.). A usable dev build must ship libtilelang.so.
1140+ if not (lib_dir / "libtilelang.so").exists():
1141+ continue
11131142 os.environ["TILELANG_DEV_BUILD_ROOT"] = str(build_root)
11141143 os.environ.setdefault("TVM_LIBRARY_PATH", str(lib_dir))
11151144 _prepend_env_path("DYLD_LIBRARY_PATH", lib_dir)
@@ -3225,7 +3254,7 @@ def fp8_path_c_training_route_payload_for_model(
32253254 compile_receipt_path: str | Path | None = None,
32263255 auto_install_fused_train_block: bool = False,
32273256 fused_train_block_artifact_lowerer: Callable[..., Any] | None = None,
3228- fused_train_block_artifact_target_name: str = "metal" ,
3257+ fused_train_block_artifact_target_name: str = _path_c_default_target() ,
32293258 fused_train_block_artifact_execution_backend: str = "tvm_ffi",
32303259) -> dict[str, Any]:
32313260 """Return Path C training route metadata using model-owned ABI banks."""
@@ -4759,7 +4788,7 @@ def compile_path_c_fused_train_block_artifact_for_model(
47594788 *,
47604789 model: Any,
47614790 sequence_length: int | None = None,
4762- target_name: str = "metal" ,
4791+ target_name: str = _path_c_default_target() ,
47634792 execution_backend: str = "tvm_ffi",
47644793 lowerer: Callable[..., Any] | None = None,
47654794) -> dict[str, Any]:
@@ -5556,7 +5585,7 @@ def install_path_c_fused_train_block_runtime_for_model(
55565585 training_runtime: Any | None = None,
55575586 compile_artifact: bool = False,
55585587 artifact_lowerer: Callable[..., Any] | None = None,
5559- artifact_target_name: str = "metal" ,
5588+ artifact_target_name: str = _path_c_default_target() ,
55605589 artifact_execution_backend: str = "tvm_ffi",
55615590 sequence_length: int | None = None,
55625591) -> dict[str, Any]:
@@ -6020,7 +6049,7 @@ def _path_c_direct_chain_artifact_for_segment(
60206049def compile_path_c_direct_fusion_chain_artifacts(
60216050 chain: Any,
60226051 *,
6023- target_name: str = "metal" ,
6052+ target_name: str = _path_c_default_target() ,
60246053 execution_backend: str = "tvm_ffi",
60256054 lowerer: Callable[..., Any] | None = None,
60266055) -> tuple[Any, ...]:
@@ -6661,7 +6690,8 @@ def install_path_c_direct_chain_training_runtime_for_model(
66616690 chain: Any | None = None,
66626691 artifacts: Any | None = None,
66636692 logical_owner: Any | None = None,
6664- artifact_compiler: Callable[[Any], Any] = compile_path_c_direct_fusion_chain_artifacts,
6693+ target_name: str | None = None,
6694+ artifact_compiler: Callable[..., Any] | None = None,
66656695 owner_name: str | None = None,
66666696 sequence_length: int | None = None,
66676697 training_critical_path: bool = False,
@@ -6733,6 +6763,13 @@ def install_path_c_direct_chain_training_runtime_for_model(
67336763 "training_critical_path": False,
67346764 }
67356765
6766+ resolved_target_name = target_name or _path_c_default_target()
6767+ if artifact_compiler is None:
6768+ def artifact_compiler(_chain: Any) -> Any:
6769+ return compile_path_c_direct_fusion_chain_artifacts(
6770+ _chain,
6771+ target_name=resolved_target_name,
6772+ )
67366773 compiled_artifacts = artifacts if artifacts is not None else artifact_compiler(selected_chain)
67376774 resolved_owner_name = owner_name or (
67386775 f"{profile_name}.path_c_direct_fusion_chain_training_runtime"
0 commit comments