C++ AMPを用いたGPUプログラミングwiki
首都大学東京 田川研究室
C++ AMP 目次へ

GPUに計算させる(extent、ラムダ式)

本当は1次元配列だけ使えればすべてのコードを書くことが可能なのですが、見た目的に煩わしいのでC++AMPでは多次元インデックスが提供されています。
今まで、index,array,array_view,extentで1と指定していた場所を2-3にすればよいだけですが。以下例になります。
    accelerator Acs;//選ばれたacceleratorオブジェクトが入っているとします。

    array<int , 2> *pvA;

    pvA = new array<int , 2>(100 , 100, Acs.get_default_view());
    array_view<int , 2> vaC = *pvA;

    extent<2> exA;

    //100*100スレッド発行予定。
    exA[0] = 100; 
    exA[1] = 100; 

    parallel_for_each(
        Acs.get_default_view() ,//計算させたいGPUを指定。
        exA  ,                  //スレッド数を指定。
        [=](index<2> iC) restrict(amp)   
        {
            //このコードは並列に動く。

            int i = iC[0]; //iC[0]にはこの場合0-99のスレッド番号が入っている。
            int j = iC[1]; //iC[1]にはこの場合0-99のスレッド番号が入っている。
            vaC[iC]   = 0;   //indexクラスでアクセス
            vaC[i][j] = 0;   //この記述はエラー
        }
    );

100*100、つまり10000のスレッドがGPU上で走ることになります。
parallel_for_eachに指定したextentクラスの次元と、ラムダ式引数のindexクラスの次元は同一でないとエラーになります。
array_viewおよびarrayの次元は発行するスレッドと一致していなくても問題はありません。[]に代入するindexクラスの次元は一致している必要があります。
以下のコードは上記コードと同一の処理を実現します。
    accelerator Acs;//選ばれたacceleratorオブジェクトが入っているとします。

    array<int , 2> *pvA;

    pvA = new array<int , 2>(100 , 100, Acs.get_default_view());
    array_view<int , 2> vaC = *pvA;

    extent<1> exA;

    //10000スレッド発行予定。
    exA[0] = 10000; 

    parallel_for_each(
        Acs.get_default_view() ,//計算させたいGPUを指定。
        exA  ,                  //スレッド数を指定。
        [=](index<1> iC) restrict(amp)   
        {
            //このコードは並列に動く。

            int i = iC[0]%100; //iC[0]にはこの場合0-9999のスレッド番号が入っている。
            int j = iC[0]/100; 
            index<1> iC2;

            iC2[0] = i;
            iC2[1] = j;
            vaC[iC2] = 0;   //indexクラスでアクセス
            vaC[iC]  = 0;   //この記述は無理。エラー
        }
    );