ixelszy commited on
Commit
3217396
·
verified ·
1 Parent(s): b4e18b3

Create fixcudn.py

Browse files
Files changed (1) hide show
  1. fixcudn.py +210 -0
fixcudn.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # fix_isotropic3d_deps.py
3
+ # Otomasi perbaikan libigl (igl) & (opsional) tinycudann untuk Isotropic3D/threestudio.
4
+
5
+ import os
6
+ import sys
7
+ import subprocess
8
+ import shlex
9
+ import json
10
+ import glob
11
+ from pathlib import Path
12
+
13
+ IS_ROOT = (os.geteuid() == 0) if hasattr(os, "geteuid") else False
14
+
15
+ def run(cmd, env=None, check=True):
16
+ print(f"\n>>> {cmd}")
17
+ result = subprocess.run(shlex.split(cmd), env=env, stdout=sys.stdout, stderr=sys.stderr)
18
+ if check and result.returncode != 0:
19
+ print(f"[ERROR] Command failed: {cmd}")
20
+ sys.exit(result.returncode)
21
+ return result.returncode
22
+
23
+ def py_run(code, check=True):
24
+ print(f"\n>>> python - <<'PY' ...")
25
+ p = subprocess.Popen([sys.executable, "-c", code])
26
+ p.wait()
27
+ if check and p.returncode != 0:
28
+ print("[ERROR] Inline python failed.")
29
+ sys.exit(p.returncode)
30
+ return p.returncode
31
+
32
+ def detect_torch():
33
+ code = r"""
34
+ import json, sys
35
+ try:
36
+ import torch
37
+ info = {
38
+ "torch_version": torch.__version__,
39
+ "cuda_runtime": getattr(torch.version, "cuda", None),
40
+ "cuda_available": torch.cuda.is_available(),
41
+ "device_capability": None,
42
+ "device_name": None,
43
+ }
44
+ if info["cuda_available"]:
45
+ info["device_name"] = torch.cuda.get_device_name(0)
46
+ info["device_capability"] = torch.cuda.get_device_capability(0)
47
+ print(json.dumps(info))
48
+ except Exception as e:
49
+ print(json.dumps({"error": str(e)}))
50
+ """
51
+ out = subprocess.check_output([sys.executable, "-c", code], text=True)
52
+ return json.loads(out.strip())
53
+
54
+ def set_cuda_env(cuda_home_guess=None):
55
+ # best-effort set CUDA paths
56
+ candidates = []
57
+ if cuda_home_guess:
58
+ candidates.append(cuda_home_guess)
59
+ candidates += [
60
+ "/usr/local/cuda",
61
+ "/usr/local/cuda-12.5", "/usr/local/cuda-12.4", "/usr/local/cuda-12.3",
62
+ "/usr/local/cuda-12.2", "/usr/local/cuda-12.1", "/usr/local/cuda-12.0",
63
+ "/usr/local/cuda-11.8", "/usr/local/cuda-11.7",
64
+ ]
65
+ for c in candidates:
66
+ if Path(c).exists():
67
+ os.environ["CUDA_HOME"] = c
68
+ os.environ["PATH"] = f"{c}/bin:" + os.environ.get("PATH", "")
69
+ os.environ["LD_LIBRARY_PATH"] = f"{c}/lib64:" + os.environ.get("LD_LIBRARY_PATH", "")
70
+ print(f"[INFO] Using CUDA at {c}")
71
+ return
72
+ print("[WARN] CUDA not found on typical paths; proceeding anyway.")
73
+
74
+ def apt_install(packages):
75
+ if not IS_ROOT:
76
+ print("[WARN] Skipping apt-get because this process is not root.")
77
+ return
78
+ run("apt-get update")
79
+ run(f"apt-get install -y {' '.join(packages)}")
80
+
81
+ def pip_install(pkgs, flags=""):
82
+ run(f"{sys.executable} -m pip install -U {flags} {' '.join(pkgs)}")
83
+
84
+ def remove_old_igl():
85
+ # pip uninstall
86
+ run(f"{sys.executable} -m pip uninstall -y igl || true", check=False)
87
+ # hard cleanup
88
+ code = r"""
89
+ import sys, os, glob, shutil
90
+ removed = []
91
+ for sp in sys.path:
92
+ for pat in ("igl", "igl-*"):
93
+ for p in glob.glob(os.path.join(sp, pat)):
94
+ try:
95
+ if os.path.isdir(p):
96
+ shutil.rmtree(p, ignore_errors=True)
97
+ else:
98
+ os.remove(p)
99
+ removed.append(p)
100
+ except Exception: pass
101
+ print("\n".join(removed))
102
+ """
103
+ print("[INFO] Removing leftover igl files (if any):")
104
+ py_run(code, check=False)
105
+
106
+ def build_libigl(src_dir="/Isotropic3D/libigl-python-bindings"):
107
+ # clone if needed
108
+ if not Path(src_dir).exists():
109
+ run(f"git clone --recursive https://github.com/libigl/libigl-python-bindings.git {src_dir}")
110
+ else:
111
+ run(f"git -C {src_dir} submodule update --init --recursive")
112
+
113
+ # install with no build isolation so it sees our env
114
+ run(f"{sys.executable} -m pip install -v --no-build-isolation .", env=os.environ | {}, check=True)
115
+
116
+ def verify_igl():
117
+ code = r"""
118
+ import igl
119
+ print("igl module path:", igl.__file__)
120
+ print("has fast_winding_number_for_meshes:", hasattr(igl, "fast_winding_number_for_meshes"))
121
+ """
122
+ py_run(code)
123
+
124
+ def compute_arch_from_capability(cap=None):
125
+ # map major.minor to CMake arch (rounded typical)
126
+ # Lovelace(8.9)=89, Ampere(8.6)=86, A100(8.0)=80, Turing(7.5)=75, Volta(7.0)=70
127
+ mapping = {(8,9): 89, (8,6): 86, (8,0): 80, (7,5): 75, (7,0): 70}
128
+ if isinstance(cap, (list, tuple)) and len(cap) >= 2:
129
+ return mapping.get((cap[0], cap[1]), cap[0]*10 + cap[1])
130
+ return None
131
+
132
+ def ensure_tinycudann(src_dir="/Isotropic3D/tiny-cuda-nn", arch=None):
133
+ # uninstall old
134
+ run(f"{sys.executable} -m pip uninstall -y tinycudann tiny-cuda-nn || true", check=False)
135
+
136
+ # clone if needed
137
+ if not Path(src_dir).exists():
138
+ run(f"git clone --recursive https://github.com/NVlabs/tiny-cuda-nn.git {src_dir}")
139
+ else:
140
+ run(f"git -C {src_dir} submodule update --init --recursive")
141
+
142
+ bind_dir = Path(src_dir) / "bindings" / "torch"
143
+ if not bind_dir.exists():
144
+ print("[ERROR] tiny-cuda-nn bindings/torch not found.")
145
+ sys.exit(2)
146
+
147
+ env = os.environ.copy()
148
+ if arch:
149
+ env["TCNN_CUDA_ARCHITECTURES"] = str(arch)
150
+ env["TORCH_CUDA_LIST"] = "" # avoid confusion
151
+ # Build with no build isolation so it can use our Torch/pybind11
152
+ run(f"{sys.executable} -m pip install -v --no-build-isolation .", env=env | {}, check=True)
153
+
154
+ def verify_tcnn():
155
+ code = r"""
156
+ import torch
157
+ import tinycudann as tcnn
158
+ print("tinycudann import OK; torch", torch.__version__)
159
+ """
160
+ py_run(code)
161
+
162
+ def main():
163
+ import argparse
164
+ ap = argparse.ArgumentParser(description="Fix igl and (optional) tinycudann for Isotropic3D.")
165
+ ap.add_argument("--cuda-home", type=str, default=None, help="Custom CUDA_HOME path (optional).")
166
+ ap.add_argument("--do-tcnn", action="store_true", help="Also build tiny-cuda-nn bindings.")
167
+ ap.add_argument("--libigl-src", type=str, default="/Isotropic3D/libigl-python-bindings")
168
+ ap.add_argument("--tcnn-src", type=str, default="/Isotropic3D/tiny-cuda-nn")
169
+ args = ap.parse_args()
170
+
171
+ # 0) Toolchain + backend
172
+ apt_install(["build-essential", "cmake", "ninja-build", "git", "libeigen3-dev"])
173
+ pip_install(["pip", "wheel", "setuptools", "scikit-build-core", "pybind11", "numpy"])
174
+
175
+ # 1) CUDA env (best effort)
176
+ set_cuda_env(args.cuda_home)
177
+
178
+ # 2) Reinstall igl properly
179
+ print("\n=== Reinstalling libigl (igl) ===")
180
+ remove_old_igl()
181
+ # Install from local clone or clone to default dir then install
182
+ if Path(args.libigl_src).exists():
183
+ run(f"git -C {args.libigl_src} submodule update --init --recursive")
184
+ run(f"{sys.executable} -m pip install -v --no-build-isolation .", env=os.environ | {}, check=True)
185
+ else:
186
+ build_libigl(args.libigl_src)
187
+ print("\n=== Verifying igl ===")
188
+ verify_igl()
189
+
190
+ # 3) (Optional) Build tinycudann
191
+ if args.do_tcnn:
192
+ print("\n=== Building tiny-cuda-nn / tinycudann ===")
193
+ info = detect_torch()
194
+ print(f"[INFO] Torch info: {info}")
195
+ arch = None
196
+ if info.get("cuda_available") and info.get("device_capability"):
197
+ arch = compute_arch_from_capability(info["device_capability"])
198
+ print(f"[INFO] Detected GPU capability {info['device_capability']} -> arch {arch}")
199
+ else:
200
+ print("[WARN] CUDA not available from torch; proceeding without arch hint.")
201
+ ensure_tinycudann(args.tcnn_src, arch=arch)
202
+ print("\n=== Verifying tinycudann ===")
203
+ verify_tcnn()
204
+
205
+ print("\n[OK] All done. You can now run Isotropic3D:")
206
+ print(" cd /Isotropic3D")
207
+ print(" python launch.py --config configs/isotropic3d-shading.yaml --train --gpu 0")
208
+
209
+ if __name__ == "__main__":
210
+ main()