4

未知のサイズの 2 つの大きな行列を合計するために CUBLAS を使用しようとしています。(可能であれば) 完全に最適化されたコードが必要なので、行列加算コード (単純) を書き直すのではなく、CUBLAS、特に A と C (B が単位行列の場合) を合計できる cublasSgemm 関数を使用することにしました: *C = alpha*op(A)*op(B)+beta*c*

問題は次のとおりです。C および C++ は行列を行優先形式で格納しますが、cublasSgemm は (fortran との互換性のために) 列優先形式で動作することを意図しています。A と B を最初に転置するかどうかを指定できますが、C を転置するように指定することはできません。そのため、行列の追加を完了することができません..

行列の最大サイズは 20000x20000 程度なので、自分で C 行列を転置することはできません。

解決方法を教えてください。

4

2 に答える 2

7

CUBLAS5.0にcublasgeamが追加されました。オプションで転置された 2 つの行列の加重和を計算します。

于 2012-09-26T16:10:39.783 に答える
5

行列を追加するだけであれば、実際には問題になりません。アルファ、Aij、ベータ、および Cij を指定します。アルファ、アジ、ベータ、および Cji を与えていると考え、Cji = ベータ Cji + アルファ アジと考えられるものを与えます。しかし、あなたに関する限り、それは正しい Cij です。私の心配は、マトリックス製品のように重要なことに行き始めるときです。そこには、おそらくそれを回避する方法はありません。

しかし、もっと重要なことは、GEMM を使用して行列の加算を行うことは望ましくありませ。 ~20,000 の2 つの操作と 1 回のパスが必要です! 行列を 20,000^2 の長さのベクトルとして扱い、saxpy を使用します。

行列の乗算はメモリ帯域幅を集中的に使用するため、自分でコーディングした場合と調整されたバージョンでは、パフォーマンスに大きな (10 倍または 100 倍の) 違いがあります。コード内の構造をライブラリに合わせて変更するのが理想的です。できない場合は、この場合、線形代数恒等式を使用するだけで管理できます。C-vs-Fortran の順序付けは、A を渡すと、CUBLAS が A T (A 転置) を「認識する」ことを意味します。これで問題ありません。回避できます。必要なものが C=AB の場合は、行列を逆の順序 BA で渡します。次に、ライブラリは (B T . A T ) を見て、C T = (AB) Tを計算します。それから C Tを返すと、(あなたの順序で) C が得られます。テストして確認してください。

于 2011-03-29T23:46:13.993 に答える