2D gpu_array の分散を計算しようとしています。リダクション カーネルは良いアイデアのように思えます。
http://documen.tician.de/pycuda/array.html
ただし、このドキュメントは、リダクション カーネルが 2 つの配列を 1 つの配列にリダクションするだけであることを暗示しています。単一の 2D 配列を単一の値に縮小するにはどうすればよいですか?
2D gpu_array の分散を計算しようとしています。リダクション カーネルは良いアイデアのように思えます。
http://documen.tician.de/pycuda/array.html
ただし、このドキュメントは、リダクション カーネルが 2 つの配列を 1 つの配列にリダクションするだけであることを暗示しています。単一の 2D 配列を単一の値に縮小するにはどうすればよいですか?
最初のステップは、この場合の分散を定義することだと思います。matlab では、2D 配列の分散関数は値のベクトル (1D 配列) を返します。しかし、単一値の分散が必要なように聞こえるので、他の人がすでに示唆しているように、おそらく最初に行うことは、2D配列を1Dとして扱うことです。C では、これを達成するために特別な手順は必要ありません。配列へのポインターがある場合は、1D 配列であるかのようにインデックスを付けることができます。1D index を使用して 2D 配列を処理する方法についてのヘルプは必要ないと思います。
それがあなたが求めている1D分散である場合、私は分散(x)=sum((x[i]-mean(x))^2)のような関数を想定しています。ここで、合計はすべてのiにわたっています。後です(ウィキペディアの記事を読んだことに基づいています)。これを 3 つのステップに分けることができます。
ステップ 1 と 3 はどちらも、配列のすべての要素を合計する古典的な削減です。ここでその根拠を説明するのではなく、このトピックに関する Mark Harris の優れた扱いと、いくつかのCUDA サンプル コードを紹介します。ステップ 2 では、カーネル コードを自分で理解できると思いますが、次のようになります。
#include <math.h>
__global__ void var(float *input, float *output, unsigned N, float mean){
unsigned idx=threadIdx.x+(blockDim.x*blockIdx.x);
if (idx < N) output[idx] = __powf(input[idx]-mean, 2);
}
リダクションと上記のコードを 1 つのカーネルに結合したい場合があることに注意してください。