views:

221

answers:

3

Hi, I am having some trouble with building my programme. I am working on Windows 7 professional 32-bit with Visual Studio 2008. I have the Cuda SDK and my project is set up with all links to cudart.lib etc. My problem is when I try to build my project it returns the following errors:

1>crowdSim.obj : error LNK2019: unresolved external symbol _setParameters referenced in function "protected: void __thiscall Crowd::_create(int)" (?_create@Crowd@@IAEXH@Z) 1>crowdSim.obj : error LNK2019: unresolved external symbol _mapBuffer referenced in function "protected: void __thiscall Crowd::_create(int)" (?_create@Crowd@@IAEXH@Z) 1>crowdSim.obj : error LNK2019: unresolved external symbol _allocToDevice referenced in function "protected: void __thiscall Crowd::_create(int)" (?_create@Crowd@@IAEXH@Z) 1>crowdSim.obj : error LNK2019: unresolved external symbol _registerBuffer referenced in function "protected: void __thiscall Crowd::_create(int)" (?_create@Crowd@@IAEXH@Z) 1>../../bin/win32/Debug/crowd.exe : fatal error LNK1120: 4 unresolved externals

It seems my problem is with how I am setting up my "allocToDevice", "mapBuffer", "setParameters", and "registerBuffer" methods since if I comment these out I can build the project no problem.

I have defined the methods in the following files:

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"

and they are only called from the _create method in my "Crowd" class from 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);

}

I feel like I am missing something very basic here but I can't work out what so any help would be great!

A: 

Have you added the cuda.rules file to enable Visual Studio to recognise the .cu extension? The cuda.rules teaches VS what to do with a .cu such that it will be compiled and linked. See this post for more information on setting it up.

As an aside, if you have extern "C" in the declaration (prototype) of a function in the header file then you shouldn't need it on the definition (implementation). It may keep your code tidier - in general I don't use extern "C" at all.

Tom
Thank you Tom for your quick reply. I have already followed your post to set up the project in visual studio though there were some of the optional parts that I could not find e.g. I was unable to see C/C++ -> General in my project's properties to add the CUDA include files to the search path. I have included cuda.rules and the runtime library so I am still stuck.
sunburntfish
Scratch the part about not finding C/C++ -> General. Apparently it is there.
sunburntfish
If you only have .cu files in your project then Visual Studio will not invoke the C/C++ compiler (cl.exe) directly so the C/C++ category in Project Properties won't be there. That's ok though, since none of the settings in there would be relevant! So if you only have .cu files, then ignore the C/C++ settings.
Tom
A: 

Hi, I recently had a problem with calling my CUDA functions from my C++ code. I decided to use extern and followed some tutorials online.

After reading your code, there is one thing I did differently. Instead of doing an include of the cuda file (crowdsim.cuh) I forward declared the function in my C++ code. I rewrote the extern declarations in my C++ file, and compiled the code, and this time it worked.

Here's the tutorial I referred. Hope it helps

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

Slartibartfast
And about the part where you couldn't find C/C++... that happened to me once when i had a project that consisted of only .cu files. I'm not sure but that maybe the reason.
Slartibartfast
See my comment on the other answer about .cu only projects.
Tom
A: 

This is true of course only if you don't have mixed c/c++ and Cuda files, in this case the NVCC can genrate some objects for regular linkage and some code in the GPU assembly object language.

Veltz