将 GotoBLAS2 与 C 一起使用

发布于 2024-12-02 04:37:37 字数 499 浏览 0 评论 0原文

我是 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半透明的墙 2024-12-09 04:37:37

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

另一个问题可能是该库不名为 libgoto2.aa 或 libgoto2.a.so 或类似的东西。您通常不会指定 .a 后缀。 (出于本答案的目的,我假设该库是 libgoto2.a 或 libgoto2.so。)

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

因此,您可能能够使用:

gcc -Wall -o outputprog main.c -lgoto2

或者您可能需要使用:

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

经过评论中的一些广泛讨论,以及该库位于当前目录中并名为 libgoto2.a 的信息,并且符号 dgemm 仍然丢失,我下载了 GotoBLAS2 版本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);

标题中的所有函数符号都以 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 包含许多其他标头:
    • config.h
    • common_x86_64.h
    • 参数.h
    • common_param.h
    • common_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”

    无效 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 therefore gcc (or the linker invoked by gcc) 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:

gcc -Wall -o outputprog main.c -lgoto2

Or you might need to use:

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

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 symbol dgemm 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:

cblas.h

In this, amongst many other function definitions, we find:

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);

All the function symbols in the header are prefixed with cblas_. Your code should be using:

#include "cblas.h"

You should be calling the functions using the Fortran name (in lower case) prefixed with cblas_:

cblas_dgemm(...);

And the correct link line to use is the first option listed above:

gcc -Wall -o outputprog main.c -lgoto2

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:

#define DGEMM cblas_dgemm

or (safer, because it checks the length of the argument list, but more verbose):

#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)

You can then write:

DGEMM(a, ..., n);

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:
    • config.h
    • common_x86_64.h
    • param.h
    • common_param.h
    • common_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
  • The following code stands a chance of linking with a complete library:

    #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;
    }
    

    (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!)

天生の放荡 2024-12-09 04:37:37

好的,我可以在 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 of function(), 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 to libgoto2.so will fail, and you need to link to that file to be able to use cblas_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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文