-
-
Notifications
You must be signed in to change notification settings - Fork 26k
BLD Add missing OpenMP dependencies in relevant meson.build #29694
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Could we not add openmp as a default dependency to everything? |
Right now, if we want to go down that route, I don't know any other way than adding the Full disclosure: I find this route not not very natural but I guess it has the advantage (as with our previous setuptools setup) of "I don't want to have to think about this". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be a good enough reason for a 1.5.2?
I agree this should be in 1.5.2
. Can we add a changelog entry for 1.5.2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My 2c: I do like the explicit verbose dependencies of meson. IIUC, it is a "feature".
From what I understand, adding |
I added a changelog. Improvements more than welcome!
Except that this is not always In an ideal world i.e. not necessarily this PR, we would have a build error (or maybe an error at import-time if easier) if somehow OpenMP is enabled in reference module (probably https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/utils/_openmp_helpers.pxd) and not the current one. Is it possible? maybe? Am I likely to work on it any time soon? Probably not 😅.
Yeah I can understand this. IMO adding a new Cython file does not happen that often and if it does, people will likely copy from somewhere else a In other words this happened for the setuptools -> meson transition (sorry about this), but I would hope that it is a lot less likely to happen now. |
Then could we add it to every single meson.build file? It won't hurt, since it just adds options to the compiler. |
I find it would make the meson.build more confusing. There are currently 13 .pyx that uses OpenMP and 114 .pyx in total. I have been quite confused a few times in the past with setuptools when seeing that OpenMP flags were used for all the extensions and also when looking at the I do understand the failure case looks bad (OpenMP silently unused whereas everything looks completely fine) but as I tried to argue I do think it is quite unlikely that it will happen again. Of course, more than happy to hear other opinions on this! I spent some time finding a way to have an import-time error if OpenMP support is enabled in a reference module (`sklearn.utils._openmp_helpers) and not the current one (or the other way around but less likely). Each from ..utils._openmp_helpers cimport check_openmp_support
check_openmp_support() This can be forgotten but if deemed necessary, we could add some kind of check in The error would happen at import-time and look like this:
The diff looks like this: diff --git a/sklearn/manifold/_barnes_hut_tsne.pyx b/sklearn/manifold/_barnes_hut_tsne.pyx
index f0906fbf2b..9bf8ee354f 100644
--- a/sklearn/manifold/_barnes_hut_tsne.pyx
+++ b/sklearn/manifold/_barnes_hut_tsne.pyx
@@ -20,6 +20,9 @@ cnp.import_array()
cdef char* EMPTY_STRING = ""
+from ..utils._openmp_helpers cimport check_openmp_support
+check_openmp_support()
+
# Smallest strictly positive value that can be represented by floating
# point numbers for different precision levels. This is useful to avoid
# taking the log of zero when computing the KL divergence.
diff --git a/sklearn/utils/_openmp_helpers.pxd b/sklearn/utils/_openmp_helpers.pxd
index a7694d0be2..c2adc957db 100644
--- a/sklearn/utils/_openmp_helpers.pxd
+++ b/sklearn/utils/_openmp_helpers.pxd
@@ -31,3 +31,18 @@ cdef extern from *:
void omp_unset_lock(omp_lock_t*) noexcept nogil
int omp_get_thread_num() noexcept nogil
int omp_get_max_threads() noexcept nogil
+
+cdef inline check_openmp_support():
+ # Need absolute rather than relative import here. Relative import would be
+ # relative to the module where check_openmp_support is cimported
+ from sklearn.utils._openmp_helpers import _openmp_parallelism_enabled
+ reference_openmp_parallelism_enabled =_openmp_parallelism_enabled()
+ print(f'{SKLEARN_OPENMP_PARALLELISM_ENABLED=}')
+ print(f'{reference_openmp_parallelism_enabled=}')
+ if SKLEARN_OPENMP_PARALLELISM_ENABLED != reference_openmp_parallelism_enabled:
+ raise ValueError(
+ f"OpenMP support discrepancy, you probably need to add openmp_dep to the extension module dependencies "
+ "in the relevant meson.build file\n"
+ f"OpenMP enabled for sklearn.utils._openmp_helpers (reference): {reference_openmp_parallelism_enabled}\n"
+ f"OpenMP enabled for {__name__}: {SKLEARN_OPENMP_PARALLELISM_ENABLED}"
+ ) Edit: another alternative is |
This looks reasonable to me. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merging as is, since there is no real reason to block this. I'm very unhappy that a module could start using openmp and we silently would just not use that in compile time, and that I can't really check whether now we actually have added openmp everywhere that we should.
So this is an improvement, but I can't double check whether we still have a regression compared to pre-meson or not.
Fix #29665
This may be a good enough reason for a 1.5.2?
I checked that the OpenMP dependencies were added for the relevant
meson.build
with this grep pattern, let me know if you have a better idea:I also checked whether omp was present in the
ldd
output of 1.4.1 .so files (1.4.1 wheels have been built with setuptools) and compare with the 1.5.1 one (1.5.1 wheels have been built with meson). This does match the missing openmp_dep.