cudaMemcpy: unresolved external symbol

I'm trying to build a Cuda project under visual studio 2008, and the linker complains:

unresolved external symbol _cudaGetErrorString@4 referenced in function "void __cdecl checkError
unresolved external symbol _cudaMemcpy@16 referenced in function "void __cdecl regression
unresolved external symbol _cudaMalloc@8 referenced in function "void __cdecl regressionunresolved external symbol _cudaSetDevice@4 referenced in function "void __cdecl Init

So obviously it can't find those functions, however I believe these functions are in the cudart.lib file that is included in Properties -> Linker -> Input -> Additional Dependencies
If I change the filename, either in the include dialog or on the actual file, I get an error message about the file not being found, so normally it is indeed used.

Someone else has the problem here: http://forums.nvidia.com/index.php?showtopic=103796
but solves it by linking to cudart.lib.

Is there a way to scan libraries for these functions so I can find where they are defined?
On linux I can find a cudaMalloc in libcudart.so with:
find . | grep so$ | while read file; do echo $file; strings $file | grep Malloc; done
Is there a tool that can do something similar in windows?
LVL 6
letharionAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

evilrixSenior Software Engineer (Avast)Commented:
Was the original library built for VS2008? You must use the correct library version that matches your version of visual studio.

Also, do these functions need to be declared with extern "C"? In other words do they have C linkage and you are trying to link them using C++ linkage?
letharionAuthor Commented:
I was not aware that libraries were dependent on specific versions of VS, but since VS2008 is the only VS version that nvidias debugger supports, I can't imagine the library would not support VS2008.

You wouldn't happen to know of a way to identify this information in the files?

>Also, do these functions need to be declared with extern "C"? In other words do they have C linkage and you are trying to link them using C++ linkage?
I don't know, how can I tell? I have imported the "cuda.rules" build rules and activated them for my project, and I thought that would be enough.
The "cuda_runtime_api.h" header that comes with the cuda sdk defines cudaMalloc like this:
extern __host__ cudaError_t CUDARTAPI cudaMalloc(void **devPtr, size_t size);
letharionAuthor Commented:
I also found "libdump" (http://www.codeproject.com/KB/DLL/libdump.aspx) which I ran on cudart, and I find "cudaMalloc", and the other functions that the linker can't find.
OWASP: Threats Fundamentals

Learn the top ten threats that are present in modern web-application development and how to protect your business from them.

evilrixSenior Software Engineer (Avast)Commented:
>> I was not aware that libraries were dependent on specific versions of VS
For C++ each version of the VC compiler has it's own ABI (Application Binary Interface) and they are not necessarily compatible. If the library has a C ABI (and, thus C linkage) there is more of a chance two libraries built by two difference versions of VC will link.

http://en.wikipedia.org/wiki/Application_binary_interface

>> You wouldn't happen to know of a way to identify this information in the files?
Afraid not.
evilrixSenior Software Engineer (Avast)Commented:
>> which I ran on cudart, and I find "cudaMalloc", and the other functions that the linker can't find.

Hmmm, take a look at the following - it may just be related to C vs. C++ linkage since the tool seems to have found undecorated makes. It certainly won't hurt to rule it out.
http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html
letharionAuthor Commented:
Can I get more information about the build commands that run?
Perhaps nvidias nvcc compiler isn't actually used, which ofcourse would make the compiler fail with nvidias non-standard functions.
evilrixSenior Software Engineer (Avast)Commented:
>> http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html

I don't have 2008 to hand but in 2005 you can enable diagnostics in Visual Studio [Tools -> Options -> Projects & Solutions -> Build & Run {MSBuild verbosity}]

Not sure how useful that will be though.
letharionAuthor Commented:
Neither am I, but until someone else shows up, I'm running out of options here >_<
letharionAuthor Commented:
The setting is there in 2008 too, but it doesn't really help either. I still can't tell which compiler is being called, only that the linker is microsofts, but that much is to be expected.
letharionAuthor Commented:
I looked around more in the header file and found that all function declarations are wrapped in:

#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */

so I'm guessing that isn't the problem either.
letharionAuthor Commented:
Thanks evilrix :)
Jose ParrotGraphics ExpertCommented:
Hi,
About the __cplusplus, that is correct.
You are right on the linker to find your lib. If fact it is.
Sounds the problem is related to others lib files.
To check if your libraries are the correct ones, you can open them as binary or even ASCII and locate the called functions. Probably they are symbol _cudaGetErrorString@anything other than symbol _cudaGetErrorString@4. I use IrfanView (a graphics tool, but has the ability to open any file in HEX, ASCII or bin).
My guess is that the lib file requires others libraries and that others aren't in the directory you set the project properties.
Another guess: are the Op System, the libraries, the compiler/link settings pointing to the same platform? Say are all together targeting to 64 bits? or to 32? Take a look at that.
Jose

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
letharionAuthor Commented:
The functions don't seem to be named @ anything at all.
They all have this format
__imp_cudaMalloc cudaMalloc __imp_cudaFree cudaFree
and so on, except they are not separated by spaces but by something else (a null char?).

