elixir-nx/ex_faiss

Make error

Closed this issue · 14 comments

When attempting to mix deps.get I'm getting this error:

==> ex_faiss
Using cached faiss build...
g++ -I/opt/homebrew/Cellar/erlang/25.2.2/lib/erlang/erts-13.1.4/include -I/Users/jamilabreu/.cache/ex_faiss/faiss-19f7696deedc93615c3ee0ff4de22284b53e0243 -fPIC -O3 -shared -std=c++14 c_src/ex_faiss.cc c_src/ex_faiss/nif_util.cc c_src/ex_faiss/index.cc \
        c_src/ex_faiss/clustering.cc -o cache/libex_faiss.so -L/Users/jamilabreu/.cache/ex_faiss/faiss-19f7696deedc93615c3ee0ff4de22284b53e0243/build/faiss -lfaiss -flat_namespace -undefined suppress

ld: library not found for -lfaiss
collect2: error: ld returned 1 exit status
make: *** [Makefile:54: cache/libex_faiss.so] Error 1
could not compile dependency :ex_faiss, "mix compile" failed. Errors may have been logged above. You can recompile this dependency with "mix deps.compile ex_faiss", update it with "mix deps.update ex_faiss" or clean it with "mix deps.clean ex_faiss"

** (Mix) Could not compile with "make" (exit status: 2).
You need to have gcc and make installed. Try running the
commands "gcc --version" and / or "make --version". If these programs
are not installed, you will be prompted to install them.
gcc --version                                            
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: arm64-apple-darwin22.1.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
make --version
GNU Make 4.4
Built for aarch64-apple-darwin22.1.0
Copyright (C) 1988-2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

I'm on a new Apple M2, @seanmor5 any ideas?

Added the following to my .zshrc file:

export CC="/opt/homebrew/bin/gcc-12"
export CXX="/opt/homebrew/bin/g++-12"

Now getting this error:

[100%] Linking CXX shared library libfaiss.dylib
Undefined symbols for architecture arm64:
  "__Z10vpaddq_f3213__Float32x4_tS_", referenced from:
      __ZN5faiss4haddERKNS_12simd8float32ES2_ in distances_simd.cpp.o
  "__Z10vqtbl1q_u812__Uint8x16_tS_", referenced from:
      __ZNK5faiss11simd32uint814lookup_2_lanesERKS0_ in pq4_fast_scan_search_1.cpp.o
      __ZNK5faiss11simd32uint814lookup_2_lanesERKS0_ in pq4_fast_scan_search_qbs.cpp.o
  "__Z11vdupq_n_u16t", referenced from:
      __ZN5faiss12simd16uint165clearEv in pq4_fast_scan_search_1.cpp.o
      __ZN5faiss12simd16uint165clearEv in pq4_fast_scan_search_qbs.cpp.o
  "__Z8vandq_u812__Uint8x16_tS_", referenced from:
      __ZNK5faiss11simd32uint8anIS0_LDnEEES0_RKT_ in pq4_fast_scan_search_1.cpp.o
      __ZNK5faiss11simd32uint8anIS0_LDnEEES0_RKT_ in pq4_fast_scan_search_qbs.cpp.o
  "__Z9vaddq_f3213__Float32x4_tS_", referenced from:
      __ZNK5faiss12simd8float32plERKS0_ in distances_simd.cpp.o
  "__Z9vaddq_u1612__Uint16x8_tS_", referenced from:
      __ZNK5faiss12simd16uint16plERKS0_ in pq4_fast_scan_search_1.cpp.o
      __ZNK5faiss12simd16uint16plERKS0_ in pq4_fast_scan_search_qbs.cpp.o
  "__Z9vcgeq_u1612__Uint16x8_tS_", referenced from:
      __ZN5faiss6detail7simdlibL8cmp_xe32IXadL_Z9vcgeq_u1612__Uint16x8_tS3_EEEEjRK12uint16x8x2_tS6_S6_ in pq4_fast_scan_search_1.cpp.o
      __ZN5faiss6detail7simdlibL8cmp_xe32IXadL_Z9vcgeq_u1612__Uint16x8_tS3_EEEEjRK12uint16x8x2_tS6_S6_ in pq4_fast_scan_search_qbs.cpp.o
  "__Z9vcleq_u1612__Uint16x8_tS_", referenced from:
      __ZN5faiss6detail7simdlibL8cmp_xe32IXadL_Z9vcleq_u1612__Uint16x8_tS3_EEEEjRK12uint16x8x2_tS6_S6_ in pq4_fast_scan_search_1.cpp.o
      __ZN5faiss6detail7simdlibL8cmp_xe32IXadL_Z9vcleq_u1612__Uint16x8_tS3_EEEEjRK12uint16x8x2_tS6_S6_ in pq4_fast_scan_search_qbs.cpp.o
  "__Z9vmaxq_u1612__Uint16x8_tS_", referenced from:
      __ZN5faiss12simd16uint168accu_maxERKS0_ in partitioning.cpp.o
  "__Z9vminq_u1612__Uint16x8_tS_", referenced from:
      __ZN5faiss12simd16uint168accu_minERKS0_ in partitioning.cpp.o
  "__Z9vmulq_f3213__Float32x4_tS_", referenced from:
      __ZNK5faiss12simd8float32mlERKS0_ in distances_simd.cpp.o
  "__Z9vmulq_u1612__Uint16x8_tS_", referenced from:
      __ZNK5faiss12simd16uint16mlERKS0_ in pq4_fast_scan_search_1.cpp.o
      __ZNK5faiss12simd16uint16mlERKS0_ in pq4_fast_scan_search_qbs.cpp.o
  "__Z9vsubq_f3213__Float32x4_tS_", referenced from:
      __ZNK5faiss12simd8float32miERKS0_ in distances_simd.cpp.o
  "__Z9vsubq_u1612__Uint16x8_tS_", referenced from:
      __ZNK5faiss12simd16uint16miERKS0_ in pq4_fast_scan_search_1.cpp.o
      __ZNK5faiss12simd16uint16miERKS0_ in pq4_fast_scan_search_qbs.cpp.o
