1818from typing import Optional , Tuple
1919
2020
21+ def skip_cuda_build () -> bool :
22+ """Check if CUDA build was skipped (FL-only mode).
23+
24+ First checks environment variable (for runtime override),
25+ then falls back to build-time configuration.
26+ """
27+ # Environment variable takes precedence (allows runtime override)
28+ if os .environ .get ("TE_FL_SKIP_CUDA" ):
29+ return bool (int (os .environ .get ("TE_FL_SKIP_CUDA" , "0" )))
30+
31+ # Fall back to build-time configuration
32+ try :
33+ from transformer_engine .plugin .core ._build_config import SKIP_CUDA_BUILD
34+ return SKIP_CUDA_BUILD
35+ except ImportError :
36+ # If build config doesn't exist, default to False
37+ return False
38+
39+ # Load plugin system - this handles module registration and backend initialization
40+ # The _module_setup inside core will:
41+ # 1. Register modules under both full and short names for relative imports
42+ # 2. Load all available backends (flagos, reference, vendor/cuda, etc.)
43+ # 3. Register transformer_engine_torch module from the selected backend
44+ import transformer_engine .plugin .core # noqa: F401
45+
2146@functools .lru_cache (maxsize = None )
2247def _is_package_installed (package ) -> bool :
2348 """Check if the given package is installed via pip."""
@@ -146,46 +171,36 @@ def get_te_core_package_info() -> Tuple[bool, str, str]:
146171@functools .lru_cache (maxsize = None )
147172def load_framework_extension (framework : str ) -> None :
148173 """
149- Load shared library with Transformer Engine framework bindings
150- and check verify correctness if installed via PyPI.
174+ Load shared library with Transformer Engine framework bindings.
175+
176+ For PyTorch: The native module is now named transformer_engine_torch_nv,
177+ and transformer_engine_torch is provided by the plugin system.
178+ This function is kept for backward compatibility but does nothing for torch.
151179 """
152180
181+ # Skip loading native extensions if CUDA build was skipped (FL-only mode)
182+ if skip_cuda_build ():
183+ return
184+
153185 # Supported frameworks.
154186 assert framework in ("jax" , "torch" ), f"Unsupported framework { framework } "
155187
156- # Name of the framework extension library.
188+ # For torch: plugin system already handles transformer_engine_torch
189+ # The native module is transformer_engine_torch_nv (imported by NVIDIA backend)
190+ if framework == "torch" :
191+ return # Nothing to do, plugin system handles this
192+
193+ # For jax: load the native module as before
157194 module_name = f"transformer_engine_{ framework } "
158195
159- # Name of the pip extra dependency for framework extensions from PyPI.
160- extra_dep_name = module_name
161- if framework == "torch" :
162- extra_dep_name = "pytorch"
196+ # Skip if already loaded
197+ if module_name in sys .modules :
198+ return
163199
164- # Find the TE packages. The core and framework packages can only be installed via PyPI.
165- # For the `transformer-engine` package, we need to check explicity.
166- te_core_installed , te_core_package_name , te_core_version = get_te_core_package_info ()
167- te_framework_installed = _is_package_installed (module_name )
168200 te_installed = _is_package_installed ("transformer_engine" )
169- te_installed_via_pypi = _is_package_installed_from_wheel ("transformer_engine" )
170-
171201 assert te_installed , "Could not find `transformer_engine`."
172202
173- # If the framework extension pip package is installed, it means that TE is installed via
174- # PyPI. For this case we need to make sure that the metapackage, the core lib, and framework
175- # extension are all installed via PyPI and have matching versions.
176- if te_framework_installed :
177- assert te_installed_via_pypi , "Could not find `transformer-engine` PyPI package."
178- assert te_core_installed , "Could not find TE core package `transformer-engine-cu*`."
179-
180- assert version (module_name ) == version ("transformer-engine" ) == te_core_version , (
181- "Transformer Engine package version mismatch. Found"
182- f" { module_name } v{ version (module_name )} , transformer-engine"
183- f" v{ version ('transformer-engine' )} , and { te_core_package_name } "
184- f" v{ te_core_version } . Install transformer-engine using "
185- f"'pip3 install --no-build-isolation transformer-engine[{ extra_dep_name } ]==VERSION'"
186- )
187-
188- # After all checks are completed, load the shared object file.
203+ # Load the shared object file for jax
189204 spec = importlib .util .spec_from_file_location (module_name , _get_shared_object_file (framework ))
190205 solib = importlib .util .module_from_spec (spec )
191206 sys .modules [module_name ] = solib
@@ -195,6 +210,10 @@ def load_framework_extension(framework: str) -> None:
195210def sanity_checks_for_pypi_installation () -> None :
196211 """Ensure that package is installed correctly if using PyPI."""
197212
213+ # Skip sanity checks if CUDA build was skipped (FL-only mode)
214+ if skip_cuda_build ():
215+ return
216+
198217 te_core_installed , te_core_package_name , te_core_version = get_te_core_package_info ()
199218 te_installed = _is_package_installed ("transformer_engine" )
200219 te_installed_via_pypi = _is_package_installed_from_wheel ("transformer_engine" )
@@ -390,13 +409,16 @@ def _load_core_library():
390409
391410if "NVTE_PROJECT_BUILDING" not in os .environ or bool (int (os .getenv ("NVTE_RELEASE_BUILD" , "0" ))):
392411 sanity_checks_for_pypi_installation ()
393- _CUDNN_LIB_CTYPES = _load_cudnn ()
394- _NVRTC_LIB_CTYPES = _load_nvrtc ()
395- _CURAND_LIB_CTYPES = _load_curand ()
396- _CUBLAS_LIB_CTYPES = _load_nvidia_cuda_library ("cublas" )
397- _CUDART_LIB_CTYPES = _load_nvidia_cuda_library ("cuda_runtime" )
398- _TE_LIB_CTYPES = _load_core_library ()
399-
400- # Needed to find the correct headers for NVRTC kernels.
401- if not os .getenv ("NVTE_CUDA_INCLUDE_DIR" ) and _nvidia_cudart_include_dir ():
402- os .environ ["NVTE_CUDA_INCLUDE_DIR" ] = _nvidia_cudart_include_dir ()
412+
413+ # Skip loading CUDA libraries if CUDA build was skipped (FL-only mode)
414+ if not skip_cuda_build ():
415+ _CUDNN_LIB_CTYPES = _load_cudnn ()
416+ _NVRTC_LIB_CTYPES = _load_nvrtc ()
417+ _CURAND_LIB_CTYPES = _load_curand ()
418+ _CUBLAS_LIB_CTYPES = _load_nvidia_cuda_library ("cublas" )
419+ _CUDART_LIB_CTYPES = _load_nvidia_cuda_library ("cuda_runtime" )
420+ _TE_LIB_CTYPES = _load_core_library ()
421+
422+ # Needed to find the correct headers for NVRTC kernels.
423+ if not os .getenv ("NVTE_CUDA_INCLUDE_DIR" ) and _nvidia_cudart_include_dir ():
424+ os .environ ["NVTE_CUDA_INCLUDE_DIR" ] = _nvidia_cudart_include_dir ()
0 commit comments