implicit icon indicating copy to clipboard operation
implicit copied to clipboard

Importing implicit has side effect causing segfault

Open lg8080 opened this issue 3 years ago • 2 comments

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
  1. What are the side effects of running import implicit?
  2. Is there a way to create a version of implicit that doesn't have these side effects?

lg8080 avatar Sep 09 '22 09:09 lg8080

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 =(

benfred avatar Sep 10 '22 00:09 benfred

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.

lg8080 avatar Sep 15 '22 18:09 lg8080

As a workaround, can you try setting export OMP_NUM_THREADS=1 to disable OpenMP threading?

This works, thank you!

lg8080 avatar Oct 05 '22 18:10 lg8080

Glad to hear the workaround is working for you,

benfred avatar Oct 12 '22 18:10 benfred

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.

monkey0head avatar Nov 16 '22 11:11 monkey0head