问题描述
先交代一下背景:从网上下载的源代码,然后用CMAKE创建为VS2010项目,使用了CUDA、QT、ITK、boost等工具库错误现象:LNK2005错误,但和常见的LNK2005错误又有区别,现摘录其中一项如下:2>TurbulenceUncertVisAnimated_generated_tileGenerator.cu.obj:errorLNK2005:"private:void__thiscallNoiseTileGenerator::_generateNoiseTile(float,int)"(?_generateNoiseTile@NoiseTileGenerator@@AAEXMH@Z)已经在TurbulenceUncertVisAnimated_generated_tileGenerator.cu.obj中定义错误说明:1、TurbulenceUncertVisAnimated_generated_tileGenerator.cu.obj,其中CU文件是CUDA文件,由CUDA编译器nvcc自动编译2、值得提出的是:普通的LNK2005一般前后的OBJ文件是不一样的,如B.obj中的某函数已经在A.obj中定义,但这个却是相同的。已查找过的原因和解决方案:1、h文件没有#pragmaonce或者#ifndef排除,全部都有2、h文件中的类定义和实现未分离,或者把实现写到了定义之外,但仍然在一个h文件中。排除我的分析:1、此代码是别人正常编译过的(但不知是用的什么平台),应该不是代码本身的问题,我怀疑是否是项目在创建或转换时的一些配置出了问题。2、从LNK2005重定义的错误来看,前后的OBJ文件竟然相同,会不会有重复链接的问题?但我不会查找错误根源。。。3、从记录的编译过程看,有几个CU文件被重复编译多次,不知道是否正常?求助:希望有CMAKE和VS.net背景的大神根据以上情况给点建议或您的看法,不胜感激。如有必要,我可以贴出部分源代码和编译过程的输出内容
解决方案
解决方案二:
在这里贴出部分源代码,CUH和CU文件都是CUDA的文件,采用扩展的C++语法:tileGenerator.cuh#pragmaonce#include<cudatemplates/array.hpp>classTileGenerator{public:typedefCuda::Array3D<short>ArrayType;TileGenerator(Cuda::Size<3>tileSize):_tile(tileSize){}virtual~TileGenerator(){}ArrayType&getTile(){return_tile;}virtualfloatgetMaxDerivative()=0;virtualfloatgetStandardDeviation()=0;virtualfloatgetFrequency()=0;protected:Cuda::Array3D<short>_tile;};classNoiseTileGenerator:publicTileGenerator{public:NoiseTileGenerator(Cuda::Size<3>tileSize,floattargetFrequency,intnGaborNoisePulses=8):TileGenerator(tileSize),_frequency(targetFrequency){_generateNoiseTile(targetFrequency,nGaborNoisePulses);}virtualfloatgetMaxDerivative(){return_maxDerivative;}virtualfloatgetStandardDeviation(){return_stdDev;}virtualfloatgetFrequency(){return_frequency;}private:void_generateNoiseTile(floattargetFrequency,intnGaborNoisePulses);float_maxDerivative;float_stdDev;float_frequency;};classSinusoidTileGenerator:publicTileGenerator{public:SinusoidTileGenerator(Cuda::Size<3>tileSize,floattargetFrequency):TileGenerator(tileSize),_frequency(targetFrequency){_generateSinusoidTile(targetFrequency);}virtualfloatgetMaxDerivative(){return_maxDerivative;}virtualfloatgetStandardDeviation(){return_stdDev;}virtualfloatgetFrequency(){return_frequency;}private:void_generateSinusoidTile(floattargetFrequency);float_maxDerivative;float_stdDev;float_frequency;};
tilegenerator.cu#include<tileGenerator.cuh>#include<cudatemplates/devicememorylinear.hpp>#include<cudatemplates/copy.hpp>#include<gaborNoise.cuh>namespacedetail{classTileGenerateFunction{public:__device__virtualshortgetValue(constfloat3&pos)=0;__device__voidd_generateTile(Cuda::DeviceMemoryLinear3D<short>::KernelDataout){intx=blockIdx.x*blockDim.x+threadIdx.x;inty=blockIdx.y*blockDim.y+threadIdx.y;if(x>=out.size[0]||y>=out.size[1]){return;}for(intz=0;z<out.size[2];++z){float3pos=make_float3(x/(float)out.size[0],y/(float)out.size[1],z/(float)out.size[2]);out.data[z*out.stride[1]+y*out.stride[0]+x]=getValue(pos);}}};classNoiseTileGenerateFunction:publicTileGenerateFunction{public:__device__NoiseTileGenerateFunction(floatr,floatomegaLen,floata,intnPulses):_noise(r,omegaLen,a,nPulses){}__device__virtualshortgetValue(constfloat3&pos){return(short)((_noise.noise_evaluate(pos)/20.f)*32767);}private:GaborNoise::KernelData_noise;};classSinusoidTileGenerateFunction:publicTileGenerateFunction{public:__device__SinusoidTileGenerateFunction(floata):_a(a){}__device__virtualshortgetValue(constfloat3&pos){floatx=sinf(_a*pos.x)*sinf(_a*pos.y)*sinf(_a*pos.z);x=x<0.f?-pow(fabsf(x),0.7f):pow(fabsf(x),0.7f);return(short)((x/20.f)*32767);}private:float_a;};__global__voidd_generateNoiseTile(Cuda::DeviceMemoryLinear3D<short>::KernelDataout,floatr,floatomegaLen,floata,intnPulses){NoiseTileGenerateFunction(r,omegaLen,a,nPulses).d_generateTile(out);}__global__voidd_generateSinusoidTile(Cuda::DeviceMemoryLinear3D<short>::KernelDataout,floata){SinusoidTileGenerateFunction(a).d_generateTile(out);}}voidNoiseTileGenerator::_generateNoiseTile(floattargetFrequency,intnGaborNoisePulses){floath_gridSize=1.f/targetFrequency;floath_omegaLen=targetFrequency;//sqrt(-logf(0.05f)/pi)=0.97650970247floath_a=0.97650970247f/h_gridSize;constfloatderivFactor=nGaborNoisePulses;//Experimentalfloatx=-h_omegaLen/(2*h_a)+sqrtf(h_omegaLen*h_omegaLen/(4*h_a*h_a)+1/(2*pi*h_a));_maxDerivative=nGaborNoisePulses*2*pi*exp(-pi*h_a*x*x)*(h_omegaLen+h_a*x)/derivFactor;_stdDev=nGaborNoisePulses/(4*sqrtf(2.f)*powf(sqrtf(-logf(0.05f)/pi),3));dim3blockSize(16,16);dim3gridSize((int)ceilf((float)_tile.size[0]/blockSize.x),(int)ceilf((float)_tile.size[1]/blockSize.y));Cuda::DeviceMemoryLinear3D<short>tileMemory(_tile.size);detail::d_generateNoiseTile<<<gridSize,blockSize>>>(tileMemory,h_gridSize,h_omegaLen,h_a,nGaborNoisePulses);//d_generateNoiseTile<<<gridSize,blockSize>>>(tileMemory,h_gridSize,h_omegaLen,h_a,nGaborNoisePulses);Cuda::copy(_tile,tileMemory);}voidSinusoidTileGenerator::_generateSinusoidTile(floattargetFrequency){//TODOfloata=targetFrequency*pi;_maxDerivative=a;_stdDev=0.2;//ENDTODOdim3blockSize(16,16);dim3gridSize((int)ceilf((float)_tile.size[0]/blockSize.x),(int)ceilf((float)_tile.size[1]/blockSize.y));Cuda::DeviceMemoryLinear3D<short>tileMemory(_tile.size);detail::d_generateSinusoidTile<<<gridSize,blockSize>>>(tileMemory,a);//d_generateSinusoidTile<<<gridSize,blockSize>>>(tileMemory,a);Cuda::copy(_tile,tileMemory);}
解决方案三:
清理一下。重新编译呢?有时候重新编译就好了