Skip to content

Commit f17b3e4

Browse files
authored
Merge branch 'flagos-ai:main' into add_qa_teat251230
2 parents e61b26c + 12b2077 commit f17b3e4

97 files changed

Lines changed: 18122 additions & 992 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,5 @@ compile_commands.json
4040
.nfs
4141
tensor_dumps/
4242
artifacts/
43+
# Auto-generated build configuration (specific to each environment)
44+
transformer_engine/plugin/core/_build_config.py

README.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
|License|
77

8+
9+
**TransformerEngine-FL is a fork of TransformerEngine that introduces a plugin-based architecture for supporting diverse AI chips, built on top of** `FlagOS <https://github.com/flagos-ai>`_, **a unified open-source AI system software stack.**
10+
811
Transformer Engine
912
==================
1013

build_tools/pytorch.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,10 @@ def setup_pytorch_extension(
8585
include_dirs = [str(path) for path in include_dirs]
8686
from torch.utils.cpp_extension import CppExtension
8787

88+
# Use transformer_engine_torch_nv as the native NVIDIA module name
89+
# This allows the plugin system to use transformer_engine_torch as the unified interface
8890
return CppExtension(
89-
name="transformer_engine_torch",
91+
name="transformer_engine_torch_nv",
9092
sources=[str(src) for src in sources],
9193
include_dirs=[str(inc) for inc in include_dirs],
9294
extra_compile_args={"cxx": cxx_flags},

build_tools/utils.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,16 @@ def get_cuda_include_dirs() -> Tuple[str, str]:
251251
]
252252

253253

254+
@functools.lru_cache(maxsize=None)
255+
def skip_cuda_build() -> bool:
256+
"""Check if CUDA build should be skipped (for AMD/ROCm or pure FL backend)"""
257+
return bool(int(os.getenv("TE_FL_SKIP_CUDA", "0")))
258+
259+
254260
@functools.lru_cache(maxsize=None)
255261
def cuda_archs() -> str:
262+
if skip_cuda_build():
263+
return "" # Return empty string when skipping CUDA build
256264
archs = os.getenv("NVTE_CUDA_ARCHS")
257265
if archs is None:
258266
version = cuda_version()

setup.py

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828

2929

3030
from setuptools.command.build_ext import build_ext as BuildExtension
31+
from setuptools.command.install import install as InstallCommand
32+
from datetime import datetime
33+
import platform
3134

3235
os.environ["NVTE_PROJECT_BUILDING"] = "1"
3336

@@ -41,6 +44,63 @@
4144
archs = cuda_archs()
4245

4346

47+
def generate_build_config(skip_cuda_build):
48+
"""Generate build-time configuration file."""
49+
config_template_path = (
50+
current_file_path / "transformer_engine" / "plugin" /
51+
"core" / "_build_config.py.template"
52+
)
53+
config_output_path = (
54+
current_file_path / "transformer_engine" / "plugin" /
55+
"core" / "_build_config.py"
56+
)
57+
58+
if config_template_path.exists():
59+
with open(config_template_path, 'r') as f:
60+
template = f.read()
61+
62+
config_content = template.format(
63+
skip_cuda=skip_cuda_build,
64+
build_time=datetime.now().isoformat(),
65+
platform=platform.platform(),
66+
)
67+
68+
with open(config_output_path, 'w') as f:
69+
f.write(config_content)
70+
71+
print(f"Generated build config: {config_output_path}")
72+
print(f" SKIP_CUDA_BUILD = {skip_cuda_build}")
73+
else:
74+
# Fallback: create minimal config if template doesn't exist
75+
config_content = f"""# Auto-generated build configuration
76+
SKIP_CUDA_BUILD = {skip_cuda_build}
77+
BUILD_TIME = "{datetime.now().isoformat()}"
78+
BUILD_PLATFORM = "{platform.platform()}"
79+
"""
80+
with open(config_output_path, 'w') as f:
81+
f.write(config_content)
82+
print(f"Generated minimal build config: {config_output_path}")
83+
84+
85+
class CustomInstall(InstallCommand):
86+
"""Custom install command to generate build config."""
87+
88+
user_options = InstallCommand.user_options + [
89+
('skip-cuda-build', None, 'Skip CUDA build'),
90+
]
91+
92+
def initialize_options(self):
93+
super().initialize_options()
94+
self.skip_cuda_build = bool(int(os.getenv("TE_FL_SKIP_CUDA", "0")))
95+
96+
def run(self):
97+
# Run the standard install
98+
super().run()
99+
100+
# Generate build config after installation
101+
generate_build_config(self.skip_cuda_build)
102+
103+
44104
class TimedBdist(bdist_wheel):
45105
"""Helper class to measure build time"""
46106

@@ -132,6 +192,14 @@ def setup_requirements() -> Tuple[List[str], List[str]]:
132192
with open("README.rst", encoding="utf-8") as f:
133193
long_description = f.read()
134194

195+
# Check if we should skip CUDA build (for AMD/ROCm or pure FL backend usage)
196+
skip_cuda_build = bool(int(os.getenv("TE_FL_SKIP_CUDA", "0")))
197+
if skip_cuda_build:
198+
print("=" * 60)
199+
print("TE_FL_SKIP_CUDA=1: Skipping CUDA/native backend compilation")
200+
print("Only FL (Flag-Gems/Triton) backend will be available")
201+
print("=" * 60)
202+
135203
# Settings for building top level empty package for dependency management.
136204
if bool(int(os.getenv("NVTE_BUILD_METAPACKAGE", "0"))):
137205
assert bool(
@@ -148,6 +216,13 @@ def setup_requirements() -> Tuple[List[str], List[str]]:
148216
"pytorch": [f"transformer_engine_torch=={__version__}"],
149217
"jax": [f"transformer_engine_jax=={__version__}"],
150218
}
219+
elif skip_cuda_build:
220+
# Skip CUDA build - only install Python packages for FL backend
221+
install_requires, test_requires = setup_requirements()
222+
ext_modules = [] # No CUDA extensions
223+
package_data = {"": ["VERSION.txt"]}
224+
include_package_data = True
225+
extras_require = {"test": test_requires}
151226
else:
152227
install_requires, test_requires = setup_requirements()
153228
ext_modules = [setup_common_extension()]
@@ -177,6 +252,9 @@ def setup_requirements() -> Tuple[List[str], List[str]]:
177252
)
178253
)
179254

