0

カーネルの起動に問題がありました。1 つの大きなカーネルを使用するプログラムがありました。同期の問題により、2 つに分割する必要がありました。最初のカーネルはいくつかの初期化処理を行い、2 番目のカーネルに渡された引数のサブセットを渡します。最初のカーネルだけを実行すると問題なく動作します。2 番目のカーネルのみを実行すると、初期化が欠落しているために実行中に失敗しますが、カーネル自体は開始されます。両方を続けて実行すると、2 番目のカーネルが「無効な引数」エラーで失敗します。必要に応じてコードを提供しますが、それがどのように役立つかは今のところわかりません。前もって感謝します。

編集:ここで要求された起動コード:

void DeviceManager::integrate(){
  assert(hostArgs->neighborhoodsSize > 0);
  size_t maxBlockSize;
  size_t blocks;
  size_t threadsPerBlock;
  // init patch kernel
  maxBlockSize = 64;
  blocks = (hostArgs->patchesSize /maxBlockSize);
  if(0 != hostArgs->patchesSize % maxBlockSize){
    blocks++;
  }
  threadsPerBlock = maxBlockSize;
  std::cout << "blocks: " << blocks << ", threadsPerBlock: " << threadsPerBlock << std::endl;
  initPatchKernel<CUDA_MAX_SPACE_DIMENSION><<<blocks,threadsPerBlock>>>(devicePatches, hostArgs->patchesSize);
  cudaDeviceSynchronize();

  //calc kernel
  maxBlockSize = 64;
  blocks = (hostArgs->neighborhoodsSize /maxBlockSize);
  if(0 != hostArgs->neighborhoodsSize % maxBlockSize){
    blocks++;
  }
  threadsPerBlock = maxBlockSize;
  size_t maxHeapSize = hostArgs->patchesSize * (sizeof(LegendreSpace) + sizeof(LinearSpline)) + hostArgs->neighborhoodsSize * (sizeof(ReactionDiffusionCCLinearForm) + sizeof(ReactionDiffusionCCBiLinearForm));
  std::cout << "maxHeapSize: " << maxHeapSize << std::endl;
  cudaDeviceSetLimit(cudaLimitMallocHeapSize, maxHeapSize);
  std::cout << "blocks: " << blocks << ", threadsPerBlock: " << threadsPerBlock << std::endl;
  integrateKernel<CUDA_MAX_SPACE_DIMENSION><<<blocks,threadsPerBlock>>>(deviceNeighborhoods, hostArgs->neighborhoodsSize, devicePatches, hostArgs->patchesSize, hostArgs->biLinearForms, hostArgs->linearForms, deviceRes);
  cudaDeviceSynchronize();
}

メモリの転送と割り当ては、カーネルを 1 つしか使用していないときに機能したため、問題にはなりません。

編集 2: ラッパー関数を介してデバッグ モードでビルドするときに、各カーネル呼び出しの後にエラーをチェックします。したがって、各カーネル呼び出しの後、次が実行されます。

cudaError_t cuda_result_code = cudaGetLastError();                        
if (cuda_result_code!=cudaSuccess) {                                      
   fprintf("message: %s\n",cudaGetErrorString(cuda_result_code));
}

これについて言及していないことをお詫び申し上げます。ラッパーは私が作成したものではないため、トリックを貼り付けていないことをお詫び申し上げます。失敗直前の出力は次のとおりです。

blocks: 1, threadsPerBlock: 64
maxHeapSize: 4480
blocks: 1, threadsPerBlock: 64
message: invalid argument
4

1 に答える 1

2

cudaDeviceSetLimit

cudaLimitMallocHeapSizeは、malloc() および free() デバイス システム コールによって使用されるヒープのサイズをバイト単位で制御します。cudaLimitMallocHeapSize の設定は、malloc() または free() デバイス システム コールを使用するカーネルを起動する前に実行する必要があります。そうしないと、 cudaErrorInvalidValueが返されます。この制限は、コンピューティング機能 2.0 以上のデバイスにのみ適用されます。計算能力が 2.0 未満のデバイスでこの制限を設定しようとすると、エラー cudaErrorUnsupportedLimit が返されます。

于 2012-12-22T14:02:43.153 に答える