卡夫特的问题 我用Cufft编写了C++和CUDA中的一个学校作业的频率过滤应用程序,我不能让它工作。您可以找到整个VisualStudio2010解决方案。(需要)

卡夫特的问题 我用Cufft编写了C++和CUDA中的一个学校作业的频率过滤应用程序,我不能让它工作。您可以找到整个VisualStudio2010解决方案。(需要),c++,cuda,fft,cufft,C++,Cuda,Fft,Cufft,以下是我认为相关的部分:(fourierUtils.cu/194) ////////////////////////////////////////////////////////////////////////////// //函数来帮助调用内核,创建参数并获取 //结果 __主人__ 空洞过程( BitmapStruct&in_img,//它们包含rgba字节数组中的图像 BitmapStruct和out\u img, MaskGenerator MaskGenerator,//这是指向设备

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

//////////////////////////////////////////////////////////////////////////////
//函数来帮助调用内核,创建参数并获取
//结果
__主人__
空洞过程(
BitmapStruct&in_img,//它们包含rgba字节数组中的图像
BitmapStruct和out\u img,
MaskGenerator MaskGenerator,//这是指向设备函数的指针
float param1,//掩码参数
浮动参数(2)
{    
//声明和分配变量
卡夫坦德尔计划;
cufftReal*img;
cufftReal*开发人员;
袖口复合体*dev_freq_img;
int imgsize=in_img.image_size();
int pixelcount=imgsize/4;
img=新浮点[像素计数];
检查结果(
Cudamaloc(&dev_img,sizeof(袖带)*像素计数);
检查结果(
Cudamaloc(&dev_freq_img,sizeof(袖套复合体)*像素计数);
//优化执行
cudafuncs;
检查结果(
cudaFuncGetAttributes(&attrs,&Filter));
std::pair参数
=优化器::获取最佳参数(像素计数、属性);
//过程r、g、b通道

对于(int chan=0;chan我还没有编译并运行您的简化版本,但我认为问题在于
dev\u img
dev\u freq\u imag
的大小

考虑《CUFFT Library用户指南》第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);
由于变换的对称特性,
nciptexecr2c
仅填充
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\u freq\u img
cufftExecR2C
填充,剩下的部分包含垃圾。如果你在
过滤器
中使用
dev\u freq\u img
的全部
dev\u freq\u img
函数,那么这可能就是你的
NaN
s的原因。

我还没有编译并运行你的代码减少了版本,但我认为问题在于
dev\u img
dev\u freq\u imag
的大小

考虑《CUFFT Library用户指南》第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);
由于变换的对称特性,
nciptexecr2c
仅填充
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\u freq\u img
cufftExecR2C
填充,剩下的部分包含垃圾。如果你在
过滤器
中使用
dev\u freq\u img
的全部
dev\u freq\u img
函数,那么这可能就是你的
NaN
s的原因。

我还没有编译并运行你的代码减少了版本,但我认为问题在于
dev\u img
dev\u freq\u imag
的大小

考虑《CUFFT Library用户指南》第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);
由于变换的对称特性,
nciptexecr2c
仅填充
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\u freq\u img
cufftExecR2C
填充,剩下的部分包含垃圾。如果你在
过滤器
中使用
dev\u freq\u img
的全部
dev\u freq\u img
函数,那么这可能就是你的
NaN
s的原因。

我还没有编译并运行你的代码减少了版本,但我认为问题在于
dev\u img
dev\u freq\u imag
的大小

考虑《CUFFT Library用户指南》第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);
由于变换的对称特性,
nciptexecr2c
仅填充
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\u freq\u img
cufftExecR2C
填充,剩下的部分包含垃圾。如果你在
过滤器
\u全局
函数中使用了
dev\u freq\u img
的全部
,那么这可能就是你的
NaN
的原因。

我的错误是忘记了在一些
cudaMemcpy
调用中,根据项目的大小对项目的数量进行叠加,因此馈送到cuFFT的向量的末端由NaN组成。修复这些问题解决了问题

我还将cufftReal数组替换为cufftComplex数组,因为C2C转换似乎更可预测,并且增加了值的规范化

因此,最终的工作方法是:

///////////////////////////////////////////////////////////////////////////////
// Function to help invoking the kernel, creates the parameters and gets 
// the result
__host__
void Process(
        BitmapStruct& in_img, 
        BitmapStruct& out_img, 
        MaskGenerator maskGenerator, 
        float param1, 
        float param2)
{    
    // Declare and allocate variables
    cufftHandle plan;

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

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

    img = new cufftComplex[pixelcount];
    checkResult(
        cudaMalloc(&dev_img, sizeof(cufftComplex) * 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].x = in_img.pixels[4 * i + chan];
            img[i].y = 0;
        }

        checkResult(
            cudaMemcpy(
                dev_img, 
                img, 
                pixelcount * sizeof(cufftComplex), 
                cudaMemcpyHostToDevice));

        // Create frequency image
        checkResult(
            cufftPlan1d(&plan, pixelcount, CUFFT_C2C, 1));
        checkResult(
            cufftExecC2C(plan, dev_img, dev_freq_img, CUFFT_FORWARD));
        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_C2C, 1));
        checkResult(
            cufftExecC2C(plan, dev_freq_img, dev_img, CUFFT_INVERSE));
        checkResult(
            cudaThreadSynchronize());
        checkResult(
            cufftDestroy(plan));
        checkResult(
            cudaMemcpy(
                img, 
                dev_img, 
                pixelcount * sizeof(cufftComplex), 
                cudaMemcpyDeviceToHost));

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

    // 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.");
}
///////////////////////////////////////////////////////////////////////////////
//函数来帮助调用内核