-1

反復式の解法で良い結果が得られません。各行に「size_x」要素を持つ「size_y」行の 2D 配列を使用しています。

問題は、エラーの累積がゼロに等しいため、コードが 1 回の反復しか実行しないことです。この累積誤差は、配列の各セルのカーネル コードで計算されます。

この解決策のソース ファイルの 2 つの部分を次に示します。

カーネルコード:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

#define min(a,b) a <= b ? a : b

// kernel code

const char *source =
"__kernel void line_compute(__global double diagx, __global double diagy,\
__global double weightx, __global double weighty, __global int size_x,\
__global double* tab_process, __global double* tab_new, __global double* r) {\
  const unsigned int iy = get_global_id(0);\
  const unsigned int ix = get_global_id(1);\
  /* do computation */\
  tab_process[iy*size_x+ix] = weighty *( tab_new[(iy-1)*size_x+ix] +\
  tab_new[(i+1)*size_x+ix] + tab_new[iy*size_x+ix]*diagy)+\
  weightx *( tab_new[iy*size_x+(ix-1)] + tab_new[iy*size_x+(ix+1)] + tab_new[iy*size_x+ix]*diagx) ; \
  r[iy*size_x+ix] = 0;\
  rk = tab_new[iy*size_x+ix] - tab_process[iy*size_x+ix];\
  r[iy*size_x+ix] =r[iy*size_x+ix]+ rk * rk;\
  tab_new[iy*size_x+ix] = tab_process[iy*size_x+ix]\
}";

実行時に、私が出力する累積エラー:

result = 0.0;
        for(i=1;i<=size_x*size_y;i++)
             { result = result + r[i];
           printf("r[%d]=%20.18f\n",i,r[i]);
         }

        printf("result=%f\n",result);
        *error=result;

ゼロに等しいです。そのため、コードは 1 回だけ反復します。

プローブがどこにあるかわかりません。誰かが何が悪いのかを見ることができれば。

4

1 に答える 1

3

スタック オーバーフローに質問を投稿するときは、コードの関連セクションのみを分離してください (そして適切にフォーマットしてください)。これは、誰が見ても多すぎます。

カーネルの最後で時期尚早に更新することに加えtab_newて (近隣の値が依存しているため、すべてのスレッドが終了した後に一度だけ実行する必要があります)、カーネル ソースに構文エラーがあります。

tab_process[iy*size_x+ix] = weighty *( tab_new[(iy-1)*size_x+ix] +\
>>>  tab_new[(i+1)*size_x+ix] <<< + tab_new[iy*size_x+ix]*diagy)+\
weightx *( tab_new[iy*size_x+(ix-1)] + tab_new[iy*size_x+(ix+1)] + tab_new[iy*size_x+ix]*diagx) ; \

iの代わりに間違って書きましたiy。そのため、プログラムは .NET でコンパイルできない可能性が高くなりますclCreateProgramWithSource。の戻りコードを確認していないため、retその事実を見逃しており、次のことclCreateKernelclEnqueueNDRangeKernel失敗しています。カーネルが実行されていない場合、 の値はr_mem_obj初期値と同じままです - すべてゼロです。これはr、新たに割り当てられたヒープ メモリとしてのコピーであるため、すべてゼロでもあります (Linux での読み取りフォールト ページの後に新しくコミットされたのは CoW です)。カーネル内の特別なすべてゼロのページにマップされます)。すべてのゼロを合計するとゼロになります。

于 2012-09-13T11:55:45.357 に答える