ld: symbol(s) not found for architecture arm64
collect2: error: ld returned 1 exit status
make[4]: *** [faiss/libfaiss.dylib] Error 1
make[3]: *** [faiss/CMakeFiles/faiss.dir/all] Error 2
make[2]: *** [faiss/CMakeFiles/faiss.dir/rule] Error 2
make[1]: *** [faiss] Error 2
make: *** [faiss] Error 2

@jamilabreu Are you able to build Faiss standalone and run the C++ API: https://github.com/facebookresearch/faiss/wiki/Installing-Faiss
https://github.com/facebookresearch/faiss/wiki/Getting-started

Just ruling out this is not a Faiss+M2 issue

I was just able to get it work! But now getting this error on this line:

ExFaiss.Index.new(384, "IDMap,Flat")

** (UndefinedFunctionError) function ExFaiss.NIF.new_index/3 is undefined (module ExFaiss.NIF is not available)

Oh that looks like the NIF shared library is failing to load, likely due to undefined symbols. This looks similar to: facebookresearch/faiss#2335 stating that ARM symbols require specific flags. It's possible the Faiss installation isn't compiled with the proper flags on ARM

Maybe also related? facebookresearch/faiss#2111

Tried adding the flags listed here:

https://github.com/facebookresearch/faiss/wiki/Installing-Faiss#compiling-faiss-on-arm

Know of any other resources like this I could try?

Here's the iex error:

 [warning] The on_load function for module Elixir.ExFaiss.NIF returned:
{:error,
 {:load_failed,
  'Failed to load NIF library: \'dlopen(/Users/jamilabreu/Code/elixir/ash/_build/dev/lib/ex_faiss/priv/libex_faiss.so, 0x0002): Library not loaded: @rpath/libfaiss.dylib\n  Referenced from: <14C09AC7-074B-344B-9B95-5D99F3B2819E> /Users/jamilabreu/Code/elixir/ash/deps/ex_faiss/cache/libex_faiss.so\n  Reason: tried: \'/System/Volumes/Preboot/Cryptexes/OS@rpath/libfaiss.dylib\' (no such file), \'/usr/local/lib/libfaiss.dylib\' (no such file), \'/usr/lib/libfaiss.dylib\' (no such file, not in dyld cache)\''}}

Seems to be looking for libfaiss.dylib in the wrong place?

Historically we needed to use rpath for things to work on Mac. You can try porting this code to ex_faiss Makefile:

https://github.com/elixir-nx/nx/blob/main/exla/Makefile#L30-L43

I was just able to get it work!

@jamilabreu We're having the same issue you had here. What did you do to get it to get it past the ld: library not found for -lfaiss error? :)

I've tried just about everything in this thread. Including reading the linked wiki's and I get the same errors:

==> ex_faiss
cp -a /Users/name/.cache/ex_faiss/faiss-19f7696deedc93615c3ee0ff4de22284b53e0243/build/faiss cache/lib
/opt/homebrew/bin/g++ -I/opt/homebrew/Cellar/erlang/25.3/lib/erlang/erts-13.2/include -I/Users/name/.cache/ex_faiss/faiss-19f7696deedc93615c3ee0ff4de22284b53e0243 -fPIC -O3 -shared -std=c++14 c_src/ex_faiss.cc c_src/ex_faiss/nif_util.cc c_src/ex_faiss/index.cc \
		c_src/ex_faiss/clustering.cc -o cache/libex_faiss.so -Lcache/lib -lfaiss -flat_namespace -undefined suppress
make: /opt/homebrew/bin/g++: No such file or directory
make: *** [cache/libex_faiss.so] Error 1
could not compile dependency :ex_faiss, "mix compile" failed. Errors may have been logged above. You can recompile this dependency with "mix deps.compile ex_faiss", update it with "mix deps.update ex_faiss" or clean it with "mix deps.clean ex_faiss"

Apple M1 Pro
mac 13.3 (22E252)

❯ gcc -v
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: arm64-apple-darwin22.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

I am able to brew instal faiss maybe a solution for mac's is to let us link to that instead? Faiss compilation issues are unfortunately common.

@jeregrine why is it trying to use g++ instead of c++ that comes with your system? perhaps that's part of the issue? maybe you have an env var messing up with your environment?

I see! We can definitely link against a system one. Torchx offers a similar option we can copy. PRs welcome!

If anyone in this thread is still having issues please try my branch.

You will need make sure to make clean in the ex_faiss dir for a fresh build. If the Makefile fails to build ex_faiss it will never try and build it again because the files don't change in the .cache dir. My make-fu is not good enough to fix that issue in the makefile.

Steps:

cd deps/ex_faiss
make clean
cd ../../
<edit mix file>
mix do deps.get, deps.compile

And that should work!