gpt4 book ai didi

c++ - cuFFT 的 NaN 问题

转载 作者:行者123 更新时间:2023-11-28 00:37:44 25 4
gpt4 key购买 nike

我正在使用 cuFFT 使用 C++ 和 Cuda 为学校作业编写频率过滤应用程序,但我无法让它工作。您可以找到完整的 Visual Studio 2010 解决方案 here . (需要 glut 。)

这是我认为相关的部分:(fourierUtils.cu/194)

//////////////////////////////////////////////////////////////////////////////
// Function to help invoking the kernel, creates the parameters and gets
// the result
__host__
void Process(
BitmapStruct& in_img, // these contain an image in an rgba byte array
BitmapStruct& out_img,
MaskGenerator maskGenerator, // this is a pointer to a device function
float param1, // mask parameters
float param2)
{
// Declare and allocate variables
cufftHandle plan;

cufftReal* img;
cufftReal* dev_img;
cufftComplex* dev_freq_img;

int imgsize = in_img.image_size();
int pixelcount = imgsize / 4;

img = new float[pixelcount];
checkResult(
cudaMalloc(&dev_img, sizeof(cufftReal) * pixelcount));
checkResult(
cudaMalloc(&dev_freq_img, sizeof(cufftComplex) * pixelcount));

// Optimize execution
cudaFuncAttributes attrs;
checkResult(
cudaFuncGetAttributes(&attrs, &Filter));
std::pair<dim3, dim3> params
= Optimizer::GetOptimalParameters(pixelcount, attrs);

// Process r, g, b channels
for(int chan = 0; chan <= 2; chan++)
{
// Init
for(int i = 0; i < pixelcount; i++)
{
img[i] = in_img.pixels[4 * i + chan];
}

checkResult(
cudaMemcpy(dev_img, img, pixelcount, cudaMemcpyHostToDevice));

// Create frequency image
checkResult(
cufftPlan1d(&plan, pixelcount, CUFFT_R2C, 1));
checkResult(
cufftExecR2C(plan, dev_img, dev_freq_img));
checkResult(
cudaThreadSynchronize());
checkResult(
cufftDestroy(plan));

// Mask frequency image
Filter<<<params.first, params.second>>>(
dev_freq_img, in_img.x, in_img.y, maskGenerator, param1, param2);
getLastCudaError("Filtering the image failed.");

// Get result
checkResult(
cufftPlan1d(&plan, pixelcount, CUFFT_C2R, 1));
checkResult(
cufftExecC2R(plan, dev_freq_img, dev_img));
checkResult(
cudaThreadSynchronize());
checkResult(
cufftDestroy(plan));
checkResult(
cudaMemcpy(img, dev_img, pixelcount, cudaMemcpyDeviceToHost));

for(int i = 0; i < pixelcount; i++)
{
out_img.pixels[4 * i + chan] = img[i];
}
}

// Copy alpha channel
for(int i = 0; i < pixelcount; i++)
{
out_img.pixels[4 * i + 3] = in_img.pixels[4 * i + 3];
}

// Free memory
checkResult(
cudaFree(dev_freq_img));
checkResult(
cudaFree(dev_img));
delete img;

getLastCudaError("An error occured during processing the image.");
}

与我见过的官方示例相比,我看不出任何实际差异,但是当我使用 Nsight 对其进行调试时,我的内核接收到的所有 cufftComplex 值都是 NaN,并且 input 之间的唯一区别是和 result图像是结果在底部有一个黑条,无论我使用哪个过滤掩码和什么参数。所有 Cuda 和 cuFFT 调用都返回成功,内核调用后也没有报错。

我做错了什么?

我试过用复杂的数组替换 img 和 dev_img 并使用 C2C 转换并就地进行它们,但它只改变了结果图像上黑条的大小。

感谢您的帮助。

编辑: here是一个不需要过剩的简化版本,也应该在 linux 上编译。

最佳答案

我没有编译和运行你的简化版本,但我认为问题出在 dev_img 的大小上。和 dev_freq_imag .

考虑 CUFFT 库用户指南第 4.2 节中的示例。它执行就地实数到复数的转换,这与您首先执行的步骤相同。

#define NX 256

cufftHandle plan;
cufftComplex *data;
cudaMalloc((void**)&data, sizeof(cufftComplex)*(NX/2+1)*BATCH);

cufftPlan1d(&plan, NX, CUFFT_R2C, BATCH);
cufftExecR2C(plan, (cufftReal*)data, data);

由于变换的对称性,cufftExecR2C仅填充 NX/2+1输出元素,其中 NX是输入数组的大小。

在您的情况下,您正在执行以下操作:

cufftHandle plan;

cufftReal* dev_img;
cufftComplex* dev_freq_img;

cudaMalloc(&dev_img, sizeof(cufftReal) * pixelcount);
cudaMalloc(&dev_freq_img, sizeof(cufftComplex) * pixelcount);

所以你正在分配一个 cufftReal数组和一个 cufftComplex相同大小的数组。当你使用

cufftPlan1d(&plan, pixelcount, CUFFT_R2C, 1);
cufftExecR2C(plan, dev_img, dev_freq_img);

然后只有一半dev_freq_imgcufftExecR2C 填充,其余部分包含垃圾。如果您使用 dev_freq_img 的完整范围在Filter __global__函数,那么这可能是你的 NaN 的原因秒。

关于c++ - cuFFT 的 NaN 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20265991/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com