我目前正在開發一個涉及CUDA的更全面的項目。在最近幾天裏,我一直在遇到錯誤,我一直在拼命地嘗試bug修復。但是,我無法弄清楚,所以現在我構成了一個最小的例子,它顯示了相同的行爲。我不得不說我對CUDA很陌生。我正在使用Visual Studio 2015和CUDA Toolkit 7.5。C++:簡單的CUDA卷重構代碼崩潰
該程序涉及在GPU內存上創建3D卷,然後計算值並將其寫入卷。我試圖使代碼儘可能簡單:
首先IST的main.cpp
文件:
#include "cuda_test.h"
int main() {
size_t const xDimension = 500;
size_t const yDimension = 500;
size_t const zDimension = 1000;
//allocate volume part memory on gpu
cudaPitchedPtr volume = ct::cuda::create3dVolumeOnGPU(xDimension, yDimension, zDimension);
//start reconstruction
ct::cuda::startReconstruction(volume,
xDimension,
yDimension,
zDimension);
return 0;
}
然後cuda_test.h
這是實際.CU文件頭文件:
#ifndef CT_CUDA
#define CT_CUDA
#include <cstdlib>
#include <stdio.h>
#include <cmath>
//CUDA
#include <cuda_runtime.h>
namespace ct {
namespace cuda {
cudaPitchedPtr create3dVolumeOnGPU(size_t xSize, size_t ySize, size_t zSize);
void startReconstruction(cudaPitchedPtr volume,
size_t xSize,
size_t ySize,
size_t zSize);
}
}
#endif
包含行爲
然後是cuda_test.cu
文件UAL功能實現:
#include "cuda_test.h"
namespace ct {
namespace cuda {
cudaPitchedPtr create3dVolumeOnGPU(size_t xSize, size_t ySize, size_t zSize) {
cudaExtent extent = make_cudaExtent(xSize * sizeof(float), ySize, zSize);
cudaPitchedPtr ptr;
cudaMalloc3D(&ptr, extent);
printf("malloc3D: %s\n", cudaGetErrorString(cudaGetLastError()));
cudaMemset3D(ptr, 0, extent);
printf("memset: %s\n", cudaGetErrorString(cudaGetLastError()));
return ptr;
}
__device__ void addToVolumeElement(cudaPitchedPtr volumePtr, size_t ySize, size_t xCoord, size_t yCoord, size_t zCoord, float value) {
char* devicePtr = (char*)(volumePtr.ptr);
//z * xSize * ySize + y * xSize + x
size_t pitch = volumePtr.pitch;
size_t slicePitch = pitch * ySize;
char* slice = devicePtr + zCoord*slicePitch;
float* row = (float*)(slice + yCoord * pitch);
row[xCoord] += value;
}
__global__ void reconstructionKernel(cudaPitchedPtr volumePtr, size_t xSize, size_t ySize, size_t zSize) {
size_t xIndex = blockIdx.x;
size_t yIndex = blockIdx.y;
size_t zIndex = blockIdx.z;
if (xIndex == 0 && yIndex == 0 && zIndex == 0) {
printf("kernel start\n");
}
//just make sure we're inside the volume bounds
if (xIndex < xSize && yIndex < ySize && zIndex < zSize) {
//float value = z;
float value = sqrt(sqrt(sqrt(5.3))) * sqrt(sqrt(sqrt(1.2))) * sqrt(sqrt(sqrt(10.8))) + 501 * 0.125 * 0.786/5.3;
addToVolumeElement(volumePtr, ySize, xIndex, yIndex, zIndex, value);
}
if (xIndex == 0 && yIndex == 0 && zIndex == 0) {
printf("kernel end\n");
}
}
void startReconstruction(cudaPitchedPtr volumePtr, size_t xSize, size_t ySize, size_t zSize) {
dim3 blocks(xSize, ySize, zSize);
reconstructionKernel <<< blocks, 1 >>>(volumePtr,
xSize,
ySize,
zSize);
printf("Kernel launch: %s\n", cudaGetErrorString(cudaGetLastError()));
cudaDeviceSynchronize();
printf("Device synchronise: %s\n", cudaGetErrorString(cudaGetLastError()));
}
}
}
功能create3dVolumeOnGPU
分配在GPU存儲器3維「音量」,並返回一個指向它的指針。這是一個主機功能。第二個主機功能是startReconstruction
。它所做的唯一的事情就是啓動實際的內核,使用與卷中的體素一樣多的塊。內核函數是reconstructionKernel
。它只是計算一些常數中的任意值,然後調用addToVolumeElement
(設備函數)將結果寫入相應的體素(添加它)。
現在,問題是它崩潰了。如果我和調試器(NSight)推出,NSight中斷給錯誤消息:
CUDA grid launch failed: CUcontext: 2358451327088 CUmodule: 2358541519888 Function: _ZN2ct4cuda20reconstructionKernelE14cudaPitchedPtryyy
控制檯輸出:
malloc3D: no error
memset: no error
kernel started
kernel end
如果我在釋放模式啓動整個機器復位。
但是,如果我改變體積的尺寸要小一些它的作品,例如:
size_t const xDimension = 100;
size_t const yDimension = 100;
size_t const zDimension = 100;
然而,自由GPU內存的數量不應該是問題(卡有4GB VRAM)。
這將是很好,如果有人可以看看它,也許給我一個小費可能會導致問題。現在
好吧,因爲它似乎是一個問題,我只使用塊,每塊只有1個線程。但爲什麼? – user1488118
您可能會遇到[WDDM TDR問題](http://http.developer.nvidia.com/NsightVisualStudio/2.2/Documentation/UserGuide/HTML/Content/Timeout_Detection_Recovery.htm)。 –
好吧,我得看看這個。因爲看起來我的問題已經通過每塊使用多個線程來解決。 – user1488118