私はCUDAプロジェクトをオブジェクト指向デザインにできるだけ近づけるようにしようとしています。現時点で私が見つけた解決策は、Structを使用してデータをカプセル化することであり、GPU処理が必要なメソッドごとに、次の3つの関数を実装する必要があります。
- オブジェクトによって呼び出されるメソッド。
- その構造体の__デバイス__メソッドを呼び出す__グローバル__関数。
- 構造体内の__デバイス__メソッド。
例を挙げましょう。構造体内のバッファを初期化するメソッドを実装する必要があるとしましょう。次のようになります。
struct Foo
{
float *buffer;
short2 buffer_resolution_;
short2 block_size_;
__device__ initBuffer()
{
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
int plain_index = (y * buffer_resolution.x) + x;
if(plain_index < buffer_size)
buffer[plain_index] = 0;
}
void init(const short2 &buffer_resolution, const short2 &block_size)
{
buffer_resolution_ = buffer_resolution;
block_size_ = block_size;
//EDIT1 - Added the cudaMalloc
cudaMalloc((void **)&buffer_, buffer_resolution.x * buffer_resolution.y);
dim3 threadsPerBlock(block_size.x, block_size.y);
dim3 blocksPerGrid(buffer_resolution.x/threadsPerBlock.x, buffer_resolution.y/threadsPerBlock.y)
initFooKernel<<<blocksPerGrid, threadsPerBlock>>>(this);
}
}
__global__ initFooKernel(Foo *foo)
{
foo->initBuffer();
}
構造体の中で__グローバル__を宣言できないように見えるので、それを行う必要があります。私はいくつかのオープンソースプロジェクトを見てこの方法を学びましたが、カプセル化されたすべてのGPUメソッドを実装するために3つの関数を実装するのは非常に面倒に見えます。だから、私の質問は:それは可能な限り最良の/唯一のアプローチですか?それも有効なアプローチですか?
編集1:initFooKernelを呼び出す前に、cudaMallocを配置してバッファーを割り当てるのを忘れました。修正しました。