2016-12-08 11 views
-3

私はCUDAプロジェクトで作業していますが、私は解決策を見つけることができない重大な問題を抱えています。CUDAカーネルは20k +スレッドで何の理由もなくクラッシュしています

NVIDIA Quadro K2000mを使用してプロジェクトを実装し、私のPC(pA)には動作します。しかし、Nvidia Tesla GPUを持つクラスタと別のPC(pB)(NVIDIA gtx 960m)でプロジェクトを展開すると、実行されません!これはのコードである未指定打ち上げ失敗

興味深いのは、私がをpB(第2 PC)上のVisual StudioでNsightデバッガを使用する場合、それはエラーを表示し、実行していないということですまずカーネル:

float blockNotFinal = data.sizeOfDistinctTerms/1024; 
int threads = 0; 
int blocks = (int)floor(blockNotFinal); 

dim3 dimGrid((blocks + 1), 1, 1); 
if (data.sizeOfDistinctTerms < 1024) 
{ 
    threads = data.sizeOfDistinctTerms; 
} 
else 
{ 
    threads = 1024; 
} 
dim3 dimBlock(threads, 1, 1); 
0:

__global__ void calcKernel(float *dev_calcMatrix, 

         int *documentarray, 
         int *documentTermArray, 
         int *distincttermsarray, 
         int *distinctclassarray, 
         int *startingPointOfClassDoc, 
         int *endingPOintOfClassDoc, 
         int sizeOfDistinctClassarray, 
         int sizeOfTerms) 
{ 

int index = blockIdx.x * blockDim.x + threadIdx.x; 

int term = distincttermsarray[index]; 

if (index <= sizeOfTerms) { 

    for (int i = 0; i < sizeOfDistinctClassarray; i++) 
    { 
     int save = (index * sizeOfDistinctClassarray) + i; 
     bool test = false; 
     for (int j = startingPointOfClassDoc[i]; j <= endingPOintOfClassDoc[i]; j++) 
     { 
      if (term == documentarray[j]) 
      { 
       printf("%i \t", index); 
       dev_calcMatrix[save] = dev_calcMatrix[save] + documentTermArray[j]; 

       //printf("TermArray: documentTermArray[j] %d\n", dev_calcMatrix[save], documentTermArray[j]); 

       test = true; 
      } 
     } 

     if (!test) dev_calcMatrix[save] = 0; 


    } 
} 
} 

これは私がスレッドとブロックを作成するために使用していたコードです

したがって、23,652スレッドを作成する必要があります。私がやっていることは、23,652/1024 = 23.09です。 23.09の値を取得した後、23に丸め、+ 1 = 24のブロックを追加します。だから私は24ブロック* 1024スレッド:24,576スレッドを作成しています。

私はいくつかのスレッドは、彼らが使用する文句を言わないにも関わらず作成されることを知っている、と私はカーネルのbegginingに声明場合は、これを追加理由です:

int index = blockIdx.x * blockDim.x + threadIdx.x; 

if (index <= sizeOfTerms (23,652 is the size)) { .... } 

問題は(私はいくつかのPRINTFを追加したことです)をIF文の前とIF文の後に挿入します。 IF文スレッドの最大インデックスの前に

それは墜落前にしたIF文の内部で24479 スレッドの最大インデックス、それがクラッシュする前にされた:23487.

ので、上記の情報から、数スレッドが最大値まで上がらない。また、クラスタ上で別のエラーが表示されます:不正なメモリアクセスが発生しました。私は、このエラーは、それがインデックスの範囲を超えている可能性があることを意味しますが、私はスレッドの数で配列の等しいサイズを与えています。

cudaStatus = cudaSetDevice(0); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaSetDevice failed! Do you have a CUDA-capable GPU installed?"); 
    goto Error; 
} 

cout << "\n Allocated GPU buffers"; 
// Allocate GPU buffers for input and output vectors 
cudaStatus = cudaMalloc((void**)&dev_calcMatrix, data.sizeOfDistinctTerms * data.sizeOfDistinctClassarray * sizeof(float)); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMalloc failed!"); 
    goto Error; 
} 
cudaStatus = cudaMalloc((void**)&dev_probMatrix, data.sizeOfDistinctTerms * data.sizeOfDistinctClassarray * sizeof(float)); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMalloc failed!"); 
    goto Error; 
} 

cudaStatus = cudaMalloc((void**)&classSummationTerms, data.sizeOfDistinctClassarray * sizeof(int)); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMalloc failed!"); 
    goto Error; 
} 

cudaStatus = cudaMalloc((void**)&documentarray, data.sizeOfTotalTermsDocsFreq * sizeof(int)); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMalloc failed!"); 
    goto Error; 
} 

cudaStatus = cudaMalloc((void**)&documentTermArray, data.sizeOfTotalTermsDocsFreq * sizeof(int)); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMalloc failed!"); 
    goto Error; 
} 

cudaStatus = cudaMalloc((void**)&distincttermsarray, data.sizeOfDistinctTerms * sizeof(int)); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMalloc failed!"); 
    goto Error; 
} 

cudaStatus = cudaMalloc((void**)&distinctclassarray, data.sizeOfDistinctClassarray * sizeof(int)); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMalloc failed!"); 
    goto Error; 
} 

cudaStatus = cudaMalloc((void**)&startingPointOfClassDoc, data.sizeOfDistinctClassarray * sizeof(int)); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMalloc failed!"); 
    goto Error; 
} 

