Skip to content
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

pykdtree requires OMP_NUM_THREADS flag on Linux #49

Open
schlegelp opened this issue Jun 30, 2021 · 8 comments
Open

pykdtree requires OMP_NUM_THREADS flag on Linux #49

schlegelp opened this issue Jun 30, 2021 · 8 comments

Comments

@schlegelp
Copy link
Collaborator

schlegelp commented Jun 30, 2021

Just to leave a paper trail for this observation:

I was setting up a large NBLAST on a Linux (Ubuntu 16.04) server and noticed that it was running suspiciously slow. Some digging flagged pykdtree as the culprit: it was much slower than scipy's KDTree solution (order 5-10 fold). This is weird because on my OSX laptop it's the other way around.

A quick glance at the pykdtree Github brought up the OMP_NUM_THREADS environment variable (which I never bothered with on OSX). Setting OMP_NUM_THREADS=4 indeed brings up pykdtree to the expected speed.

FYI: @clbarnes @sdorkenw

@schlegelp
Copy link
Collaborator Author

Another breadcrumb to chase up: while individual KNN queries with pykdtree are faster, it looks like there is some blocking when used with multiprocessing that makes it slower than scipy.

@clbarnes
Copy link
Collaborator

clbarnes commented Jul 2, 2021

I think multiprocessing can misbehave if there's more than one layer of concurrency - I think it depends on how everything is implemented (and can be platform-dependent too because the default forking behaviour is different for different OSs). Something like if different multiprocessing processes are sharing some object which has its own locks, they end up sharing that lock too, unless due care is taken.

@schlegelp
Copy link
Collaborator Author

Good point!

Confusingly, I managed to get pykdtree to behave similar to on my Mac in both concurrent and non-concurrent contexts by setting OMP_NUM_THREADS=1.

On a related note: I've been working on another NBLAST variant that uses mostly matrix operations via numpy and I observed a similar behaviour. At a certain point throwing more cores at this NBLAST makes it go slower than faster - presumably because numpy already employs some level of concurrency.

@schlegelp
Copy link
Collaborator Author

@jefferis had a very good explanation for this behaviour: Apple's clang compiler doesn't support openmp which is why that flag might not need to be set on OSX.

@jefferis
Copy link

NB if you have homebrew clang, that may support openmp.

@schlegelp
Copy link
Collaborator Author

Just to leave a note that threadpoolctl might be handy here to avoid multiple layers of concurrency. Will see if it does the trick.

@schlegelp
Copy link
Collaborator Author

Leaving another breadcrumb: on ARM Macs, pykdtree seems to be compiled with openmp support.

Also: I tried threadpoolctl in the past and it didn't work 🤷

@schlegelp
Copy link
Collaborator Author

Just to leave a note that since version 1.5.0 (July 2023), navis is automatically setting the OMP_NUM_THREADS flag before spawning the child processes. By default it is set to 1 but that can be changed:

# Increase limit to 2
navis.nbl.nblast_funcs.OMP_NUM_THREADS_LIMIT = 2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants