Проблемы со сборкой программы Cuda в VS2008: LNK2019 - PullRequest
2 голосов
/ 30 июня 2010

У меня проблемы с созданием моей программы.Я работаю на 32-битной Windows 7 Professional с Visual Studio 2008. У меня есть Cuda SDK, и мой проект настроен со всеми ссылками на cudart.lib и т. Д. Моя проблема в том, что когда я пытаюсь построить свой проект, он возвращает следующие ошибки:

1> crowdSim.obj: ошибка LNK2019: неразрешенный внешний символ _setParameters, указанный в функции «protected: void __thiscall Crowd :: _ create (int)" (? _Create @ Crowd @@ IAEXH @ Z)1> crowdSim.obj: ошибка LNK2019: неразрешенный внешний символ _mapBuffer, на который ссылается функция "protected: void __thiscall Crowd :: _ create (int)" (? _Create @ Crowd @@ IAEXH @ Z) 1> crowdSim.obj: ошибка LNK2019: не разрешенавнешний символ _allocToDevice, на который ссылается функция «protected: void __thiscall Crowd :: _ create (int)» (? _create @ Crowd @@ IAEXH @ Z) 1> crowdSim.obj: ошибка LNK2019: неразрешенный внешний символ _registerBuffer, на который есть ссылка в функции "protected: void__thiscall Crowd :: _ create (int) "(? _create @ Crowd @@ IAEXH @ Z) 1> ../../ bin / win32 / Debug / crowd.exe: фатальная ошибка LNK1120: 4 не удалось разрешитьd externals

Кажется, моя проблема в том, как я настраиваю свои методы "allocToDevice", "mapBuffer", "setParameters" и "registerBuffer", поскольку, если я закомментирую их, я смогу построитьпроект не проблема.

Я определил методы в следующих файлах:

crowdSim.cuh:

    extern "C"
{
    void checkCUDAError(const char *msg);

    void setParameters(SimParams *hostParams);

    void registerBuffer(uint vbo);

    void allocToDevice(void **ptr, int memSize);

    void mapBuffer(void **ptr, uint vbo);
}

crowdSim.cu:

#include <cstdlib.h>
#include <cstdio.h>
#include <string.h>

#include <cuda_gl_interop.h>

// includes, kernels
#include "crowd_kernel.cu"

extern "C"
{
void checkCUDAError(const char *msg)
{
    cudaError_t err = cudaGetLastError();
    if( cudaSuccess != err) 
    {
        fprintf(stderr, "Cuda error: %s: %s.\n", msg, cudaGetErrorString( err) );
        exit(-1);
    }                         
}

void setParameters(SimParams *hostParams)
{
    // copy parameters to constant memory
    cudaMemcpyToSymbol(params, hostParams, sizeof(SimParams));
}

void registerBuffer(uint vbo)
{
    cudaGLRegisterBufferObject(vbo);
}



void allocToDevice(void **ptr, size_t memSize)
{
    cudaMalloc(ptr, memSize);
}

void mapBuffer(void **ptr, uint vbo)
{
    cudaGLMapBufferObject(ptr, vbo);
}
} //extern "C"

и они вызываются только из метода _create в моем классе "Crowd" из crowdSim.cpp:

#include <math.h>
#include <memory.h>
#include <cstdio>
#include <cstdlib>
#include <GL/glew.h>

#include "crowdSim.h"
#include "crowdSim.cuh"
#include "crowd_kernel.cuh"

Crowd::Crowd(uint crowdSize) :
    //numP(crowdSize),
    hPos(0),
    hVel(0),
    dPosIn(0),
    dVelIn(0),
    dPosOut(0),
    dVelOut(0)
    {
        params.numBodies = crowdSize;
        _create(crowdSize);
    }

Crowd::~Crowd()
    {
        //_remove();
        crowdSize = 0;
    }

uint
Crowd::newVBO(uint size)
{
    GLuint vbo;
 //   glGenBuffers(1, &vbo);
 //   glBindBuffer(GL_ARRAY_BUFFER, vbo);
 //   glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);
 //   glBindBuffer(GL_ARRAY_BUFFER, 0);
    return vbo;
}

void
Crowd::_create(int numPeople)
{
    crowdSize = numPeople;

    unsigned int memSize = sizeof(float) * crowdSize * 4;

    hPos = new float[crowdSize*4];
    hVel = new float[crowdSize*4];

    hPos = (float*) malloc(memSize);
    hVel = (float*) malloc(memSize);

    posVbo = newVBO(memSize);

    registerBuffer(posVbo);

    allocToDevice((void**) &dPosIn, memSize);
    allocToDevice((void**) &dPosOut, memSize);
    allocToDevice((void**) &dVelIn, memSize);
    allocToDevice((void**) &dVelOut, memSize);

    mapBuffer((void**)&dPosVbo, posVbo);

    setParameters(&params);

}

Мне кажется, что я здесь упускаю что-то очень простое, но не могу понять, что таклюбая помощь будет отличной!

Ответы [ 3 ]

2 голосов
/ 01 июля 2010

Вы добавили файл cuda.rules, чтобы Visual Studio могла распознавать расширение .cu?Cuda.rules учит VS, что делать с .cu таким образом, что он будет компилироваться и связываться.См. этот пост для получения дополнительной информации о его настройке.

Кроме того, если у вас есть extern "C" в объявлении (прототипе) функции в заголовочном файле, то вам не следуетЭто нужно для определения (реализации).Это может сделать ваш код более аккуратным - обычно я вообще не использую extern "C".

1 голос
/ 02 июля 2010

У меня недавно была проблема с вызовом моих функций CUDA из моего кода C ++.Я решил использовать extern и следовал некоторым учебникам онлайн.

После прочтения вашего кода, я кое-что сделал по-другому.Вместо включения файла cuda (crowdsim.cuh) я перешел к объявлению функции в моем коде C ++.Я переписал объявления extern в своем файле C ++ и скомпилировал код, и на этот раз он работал.

Вот учебник, на который я ссылался.Надеюсь, это поможет

http://codereflect.com/2008/09/29/how-to-call-cuda-programs-from-a-cc-application/

0 голосов
/ 05 июля 2010

Это верно, конечно, только если у вас нет смешанных файлов c / c ++ и Cuda, в этом случае NVCC может генерировать некоторые объекты для регулярного связывания и некоторый код на языке объектов ассемблера GPU.

...