0

私はCコーディングの初心者ですが、ニューラルネットワークをシミュレートするためのMatlabプログラムを作成しました。スーパーコンピュータークラスターでは、一度に複数のMatlabシミュレーションを実行できないため、Cコードに変換したいと思います。そのために、GotoBLASが行列の計算を処理することを発見しました。

残念ながら、Cや外部ライブラリの使用経験が少ないため、使用方法がわかりません。'dgemm'はBLASガイドpdfを読んで、GotoBLASの関数だと思います。GotoBLASを正常にコンパイルできましたが、コンパイルすると次のようになります。

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

メッセージが表示されます:

undefined reference to 'dgemm'

私が理解しているように、GotoBLASからのファイルを含める必要があり.hます(または含まない可能性があります)が、どれが正しいか(またはこれが正しいかどうか)はわかりません。

これに関する助けをいただければ幸いです。さらに情報が必要な場合はお知らせください。

4

2 に答える 2

6

問題の 1 つは、-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、おそらくx86_64 アーキテクチャの Linux のふりをしている)。ビルドは完全には成功しませんでした - 一部のアセンブラー コードに問題があります。ただし、ヘッダーを調べてみると、問題の解決策を提供しているように見えるものがあります。

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"

Fortran 名 (小文字) の前に を付けて関数を呼び出す必要がありますcblas_

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
    • 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
  • 次のコードは、完全なライブラリとリンクする可能性があります。

    #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()見つからない」から、他の多くの機能が見つからないというものになりました。これは大幅な改善です!)

于 2011-09-01T05:43:40.933 に答える