Cuda and MFC

Hi Cuda Fans,

I am new to Cuda, and am trying to get Cuda functionality inside an MFC application in VS2005. I first tried just adding a .cu file to an existing MFC dialog app, then set the build properties using the build rules in one of the examples. The .cu file seems to compile ok, but I get about 25 link errors related to multiply defined symbols (error LNK2005: _malloc already defined in LIBCMT.lib(malloc.obj) libcmtd.lib). I do have the $(CUDA_LIB_PATH) value set in the linker options along with the cudart.lib dependency.

Anyone have a clue what this means? Is there some fundamental incompatibility between MFC and Cuda? The same code compiles, links and runs fine in a console application.

To get around this, I tried using Kaiyong Zhao’s VS Wizard 2.0 (Thanks for making that available!) to add a dll project to an existing MFC project. I then call the dll from the MFC code, this seems to work pretty well. I have two questions about this though:

  1. Using the sample.cu that is generated by the wizard, I get a compile error in the next to last line:

CUT_EXIT(argc, argv);

since argc and argv aren’t defined in the code. If I comment out that line the code compiles, links, and runs fine.

  1. If I run my MFC app in debug or emudebug mode and execute the .cu sample code twice, it will throw an error on the second execution. It doesn’t do this in release or emurelease mode. The error seems thread related

Unhandled exception at 0x7835b701 (mfc80ud.dll) in CudaProj.exe: 0xC0000005: Access violation reading location 0xf78d86d8.

The error is in the file afxtls.cpp at the last line copied here:

/ special version of CThreadSlotData::GetData that only works with
// thread local storage (and not process local storage)
// this version is inlined and simplified for speed
inline void* CThreadSlotData::GetThreadValue(int nSlot)
{
EnterCriticalSection(&m_sect);
ASSERT(nSlot != 0 && nSlot < m_nMax);
ASSERT(m_pSlotData != NULL);
ASSERT(m_pSlotData[nSlot].dwFlags & SLOT_USED); //error on this line
********************************************

Is this because a thread isn’t exiting properly because I commented out the CUT_EXIT function? If so, how do I get that function to properly compile? I have looked in the 2.1 programming guide and 2.1 reference manual but I don’t see this function or some of the others in the sample. Where are these documented?

Any help appreciated!

Kent

I found the answer to part of my question, i.e. the source of the CUT_ utility functions in cutil.h and cutil.cpp.

Still wondering about the basic compatibility of cuda and MFC, as well as the reason for the errors being asserted.

Kent

The reason linking fails is because MFC projects are built (by default) with /MD runtime library (multi-threaded DLL) while CUDA is built with /MT (statically linked multi-threading). This confuses the linker, it tries to resolve external symbols by looking into both MSVCRT.lib and LIBCMT.lib and you get redefinitions.

More about runtime libraries here http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.80).aspx
“All modules passed to a given invocation of the linker must have been compiled with the same run-time library compiler option”

One way to fix this is, as you noticed, to precompile your CUDA code into some sort of library (either static or dynamic). Another would be to wait until CUDA 2.2 is released, NVIDIA will probably support an /MD version which should work with /MD projects out of the box.

By the way, what was the answer to the other part of your question? I’ve stumbled upon similar things recently.

I also have this kind of problem : I have a DLL using CUDA and a MFC application. When compiling in Debug mode everything works fine, but it crashes when the DLL is compiled in Emudebug (error in GetThreadValue function when calling the first cuda function) mode although I checked the compiler options are both /MTd for visual and cuda compilers. (I am running cuda2.0)