Skip to content

Commit 909d84b

Browse files
rocm: address PR review comments on repair_wheel.py and install_rocjpeg.sh
repair_wheel.py: - Extract _get_rocm_search_roots() helper shared by _find_rocjpeg_license() and _find_rocjpeg_lib() (removes duplicated env-var + torch ROCM_HOME logic) - Remove hardcoded /opt/rocm fallback from _find_rocjpeg_lib() - Use librocjpeg.so.* glob instead of hardcoded .so.1 version suffix - Remove the unversioned-symlink fallback (redundant with the glob) install_rocjpeg.sh: - Replace conda-specific /opt/conda glob with importlib.util.find_spec so the already-installed check works in any Python environment (conda or not) - Only skip dnf install when rocjpeg is detected via pip-wheel (_rocm_sdk_core / _rocm_sdk_devel); for ROCm <=7.2 the dnf path always runs (idempotent) Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent fc67147 commit 909d84b

2 files changed

Lines changed: 41 additions & 51 deletions

File tree

packaging/install_rocjpeg.sh

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,21 @@
1313

1414
set -euo pipefail
1515

16-
# Skip if rocjpeg is already installed (e.g. via the ROCm pip-wheel distribution).
16+
# Skip if rocjpeg is already installed via the ROCm pip-wheel distribution
17+
# (ROCm >= 7.14: librocjpeg ships inside _rocm_sdk_core / _rocm_sdk_devel
18+
# site-packages). Use importlib to find the package regardless of the Python
19+
# environment (conda or not).
1720
if python3 -c "
18-
import glob, sys
19-
found = (glob.glob('/opt/rocm/include/rocjpeg/rocjpeg.h') or
20-
glob.glob('/opt/conda/**/rocjpeg.h', recursive=True))
21-
sys.exit(0 if found else 1)
21+
import importlib.util, pathlib, sys
22+
for pkg in ('_rocm_sdk_core', '_rocm_sdk_devel'):
23+
spec = importlib.util.find_spec(pkg)
24+
if spec and spec.submodule_search_locations:
25+
pkg_root = pathlib.Path(list(spec.submodule_search_locations)[0])
26+
if (pkg_root / 'include' / 'rocjpeg' / 'rocjpeg.h').exists():
27+
sys.exit(0)
28+
sys.exit(1)
2229
" 2>/dev/null; then
23-
echo "rocjpeg already installed; skipping dnf install."
30+
echo "rocjpeg already installed via ROCm pip-wheel; skipping dnf install."
2431
exit 0
2532
fi
2633

packaging/repair_wheel.py

Lines changed: 28 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,17 @@ def _find_nvjpeg_license():
133133
return None
134134

135135

