cuda11.x cufft bug 报告 (rtx 3090 )

刚买了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

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[i].x = i+1;
	hst_dat[i].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;
}