c - 将 GotoBLAS2 与 C 结合使用

标签 c linker blas

我是 C 编码的新手,但我已经编写了一个用于模拟神经网络的 Matlab 程序,我希望将其转换为 C 代码,因为我们的 super 计算机集群不允许运行超过几个 Matlab 模拟一次。为此,我发现 GotoBLAS 可以处理矩阵数学。

不幸的是,我不确定如何使用它,因为我在 C 和使用外部库方面没有太多经验。我假设 'dgemm' 是 GotoBLAS 中的一个函数,来自阅读 BLAS 指南 pdf。我已经能够成功编译 GotoBLAS,但是当我这样做时:

gcc -o outputprog main.c -Wall -L -lgoto2.a

我收到消息:

undefined reference to 'dgemm'

据我所知,我应该包括一些来自 GotoBLAS 的 .h 文件(或者可能不包括),但我不确定是哪一个(或者这是否正确)。

如有任何帮助,我们将不胜感激。如果需要更多信息,请告诉我。

最佳答案

一个问题可能是 -L 选项需要一个“目录”名称,因此 gcc(或 gcc 调用的链接器) code>) 将 -lgoto2.a 视为一个目录。编译器不会提示不存在的目录;它只是忽略它们。您希望在哪个目录中找到该库? (为了这个答案的目的,我假设它在 /usr/local/lib 中。)

另一个问题可能是该库未称为 libgoto2.a.a 或 libgoto2.a.so 或类似名称。您通常不会指定 .a 后缀。 (为了这个答案的目的,我假设库是 libgoto2.a 或 libgoto2.so。)

看来您不需要指定 header 的位置;这意味着它们位于足够常规的位置,编译器无论如何都会在那里查找。如果这是正确的,那么库也可能位于足够常规的位置,并且可能不需要 -L 选项。

因此,您可以使用:

gcc -Wall -o outputprog main.c -lgoto2

或者您可能需要使用:

gcc -Wall -o outputprog main.c -L/usr/local/lib -lgoto2

在评论中进行了一些广泛的讨论之后,以及库在当前目录中并命名为 libgoto2.a 并且符号 dgemm 仍然缺失的信息,我下载了GotoBLAS2 version 1.13并尝试在半支持平台(MacOS X,可能伪装成 Linux,具有 x86_64 架构)上编译它。构建并未完全成功 - 某些汇编代码中存在问题。但是,仔细查看标题,有一个看起来可以解决您的问题:

cblas.h

在许多其他函数定义中,我们发现:

void cblas_dgemm(enum CBLAS_ORDER Order, enum CBLAS_TRANSPOSE TransA,
                 enum CBLAS_TRANSPOSE TransB, blasint M, blasint N, blasint K,
                 double alpha, double *A, blasint lda, double *B, blasint ldb,
                 double beta, double *C, blasint ldc);

header 中的所有函数符号都以cblas_ 为前缀。您的代码应该使用:

#include "cblas.h"

您应该使用前缀为 cblas_ 的 Fortran 名称(小写)调用函数:

cblas_dgemm(...);

要使用的正确链接行是上面列出的第一个选项:

gcc -Wall -o outputprog main.c -lgoto2

在紧要关头,您可以定义宏以将常规(无前缀)名称映射到正确的 C 函数名称,但我认为这样做不值得:

#define DGEMM cblas_dgemm

或(更安全,因为它检查参数列表的长度,但更冗长):

#define DGEMM(a,b,c,d,e,f,g,h,i,j,k,l,m,n) cblas_dgemm(a,b,c,d,e,f,g,h,i,j,k,l,m,n)

然后你可以写:

DGEMM(a, ..., n);

然后将调用正确的函数。


对上述 GotoBLAS2 部分成功构建的实验表明:

  • cblas.h 不是独立的(与良好的编码标准相反)。
  • common.h 必须放在它之前。
  • common.h 包含许多其他 header :
    • 配置.h
    • common_x86_64.h
    • 参数.h
    • common_param.h
    • 通用接口(interface).h
    • common_macro.h
    • common_s.h
    • common_d.h
    • common_q.h
    • common_c.h
    • common_z.h
    • common_x.h
    • common_level1.h
    • common_level2.h
    • common_level3.h
    • common_lapack.h
  • 以下代码有机会链接到一个完整的库:

    #include "common.h"
    #include "cblas.h"
    
    void check_dgemm(void)
    {
        double A[33] = { 0.0 };
        double B[33] = { 0.0 };
        double C[33] = { 0.0 };
        cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
                    3, 3, 3, 2.0, A, 3, B, 3, 3.0, C, 3);
    }
    
    int main(void)
    {
        check_dgemm();
        return 0;
    }
    

    (在我公认的损坏的库构建中,提示从“cblas_dgemm() not found”变成了缺少许多其他函数。这是一个巨大的改进!)

关于c - 将 GotoBLAS2 与 C 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7266339/

相关文章:

从 16 位架构中的给定索引计算位掩码

编译多个 .c 和 .h 文件

c - 在数组初始化期间从不兼容的指针类型进行初始化

c++ - 与 glfw3 链接时出错

python - 在 python 中导入 nltk 时出现段错误

c - 内联汇编后指针取消引用 (SIGSEGV) 失败

c - 如何链接 X11 程序

c++ - 在 VS2013 中编译 : error LNK2001 using C++

c++ - 泛化到多个 BLAS/LAPACK 库

c++ - 将 gsl c++ 程序与英特尔 MKL 链接