我是 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/