将 GotoBLAS2 与 C 一起使用
我是 C 编码的新手,但我已经编写了一个用于模拟神经网络的 Matlab 程序,我希望将其转换为 C 代码,因为我们的超级计算机集群不允许同时运行多个 Matlab 模拟。为此,我找到了 GotoBLAS 来处理矩阵数学。
不幸的是,我不确定如何使用它,因为我在 C 和使用外部库方面没有很多经验。通过阅读 BLAS 指南 pdf,我假设“dgemm”是 GotoBLAS 中的一个函数。我已经能够成功编译 GotoBLAS,但是当我这样做时:
gcc -o outputprog main.c -Wall -L -lgoto2.a
我收到消息:
undefined reference to 'dgemm'
据我了解,我应该包含来自 GotoBLAS 的一些 .h
文件(或者可能不包含),但我'我不确定是哪一个(或者这是否正确)。
任何对此的帮助将不胜感激。如果需要更多信息,请告诉我。
I'm sort of a newbie to C coding but I've written a Matlab program for simulating neural networks and I wish to translate it to C code because our supercomputer cluster won't allow running more than a few Matlab simulations at once. To that end, I've found GotoBLAS to take care of the matrix math.
Unfortunately I'm not sure how to use it as I don't have a lot of experience in C and using external libraries. I'm assuming that 'dgemm' is a function in GotoBLAS from reading the BLAS guide pdf. I've been able to successfully compile GotoBLAS, but when I do:
gcc -o outputprog main.c -Wall -L -lgoto2.a
I get the messages:
undefined reference to 'dgemm'
As I understand it, I should be including some .h
file (or maybe not) from GotoBLAS but I'm not sure which one (or if this is right at all).
Any help with this would be appreciated. Let me know if more information is needed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一个问题可能是
-L
选项需要在其后面有一个“目录”名称,因此gcc
(或由gcc
调用的链接器)将-lgoto2.a
视为目录。编译器不会抱怨不存在的目录;它只是忽略它们。您希望在哪个目录中找到该库? (出于本答案的目的,我假设它位于/usr/local/lib
中。)另一个问题可能是该库不名为 libgoto2.aa 或 libgoto2.a.so 或类似的东西。您通常不会指定
.a
后缀。 (出于本答案的目的,我假设该库是 libgoto2.a 或 libgoto2.so。)看来您不需要指定标头的位置;这意味着它们位于一个足够传统的位置,编译器无论如何都会在那里查找。如果这是正确的,则库也可能位于足够传统的位置,并且
-L
选项可能是不必要的。因此,您可能能够使用:
或者您可能需要使用:
经过评论中的一些广泛讨论,以及该库位于当前目录中并名为
libgoto2.a
的信息,并且符号dgemm
仍然丢失,我下载了 GotoBLAS2 版本1.13 并尝试在半支持的平台上编译它(MacOS X,可能假装是 Linux,具有 x86_64 架构)。构建并未完全成功 - 某些汇编代码存在问题。然而,浏览一下标题,有一个看起来像是为您的问题提供了解决方案:在这个标题中,在许多其他函数定义中,我们发现:
标题中的所有函数符号都以
cblas_
。您的代码应该使用:您应该使用带有
cblas_
前缀的 Fortran 名称(小写)来调用函数:并且要使用的正确链接行是上面列出的第一个选项:
在紧要关头, 可以定义宏来将常规(无前缀)名称映射到正确的 C 函数名称,但我不相信这是值得的:
或者(更安全,因为它检查参数列表的长度,但更详细):
你 可以写:
然后 将调用正确的函数。
对上述 GotoBLAS2 部分成功构建的实验表明:
cblas.h
不是独立的(与良好的编码标准相反)。common.h
必须包含在它之前。common.h
包含许多其他标头:以下代码有可能链接到完整的库:
<前><代码>#include“common.h”
#include“cblas.h”
无效 check_dgemm(无效)
{
双 A[33] = { 0.0 };
双 B[33] = { 0.0 };
双 C[33] = { 0.0 };
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
3、3、3、2.0、A、3、B、3、3.0、C、3);
}
int 主函数(无效)
{
check_dgemm();
返回0;
}
(在我承认的损坏的库构建中,抱怨从“找不到cblas_dgemm()”变成了许多其他函数丢失。这是一个巨大的改进!)
One problem could be that the
-L
option expects a 'directory' name after it, and thereforegcc
(or the linker invoked bygcc
) is treating-lgoto2.a
as a directory. The compiler does not complain about non-existent directories; it simply ignores them. Which directory did you expect to find the library in? (For the purposes of this answer, I'll assume it is in/usr/local/lib
.)Another problem could be that the library is not called libgoto2.a.a or libgoto2.a.so or something similar. You would not normally specify the
.a
suffix. (For the purposes of this answer, I'll assume that the library is either libgoto2.a or libgoto2.so.)It appears that you don't need to specify where the headers are found; that means they're in a sufficiently conventional location that the compiler looks there anyway. If that's correct, the library too may be in a sufficiently conventional location too, and the
-L
option may be unnecessary.So, you might be able to use:
Or you might need to use:
After some extensive discussion in the comments, and the information that the library is in the current directory and named
libgoto2.a
and that the symboldgemm
is still missing, I downloaded GotoBLAS2 version 1.13 and tried to compile it on a semi-supported platform (MacOS X, probably pretending to be Linux, with x86_64 architecture). The build was not completely successful - problems in some assembler code. However, poking around at the headers, there is one that looks like giving the solution to your problems:In this, amongst many other function definitions, we find:
All the function symbols in the header are prefixed with
cblas_
. Your code should be using:You should be calling the functions using the Fortran name (in lower case) prefixed with
cblas_
:And the correct link line to use is the first option listed above:
At a pinch, you could define macros to map the regular (unprefixed) names to the correct C function names, but I'm not convinced it is worth it:
or (safer, because it checks the length of the argument list, but more verbose):
You can then write:
and the correct function would be called.
Experimentation with the partially successful build of GotoBLAS2 mentioned above shows that:
cblas.h
is not self-contained (contrary to good coding standards).common.h
must be included before it.common.h
includes a lot of other headers:The following code stands a chance of linking with a complete library:
(In my admittedly broken build of the library, the complaints went from being '
cblas_dgemm()
not found' to a number of other functions missing. This is a vast improvement!)好的,我可以在 GotoBLAS 邮件列表 https://lists.tacc 上找到答案。 utexas.edu/mailman/listinfo/gotoblas(据我所知,网站上没有列出)。以下是通过 C 和 GCC 编译器使用 GotoBLAS2 的快速步骤。
构建 GotoBLAS2 库(.so 和 .a),库中包含有关该内容的良好文档,因此我不会将其发布在这里。将这两个文件包含在您选择的 -L 设置的 libs 目录中。我只包含一个,因为我认为它们只是同一库的不同版本,这是不正确的。
如果您希望使用 gcc 进行编译,还可以链接到
-lgfortran
。-lpthread
可能也很有用,尽管我不确定,我见过使用它的示例,但它没有编译。您的 gcc 应该如下所示:gcc -Wall -o outprog -L./GotoLIBSDIR -lgoto2 -lgfortran -lpthread(maybe) main.c
最后,调用
function_()
而不是function()
,例如,使用 gfortran 编译 fortran 接口时使用dgemm_()
。作为 Fortran 接口的替代方案,cblas 接口可以用作
cblas_dgemm()
。为此,您仍然需要链接到-lgfortran
,否则链接到libgoto2.so
将失败,并且您需要链接到该文件才能使用cblas_dgemm()
正确。似乎不需要包含任何 .h 文件或其他任何内容。
希望其他人会发现这很有用。感谢您的帮助!
Ok I was able to find the answer on the GotoBLAS mailing list https://lists.tacc.utexas.edu/mailman/listinfo/gotoblas (which is not listed on the website as far as I can see). Here's a quick step by step on using GotoBLAS2 with C and GCC compiler.
Build GotoBLAS2 libraries (.so and .a), there's good documentation on that included with the libraries so I won't post it here. Include BOTH of these files in the libs directory of your choice as set by -L. I was only including one because I thought they were just different versions of the same library which was not correct.
Also link to
-lgfortran
as well if you wish to compile with gcc.-lpthread
might also be useful, although I'm not sure, I've seen examples with it but it compiles without. Your gcc should look something like this:gcc -Wall -o outprog -L./GotoLIBSDIR -lgoto2 -lgfortran -lpthread(maybe) main.c
Finally, call
function_()
instead offunction()
, so for example,dgemm_()
when using gfortran to compile the fortran interfaces.Alternatively to the fortran interface the cblas interface can be used as
cblas_dgemm()
. You still need to link to-lgfortran
for this as otherwise linking tolibgoto2.so
will fail, and you need to link to that file to be able to usecblas_dgemm()
correctly.There doesn't appear to be any need to include any of the .h files or anything else.
Hopefully someone else will find this useful. Thanks for all the help!