How to integrate CUDA into existing Visual Studio project - The "right" way?

What is the recommended way to integrate CUDA into an existing Visual Studio (2008) C++ project?

There seem to be two ways of using CUDA in a Visual Studio project:

  1. Based on the “template” project from the CUDA SDK: for each .cu file, set a custom build step, and call nvcc from the Command Line.

  2. Based on other projects from the CUDA SDK: Import the Cuda.rules file into the project and the project’s .cu files will be built based on these rules.

We have successfully created projects from scratch using either method. An advantage to method 1 seems that one could have greater control over nvcc and the environment in general. An advantage to method 2 seems that settings won’t have to be done on a per .cu file basis, simplifying the project setup.

What are other advantages/disadvantages of these 2 methods?

Why does the “template” project of the CUDA SDK use a Command Line Custom Build Step when all of the other SDK examples [that I have examined] seem to use the .rules file?

If we integrate CUDA into an existing project, which method is recommended? Which method is generally considered the “right” way in this case?

I’m also looking for guidance with this topic. If I have a large existing framework and I want to outsource specific functions to a GPU what’s the best/simplest/most reliable way to do this?

Any progress on this topic? I’d like to know how to do this as well. I can’t even get started, the documentation is so sparse…

These forums are so unhelpful aren’t they?

And not only is the documentation sparse, it’s often completely wrong. What’s worse, some examples from the cuda programming guide don’t even compile!

In the last several months of experience I have determined that you should use method #1 mentioned in my OP.

Both methods are valid. There’s a third one.

Integrating CUDA in a project is easy enough, the only real crux is having CUDA C compiled by nvcc and not by whichever compiler you have in the framework. That usually requires a custom build step. An easier way: download and install http://sourceforge.net/projects/cudavswizard/ , it will add a CUDA build rule and integrate with Visual Studio. Now you can Add a new Item and name a file any way you want with a .cu extension (like cudaFunctions.cu), the extension will be automatically recognized and the CUDA build rule will be applied. Check this item’s properties, it will be compiled with nvcc.

Now have all your CUDA code (kernels and host code that launches the kernels) in .cu files and you can create wrappers around them so that they work in C/C++. You can even have:

//cudaWorker.h, framework friendly C++ with no notion of CUDA/nvcc etc.

class CudaWorker 

{

public:

   void doCuda(std::vector<float> hostData);

}
//cudaWorker.cu

#include "cudaWorker.h"

__global__ void kernel1(float deviceData[])

{

...

}

void CudaWorker::doCuda(std::vector<float> hostData)

{

//unpack the vector into an array

//use CUDA functions to to memcpy data and to launch a kernel

kernel1<<<64,64>>>(deviceData); //launching kernel legal, it's a .cu file

}

Or you could compile this .cu implementation to a library (there’s an option in CUDA build rules) so people without nvcc can still compile the framework or can switch it over for a CPU only lib. Just remember to sort out /MT vs /MTD.

Wow Big_Mac that’s great, thanks.

I’ve been using a bunch of extern functions in my .cu for calling kernels, and calling those functions from a C++ class.
But now I see that I can just put the implementation of some C++ class functions straight into the .cu!
Thanks again!

Yeah props to BigMac…

I’ll have a closer look at your suggestion tomorrow. The VS Wizard seems to work pretty well, that got me going. I’ve been banging my head against a brick wall all day with all sorts of other stupid problems.

To the more negative posters in this thread, I don’t believe it’s a problem with CUDA or the CUDA documentation. I’ve been using CUDA successfully for a year now and both the documentation and the forums are very helpful if you have problems with CUDA. What we talking about here are problems with VS which is such a bloated, unwieldy, illogical, pain-in-the-arse system to work with it drives me to despair.

Right now my problems are:

-Despite compiling and running correctly previously, the linker now says “warning: kernel_name declared but never referenced”… The code is unchanged…

-Kernels appear to run, but don’t do anything!

-Only Debug mode works. Release, EmuDebug and EmuRelease stopped working and now generate strings of both compiler and linker errors…

If anybody has any suggestions I’d be very glad to hear them. When I have some tips ‘n’ tricks of my own I’ll stop back and post them… For now all I can say is VS for Windows developers and something else for everybody else 

Same problem here. Damn, spent a lot of time changing to the c++ style, hope I don’t have to go back to how it was before…

Hope you have some advice timmiroon!

Edit 1 - My kernels run, and function in Debug mode. Also, I don’t get your funny linker error about the kernel declared but never referenced.

Edit 2 - Foolish mistake: The .cu file was not being compiled in Release mode. No problems with unresolved externals there now.

