私は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にメモリを割り当てるコードはありますか?
いいえ、23,652は問題ありませんでした。問題は、彼は23,653のスレッドを実行しているということです。 – tera
あなたは[mcve]を製造するのに非常に苦労するつもりだと思います。 – user4581301
スレッドの数はGPUで制限されていますか?この制限はGPUごとに異なりますか? – Ripi2