4

私はCUDAプロジェクトをオブジェクト指向デザインにできるだけ近づけるようにしようとしています。現時点で私が見つけた解決策は、Structを使用してデータをカプセル化することであり、GPU処理が必要なメソッドごとに、次の3つの関数を実装する必要があります。

  1. オブジェクトによって呼び出されるメソッド。
  2. その構造体の__デバイス__メソッドを呼び出す__グローバル__関数。
  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を配置してバッファーを割り当てるのを忘れました。修正しました。

4

1 に答える 1

3

外からは普通のクラスに見えながら、CUDAを使ったクラスを作るのが目標ですか?

もしそうなら、O'Conbhui が言ったことを拡張するには、CUDA 機能の C スタイルの呼び出しを作成し、それらの呼び出しをラップするクラスを作成するだけです。

したがって、.cu ファイルには、テクスチャ参照、カーネル、カーネルを呼び出す C スタイル関数、および GPU メモリの割り当てと解放を行う C スタイル関数の定義を配置します。あなたの例では、これには GPU メモリを初期化するカーネルを呼び出す関数が含まれます。

次に、対応する .cpp ファイルで、.cu ファイル内の関数の宣言を含むヘッダーをインポートし、クラスを定義します。コンストラクターでは、CUDA メモリを割り当て、独自のメモリ初期化関数を含むテクスチャなどの他の CUDA リソースを設定する .cu 関数を呼び出します。デストラクタでは、CUDA リソースを解放する関数を呼び出します。メンバー関数では、カーネルを呼び出す関数を呼び出します。

于 2012-04-16T15:45:07.840 に答える