255+
# Generate build config before setup
256+
generate_build_config(skip_cuda_build)
257+
180258
# Configure package
181259
setuptools.setup(
182260
name="transformer_engine",
@@ -193,7 +271,11 @@ def setup_requirements() -> Tuple[List[str], List[str]]:
193271
long_description=long_description,
194272
long_description_content_type="text/x-rst",
195273
ext_modules=ext_modules,
196-
cmdclass={"build_ext": CMakeBuildExtension, "bdist_wheel": TimedBdist},
274+
cmdclass={
275+
"build_ext": CMakeBuildExtension,
276+
"bdist_wheel": TimedBdist,
277+
"install": CustomInstall,
278+
},
197279
python_requires=f">={min_python_version_str()}",
198280
classifiers=["Programming Language :: Python :: 3"],
199281
install_requires=install_requires,

transformer_engine/common/__init__.py

Lines changed: 58 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,31 @@
1818
from 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)
2247
def _is_package_installed(package) -> bool:
2348
"""Check if the given package is installed via pip."""
@@ -107,7 +132,7 @@ def _get_shared_object_file(library: str) -> Path:
107132
"""
108133

109134
# Check provided input and determine the correct prefix for .so.
110-
assert library in ("core", "torch", "jax"), f"Unsupported TE library {library}."
135+
assert library in ("core", "torch_nv", "jax"), f"Unsupported TE library {library}."
111136
if library == "core":
112137
so_prefix = "libtransformer_engine"
113138
else:
@@ -146,46 +171,31 @@ def get_te_core_package_info() -> Tuple[bool, str, str]:
146171
@functools.lru_cache(maxsize=None)
147172
def 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.
154-
assert framework in ("jax", "torch"), f"Unsupported framework {framework}"
186+
assert framework in ("jax", "torch_nv"), f"Unsupported framework {framework}"
155187

156-
# Name of the framework extension library.
188+
# For jax: load the native module as before
157189
module_name = f"transformer_engine_{framework}"
158190

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"
191+
# Skip if already loaded
192+
if module_name in sys.modules:
193+
return
163194

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)
168195
te_installed = _is_package_installed("transformer_engine")
169-
te_installed_via_pypi = _is_package_installed_from_wheel("transformer_engine")
170-
171196
assert te_installed, "Could not find `transformer_engine`."
172197

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.
198+
# Load the shared object file for jax
189199
spec = importlib.util.spec_from_file_location(module_name, _get_shared_object_file(framework))
190200
solib = importlib.util.module_from_spec(spec)
191201
sys.modules[module_name] = solib
@@ -195,6 +205,10 @@ def load_framework_extension(framework: str) -> None:
195205
def sanity_checks_for_pypi_installation() -> None:
196206
"""Ensure that package is installed correctly if using PyPI."""
197207

208+
# Skip sanity checks if CUDA build was skipped (FL-only mode)
209+
if skip_cuda_build():
210+
return
211+
198212
te_core_installed, te_core_package_name, te_core_version = get_te_core_package_info()
199213
te_installed = _is_package_installed("transformer_engine")
200214
te_installed_via_pypi = _is_package_installed_from_wheel("transformer_engine")
@@ -390,13 +404,16 @@ def _load_core_library():
390404

391405
if "NVTE_PROJECT_BUILDING" not in os.environ or bool(int(os.getenv("NVTE_RELEASE_BUILD", "0"))):
392406
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()
407+
408+
# Skip loading CUDA libraries if CUDA build was skipped (FL-only mode)
409+
if not skip_cuda_build():
410+
_CUDNN_LIB_CTYPES = _load_cudnn()
411+
_NVRTC_LIB_CTYPES = _load_nvrtc()
412+
_CURAND_LIB_CTYPES = _load_curand()
413+
_CUBLAS_LIB_CTYPES = _load_nvidia_cuda_library("cublas")
414+
_CUDART_LIB_CTYPES = _load_nvidia_cuda_library("cuda_runtime")
415+
_TE_LIB_CTYPES = _load_core_library()
416+
417+
# Needed to find the correct headers for NVRTC kernels.
418+
if not os.getenv("NVTE_CUDA_INCLUDE_DIR") and _nvidia_cudart_include_dir():
419+
os.environ["NVTE_CUDA_INCLUDE_DIR"] = _nvidia_cudart_include_dir()
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright (c) 2025, BAAI. All rights reserved.
2+
#
3+
# See LICENSE for license information.
4+
5+
from .core import (
6+
TEFLBackendBase,
7+
TEFLModule,
8+
get_tefl_module as _get_tefl_module,
9+
get_registry,
10+
)
11+
12+
def __getattr__(name):
13+
if name == "tefl":
14+
return _get_tefl_module()
15+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
16+
17+
__all__ = [
18+
"TEFLBackendBase",
19+
"TEFLModule",
20+
"get_tefl_module",
21+
"get_registry",
22+
"tefl",
23+
]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Copyright (c) 2025, BAAI. All rights reserved.
2+
#
3+
# See LICENSE for license information.
4+
5+
__all__ = []

0 commit comments

Comments
 (0)