Ok, some partial solutions which work for me. Maybe this’ll be helpful for someone else…

  1. Somehow I ended up with two CUDA custom build rules installed. They might be the same. Either way, if I only use the one found in the actual CUDA SDK and not the one in the VS install directory things work a bit better.

Now I have both Debug and Release working for some, but not all, projects. Emu release and debug still don’t work ‘out-of-the-box’ but you can set it in properties->CUDA build-rule->general…

  1. This might be specific to my set-up but I’ve found that rebuilding a CUDA project doesn’t rebuild it. For me to see changes in behavior from changes in code I must ‘clean’ and then rebuild each time. Took a while to figure that one out…

Hi,

I just wanna bump this thread to see if someone knows tell how to successfully get EmuDebug running in an integrated project ?

I’m sure it’s just a few clicks away :)

Thanks
Jimmy

Hi all,

just tried the VS Wizard using Visual Studio 2008 Express edition and CUDA2.3 under WinXP 32. The “Hello World” does not build
due to “Cutil64D.lib” missing and I cannot find it anywhere on the computer. Is this Wizard only for 64Bit? Is there something similar for WinXP 32 Bit?

Many thanks!

Hmm the wizard worked fine for me running on win xp 32 bit. I don’t think you have a wizard problem…

Are you sure you’ve installed the 32 bit cuda drivers and and not the 64 bit ones? Im guessing this is your problem.

Normally after just running the wizard you will be asked for the cutil32d.dll , which should be present.

There’s a known bug with SDK include and lib paths being wrong for cuda 2.3 (they’ve changed the directory structure). To fix it, open Properties → CUDA → General and make sure your “Additional Include directories” have $(NVSDKCOMPUTE_ROOT)\C\common\inc instead of $(NVSDKCUDA_ROOT)\common\inc

Then go to Properties → Linker → General and make sure your “Additional Library Directories” have $(NVSDKCOMPUTE_ROOT)\C\common\lib instead of $(NVSDKCUDA_ROOT)\common\lib

This should be fixed in the next release of the Wizard.

You might be using the wrong wizard. There are two versions, 32 and 64 bit. The link on the project’s main page leads to the 64 bit version, you can get the 32 bit one here [url=“Download CUDA VS Wizard from SourceForge.net”]http://sourceforge.net/projects/cudavswiza....0.zip/download[/url]. The fix with include and lib directories applies to both.

Hopefully a future version of the wizard will work for both 32 and 64 bits and for cuda versions <2.3 and 2.3+.

Many thanks, Big_Mac, this did the trick!

Hi,

I tried integrating my cuda code with an existing c++ project today. After a bit of work i got the integrated program running.

Later i did the mistake of entering faulty input (basically got cudaError at location ). After this my cpp intregrated project refuses to run properly, basically just producing garbage, it seems no matter what i do. Cleaning, rebuilding, rebooting… I tried causing the same problem in my “purely cuda” project but with no bad luck there.

I started up my vista partition instead, where the program runs fine.

What to do? Reinstall drivers ? It’s of course very possible that the actual problem has nothing to do with the fact that i was integrating this into an existing c++ project.

Thanks for any help.

Jimmy

First confirm whether you have 32bit or 64bit drivers and SDK installed.

The linker is searching for cutil64D.lib because its specified as an additional dependency in Project Properties → Linker. Go there and change it to cutil32D.lib

First confirm whether you have 32bit or 64bit drivers and SDK installed.

The linker is searching for cutil64D.lib because its specified as an additional dependency in Project Properties → Linker. Go there and change it to cutil32D.lib

You can go about integrating CUDA into your existing VS projects by building a DLL or your CUDA code and linking it into your projects. That will sacrifice some performance but the code will become modular and reusable.

always wrap all your CUDA kernels so they can be easily called from your other project files.

We have created DLLs for CUVI Lib (CUDA for Vision and Imaging) which is a 3rd party CUDA accelerated Imaging library. I would recommend you download and take a look. You can easily call all the library’s functions which are actually wrappers of their respective kernels from any external C/C++ file.

You can go about integrating CUDA into your existing VS projects by building a DLL or your CUDA code and linking it into your projects. That will sacrifice some performance but the code will become modular and reusable.

always wrap all your CUDA kernels so they can be easily called from your other project files.

We have created DLLs for CUVI Lib (CUDA for Vision and Imaging) which is a 3rd party CUDA accelerated Imaging library. I would recommend you download and take a look. You can easily call all the library’s functions which are actually wrappers of their respective kernels from any external C/C++ file.