Skip to content

Commit

Permalink
Detect, contain, and warn about the OpenMP issue of having multiple O…
Browse files Browse the repository at this point in the history
…penMP runtimes that occurs in conda environments containing numpy and pip-installed galpy
  • Loading branch information
jobovy committed Jul 4, 2024
1 parent c808134 commit b602118
Showing 1 changed file with 46 additions and 1 deletion.
47 changes: 46 additions & 1 deletion galpy/util/_load_extension_libs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# _load_extension_libs.py: centralized place to load the C extensions
import ctypes
import re
import subprocess
import sys
import sysconfig
import warnings
Expand All @@ -19,12 +21,55 @@
_libgalpy_actionAngleTorus = None
_libgalpy_actionAngleTorus_loaded = None

_checked_openmp_issue = False

def load_libgalpy():

def _detect_openmp_issue():
# Check whether we get an error of the type "OMP: Error #15: Initializing libomp.dylib, but found libomp.dylib already initialized.", which occurs, e.g., when using pip-installed galpy with conda-installed numpy and causes segmentation faults and general issues
# This is a known issue with OpenMP and is not galpy's fault (GitHub Copilot suggested this comment!)

# Check this by running a subprocess that tries to import the C library without this check
try:
subprocess.run(
[
sys.executable,
"-c",
"from galpy.util._load_extension_libs import load_libgalpy; load_libgalpy(check_openmp_issue=False)",
],
check=True,
capture_output=True,
)
except subprocess.CalledProcessError as e: # pragma: no cover
if re.match(
r"OMP: Error #15: Initializing libomp[0-9]*.dylib, but found libomp[0-9]*.dylib already initialized",
e.stderr.decode("utf-8"),
):
warnings.warn(
"Encountered OpenMP issue with multiple OpenMP runtimes causing conflicts and segmentation faults (similar to https://github.com/pytorch/pytorch/issues/78490). "
"This generally happens when you combine a pip-installed galpy with a conda-installed numpy. "
"If you are using conda, your best bet is to install galpy with conda-forge, because there is little advantage to using pip. "
"If you insist on using pip, you can try installing galpy with the --no-binary galpy flag, but note that you have to have the GSL and OpenMP installed and available for linking (e.g., using 'brew install gsl libomp' on a Mac, but make sure to add the OpenMP library to your CFLAGS/LDFLAGS/LD_LIBRARY_PATH as it is keg-only; please refer to galpy's installation page for more info). "
"Please open an Issue or Discussion on the galpy GitHub repository if you require further assistance.\n"
"For now, we will disable the libgalpy C extension module to avoid segmentation faults and other issues, but be aware that this significantly slows down the code.",
galpyWarning,
)
return True
else:
return False
finally:
global _checked_openmp_issue
_checked_openmp_issue = True


def load_libgalpy(check_openmp_issue=True):
global _libgalpy
global _libgalpy_loaded
if _libgalpy_loaded is False or not _libgalpy is None:
return (_libgalpy, _libgalpy_loaded)
if check_openmp_issue and not _checked_openmp_issue:
if _detect_openmp_issue(): # pragma: no cover
_libgalpy_loaded = False
return (_libgalpy, _libgalpy_loaded)
outerr = None
# Add top-level galpy repository directory for pip install (-e) .,
# just becomes site-packages for regular install
Expand Down

0 comments on commit b602118

Please sign in to comment.