Skip to content

Commit 976417b

Browse files
feat: better build_wheel.py venv handling
Signed-off-by: Yuan Tong <13075180+tongyuantongyu@users.noreply.github.com>
1 parent a201ce9 commit 976417b

File tree

1 file changed

+71
-18
lines changed

1 file changed

+71
-18
lines changed

scripts/build_wheel.py

Lines changed: 71 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
import os
1818
import platform
1919
import sys
20+
import sysconfig
21+
import time
22+
import warnings
2023
from argparse import ArgumentParser
2124
from contextlib import contextmanager
2225
from functools import partial
@@ -67,46 +70,90 @@ def clear_folder(folder_path):
6770
os.remove(item_path)
6871

6972

70-
def setup_venv(project_dir: Path, requirements_file: Path):
71-
"""Creates/updates a venv and installs requirements.
73+
def sysconfig_scheme():
74+
# Backported 'venv' scheme from Python 3.11+
75+
if os.name == 'nt':
76+
scheme = {
77+
'purelib': '{base}/Lib/site-packages',
78+
'scripts': '{base}/Scripts',
79+
}
80+
else:
81+
scheme = {
82+
'purelib': '{base}/lib/python{py_version_short}/site-packages',
83+
'scripts': '{base}/bin',
84+
}
7285

73-
Args:
74-
project_dir: The root directory of the project.
75-
requirements_file: Path to the requirements file.
86+
vars_ = sysconfig.get_config_vars()
87+
return {key: value.format(**vars_) for key, value in scheme.items()}
7688

77-
Returns:
78-
Tuple[Path, Path]: Paths to the python and conan executables in the venv.
79-
"""
89+
90+
def create_venv(project_dir: Path):
8091
py_major = sys.version_info.major
8192
py_minor = sys.version_info.minor
82-
venv_dir = project_dir / f".venv-{py_major}.{py_minor}"
93+
venv_prefix = project_dir / f".venv-{py_major}.{py_minor}"
8394
print(
84-
f"-- Using virtual environment at: {venv_dir} (Python {py_major}.{py_minor})"
95+
f"-- Using virtual environment at: {venv_prefix} (Python {py_major}.{py_minor})"
8596
)
8697

8798
# Ensure compatible virtualenv version is installed (>=20.29.1, <22.0)
8899
print("-- Ensuring virtualenv version >=20.29.1,<22.0 is installed...")
89100
build_run(f'"{sys.executable}" -m pip install "virtualenv>=20.29.1,<22.0"')
90101

91102
# Create venv if it doesn't exist
92-
if not venv_dir.exists():
93-
print(f"-- Creating virtual environment in {venv_dir}...")
103+
if not venv_prefix.exists():
104+
print(f"-- Creating virtual environment in {venv_prefix}...")
94105
build_run(
95-
f'"{sys.executable}" -m virtualenv --system-site-packages "{venv_dir}"'
106+
f'"{sys.executable}" -m virtualenv --system-site-packages "{venv_prefix}"'
96107
)
97108
else:
98109
print("-- Virtual environment already exists.")
99110

111+
return venv_prefix
112+
113+
114+
def setup_venv(project_dir: Path, requirements_file: Path, no_venv: bool):
115+
"""Creates/updates a venv and installs requirements.
116+
117+
Args:
118+
project_dir: The root directory of the project.
119+
requirements_file: Path to the requirements file.
120+
no_venv: Use current Python environment as is.
121+
122+
Returns:
123+
Tuple[Path, Path]: Paths to the python and conan executables in the venv.
124+
"""
125+
if no_venv or sys.prefix != sys.base_prefix:
126+
reason = "Explicitly requested by user" if no_venv else "Already inside virtual environment"
127+
print(f"-- {reason}, using environment {sys.prefix} as is.")
128+
venv_prefix = Path(sys.prefix)
129+
else:
130+
venv_prefix = create_venv(project_dir)
131+
132+
scheme = sysconfig_scheme()
100133
# Determine venv executable paths
101-
scripts_dir = venv_dir / "bin"
102-
venv_python = scripts_dir / "python"
134+
scripts_dir = Path(scheme["scripts"])
135+
venv_python = venv_prefix / sys.executable.removeprefix(sys.prefix)[1:]
103136

104137
# Install/update requirements
105138
print(
106-
f"-- Installing requirements from {requirements_file} into {venv_dir}..."
139+
f"-- Installing requirements from {requirements_file} into {venv_prefix}..."
107140
)
108141
build_run(f'"{venv_python}" -m pip install -r "{requirements_file}"')
109142

143+
purelib_dir = Path(scheme["purelib"])
144+
pytorch_package_dir = purelib_dir / "torch"
145+
has_non_system_pytorch = venv_prefix != sys.base_prefix and pytorch_package_dir.exists(
146+
)
147+
if os.environ.get(
148+
"NVIDIA_PYTORCH_VERSION") is not None and has_non_system_pytorch:
149+
warnings.warn(
150+
"You are using the NVIDIA PyTorch container, but not using the provided PyTorch installation. "
151+
"This will very likely cause issues. "
152+
f"If anything goes wrong, please remove the environment at {venv_prefix} "
153+
"to let build_wheel.py rebuild virtual environment.")
154+
print("^^^^^^^^^^ IMPORTANT WARNING ^^^^^^^^^^", file=sys.stderr)
155+
time.sleep(15)
156+
110157
venv_conan = setup_conan(scripts_dir, venv_python)
111158

112159
return venv_python, venv_conan
@@ -218,7 +265,8 @@ def main(*,
218265
micro_benchmarks: bool = False,
219266
nvtx: bool = False,
220267
skip_stubs: bool = False,
221-
generate_fmha: bool = False):
268+
generate_fmha: bool = False,
269+
no_venv: bool = False):
222270

223271
if clean:
224272
clean_wheel = True
@@ -241,7 +289,8 @@ def main(*,
241289

242290
# Setup venv and install requirements
243291
venv_python, venv_conan = setup_venv(project_dir,
244-
project_dir / requirements_filename)
292+
project_dir / requirements_filename,
293+
no_venv)
245294

246295
# Ensure base TRT is installed (check inside the venv)
247296
reqs = check_output([str(venv_python), "-m", "pip", "freeze"])
@@ -694,6 +743,10 @@ def add_arguments(parser: ArgumentParser):
694743
parser.add_argument("--generate_fmha",
695744
action="store_true",
696745
help="Generate the FMHA cu files.")
746+
parser.add_argument(
747+
"--no-venv",
748+
action="store_true",
749+
help="Use current Python interpreter as is, don't create venv.")
697750

698751

699752
if __name__ == "__main__":

0 commit comments

Comments
 (0)