Faiss 项目未编译,未定义的引用

问题描述 投票:0回答:1

我正在尝试在 Ubuntu(wsl) 中编译这个项目。 应该安装 Intel-mkl 库(sudo apt install intel-mkl)并且 faiss 已经构建并安装,看起来没有任何问题。但是,当我尝试使用 make 命令构建项目时,我遇到了错误。

CMakeLists

project(faiss_clustering)


set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -Wall -pedantic -Wextra -fopenmp")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -fsanitize=address")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -flto -ftree-vectorize -march=native")


add_executable(faiss_clustering main.cpp)
target_link_libraries(faiss_clustering PRIVATE faiss blas)

主.cpp

#include <iostream>
#include <vector>
#include <string>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <faiss/Clustering.h>
#include <faiss/IndexFlat.h>
#include <faiss/utils/utils.h>


using namespace std;

struct sfile_info {
    size_t dim;
    size_t count;
    char file_name[256];

    sfile_info(char* p_file_name) {
        strcpy(file_name, p_file_name);
    }
};

float* fvecs_read(sfile_info& fi)
{
    FILE* f = fopen(fi.file_name, "r");
    if (!f) {
        fprintf(stderr, "could not open %s\n", fi.file_name);
        perror("");
        abort();
    }
    int d;
    fread(&d, 1, sizeof(int), f);
    assert((d > 0 && d < 1000000) || !"unreasonable dimension");
    fseek(f, 0, SEEK_SET);
    struct stat st;
    fstat(fileno(f), &st);
    size_t sz = st.st_size;
    assert(sz % ((d + 1) * 4) == 0 || !"weird file size");
    size_t n = sz / ((d + 1) * 4);

    fi.dim = d;
    fi.count = n;
    float* x = new float[n * (d + 1)];
    size_t nr = fread(x, sizeof(float), n * (d + 1), f);
    assert(nr == n * (d + 1) || !"could not read whole file");

    // shift array to remove row headers
    for (size_t i = 0; i < n; i++)
        memmove(x + i * d, x + 1 + i * (d + 1), d * sizeof(*x));

    fclose(f);
    return x;
}

// not very clean, but works as long as sizeof(int) == sizeof(float)
int* ivecs_read(sfile_info& fi) {
    return (int*)fvecs_read(fi);
}

double distance(float* data, float* query, size_t dim)
{
    double dist = 0;
    for (int k = 0; k < dim; k++)
    {
        double r = data[k] - query[k];
        dist += r * r;
    }
    return dist;
}


int main()
{
    int numberOfEMIterations = 20;
    size_t numberOfClusters = 1000;

    /////////////////////////////////////////////////////// READ DATA
    sfile_info fi_base("../../sift/sift_base.fvecs");
    sfile_info fi_learn("../../sift/sift_learn.fvecs");
    sfile_info fi_query("../../sift/sift_query.fvecs");
    sfile_info fi_groundtruth("../../sift/sift_groundtruth.ivecs");

    float* mass = fvecs_read(fi_base);
    float* massL = fvecs_read(fi_learn);
    float* massQ = fvecs_read(fi_query);
    int* massQA = ivecs_read(fi_groundtruth);

    assert(fi_base.dim == fi_query.dim || !"query does not have same dimension as base set");
    assert(fi_base.dim == fi_learn.dim || !"learn does not have same dimension as base set");
    assert(fi_query.count == fi_groundtruth.count || !"incorrect number of ground truth entries");


    /////////////////////////////////////////////////////// PROCESS CLUSTERING

    faiss::ClusteringParameters cp;
    cp.niter = numberOfEMIterations;
    cp.verbose = true; // print out per-iteration stats

    faiss::IndexFlatL2 index(fi_learn.dim);
    faiss::Clustering kMeans(fi_learn.dim, numberOfClusters, cp);
    kMeans.train(fi_learn.count, massL, index);

    // Print first ten centroids
    int print_center_count = 10;
    for (int c = 0; c < numberOfClusters; c++)
    {
        if (print_center_count-- == 0) break;
        for (int d = 0; d < fi_learn.dim; d++) {
            std::cout << kMeans.centroids[c * fi_learn.dim + d] << " ";    
        }
        std::cout << c << "\n";
    }
  
}

错误:

kudlic@LAPTOP-FUCA8DQ5:/mnt/d/codes/AVD/AVD/faiss_clustering/build$ make
[ 50%] Linking CXX executable faiss_clustering
/usr/bin/ld: /usr/local/lib/libfaiss.a(VectorTransform.cpp.o): in function `(anonymous namespace)::eig(unsigned long, double*, double*, int)':
VectorTransform.cpp:(.text+0x176a): undefined reference to `dsyev_'
/usr/bin/ld: VectorTransform.cpp:(.text+0x17e4): undefined reference to `dsyev_'
/usr/bin/ld: /usr/local/lib/libfaiss.a(VectorTransform.cpp.o): in function `faiss::ITQMatrix::train(long, float const*)':
VectorTransform.cpp:(.text+0x43d4): undefined reference to `dgesvd_'
/usr/bin/ld: VectorTransform.cpp:(.text+0x4606): undefined reference to `dgesvd_'
/usr/bin/ld: /usr/local/lib/libfaiss.a(VectorTransform.cpp.o): in function `faiss::OPQMatrix::train(long, float const*)':
VectorTransform.cpp:(.text+0x6a7c): undefined reference to `sgesvd_'
/usr/bin/ld: VectorTransform.cpp:(.text+0x6b63): undefined reference to `sgesvd_'
/usr/bin/ld: /usr/local/lib/libfaiss.a(utils.cpp.o): in function `faiss::matrix_qr(int, int, float*)':
utils.cpp:(.text+0x86b): undefined reference to `sgeqrf_'
/usr/bin/ld: utils.cpp:(.text+0x93d): undefined reference to `sgeqrf_'
/usr/bin/ld: utils.cpp:(.text+0x9a5): undefined reference to `sorgqr_'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/faiss_clustering.dir/build.make:97: faiss_clustering] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/faiss_clustering.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

如果我尝试在 vscode 中转到 VectorTransform.cpp 并将鼠标悬停在有问题的函数之一上,似乎只有声明,因为这些似乎是 intel-mkl 函数。

我首先尝试在项目所在的 Windows 目录中构建和安装 faiss 库。然后我尝试在 linux 用户目录中再次构建并安装它,希望它可以修复它,可惜没有成功。

您知道我应该采取什么步骤来解决这个问题吗? 如果我忘记任何信息,请告诉我,我会添加它。

c++ linux intel-mkl faiss
1个回答
0
投票

如指定: https://cmake.org/cmake/help/latest/module/FindLAPACK.html 将以下代码片段添加到 CMakeLists 解决了问题

set(BLA_VENDOR Intel10_64lp) 
find_package(LAPACK) 
© www.soinside.com 2019 - 2024. All rights reserved.