1

deviceで定義されたグローバル メモリを使用するアプリケーションを CUDA で実行しようとしています。この変数は、.cuh ファイルで宣言されます。

別のファイルでは、.cu がメインで、cudaMallocs と cudaMemCpy を実行します。

それは私のコードの一部です:

cudaMalloc((void**)&varOne,*tam_varOne * sizeof(cuComplex));
cudaMemcpy(varOne,C_varOne,*tam_varOne * sizeof(cuComplex),cudaMemcpyHostToDevice);

varOne は、.cuh ファイルで次のように宣言されます。

    __device__ cuComplex *varOne;

カーネルを起動し (パラメーターとして varOne を渡していません)、デバッガーで varOne を読み込もうとすると、変数を読み込めないと表示されます。ポインタのアドレスは 000..0 なので、明らかに間違っています。

では、CUDA でグローバル メモリを宣言してコピーするにはどうすればよいでしょうか。

4

2 に答える 2

2

まず、CPU から GPU にコピーされるデータへのポインターを宣言する必要があります。上記の例では、配列original_cpu_arrayを CUDA グローバル メモリにコピーします。

int original_cpu_array[array_size];   
int *array_cuda;

データが占有するメモリ サイズを計算します。

int size = array_size * sizeof(int);

Cuda メモリ割り当て:

msg_erro[0] = cudaMalloc((void **)&array_cuda,size);

CPU から GPU へのコピー:

msg_erro[0] = cudaMemcpy(array_cuda, original_cpu_array,size,cudaMemcpyHostToDevice);

カーネルを実行

GPU から CPU へのコピー:

msg_erro[0] = cudaMemcpy(original_cpu_array,array_cuda,size,cudaMemcpyDeviceToHost);

空きメモリ:

cudaFree(array_cuda);

デバッグ上の理由から、通常、関数呼び出しのステータスを配列に保存します。(例: cudaError_t msg_erro[var]; )。これは厳密には必要ではありませんが、割り当てとメモリ転送中にエラーが発生した場合に時間を節約できます。

エラーが発生した場合は、次のような関数を使用して出力します。

void printErros(cudaError_t *erros,int size, int flag)
{
 for(int i = 0; i < size; i++)
     if(erros[i] != 0)
     {
         if(flag == 0) printf("Alocacao de memoria");
         if(flag == 1) printf("CPU -> GPU  ");
         if(flag == 2) printf("GPU -> CPU  ");
         printf("{%d} => %s\n",i ,cudaGetErrorString(erros[i]));
     }
}

フラグは主に、エラーが発生したコード内の部分を示すためのものです。たとえば、メモリ割り当て後:

msg_erro[0] = cudaMalloc((void **)&array_cuda,size);
printErros(msg_erro,msg_erro_size, 0);
于 2012-11-07T18:00:45.693 に答える
0

いくつかの例を試してみたところ、グローバル変数をカーネルに渡さずに直接使用できないことがわかりました。.cuh ファイルで初期化しても、main() で初期化する必要があります。

理由:

  1. グローバルに宣言すると、メモリは GPU グローバル メモリに割り当てられません。cudaMalloc((void**)&varOne,sizeof(cuComplex))メモリの割り当てに使用する必要があります。GPU でのみメモリを割り当てることができます。宣言__device__ cuComplex *varOne;は、プロトタイプおよび変数宣言と同じように機能します。ただし、メモリはcudaMalloc((void**)&varOne,sizeof(cuComplex))使用されるまで割り当てられません。
  2. *varOneまた、最初に in main() を Host ポインターとして初期化する必要があります。を使用cudaMalloc()すると、ポインタがデバイスポインタであることがわかります。

一連の手順は次のとおりです。(テストしたコードの場合)

int *Ad;        //If you can allocate this in .cuh file, you dont need the shown code in main()

__global__ void Kernel(int *Ad){
....
}

int main(){
....
      int size=100*sizeof(int);
      cudaMalloc((void**)&Ad,size);
      cudaMemcpy(Ad,A,size,cudaMemcpyHostToDevice);
....
}
于 2012-11-07T19:53:40.950 に答える