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