引き続きGPUで遊んでみます
にゃんぱすー。かえるのクーです。
GPUに入門中です。
今回はReduceしてみます
ReduceもしくはReductionは、最初説明を読んだときは?が頭の周りを飛び回りましたが、少しだけわかってきました。ECOなのが一番です。
たくさんあるコアで、どうすれば、合計(など)を早く計算できるか!を考えると、「なるほど」と感じられました。
でも、説明できるレベルには到底ないので、説明はいつものように諸先輩にお尋ねください。
Reduceの説明(前回貼ったのと同じです)
CUDAのアーキテクチャとも密接に関係しているのですね。
Reduceの最適化・高速化はいろいろな手法があるようですが、cupyを使うだけの場合は計算部分をいれるだけなので、意識は不要だと思います。
Reduceの高速化の説明を読めば、高速に計算するためには、カーネル内での分岐やLoopは基本的に御法度であることがよくわかります。
L2距離を求める例がCuPyのスライドの13ページにありますのでそのまま実行してみます。(公式チュートリアルのものと同じです)
わからないままL2norm計算式
import cupy as cp
import numpy as np
if __name__ == '__main__':
x = cp.arange(10, dtype=np.float32).reshape(2,5)
# 以下はCuPyの説明スライドから
L2norm_kernel = cp.ReductionKernel(
'T x', # in_params:入力
'T y', # out_params:出力
' x * x', #map_expr:前処理
'a + b', #reduce_expr:リデュース
'y = sqrt(a)', #post_map_expr:後処理
'0', #identity:初期値
'l2norm') #name:名前
y = L2norm_kernel(x)
print(x)
print(y)
[[0. 1. 2. 3. 4.]
[5. 6. 7. 8. 9.]]
16.881943
でした。今回は入力もprintしています。
これは sqrt(0*0 + 1*1 + 2*2 + 3*3 + ... 8*8 + 9*9) で答えが16.881943です。
電卓やExcelでもそうなります。
’a + b’ の部分と後処理で a がでてくる部分がどうしてもしっくりこなかったのですが、
a も b も予約語で、自分はa + bのreduce結果は a に格納される感覚がわかるとしっくりきました。
行ごとの計算も指定で行えます。
y = L2norm_kernel(x, axis=1)
なら列方向のreduceを行い、それぞれの行の計算値を出してくれます。
[ 5.477226 15.9687195]
y = L2norm_kernel(x, axis=0)
なら、行方向のreduceを行ってくれます。
[5. 6.0827627 7.28011 8.5440035 9.848858 ]
例えば(ゼロからかぞえて)2列目はsqrt(2*2 + 7*7) = 7.28011 です。
y = L2norm_kernel(x, axis=1, keepdims=True)
とすれば、配列の次元をそのままにしてくれます。
[[0. 1. 2. 3. 4.]
[5. 6. 7. 8. 9.]]
[[ 5.477226 ]
[15.9687195]]
合計系や統計系の演算はひととおりそろっていると思うので、ReductionKernelを使うのは稀かもしれませんが、計算としてはとってもおもしろいです。
普通に合計してみます
import cupy as cp
import numpy as np
if __name__ == '__main__':
x = cp.arange(10, dtype=np.float32).reshape(2,5)
# 以下はCuPyの説明スライドから
array_sum = cp.ReductionKernel(
'T x', #入力
'T y', #出力
'x', #前処理
'a + b', #リデュース
'y = a', #後処理
'0', #初期値
'l2norm') #名前
y = array_sum(x, axis=1)
print(x)
print(y)
[[0. 1. 2. 3. 4.]
[5. 6. 7. 8. 9.]]
[10. 35.]
ウェーブレット変換をCUDAでやる記事もあったので見てみます。
CUDAで連続ウェーブレット変換 - PukiWiki for PBCG Lab
ボクは離散ウェーブレット変換で十分なのですが(それはCUDAのSDKにあるらしいです。今度探してみます)