奇怪的LNK2005错误

xiao88yan 2016-01-25 10:33:29
先交代一下背景:
从网上下载的源代码,然后用CMAKE创建为VS2010项目,使用了CUDA、QT、ITK、boost等工具库

错误现象:
LNK2005错误,但和常见的LNK2005错误又有区别,现摘录其中一项如下:
2>TurbulenceUncertVisAnimated_generated_tileGenerator.cu.obj : error LNK2005: "private: void __thiscall NoiseTileGenerator::_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文件没有#pragma once或者#ifndef
排除,全部都有
2、h文件中的类定义和实现未分离,或者把实现写到了定义之外,但仍然在一个h文件中。
排除

我的分析:
1、此代码是别人正常编译过的(但不知是用的什么平台),应该不是代码本身的问题,我怀疑是否是项目在创建或转换时的一些配置出了问题。
2、从LNK2005重定义的错误来看,前后的OBJ文件竟然相同,会不会有重复链接的问题?但我不会查找错误根源。。。
3、从记录的编译过程看,有几个CU文件被重复编译多次,不知道是否正常?

求助:
希望有CMAKE和VS.net背景的大神根据以上情况给点建议或您的看法,不胜感激。如有必要,我可以贴出部分源代码和编译过程的输出内容
...全文
591 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
清理一下。重新编译呢?有时候重新编译就好了
xiao88yan 2016-01-25
  • 打赏
  • 举报
回复
在这里贴出部分源代码,CUH和CU文件都是CUDA的文件,采用扩展的C++语法: tileGenerator.cuh
#pragma once
#include <cudatemplates/array.hpp>

class TileGenerator {
public:
    typedef Cuda::Array3D<short> ArrayType;

    TileGenerator(Cuda::Size<3> tileSize) : _tile(tileSize) {}
    virtual ~TileGenerator() {}

    ArrayType& getTile()
    {
        return _tile;
    }

    virtual float getMaxDerivative() = 0;
    virtual float getStandardDeviation() = 0;
    virtual float getFrequency() = 0;


protected:
    Cuda::Array3D<short> _tile;
};

class NoiseTileGenerator : public TileGenerator {
public:
    NoiseTileGenerator(Cuda::Size<3> tileSize, float targetFrequency, int nGaborNoisePulses = 8)
        : TileGenerator(tileSize)
        , _frequency(targetFrequency)
    {
        _generateNoiseTile(targetFrequency, nGaborNoisePulses);
    }

    virtual float getMaxDerivative() { return _maxDerivative; }
    virtual float getStandardDeviation() { return _stdDev; }
    virtual float getFrequency() { return _frequency; }

private:
    void _generateNoiseTile(float targetFrequency, int nGaborNoisePulses);

    float _maxDerivative;
    float _stdDev;
    float _frequency;
};

class SinusoidTileGenerator : public TileGenerator {
public:
    SinusoidTileGenerator(Cuda::Size<3> tileSize, float targetFrequency)
        : TileGenerator(tileSize)
        , _frequency(targetFrequency)
    {
        _generateSinusoidTile(targetFrequency);
    }

    virtual float getMaxDerivative() { return _maxDerivative; }
    virtual float getStandardDeviation() { return _stdDev; }
    virtual float getFrequency() { return _frequency; }

private:
    void _generateSinusoidTile(float targetFrequency);

    float _maxDerivative;
    float _stdDev;
    float _frequency;
};
tilegenerator.cu
#include <tileGenerator.cuh>
#include <cudatemplates/devicememorylinear.hpp>
#include <cudatemplates/copy.hpp>

#include <gaborNoise.cuh>

namespace detail {
    
    class TileGenerateFunction {
    public:
        __device__ virtual short getValue(const float3& pos) = 0;
        __device__ void d_generateTile(Cuda::DeviceMemoryLinear3D<short>::KernelData out)
        {
            int x = blockIdx.x * blockDim.x + threadIdx.x;
            int y = blockIdx.y * blockDim.y + threadIdx.y;

            if (x >= out.size[0] || y >= out.size[1]) {
                return;
            }

            for (int z = 0; z < out.size[2]; ++z) {
                float3 pos = 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);
            }
        }
    };

    class NoiseTileGenerateFunction : public TileGenerateFunction {
    public:
        __device__ NoiseTileGenerateFunction(float r, float omegaLen, float a, int nPulses)
            : _noise(r, omegaLen, a, nPulses) {}

        __device__ virtual short getValue(const float3& pos)
        {
            return (short)((_noise.noise_evaluate(pos) / 20.f) * 32767);
        }

    private:
        GaborNoise::KernelData _noise;
    };

    class SinusoidTileGenerateFunction : public TileGenerateFunction {
    public:
        __device__ SinusoidTileGenerateFunction(float a)
            : _a(a) {}

        __device__ virtual short getValue(const float3& pos)
        {
            float x = 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__ void d_generateNoiseTile(Cuda::DeviceMemoryLinear3D<short>::KernelData out, float r, float omegaLen, float a, int nPulses)
    {
        NoiseTileGenerateFunction(r, omegaLen, a, nPulses).d_generateTile(out);
    }

    __global__ void d_generateSinusoidTile(Cuda::DeviceMemoryLinear3D<short>::KernelData out, float a)
    {
        SinusoidTileGenerateFunction(a).d_generateTile(out);
    }
}

void NoiseTileGenerator::_generateNoiseTile(float targetFrequency, int nGaborNoisePulses)
{
    float h_gridSize = 1.f / targetFrequency;
    float h_omegaLen = targetFrequency;

    // sqrt(-logf(0.05f) / pi) = 0.97650970247
    float h_a = 0.97650970247f / h_gridSize;

    const float derivFactor = nGaborNoisePulses; // Experimental
    float x = -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)); 

    dim3 blockSize(16, 16);
    dim3 gridSize((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);
}

void SinusoidTileGenerator::_generateSinusoidTile(float targetFrequency)
{
    // TODO
    float a = targetFrequency * pi; 
    _maxDerivative = a;
    _stdDev = 0.2;
    // ENDTODO

    dim3 blockSize(16, 16);
    dim3 gridSize((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);
}

7,540

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 VC.NET
社区管理员
  • VC.NET社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