136-
def _find_rocjpeg_license():
137-
"""Find rocjpeg's LICENSE file to document the runtime dependency."""
138-
search_roots = []
136+
def _get_rocm_search_roots() -> list[Path]:
137+
"""Return candidate ROCm prefix directories in priority order.
138+
139+
Checks ROCM_HOME / ROCM_PATH environment variables, then torch's own
140+
ROCM_HOME. No hard-coded fallback is added so misconfigurations surface
141+
as warnings rather than silently using the wrong path.
142+
"""
143+
roots: list[Path] = []
139144
for var in ("ROCM_HOME", "ROCM_PATH"):
140145
if v := os.environ.get(var):
141-
search_roots.append(Path(v))
146+
roots.append(Path(v))
142147
try:
143148
result = subprocess.run(
144149
[
@@ -151,10 +156,15 @@ def _find_rocjpeg_license():
151156
check=False,
152157
)
153158
if result.returncode == 0 and result.stdout.strip():
154-
search_roots.append(Path(result.stdout.strip()))
159+
roots.append(Path(result.stdout.strip()))
155160
except Exception:
156161
pass
157-
for root in search_roots:
162+
return roots
163+
164+
165+
def _find_rocjpeg_license():
166+
"""Find rocjpeg's LICENSE file to document the runtime dependency."""
167+
for root in _get_rocm_search_roots():
158168
candidate = root / "share" / "doc" / "rocjpeg" / "LICENSE"
159169
if candidate.is_file():
160170
return candidate
@@ -169,46 +179,21 @@ def _find_rocjpeg_lib():
169179
in the user's ROCm install). This function returns the directory to add to
170180
LD_LIBRARY_PATH before calling auditwheel.
171181
172-
Searches ROCM_HOME / ROCM_PATH env vars, torch's ROCM_HOME, the standard
173-
/opt/rocm fallback, and (for ROCm >= 7.14) the _rocm_sdk_* pip-wheel
174-
site-packages layout where librocjpeg lives inside _rocm_sdk_core/lib.
182+
Searches ROCM_HOME / ROCM_PATH env vars and torch's ROCM_HOME first, then
183+
(for ROCm >= 7.14) the _rocm_sdk_* pip-wheel site-packages layout where
184+
librocjpeg lives inside _rocm_sdk_core/lib.
175185
"""
176-
search_roots = []
177-
for var in ("ROCM_HOME", "ROCM_PATH"):
178-
if v := os.environ.get(var):
179-
search_roots.append(Path(v))
180-
# Ask torch where it found ROCm at its own build time.
181-
try:
182-
result = subprocess.run(
183-
[
184-
sys.executable,
185-
"-c",
186-
"from torch.utils.cpp_extension import ROCM_HOME; print(ROCM_HOME or '')",
187-
],
188-
capture_output=True,
189-
text=True,
190-
check=False,
191-
)
192-
if result.returncode == 0 and result.stdout.strip():
193-
search_roots.append(Path(result.stdout.strip()))
194-
except Exception:
195-
pass
196-
search_roots.append(Path("/opt/rocm"))
186+
import glob as _glob
187+
import site as _site
197188

198-
for root in search_roots:
189+
for root in _get_rocm_search_roots():
199190
for lib_dir in (root / "lib", root / "lib64"):
200-
candidate = lib_dir / "librocjpeg.so.1"
201-
if not candidate.exists():
202-
# Try unversioned symlink
203-
candidate = lib_dir / "librocjpeg.so"
204-
if candidate.exists():
191+
if _glob.glob(str(lib_dir / "librocjpeg.so.*")):
205192
return lib_dir
206193

207194
# ROCm >= 7.14 pip-wheel fallback: librocjpeg lives in _rocm_sdk_core/lib
208195
# (or _rocm_sdk_devel/lib) inside site-packages rather than in a system
209196
# prefix like /opt/rocm. Use the same glob strategy as install_rocjpeg.sh.
210-
import glob as _glob
211-
import site as _site
212197
# Search the current interpreter's site-packages first (avoids crossing
213198
# conda env boundaries), then fall back to the broader /opt/conda tree.
214199
candidate_dirs: list[str] = []
@@ -223,14 +208,12 @@ def _find_rocjpeg_lib():
223208
for site_dir in candidate_dirs:
224209
for pkg in ("_rocm_sdk_core", "_rocm_sdk_devel"):
225210
lib_dir = Path(site_dir) / pkg / "lib"
226-
for lib_name in ("librocjpeg.so.1", "librocjpeg.so"):
227-
if (lib_dir / lib_name).exists():
228-
return lib_dir
211+
if _glob.glob(str(lib_dir / "librocjpeg.so.*")):
212+
return lib_dir
229213
# Last-resort broad glob (covers non-standard conda prefixes).
230-
for pattern in ("/opt/conda/**/librocjpeg.so.1", "/opt/conda/**/librocjpeg.so"):
231-
hits = sorted(_glob.glob(pattern, recursive=True))
232-
if hits:
233-
return Path(hits[0]).parent
214+
hits = sorted(_glob.glob("/opt/conda/**/librocjpeg.so.*", recursive=True))
215+
if hits:
216+
return Path(hits[0]).parent
234217
return None
235218

236219

0 commit comments

Comments
 (0)