• 検索結果がありません。

CSR への RBP 法の適用 (RBP-CSR)

ドキュメント内 に関する研究 (ページ 80-85)

Row Block Packing method (RBP 法 )

5.4 CSR への RBP 法の適用 (RBP-CSR)

からRBP-CSRへ,ELLからRBP-ELLへの変換を想定する.ただしCOOから直接変換 を行うことも容易に実装することが可能である.

までがi行目の非ゼロ要素の情報が格納されている,V aluesColumns配列のインデッ クスとなる.Algorithm9中のColCSR, V alCSR, RowP trCSRは図3.8のCSRの配列に対応 している.また,その他の配列は図5.3に対応している.

Algorithm9の6行目から23行目までがAlgorithm8の2行目から7行目までの非ゼロ要 素の連続部の処理に対応する.6行目からのWhile処理によりT mpColに格納された一つ前 の非ゼロ要素の列番号と,その次の非ゼロ要素の列番号が連続している間,Comp V alues へ非ゼロ要素の値を追加し続ける(Algorithm8の3行目に対応).Wlile処理の終了時に は,Comp Columnsに2つ以上連続した非ゼロ要素の先頭と末尾の列番号が追加される (Algorithm8の4から6行目に対応).例えば,図5.3の疎行列の最初の“a, b, c, d”は連続し た非ゼロ要素であることから,連続した非ゼロ要素の値はすべてそのままComp V alues へ格納される.また,先頭の非ゼロ要素“a”,末尾の要素“d”の列番号がそれぞれ順に

Comp Columnsに格納される.

Algorithm8の8から10行目までの不連続部の要素に対する処理は,Algorithm9の24 行目から29行目に対応する.T mpColに各格納されている列番号の非ゼロ要素が,不連続 と判明した場合に,非ゼロ要素の値をV aluesCSRへ,列番号をColumnsCSRへ追加す る.例として,図5.3の疎行列中,最初の不連続な非ゼロ要素“g”の非ゼロ要素は,8から 10行目の処理が適用され,“g”の値と列番号はそれぞれ,V aluesCSRとColumnsCSR へ格納される.

Algorithm9の30行目から40行目は,調査している非ゼロ要素が1行中の最後の非ゼロ 要素が不連続だった場合の処理と,1行中に1つの不連続な非ゼロ要素しか存在しない場合 の処理を示している.この2つの処理は実装の都合上,追加したものであり,Algorithm8 の不連続部の要素の処理に含まれる.

また,RBP法をCSRへ適用することで多少の変更が生ずる.図5.3の疎行列をCSRで格 納する場合,値と列番号は1対1で対応することから,1行目の要素はV aluesが“a, b, c, d”,

“e, f”,Columnsが“0,1,2,3”, “6,7”のようにそれぞれの配列で要素数が一致し,Ptr配列

RowP trの1つのみ使用する.しかしRBP法の圧縮により,値と列番号の数に差異が

生じるため,RBP-CSRでは2行目の要素が始まるインデックスはComp valuesで6番目,

Comp Columnsでは4番目となる.そのためRBP法ではComp V alues,Comp Columns の何番目のインデックスで行が変わるのかを表す値を格納するV al ptrCol ptrの2つの 配列を用意し,並列計算に必要な各行の先頭の要素のインデックスを判別する.Algorithm9 の41行目にて,不連続部を格納するCSRの配列,Comp Values配列,Comp Columns配 列,それぞれに対して,各行の先頭の非ゼロ要素が配列内の何番目のインデックスに格納 されているか記録するため,各行終了時点での非ゼロ要素数を格納している.RBP-CSR では追加の配列を必要とするため,全く連続した非ゼロ要素が存在しない疎行列において はCSRよりメモリ使用量が増える可能性がある.

さらに,連続部と不連続部の分割により,5行目(最初の行を0行目とする)のような 連続した非ゼロ要素が存在しない行も出現する.その場合にはV al ptr, Col ptrに同じイ ンデックスを続けて格納することで,行中に要素が存在しないことを示す.図5.3の行列

では1行目には不連続な非ゼロ要素が存在せず,2行目から不連続な非ゼロ要素“g”が出 現する.そのため,RowP trの1番目と2番目に“0,0”(図5.3中,赤い波線)を格納する.

2行目はRowP tr内2番目と3番目“0,1”(図5.3中,青い直線)のように非ゼロ要素“g”が 1つ存在することを示す.上記に説明したAlgorithm9を図5.3の疎行列中,すべての非ゼ ロ要素に対し,適用することで図5.3中のRBP-CSRを得ることが可能である.

式(5.1)にRBP-CSRを用いて疎行列を格納した場合のメモリ使用量を示す.以降,Ncol は圧縮した後の列番号を格納するComp Columnsの要素数,NvalComp V aluesの要 素数,NnonV aluesCSR, ColumnsCSRの要素数(疎行列内の不連続な非ゼロ要素の数) を示す.

図5.3中のV al ptr,Col ptr,RowP trの要素数は,CSRのRowP trと同様に(N+ 1)と なる.そのため,式(5.1)中12(N+ 1)は,3つの配列(V al ptr,Col ptr,RowP tr)のメモ リ使用量の合計を示す.次に4Ncol+ 8Nvalは連続した非ゼロ要素の列番号と値を格納す るComp ColumnsComp V aluesのメモリ使用量を示す.4Nnon+ 8Nnonは不連続な非 ゼロ要素の列番号と値を格納するColumnsCSR,V aluesCSR のメモリ使用量を示す.

