Skip to content

Commit e691eb2

Browse files
committed
Optimize openmp source extraction and building
- Extract and apply patches once per build - Remove symlinks - Change pyomp to load the versioned libomptarget library
1 parent 0949314 commit e691eb2

2 files changed

Lines changed: 54 additions & 44 deletions

File tree

setup.py

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ def _build_cmake(self, ext: CMakeExtension):
129129
include_dir = install_dir / "lib/cmake"
130130
if include_dir.exists():
131131
shutil.rmtree(include_dir)
132+
# Remove symlinks in the install directory to avoid copies.
133+
for file in install_dir.rglob("*"):
134+
if file.is_symlink():
135+
file.unlink()
132136

133137
def _env_toolchain_args(self, ext):
134138
args = []
@@ -183,50 +187,53 @@ def _prepare_source_openmp(cls):
183187
print(f"Using downloaded llvm-project at {tmp}", flush=True)
184188

185189
print("Extracting llvm-project...", flush=True)
186-
with tarfile.open(tmp) as tf:
187-
# The root dir llvm-project-20.1.8.src
188-
root_name = tf.getnames()[0]
189-
190-
# Extract only needed subdirectories
191-
members = [
192-
m
193-
for m in tf.getmembers()
194-
if m.name.startswith(f"{root_name}/openmp/")
195-
or m.name.startswith(f"{root_name}/offload/")
196-
or m.name.startswith(f"{root_name}/runtimes/")
197-
or m.name.startswith(f"{root_name}/cmake/")
198-
or m.name.startswith(f"{root_name}/llvm/cmake/")
199-
or m.name.startswith(f"{root_name}/llvm/utils/")
200-
or m.name.startswith(f"{root_name}/libc/")
201-
]
190+
root_dir = Path(f"_downloads/libomp/llvm-project-{cls.LLVM_VERSION}.src")
191+
if not root_dir.exists():
192+
with tarfile.open(tmp) as tf:
193+
# Extract only needed subdirectories
194+
root_name = f"llvm-project-{cls.LLVM_VERSION}.src"
195+
196+
# Use prefix tuple + any() for faster membership testing
197+
prefixes = (
198+
f"{root_name}/openmp/",
199+
f"{root_name}/offload/",
200+
f"{root_name}/runtimes/",
201+
f"{root_name}/cmake/",
202+
f"{root_name}/llvm/cmake/",
203+
f"{root_name}/llvm/utils/",
204+
f"{root_name}/libc/",
205+
)
202206

203-
parentdir = tmp.parent
204-
# Base arguments for extractall.
205-
kwargs = {"path": parentdir, "members": members}
206-
207-
# Check if data filter is available.
208-
if hasattr(tarfile, "data_filter"):
209-
# If this exists, the 'filter' argument is guaranteed to work
210-
kwargs["filter"] = "data"
211-
212-
tf.extractall(**kwargs)
213-
214-
source_dir = parentdir / root_name
215-
print("Extracted llvm-project to:", source_dir, flush=True)
216-
217-
print("Applying patches to llvm-project...", flush=True)
218-
for patch in sorted(
219-
Path(f"src/numba/openmp/libs/openmp/patches/{cls.LLVM_VERSION}")
220-
.absolute()
221-
.glob("*.patch")
222-
):
223-
print("applying patch", patch, flush=True)
224-
subprocess.run(
225-
["patch", "-p1", "-i", str(patch)],
226-
cwd=source_dir,
227-
check=True,
228-
stdin=subprocess.DEVNULL,
229-
)
207+
include_members = [
208+
m
209+
for m in tf.getmembers()
210+
if any(m.name.startswith(p) for p in prefixes)
211+
]
212+
213+
parentdir = tmp.parent
214+
# Base arguments for extractall.
215+
kwargs = {"path": parentdir, "members": include_members}
216+
217+
# Check if data filter is available.
218+
if hasattr(tarfile, "data_filter"):
219+
# If this exists, the 'filter' argument is guaranteed to work
220+
kwargs["filter"] = "data"
221+
222+
tf.extractall(**kwargs)
223+
224+
print("Applying patches to llvm-project...", flush=True)
225+
for patch in sorted(
226+
Path(f"src/numba/openmp/libs/openmp/patches/{cls.LLVM_VERSION}")
227+
.absolute()
228+
.glob("*.patch")
229+
):
230+
print("applying patch", patch, flush=True)
231+
subprocess.run(
232+
["patch", "-p1", "-N", "-i", str(patch)],
233+
cwd=root_dir,
234+
check=True,
235+
stdin=subprocess.DEVNULL,
236+
)
230237

231238

232239
def _check_true(env_var):

src/numba/openmp/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,10 @@ def _init():
9292
if sys_platform.startswith("darwin") or sys_platform.startswith("win32"):
9393
return
9494

95-
omptargetlib = libpath / "openmp" / "lib" / "libomptarget.so"
95+
llvm_major, llvm_minor, _ = ll.llvm_version_info
96+
omptargetlib = (
97+
libpath / "openmp" / "lib" / f"libomptarget.so.{llvm_major}.{llvm_minor}"
98+
)
9699
if omptargetlib.exists():
97100
if DEBUG_OPENMP >= 1:
98101
print("Found OpenMP target runtime library at", omptargetlib)

0 commit comments

Comments
 (0)