问题:描述问题
在CUDA C++ 编程中,使用cufft.h中的cufftExecC2C,编译时,执行以下命令:
nvcc -arch=sm_61 -O2 .\main.cu -o main
出现报错:
tmpxft_000051d8_00000000-19_main.obj : error LNK2019: 无法解析的外部符号 cufftPlan1d,函数 "void __cdecl fftFun(int,struct float2 *,struct float2 *)" (?fftFun@@YAXHPEAUfloat2@@0@Z) 中引用了该符号
tmpxft_000051d8_00000000-19_main.obj : error LNK2019: 无法解析的外部符号 cufftExecC2C,函数 "void __cdecl fftFun(int,struct float2 *,struct float2 *)" (?fftFun@@YAXHPEAUfloat2@@0@Z) 中引用了该符号
tmpxft_000051d8_00000000-19_main.obj : error LNK2019: 无法解析的外部符号 cufftDestroy,函数 "void __cdecl fftFun(int,struct float2 *,struct float2 *)" (?fftFun@@YAXHPEAUfloat2@@0@Z) 中引用了该符号
main.exe : fatal error LNK1120: 3 个无法解析的外部命令
编写的代码为(我使用的是vscode进行编写):
#include <stdio.h>
#include <cufft.h>
#include "../common/common.h"
void fftFun(int n, cufftComplex *in, cufftComplex *out){
//傅里叶变换数据
//cufftComplex是单精度,如果要使用双精度要改为cufftDoubleComplex
cufftComplex *DataIn, *DataOut;
cudaMalloc((void**)&DataIn, sizeof(cufftComplex)*n);
cudaMalloc((void**)&DataOut, sizeof(cufftComplex)*n);
cufftHandle plan;
//双精度使用CUFFT_Z2Z
cufftPlan1d(&plan, n, CUFFT_C2C, 1);
//数据从CPU复制到GPU
cudaMemcpy(DataIn, in, n*sizeof(cufftComplex), cudaMemcpyHostToDevice);
// set time data
cudaEvent_t start, stop;
float elapsed_time;
CHECK(cudaEventCreate(&start));
CHECK(cudaEventCreate(&stop));
//傅里叶变换
//CUFFT_FORWORD正向FFT, CUFFT_INVERSE为逆向FFT
CHECK(cudaEventRecord(start));
cudaEventQuery(start);
cufftExecC2C(plan, DataIn, DataOut, CUFFT_FORWARD);
CHECK(cudaEventRecord(stop));
CHECK(cudaEventSynchronize(stop));
CHECK(cudaEventElapsedTime(&elapsed_time, start, stop));
printf("fftFun Time elapsed %g ms.\n", elapsed_time);
//数据从GPU复制到CPU
cudaMemcpy(out, DataOut, n*sizeof(cufftComplex), cudaMemcpyDeviceToHost);
//销毁GPU开辟的资源
cufftDestroy(plan);
cudaFree(DataIn);
cudaFree(DataOut);
return;
}
int main(){
//数据初始化
int n = 6 * 256 * 16384;
//cpu傅里叶变换数据分配内存
cufftComplex *in = (cufftComplex*)malloc(n * sizeof(cufftComplex));
cufftComplex *out = (cufftComplex*)malloc(n * sizeof(cufftComplex));
for(int i=0; i<n; i++){
in[i].x = 2.0;
in[i].y = 0;
}
fftFun(n, in, out);
// 输出傅里叶变换后的振幅,傅里叶变换左右对称所以只需要n/2个点
// for (int i = 0; i < n; i++) {
// printf("(%g)+(%g)j\n", out[i].x, out[i].y);
// }
return 0;
}
解决方法:
出现以上问题,主要原因为以下几点:
1.确保 CUFFT 头文件被包含:
在你的 main.cu 文件中,确保你已经包含了 CUFFT 的头文件,通常是 #include <cufft.h>
2.指定 CUFFT 库路径:
如果你的 CUDA 安装不是标准的,或者你有多个版本的 CUDA,你可能需要告诉编译器和链接器在哪里可以找到 CUFFT 库。你可以通过设置环境变量或直接在编译和链接命令中指定库路径来实现。
3.链接 CUFFT 库:
在你的 nvcc 命令中,需要添加 -lcufft 标志来告诉链接器链接到 CUFFT 库。此外,由于 CUFFT 依赖于 CUDA 运行时库,你通常也需要链接到 -lcudart。
4.使用正确的编译器和链接器选项:
确保你使用了与你的 CUDA 版本和硬件架构相匹配的编译器和链接器选项。例如,-arch=sm_61 是针对 Kepler 架构的 GPU 的,确保这与你的硬件相符。
分析结论:
根据以上分析,我的原因应该是第3个,由此重新编译:
nvcc -arch=sm_61 -O2 .\main.cu -o main -lcufft
果然,报错没有了!!