01. ベクトル加算
長さ N の配列 x と y から、z[i] = x[i] + y[i] を計算します。
第 7 章の配列の確保、View、for_each、ホスト側での読み出しを組み合わせます。
実装する内容
N = 1000とし、Array1D<double, Backend>で 3 つの配列x,y,zを用意します(Backendは 実習の入口の書き方)。各配列から
view()で View を取り出します。for_eachとMISO_LAMBDAで、x[i] = 0.37 * i、y[i] = 1.3 * iと初期化します。別の
for_eachでz[i] = x[i] + y[i]を計算します。Array1D<double, backend::Host>を用意し、copy_fromでzを写して確かめます。
Array1D の要素は確保しただけでは初期化されないので、3 で全要素に値を入れてから 4 で読みます。
ラムダ式の中では、Array1D ではなく View を使います。
結果の確認
ホスト側でも同じ初期化の式を別々に計算し、その 2 つの値を足して期待値を作ります。
z[0] = 0、z[999] は約 1668.33 になります。
全要素について差を求め、最大絶対誤差を表示してください。
あわせて、1e-15 * max(1, |期待値|) 以下の差を許容する比較で合格した要素数と、完全に一致した要素数を表示します。
期待値が 0 の点もあるため、期待値そのもので割る相対誤差は使いません。
CPU でこの確認ができたら、次の課題へ進めます。
GPU で実行する段階
第 9 章を読んだ後、同じソースを CUDA 用の別のビルドフォルダでビルドします。 入力を揃え、CPU と同じ比較を行います。 GPU では、乗算と加算を 1 つの命令にまとめる最適化(FMA)などで、丸めが CPU と変わる場合があります。 完全一致の数だけでなく、許容誤差による比較で確かめます。