facebookresearch / faiss

A library for efficient similarity search and clustering of dense vectors.
https://faiss.ai
MIT License
31.14k stars 3.62k forks source link

[undefined reference to `sgemm_'/`sgetrf_'/`sgelsd_'] errors occur when cross-compiling faiss for armv7l #2305

Open SherlockC787 opened 2 years ago

SherlockC787 commented 2 years ago

Summary

I tried to run faiss on arm32 platform by cross-compiling. i followed the following steps.

  1. follow the official 'INSTALL.md' file exactly to compile the faiss library. I can successfully run 'demo_ivfpq_indexing.cpp', '1-Flat.cpp' and other examples on Ubuntu 16.04.

  2. Based on the success of step 1, I recompiled the faiss library using the cross-compilation chain following the steps in 'INSTALL.md' (manually installing the LAPACK and OPEN_Blas libraries, where the OPEN_Blas library was also cross-compiled), I wrote the 'build.sh' file (given later), and all the steps went smoothly (including ' make faiss') until I compile the example 'demo_ivfpq_indexing' and get a series of "undefined reference to 'xxx'" errors. I don't know how to deal with these problems.

Platform

OS: Host_platform->Ubuntu 16.04 (x86_64). Target_platform->Linux 4.19.111 (armv7l)

Faiss version: 1.7.2

Installed from: anaconda (follow INSTALL.md)

Faiss compilation options: (follow INSTALL.md)

Running on:

Interface:

Reproduction instructions

build.sh for cross-compile

BUILD_DIR=${ROOT_PWD}/build

if [[ ! -d "${BUILD_DIR}" ]]; then
  mkdir -p ${BUILD_DIR}
fi

cd ${BUILD_DIR}

cmake -DCMAKE_BUILD_TYPE=Debug .. \
    -DCMAKE_C_COMPILER=${GCC_COMPILER}-gcc \
    -DCMAKE_CXX_COMPILER=${GCC_COMPILER}-g++

make -j4 faiss          # No errors in this step
make demo_ivfpq_indexing    # The errors appear here
make 1-Flat

The errors

/usr/local/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: ../faiss/libfaiss.a(ProductQuantizer.cpp.o): in function `faiss::ProductQuantizer::compute_inner_prod_tables(unsigned int, float const*, float*) const':
/home/liu/codes/faiss-main/faiss/impl/ProductQuantizer.cpp:618: undefined reference to `sgemm_'
/usr/local/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: ../faiss/libfaiss.a(distances.cpp.o): in function `faiss::pairwise_L2sqr(long long, long long, float const*, long long, float const*, float*, long long, long long, long long)':
/home/liu/codes/faiss-main/faiss/utils/distances.cpp:834: undefined reference to `sgemm_'
/usr/local/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: ../faiss/libfaiss.a(distances.cpp.o): in function `void faiss::(anonymous namespace)::exhaustive_inner_product_blas<faiss::HeapResultHandler<faiss::CMin<float, long long> > >(float const*, float const*, unsigned int, unsigned int, unsigned int, faiss::HeapResultHandler<faiss::CMin<float, long long> >&)':
/home/liu/codes/faiss-main/faiss/utils/distances.cpp:196: undefined reference to `sgemm_'
/usr/local/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: ../faiss/libfaiss.a(distances.cpp.o): in function `void faiss::(anonymous namespace)::exhaustive_inner_product_blas<faiss::ReservoirResultHandler<faiss::CMin<float, long long> > >(float const*, float const*, unsigned int, unsigned int, unsigned int, faiss::ReservoirResultHandler<faiss::CMin<float, long long> >&)':
/home/liu/codes/faiss-main/faiss/utils/distances.cpp:196: undefined reference to `sgemm_'

...

/usr/local/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: ../faiss/libfaiss.a(LocalSearchQuantizer.cpp.o): in function `(anonymous namespace)::fmat_inverse(float*, int)':
/home/liu/codes/faiss-main/faiss/impl/LocalSearchQuantizer.cpp:104: undefined reference to `sgetrf_'
/usr/local/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: /home/liu/codes/faiss-main/faiss/impl/LocalSearchQuantizer.cpp:106: undefined reference to `sgetri_'
/usr/local/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: ../faiss/libfaiss.a(LocalSearchQuantizer.cpp.o): in function `(anonymous namespace)::dmat_inverse(double*, int)':
/home/liu/codes/faiss-main/faiss/impl/LocalSearchQuantizer.cpp:123: undefined reference to `dgetrf_'
/usr/local/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: /home/liu/codes/faiss-main/faiss/impl/LocalSearchQuantizer.cpp:125: undefined reference to `dgetri_'
mdouze commented 2 years ago

These functions are from the BLAS library. Please check if the link command line includes BLAS.

SherlockC787 commented 2 years ago

These functions are from the BLAS library. Please check if the link command line includes BLAS.

Thank you for your reply. I found that I was using the OPEN_BLAS library before and I tried to use the BLAS library just now, however, it still reported the same error. Here is the FindBLAS.cmake I wrote, which corresponds to line 238 of /faiss/Cmakelists.txt.

# This is the previous version
FIND_PATH(BLAS_INCLUDE_DIR *.h /home/liu/myLib/openblas_arm/include/)
message("./h dir ${BLAS_INCLUDE_DIR}")

# 
FIND_LIBRARY(BLAS_LIBRARY *.a /home/liu/myLib/openblas_arm/lib)
message("lib dir: ${BLAS_LIBRARY}")

if(BLAS_INCLUDE_DIR AND BLAS_LIBRARY)
    # set result
    set(BLAS_FOUND TRUE)
endif(BLAS_INCLUDE_DIR AND BLAS_LIBRARY)

# This is the new version

FIND_LIBRARY(BLAS_LIBRARY *.a /home/liu/myLib/blas/lib)
message("lib dir: ${BLAS_LIBRARY}")

if(BLAS_INCLUDE_DIR AND BLAS_LIBRARY)
    # set result
    set(BLAS_FOUND TRUE)
endif(BLAS_INCLUDE_DIR AND BLAS_LIBRARY)

I don't know what's wrong, but it makes sense that after make -j4 faiss runs successfully, it should be fine to run the demo...

myworldraj commented 1 year ago

Is the problem resolved?

I am facing the same issue.

I cross-compiled OpenBLAS using NDK I cross-compiled FAISS using the NDK (same toolchain)

I want to use the cross-compiled OpenBLAS with FAISS, so I do the following in the faiss/CMakeLists.txt find_package(BLAS REQUIRED) target_link_libraries(faiss PRIVATE ${BLAS_LIBRARIES})

The faiss cross-compiles successfully, but when the compile the SIFT demo, it gives me basic errors in linking with OpenBLAS

ld: error: undefined symbol: sgemm_

referenced by IndexHNSW.cpp