M emU sageRBP−CSR = 12(N + 1) + 4Ncol+

8Nval+ 4Nnon+ 8Nnon [byte] (5.1)

Algorithm 9 Matrix compression of RBP-CSR

1: V al ptr[0] = 0, Col ptr[0] = 0, RowP tr[0] = 0 2: Cnt1 = 0, Cnt2 = 0, Cnt3 = 0

3: fori= 0 to N umRow do

4: T mpCol=ColumnsCSR[RowP trCSR[i]]

5: for j=RowP trCSR[i] + 1 toRowP trCSR[i+ 1] do 6: while ColumnsCSR[j]−T mpCol== 1 do

7: if T mpCol is head of consecutive columnsthen 8: Comp Columns[Cnt1] =T mpCol

9: Comp V alues[Cnt2] =V aluesCSR[j1]

10: Comp Columns[Cnt1 + 1] =ColumnsCSR[j]

11: Comp V alues[Cnt2 + 1] =V aluesCSR[j]

12: Cnt2 =Cnt2 + 2

13: else

14: Comp Columns[Cnt1 + 1] =ColumnsCSR[j]

15: Comp V alues[Cnt2] =V aluesCSR[j]

16: Cnt2 =Cnt2 + 1 17: end if

18: T mpCol=T mpCol+ 1

19: j=j+ 1

20: end while

21: if Previous elements is consecutivethen 22: T mpCol=ColumnsCSR[j]

23: Cnt1 =Cnt1 + 2

24: else

25: ColumnsCSR[Cnt3] =T mpCol 26: V aluesCSR[Cnt3] =V aluesCSR[j1]

27: Cnt3 =Cnt3 + 1

28: T mpCol=ColumnsCSR[j]

29: end if

30: if T mpCol is last element’s column in the row then 31: ColumnsCSR[Cnt3] =T mpCol

32: V aluesCSR[Cnt3] =V aluesCSR[j]

33: Cnt3 =Cnt3 + 1 34: end if

35: end for

36: if There is just one element in the rowthen 37: ColumnsCSR[Cnt3] =T mpCol

38: V aluesCSR[Cnt3] =V aluesCSR[RowP trCSR[i]]

39: Cnt3 =Cnt3 + 1 40: end if

41: Col ptr[i+ 1] =Cnt1, V al ptr[i+ 1] =Cnt2, RowP tr[i+ 1] =Cnt3 42: end for

Algorithm 10 SpMV code of RBP-CSR on GPU

1: Letid be thread ID (id: 0 to n-1)

2: Set Count, T mpReslut= 0

/* Calculation of compression part */

3: RowStart=col ptr[id]

4: for jj =val ptr[id] to val ptr[id+ 1]1 do

5: ColN ow =Comp Columns[RowStart+Count]

6: ColN ext =Comp Columns[RowStart+Count+ 1]

7: T mpResult+ =Comp V alues[jj]∗dV ector[ColN ow]

8: for j =ColN ow+ 1 to ColN ext do

9: jj+ +

10: T mpResult+ =Comp V alues[jj]∗dV ector[j]

11: end for

12: Count+ = 2

13: end for

/* Calculation of non-compression part */

14: RowStart=RowP tr[id]

15: RowEnd=RowP tr[id+ 1]

16: for j =RowStart to RowEnd−1 do

17: T mpResult+ =V alues[j]∗dV ector[Colmuns[j]]

18: end for

19: Result[id] =T mpResult

Algorithm10は,RBP-CSR形式で格納された疎行列を用いたSpMV演算を示す.各 スレッドがAlgorithm10を同時に実行し,それぞれが疎行列内の1行を担当する.idは カーネル関数を実行する各スレッドの番号を示している.idは,CUDAの関数を用いる ことで各スレッドが取得することが可能である.RBP-CSRのSpMVカーネルは連続し た非ゼロ要素を計算するパートと不連続な非ゼロ要素を計算するパートに分かれている.

Algorithm10内,3行目から13行目までが連続した非ゼロ要素を計算するパートである.

4行目からのforループでは,スレッドが担当する行の非ゼロ要素の値をComp V aluesか ら値を読み出すため,V al ptrから担当する行の先頭の非ゼロ要素の値が格納されている インデックス番号を読み込む.5,6行目のColN owColN extには連続した非ゼロ要素 の最初と最後の列番号が代入される.7行目の処理は,連続した非ゼロ要素の先頭の要素 とSpMVで用いられるベクトルの要素との掛け算を計算する.8行目のforループにて,

ColN owからColN extになるまでjをインクリメントしていくことで,先頭以降の要素

の列番号を毎回グローバルメモリから読み出すことなく,インクリメントのみで列番号を 復元し,SpMVの演算を行う.レジスタ中の値をインクリメントするだけでよく,GPU メモリへのアクセスが必要ないことから,従来のCSRに比べメモリアクセス回数の削減

が可能である.

14行目から18行目は,不連続な非ゼロ要素を演算する部分であり,CSRのSpMVカー ネルと同様の処理を行っている.不連続な非ゼロ要素に対し演算を行い,連続した非ゼロ 要素に対する演算結果と合算している.最後に結果を各スレッドが担当していた行と同じ ベクトル中の行に格納し,終了する.

ドキュメント内 に関する研究 (ページ 80-85)