2010-06-30 15 views
1

Je rencontre des problèmes avec la construction de mon programme. Je travaille sur Windows 7 Professional 32 bits avec Visual Studio 2008. J'ai le Cuda SDK et mon projet est mis en place avec tous les liens vers cudart.lib etc. Mon problème est que lorsque j'essaie de construire mon projet, il renvoie les erreurs suivantes :Problème avec la construction du programme Cuda dans VS2008: LNK2019

1> crowdSim.obj: erreur LNK2019: symbole externe non résolu _setParameters référencé dans la fonction "protégées: __thiscall vide Crowd :: _ créer (int)"? (_create @ Crowd @ Z @@ IAEXH) 1> crowdSim.obj: erreur LNK2019: symbole externe non résolu _mapBuffer référencé dans la fonction "protégé: Crowd __thiscall vide :: _ créer (int)" (_create @ Crowd @@ IAEXH @ Z?) 1> crowdSim.obj: erreur LNK2019: symbole externe non résolu _allocToDevice référencé dans la fonction? "Protégé: __thiscall vide Crowd :: _ créer (int)" (_create @ @@ foule IAEXH @ Z) 1> crowdSim.obj: erreur LNK2019: symbole externe non résolu _registerBuffer référencé dans la fonction? "protégé: __thiscall vide Crowd :: _ créer (int)" (_create @ foule @@ @ IAEXH Z) 1> ../../ bin/win32/Debug/crowd.exe: LNK1120 erreur fatale: 4

non résolues externes

Il semble que mon problème est avec la façon dont je configure mes méthodes "allocToDevice", "mapBuffer", "setParameters", et "registerBuffer" puisque si je commente cela, je peux construire le projet sans problème.

J'ai défini les méthodes dans les fichiers suivants:

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" 

et ils ne sont appelés à partir de la méthode _create dans ma classe "Crowd" de 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); 

} 

J'ai l'impression qu'il me manque quelque chose de très basique mais je ne sais pas quoi faire pour que ça aide!

Répondre

1

Avez-vous ajouté le fichier cuda.rules pour permettre à Visual Studio de reconnaître l'extension .cu? Le cuda.rules enseigne VS quoi faire avec un .cu tel qu'il sera compilé et lié. Voir this post pour plus d'informations sur la configuration. En outre, si vous avez extern "C" dans la déclaration (prototype) d'une fonction dans le fichier d'en-tête, vous ne devriez pas en avoir besoin sur la définition (implémentation). Il peut garder votre code plus propre - en général, je n'utilise pas extern "C" du tout.

+0

Merci Tom pour votre réponse rapide. J'ai déjà suivi votre post pour mettre en place le projet en studio visuel, bien qu'il y ait quelques parties optionnelles que je n'ai pas pu trouver par exemple. Je n'ai pas pu voir C/C++ -> General dans les propriétés de mon projet pour ajouter les fichiers d'inclusion CUDA au chemin de recherche. J'ai inclus cuda.rules et la bibliothèque d'exécution ainsi je suis toujours bloqué. – sunburntfish

+0

Scratch la partie de ne pas trouver C/C++ -> Général. Apparemment c'est là. – sunburntfish

+0

Si vous avez uniquement des fichiers .cu dans votre projet, Visual Studio n'appelle pas directement le compilateur C/C++ (cl.exe), donc la catégorie C/C++ dans Propriétés du projet ne sera pas là. Ce n'est pas grave, car aucun des paramètres ici ne serait pertinent! Donc, si vous avez seulement des fichiers .cu, alors ignorez les paramètres C/C++. – Tom

0

J'ai récemment eu un problème avec l'appel de mes fonctions CUDA à partir de mon code C++. J'ai décidé d'utiliser extern et suivi quelques tutoriels en ligne. Après avoir lu votre code, il y a une chose que j'ai faite différemment. Au lieu de faire une inclusion du fichier cuda (crowdsim.cuh), j'ai renvoyé la fonction dans mon code C++.J'ai réécrit les déclarations externes dans mon fichier C++, et compilé le code, et cette fois cela a fonctionné.

Voici le tutoriel dont j'ai parlé. Espérons que cela aide

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

+0

Et sur la partie où vous ne pouviez pas trouver C/C++ ... qui m'est arrivé une fois quand j'avais un projet qui se composait uniquement de fichiers .cu. Je ne suis pas sûr mais c'est peut-être la raison. – Slartibartfast

+0

Voir mon commentaire sur l'autre réponse à propos de projets .cu seulement. – Tom

0

Cela est vrai bien sûr que si vous n'avez pas mélangé c/C++ et les fichiers Cuda, dans ce cas, le FPUNV peut genrate certains objets pour la liaison régulière et un code dans le GPU langage objet d'assemblage.