cuSOLVERって何?
行列のQR分解やSVDなどを行うCUDAのライブラリです.
使い方としてはcuBLASの様にhandleを作って目的の関数を呼べばいいのですが,中には別途作業用のメモリを確保して引数としてそのアドレスを渡してあげる必要のあるものがあります.
疑問って?
例えば密単精度行列に対してQR分解を行うための関数であるcusolverDnSgeqrfで必要な作業用メモリのサイズを計算する関数cusolverDnSgeqrf_bufferSizeは
cusolverStatus_t
cusolverDnSgeqrf_bufferSize(cusolverDnHandle_t handle,
int m,
int n,
float *A,
int lda,
int *Lwork );
という宣言となっています.(cuSOLVER cusolverDn疑問というのは4つ目の引数のfloat* Aです.
これいりますか?
実験
この値によって作業用メモリの大きさが変わるかを実験してみました.
テストコードはcutfというCUDA関係のラッパーを使っていますが雰囲気で読めると思います
*AがGlobalメモリのアドレスを指している場合,ホストメモリのアドレスを指している場合,nullptrの場合での作業用メモリの大きさを表示します.
いくつかのM,Nで実験しましたが,これら3つは毎回同じ値となりました.
nullptrでさえ同じなので何でもいい気になります.
MAGMAはどうなっているの?
cuSOLVERはオープンソースではないですが,MAGMAはオープンソースなのでsgeqrf周りを見てみたところ,作業用メモリに関してこんな記述がありました.(MAGMA - geqrf)
(workspace) REAL array on the GPU, dimension (2*MIN(M, N) + ceil(N/32)*32 )*NB, where NB can be obtained through magma_get_sgeqrf_nb( M, N ). It starts with a MIN(M,N)*NB block that stores the triangular T matrices, followed by a MIN(M,N)*NB block that stores inverses of the diagonal blocks of the R matrix. The rest of the array is used as workspace.
MAGMAでは型やAの指すアドレスによらず作業用メモリの大きさを決定しているようです.
cuSOLVERはなぜ*Aが必要なんでしょうね?
おわり
疑問といえばgeqrf batchedがcuSOLVERではなくcuBLASに入っているのも不思議です.