The OS is 64bit Win 7. The library comes with both 32 and 64 versions, and I've added only the 64-bit dir to the linkers include directories. There is definitely a chance I've made "bad" choices during solution/project creation, and the compiler/link settings are targeting 32.
Below is the build command, and there's a bunch of references to 32-bit windows libs, not sure if that's problem or not. There's a also /MACHINE:X86, which may also be a problem?

C:\Users\Claes\Documents\Visual Studio 2008\Projects\CudaRegression1\Debug\CudaRegression1.exe"
/INCREMENTAL /LIBPATH:"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v3.1\lib\x64" /LIBPATH:"C:\CUDA\lib64"
/LIBPATH:"C:\Users\Claes\Documents\Visual Studio 2008\Projects\CudaRegression1\CudaRegression1\xerces-c-3.1.1\Build\Win32\VC9\Debug"
/LIBPATH:"C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK\C\common\lib" /LIBPATH:"C:\CUDA\lib64"
/MANIFEST /MANIFESTFILE:"Debug\CudaRegression1.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG
/PDB:"C:\Users\Claes\Documents\Visual Studio 2008\Projects\CudaRegression1\Debug\CudaRegression1.pdb" /SUBSYSTEM:CONSOLE /DYNAMICBASE /NXCOMPAT /MACHINE:X86
cudart.lib xerces-c_3D.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
letharionAuthor Commented:
I took a look in Visual Studio on creating a new project, and there's no Win64 choice that I can see, only Win32, so in creating my project I have likely chosen Win32 -> Win32 Console Application.

Will that be a problem, is this "normal"?
I'm gonna try with a clean slate and create a very minimal project to see what happens.

To the best of my knowledge the cuda runtime depends on no other libraries, but I could of course be wrong. Linking successfully with this library on linux requires no other dependencies.
letharionAuthor Commented:
I tried removing the lib64 directory, and setting it to "just" lib instead, and now it links correctly.
Took a look at the content of this version of cudart, which does contain the @x function names. Not sure why the lib64 dir is there if I shouldn't use it?
Jose ParrotGraphics ExpertCommented:
Your analysis is pretty good, because you have reached the problem at its root. Actually 32 and 64 is a confusing land, because Windows 64 has a lot of 32 bit DLLs and even a strange WOW, which means Windows on Windows, where Microsoft Windows 64 bits emulates a Microsoft Windows 32... very "nice"... So, the ISV (independent software vendors), like Nvidia, are envolved in such confuse environment and each one has a different approach to circumvect that.
I think these improvements are still "new" and the tools aren't prepared at all to them.
About Visual Studio to use 64 libs, take a look at http://jenshuebel.wordpress.com/2009/02/12/visual-c-2008-express-edition-and-64-bit-targets/
and
http://stackoverflow.com/questions/2970493/cuda-linking-error-visual-express-2008-nvcc-fatal-due-to-null-configuration
Jose
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Game Programming

From novice to tech pro — start learning today.