Importing implicit has side effect causing segfault
This snippet results in a segmentation fault on the last line on Mac:
import implicit
import faiss, numpy as np
index = faiss.IndexFlatIP(1)
index.add(np.ascontiguousarray([[0.5]], dtype='float32'))
index.search(np.ascontiguousarray([[0.5]] * 30, dtype='float32'), 1)
Strangely, the code runs fine if I remove the first line. It seems that importing implicit has some undocumented side-effects that are indirectly causing this crash.
System: macOS 11.6.4, 2.3 GHz Quad-Core Intel Core i7, CPython 3.10.2 (but the crash also happens on 3.8.12). Implicit installed from implicit-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl with pip install implicit.
List of packages installed:
faiss-cpu==1.7.2
implicit==0.6.1
numpy==1.23.2
scipy==1.9.1
tqdm==4.64.1
- What are the side effects of running
import implicit? - Is there a way to create a version of
implicitthat doesn't have these side effects?
Thanks for the bug report - I've managed to reproduce and get a stack trace with lldb:
* frame #0: 0x000000012e95654d libomp.dylib`void __kmp_suspend_64<false, true>(int, kmp_flag_64<false, true>*) + 33
frame #1: 0x000000012fcc97e7 _swigfaiss.cpython-39-darwin.so`kmp_flag_64<false, true>::wait(kmp_info*, int) + 1431
frame #2: 0x000000012fcc6834 _swigfaiss.cpython-39-darwin.so`__kmp_hyper_barrier_release(barrier_type, kmp_info*, int, int, int) + 132
frame #3: 0x000000012fcc8fa1 _swigfaiss.cpython-39-darwin.so`__kmp_fork_barrier(int, int) + 241
frame #4: 0x000000012fca8d5a _swigfaiss.cpython-39-darwin.so`__kmp_launch_thread + 266
frame #5: 0x000000012fcdebc1 _swigfaiss.cpython-39-darwin.so`__kmp_launch_worker(void*) + 161
frame #6: 0x00007fff725cc109 libsystem_pthread.dylib`_pthread_start + 148
frame #7: 0x00007fff725c7b8b libsystem_pthread.dylib`thread_start + 15
With libomp.dylib coming from implicit @
/Users/benf/miniconda3/lib/python3.9/site-packages/implicit/.dylibs/libomp.dylib
Since implicit run's https://github.com/matthew-brett/delocate as part of creating the wheel, this vendors a copy of the OpenMP library with the implicit install.
Faiss on the otherhand also depends on OpenMP, but seems to statically link it:
nm -A /Users/benf/miniconda3/lib/python3.9/site-packages/faiss/_swigfaiss.cpython-39-darwin.so | grep __kmp_suspend_64
/Users/benf/miniconda3/lib/python3.9/site-packages/faiss/_swigfaiss.cpython-39-darwin.so: 000000000043e040 T __Z16__kmp_suspend_64ILb0ELb1EEviP11kmp_flag_64IXT_EXT0_EE
/Users/benf/miniconda3/lib/python3.9/site-packages/faiss/_swigfaiss.cpython-39-darwin.so: 000000000043e230 T __Z16__kmp_suspend_64ILb1ELb0EEviP11kmp_flag_64IXT_EXT0_EE
It looks like by importing implicit before Faiss, is causing faiss to pick up the libomp.dylib included with implicit causing this issue.
As a workaround, can you try setting export OMP_NUM_THREADS=1 to disable OpenMP threading?
I'm not sure how to fix this though =(
Thank you! Appreciate the answer and the thorough investigation. Thanks also for linking this issue and the one on the faiss repo together.
I will try your suggested workaround.
As a workaround, can you try setting
export OMP_NUM_THREADS=1to disable OpenMP threading?
This works, thank you!
Glad to hear the workaround is working for you,
Hi! I have the same issue with segfault on mac os 12.4. The workaround above helps, but it complicates installation, and disable OpenMP threading may be a limitation. Could you please fix the import issue?
We use implicit as a dependancy in our project and it would be great if implicit will be installed with pip without modifying any Environment Variables.