cudaStatus = cudaMalloc((void**)&endingPOintOfClassDoc, data.sizeOfDistinctClassarray * sizeof(int)); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMalloc failed!"); 
    goto Error; 
} 

cout << "\n Copied input vectors from host to GPU"; 
// Copy input vectors from host memory to GPU buffers. 
cudaStatus = cudaMemcpy(documentarray, data.documentarray, data.sizeOfTotalTermsDocsFreq * sizeof(int), cudaMemcpyHostToDevice); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMemcpy failed!"); 
    goto Error; 
} 

cudaStatus = cudaMemcpy(documentTermArray, data.documentTermArray, data.sizeOfTotalTermsDocsFreq * sizeof(int), cudaMemcpyHostToDevice); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMemcpy failed!"); 
    goto Error; 
} 

cudaStatus = cudaMemcpy(distincttermsarray, data.distincttermsarray, data.sizeOfDistinctTerms * sizeof(int), cudaMemcpyHostToDevice); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMemcpy failed!"); 
    goto Error; 
} 

cudaStatus = cudaMemcpy(classSummationTerms, data.classSummationTerms, data.sizeOfDistinctClassarray * sizeof(int), cudaMemcpyHostToDevice); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMemcpy failed!"); 
    goto Error; 
} 

cudaStatus = cudaMemcpy(distinctclassarray, data.distinctclassarray, data.sizeOfDistinctClassarray * sizeof(int), cudaMemcpyHostToDevice); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMemcpy failed!"); 
    goto Error; 
} 

cudaStatus = cudaMemcpy(startingPointOfClassDoc, data.startingPointOfClassDoc, data.sizeOfDistinctClassarray * sizeof(int), cudaMemcpyHostToDevice); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMemcpy failed!"); 
    goto Error; 
} 

cudaStatus = cudaMemcpy(endingPOintOfClassDoc, data.endingPOintOfClassDoc, data.sizeOfDistinctClassarray * sizeof(int), cudaMemcpyHostToDevice); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "cudaMemcpy failed!"); 
    goto Error; 
} 


cout << "\n Now we call the CALCKERNL()"; 
// Launch a kernel on the GPU with one thread for each element. 
calcKernel <<<dimGrid, dimBlock >>>(dev_calcMatrix, 
          documentarray, 
          documentTermArray, 
          distincttermsarray, 
          distinctclassarray, 
          startingPointOfClassDoc, 
          endingPOintOfClassDoc, 
          sizi, 
          sizeOfTerms); 

//// cudaDeviceSynchronize waits for the kernel to finish, and returns 
//// any errors encountered during the launch. 
//cudaStatus = cudaDeviceSynchronize(); 
//if (cudaStatus != cudaSuccess) { 
// fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus); 
// goto Error; 
//} 

cudaStatus = cudaStreamSynchronize(0); 
if (cudaStatus != cudaSuccess) { 
    //fprintf(stderr, "calcKernel launch failed: %s\n", cudaGetErrorString(cudaStatus)); 
    cout << "\n Synchronization failed: " << cudaGetErrorString(cudaStatus); 
    goto Error; 
} 
// Check for any errors launching the kernel 
cudaStatus = cudaGetLastError(); 
if (cudaStatus != cudaSuccess) { 
    fprintf(stderr, "calcKernel launch failed: %s\n", cudaGetErrorString(cudaStatus)); 
    goto Error; 
} 

なぜこれが起こっているすべてのアイデア:ここ

は、私はGPUにメモリを割り当てるコードはありますか?

+0

いいえ、23,652は問題ありませんでした。問題は、彼は23,653のスレッドを実行しているということです。 – tera

+0

あなたは[mcve]を製造するのに非常に苦労するつもりだと思います。 – user4581301

+0

スレッドの数はGPUで制限されていますか?この制限はGPUごとに異なりますか? – Ripi2

答えて

1

Minimal, Complete, and Verifiable exampleがないか、完全なコードであっても、答えることはできません。

int index = blockIdx.x * blockDim.x + threadIdx.x; 

    int term = distincttermsarray[index]; 

    if (index <= sizeOfTerms) { 

まず、配列のインデックスは、それが所望の範囲内にあるチェックする前に、安全でないとしてindexを使用して:しかし、すでにカーネルの始まりは、おそらく範囲外のメモリアクセスにつながる2つのバグがあります。第2に、sizeOfTermsが配列要素の数である場合、チェックはindex < sizeOfTerms<=でない)である必要があります。

+0

Wow私は実際にいくつかの間違いを犯しました:(私はあなたが私に言ったことを修正しましたが、私はまだ同じ問題があります:(私はVisual Studioできれいにしました。私はそれをコンパイルし、私が言及したクラスターで実行しましたが、同じ問題です:( – user3774470

+1

cuda-memcheckの下でコードを実行し、問題を指摘してください。 – tera

0

このエラーを見つけて、それが@teraで推薦して上CUDA-memcheckをオンにして、単一のヒットポイントwithiout クーダデバッガを使用してコードを実行することです解決する簡単な方法。 エラーが発生した瞬間にデバッガを停止する必要があります。

私の提案はです。TDRがオフのであるNsight + Visual Studioは、不正なエラーが発生するまでに時間がかかることはありません。

関連する問題