6

適切なものを呼び出すために使用する関数ポインター配列がありますcblas_xgemm(たとえば、ATLAS/CBLAS からのcblas_dgemmorなど)。cblas_sgemm

これはcblas_dgemm、関数ポインターで使用するように指示するとうまく機能します。dgemm は適切な引数で呼び出され、正しい結果を返します。

ただし、cblas_sgemm関数ポインターで呼び出すと、次の出力が得られます。

ldc must be >= MAX(N,1): ldc=0 N=2Parameter 14 to routine cblas_sgemm was incorrect

問題を示す短いテスト プログラムを作成しました。cblas_sgemm関数ポインターなしでの呼び出しは正常に機能します。

特に次の gcc 警告に注意してください (完全な gcc 出力がある上記のリンクの要旨も参照してください)。

test_cblas_sgemm.c:20:3: warning: initialization from incompatible pointer type [enabled by default]

関数ポインター配列定義の行をコメントアウトすると、そのcblas_sgemm行であってもそのような警告は表示されませんcblas_dgemm。しかし、これらの関数はどちらも同じ戻り値の型を持つ必要があるため、意味がありません!

からの適切な行は次のcblas.hとおりです。

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

それで、何が得られますか?xgemmあるヘッダーから関数の1つを取得し、別のヘッダーから別の関数を取得していますか? または、奇妙な関数ポインターの問題に対処していますか?

4

1 に答える 1

1

あなたの質問は、関数ポインタ配列から呼び出そうとしている異なるシグネチャの関数があるという事実に要約されるようです。私はこれを自分で試したことはありませんが、少し調査したところ、これは可能ではないようです。静的に型付けされた言語はこの操作の型安全性を評価できないため、これは理にかなっています。

boost::variant を使用する提案や、これに対する他の回避策を見てきましたが、私たちの yown ではないライブラリにリンクしているので、それらのオプションを追求する価値があるかどうかはわかりません。

証明または反証したい場合は、テスト プログラムから CBLAS を削除し、データ型のみが異なる複数の署名メソッドを持つクラスを実装するだけで済みます。

余談ですが、列メジャーは大きな問題です。

于 2012-02-01T22:27:21.537 に答える