用户
 找回密码
 立即注册
发表于 2020-12-13 16:53:05
75520
刚买了rtx3090 ,程序从cuda10.x 升级到cuda11.x 发现以前正常运行的程序结果出现问题。
检查后发现是cuda11.x  cufft 函数库的问题。

现象: 在信号长度为特定长度的时候,创建的fft句柄第一次变换可以正常进行,用同一个句柄继续做fft变换,发现变换后的数据和变换前的值不变
这种bug只出现在特定的信号长度,对大部分信号长度都是正常的。注:cuda10.x 下没有此现象。
下面是测试代码。

请忽略数据的实际意义,主要验证fft句柄的问题:既对特定长度的信号只能变换一次,不能多次变换。cuda11.0 cuda11.1.1 都有此bug存在。

由于cufft是工作上经常用的,出现此问题,暂时无法在rtx3090 上用cuda11.x 开发程序。

软件环境:win10 64  vs2017
安装: cuda_11.1.1_456.81_win10.exe 工具包。 其它cuda版本均提前卸载。
驱动:456.81

显卡:rtx3090 (技嘉涡轮版, 微星 万图师)
先后在 几台 dell 工作站(单路,双路),组装机上,技嘉,微星的rtx3090都有此问题。

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <cufft.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

int createfftHandle(cufftHandle * handle, int signalNumbers, int signalLength, cufftType fftType = CUFFT_C2C);

int createfftHandle(cufftHandle * handle, int signalNumbers, int signalLength, cufftType fftType)
{

        const int rank = 1; // 1d fft
        int inembed[1] = { 0 };
        int onembed[1] = { 0 };

        int rowNfft = signalLength;  
        int rowNXWITH0 = 1;
        int rowNX = signalNumbers;  
        int rowNum[rank] = { rowNfft };
        int rowIstride = rowNXWITH0;
        int rowIdist = rowNfft;
        int rowOstride = rowNXWITH0;
        int rowOdist = rowNfft;
        int rowBatch = rowNX;
       
        cufftPlanMany(handle, rank, rowNum, inembed, rowIstride, rowIdist, onembed, rowOstride, rowOdist, fftType, rowBatch);

        if (*handle != 0)
                return 0;
        else
                return -2;

}
int main()
{
        cufftHandle fftHanle;
        cufftComplex *dev_dat,*hst_dat;
        int row;
        int col;
        row = 12;
        col= 6203;   //  6202也有问题; 6204正常。
        hst_dat = (cufftComplex *)malloc(sizeof(cufftComplex) * row * col);
        if (hst_dat == NULL)
                return -1;
        cudaMalloc(&dev_dat, row * col * sizeof(cufftComplex));
       
        if (dev_dat == NULL)
                return -1;
       
        if (createfftHandle(&fftHanle, row, col)!= 0)
                return  -2;
                       
        for (int i = 0; i < col; i++)
        {
                hst_dat.x = i+1;
                hst_dat.y = 2 * i+1;

        }


        cudaMemcpy(dev_dat, hst_dat, sizeof(cufftComplex) *row * col, cudaMemcpyHostToDevice);
                    
        //第一次
        cufftExecC2C(fftHanle, dev_dat, dev_dat, CUFFT_FORWARD);
       

        cudaMemcpy(hst_dat, dev_dat, sizeof(cufftComplex) *row * col, cudaMemcpyDeviceToHost);

        cufftComplex x0 = hst_dat[0];
        // 第二次       
         cufftExecC2C(fftHanle, dev_dat, dev_dat, CUFFT_FORWARD);

         cudaMemcpy(hst_dat, dev_dat, sizeof(cufftComplex) * row * col, cudaMemcpyDeviceToHost);
         
         if ( (x0.x == hst_dat[0].x) && (x0.y == hst_dat[0].y))  //结果没有变化,异常。
                 std::cout << "fft Err!" << std::endl;
         else
                 std::cout << "fft Ok!" << std::endl;              //结果变化,正常。


         cufftDestroy(fftHanle);
         system("pause");
    return 0;
}



使用道具 举报 回复
发新帖
您需要登录后才可以回帖 登录 | 立即注册