01. ベクトル加算

長さ N の配列 x と y から、z[i] = x[i] + y[i] を計算します。 第 7 章の配列の確保、View、for_each、ホスト側での読み出しを組み合わせます。

実装する内容

  1. N = 1000 とし、Array1D<double, Backend> で 3 つの配列 x, y, z を用意します(Backend は 実習の入口の書き方)。

  2. 各配列から view() で View を取り出します。

  3. for_each と MISO_LAMBDA で、x[i] = 0.37 * i、y[i] = 1.3 * i と初期化します。

  4. 別の for_each で z[i] = x[i] + y[i] を計算します。

  5. 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 と変わる場合があります。 完全一致の数だけでなく、許容誤差による比較で確かめます。